add location support
This commit adds basic support for adding, deleting, ... locations. This needed a bit of rework for the ResourceName, as it was kind of stupid to have different implementations server internally and in the lib. There is still some need for cleanup, but it works basically.
This commit is contained in:
parent
bc8e1353af
commit
bc84bc4a28
|
@ -0,0 +1,130 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/gibheer/pkiadm"
|
||||
"github.com/pkg/errors"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
func createLocation(args []string, client *pkiadm.Client) error {
|
||||
fs := flag.NewFlagSet("pkiadm create-location", flag.ExitOnError)
|
||||
fs.Usage = func() {
|
||||
fmt.Printf("Usage of %s:\n", "pkiadm create-location")
|
||||
fmt.Println(`
|
||||
Create a new file containing the referenced resources, which will be converted to pem format.
|
||||
The pre command will be run before writing the file and the post command will be run after the file is written.
|
||||
Resource names are defined as "type/id", where type is one of private, public, csr or cert.
|
||||
`)
|
||||
fs.PrintDefaults()
|
||||
}
|
||||
loc := pkiadm.Location{}
|
||||
fs.StringVar(&loc.ID, "id", "", "the ID of the location to modify")
|
||||
if err := parseLocationArgs(&loc, fs, args); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := client.CreateLocation(loc); err != nil {
|
||||
return errors.Wrap(err, "could not create new location")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setLocation(args []string, client *pkiadm.Client) error {
|
||||
fs := flag.NewFlagSet("pkiadm set-location", flag.ExitOnError)
|
||||
loc := pkiadm.Location{}
|
||||
fs.StringVar(&loc.ID, "id", "", "the ID of the location to modify")
|
||||
if err := parseLocationArgs(&loc, fs, args); err != nil {
|
||||
return err
|
||||
}
|
||||
fieldList := []string{}
|
||||
for _, field := range []string{"path", "pre-cmd", "post-cmd", "resources"} {
|
||||
flag := fs.Lookup(field)
|
||||
if flag.Changed {
|
||||
fieldList = append(fieldList, field)
|
||||
}
|
||||
}
|
||||
if err := client.SetLocation(loc, fieldList); err != nil {
|
||||
return errors.Wrap(err, "could not change location")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseLocationArgs(loc *pkiadm.Location, fs *flag.FlagSet, args []string) error {
|
||||
resources := []string{}
|
||||
fs.StringVar(&loc.Path, "path", "", "the filename of the location where replaces will be placed")
|
||||
fs.StringSliceVar(&resources, "resources", []string{}, "the resource description to add to the location")
|
||||
fs.StringVar(&loc.PreCommand, "pre-cmd", "", "the pre command to run before writing the file")
|
||||
fs.StringVar(&loc.PostCommand, "post-cmd", "", "the oste command to run after writing the file")
|
||||
fs.Parse(args)
|
||||
|
||||
for _, res := range resources {
|
||||
parts := strings.Split(res, "/")
|
||||
if len(parts) != 2 {
|
||||
return errors.Errorf("could not parse resource: '%s'\n", res)
|
||||
}
|
||||
resType, err := pkiadm.StringToResourceType(parts[0])
|
||||
if err != nil {
|
||||
return errors.Errorf("invalid resource type '%s'", parts[0])
|
||||
}
|
||||
loc.Dependencies = append(loc.Dependencies, pkiadm.ResourceName{parts[1], resType})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func deleteLocation(args []string, client *pkiadm.Client) error {
|
||||
fs := flag.NewFlagSet("pkiadm delete-location", flag.ExitOnError)
|
||||
id := fs.String("id", "", "the id of the location to delete")
|
||||
fs.Parse(args)
|
||||
|
||||
if err := client.DeleteLocation(*id); err != nil {
|
||||
return errors.Wrap(err, "could not remove location")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func showLocation(args []string, client *pkiadm.Client) error {
|
||||
fs := flag.NewFlagSet("pkiadm show-location", flag.ExitOnError)
|
||||
id := fs.String("id", "", "the id to view in detail")
|
||||
fs.Parse(args)
|
||||
|
||||
loc, err := client.ShowLocation(*id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
deps := []string{}
|
||||
for _, dep := range loc.Dependencies {
|
||||
deps = append(deps, dep.String())
|
||||
}
|
||||
out := tabwriter.NewWriter(os.Stdout, 2, 2, 1, ' ', tabwriter.AlignRight)
|
||||
fmt.Fprintf(out, "ID:\t%s\t\n", loc.ID)
|
||||
fmt.Fprintf(out, "path:\t%s\t\n", loc.Path)
|
||||
fmt.Fprintf(out, "pre-cmd:\t%s\t\n", ReplaceEmpty(loc.PreCommand))
|
||||
fmt.Fprintf(out, "post-cmd:\t%s\t\n", ReplaceEmpty(loc.PostCommand))
|
||||
fmt.Fprintf(out, "deps:\t%s\t\n", strings.Join(deps, ", "))
|
||||
out.Flush()
|
||||
return nil
|
||||
}
|
||||
|
||||
func listLocation(args []string, client *pkiadm.Client) error {
|
||||
fs := flag.NewFlagSet("pkiadm list-location", flag.ExitOnError)
|
||||
fs.Parse(args)
|
||||
|
||||
locs, err := client.ListLocation()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(locs) == 0 {
|
||||
return nil
|
||||
}
|
||||
out := tabwriter.NewWriter(os.Stdout, 2, 2, 1, ' ', tabwriter.AlignRight)
|
||||
fmt.Fprintf(out, "%s\t%s\t%s\t\n", "id", "path", "deps")
|
||||
for _, loc := range locs {
|
||||
fmt.Fprintf(out, "%s\t%s\t%d\t\n", loc.ID, loc.Path, len(loc.Dependencies))
|
||||
}
|
||||
out.Flush()
|
||||
return nil
|
||||
}
|
|
@ -50,6 +50,16 @@ func main() {
|
|||
err = setPrivateKey(args, client)
|
||||
case `show-private`:
|
||||
err = showPrivateKey(args, client)
|
||||
case `create-location`:
|
||||
err = createLocation(args, client)
|
||||
case `delete-location`:
|
||||
err = deleteLocation(args, client)
|
||||
case `list-location`:
|
||||
err = listLocation(args, client)
|
||||
case `set-location`:
|
||||
err = setLocation(args, client)
|
||||
case `show-location`:
|
||||
err = showLocation(args, client)
|
||||
default:
|
||||
fmt.Printf("unknown subcommand '%s'\n", cmd)
|
||||
printCommands()
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/gibheer/pki"
|
||||
"github.com/gibheer/pkiadm"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -14,16 +15,16 @@ type (
|
|||
IsCA bool
|
||||
Duration time.Duration
|
||||
|
||||
PrivateKey ResourceName
|
||||
Serial ResourceName
|
||||
CSR ResourceName
|
||||
CA ResourceName
|
||||
PrivateKey pkiadm.ResourceName
|
||||
Serial pkiadm.ResourceName
|
||||
CSR pkiadm.ResourceName
|
||||
CA pkiadm.ResourceName
|
||||
|
||||
Data []byte
|
||||
}
|
||||
)
|
||||
|
||||
func NewCertificate(id string, privateKey, serial, csr, ca ResourceName, isCA bool, duration time.Duration) (*Certificate, error) {
|
||||
func NewCertificate(id string, privateKey, serial, csr, ca pkiadm.ResourceName, isCA bool, duration time.Duration) (*Certificate, error) {
|
||||
return &Certificate{
|
||||
ID: id,
|
||||
PrivateKey: privateKey,
|
||||
|
@ -36,8 +37,8 @@ func NewCertificate(id string, privateKey, serial, csr, ca ResourceName, isCA bo
|
|||
}
|
||||
|
||||
// Return the unique ResourceName
|
||||
func (c *Certificate) Name() ResourceName {
|
||||
return ResourceName{c.ID, RTCertificate}
|
||||
func (c *Certificate) Name() pkiadm.ResourceName {
|
||||
return pkiadm.ResourceName{c.ID, pkiadm.RTCertificate}
|
||||
}
|
||||
|
||||
// AddDependency registers a depending resource to be retuened by Dependencies()
|
||||
|
@ -116,8 +117,8 @@ func (c *Certificate) Pem() ([]byte, error) { return c.Data, nil }
|
|||
func (c *Certificate) Checksum() []byte { return Hash(c.Data) }
|
||||
|
||||
// DependsOn must return the resource names it is depending on.
|
||||
func (c *Certificate) DependsOn() []ResourceName {
|
||||
res := []ResourceName{
|
||||
func (c *Certificate) DependsOn() []pkiadm.ResourceName {
|
||||
res := []pkiadm.ResourceName{
|
||||
c.PrivateKey,
|
||||
c.Serial,
|
||||
c.CSR,
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"net"
|
||||
|
||||
"github.com/gibheer/pki"
|
||||
"github.com/gibheer/pkiadm"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -19,8 +20,8 @@ type (
|
|||
IPAddresses []net.IP
|
||||
|
||||
// PrivateKey is needed to sign the certificate sign request.
|
||||
PrivateKey ResourceName
|
||||
Subject ResourceName
|
||||
PrivateKey pkiadm.ResourceName
|
||||
Subject pkiadm.ResourceName
|
||||
|
||||
// Data contains the pem representation of the CSR.
|
||||
Data []byte
|
||||
|
@ -28,7 +29,7 @@ type (
|
|||
)
|
||||
|
||||
// NewCSR creates a new CSR.
|
||||
func NewCSR(id string, pk, subject ResourceName, commonName string, dnsNames []string,
|
||||
func NewCSR(id string, pk, subject pkiadm.ResourceName, commonName string, dnsNames []string,
|
||||
emailAddresses []string, iPAddresses []net.IP) (*CSR, error) {
|
||||
return &CSR{
|
||||
ID: id,
|
||||
|
@ -42,8 +43,8 @@ func NewCSR(id string, pk, subject ResourceName, commonName string, dnsNames []s
|
|||
}
|
||||
|
||||
// Return the unique ResourceName
|
||||
func (c *CSR) Name() ResourceName {
|
||||
return ResourceName{c.ID, RTCSR}
|
||||
func (c *CSR) Name() pkiadm.ResourceName {
|
||||
return pkiadm.ResourceName{c.ID, pkiadm.RTCSR}
|
||||
}
|
||||
|
||||
// AddDependency registers a depending resource to be retuened by Dependencies()
|
||||
|
@ -88,8 +89,8 @@ func (c *CSR) Pem() ([]byte, error) { return c.Data, nil }
|
|||
func (c *CSR) Checksum() []byte { return Hash(c.Data) }
|
||||
|
||||
// DependsOn must return the resource names it is depending on.
|
||||
func (c *CSR) DependsOn() []ResourceName {
|
||||
return []ResourceName{c.PrivateKey}
|
||||
func (c *CSR) DependsOn() []pkiadm.ResourceName {
|
||||
return []pkiadm.ResourceName{c.PrivateKey}
|
||||
}
|
||||
|
||||
func (c *CSR) GetCSR() (*pki.CertificateRequest, error) {
|
||||
|
|
|
@ -2,6 +2,11 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/gibheer/pkiadm"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -12,12 +17,15 @@ type (
|
|||
Location struct {
|
||||
ID string
|
||||
|
||||
PreCommand string
|
||||
PostCommand string
|
||||
|
||||
Path string
|
||||
Dependencies []ResourceName
|
||||
Dependencies []pkiadm.ResourceName
|
||||
}
|
||||
)
|
||||
|
||||
func NewLocation(id, path string, res []ResourceName) (*Location, error) {
|
||||
func NewLocation(id, path, preCom, postCom string, res []pkiadm.ResourceName) (*Location, error) {
|
||||
if id == "" {
|
||||
return nil, ENoIDGiven
|
||||
}
|
||||
|
@ -32,8 +40,8 @@ func NewLocation(id, path string, res []ResourceName) (*Location, error) {
|
|||
return l, nil
|
||||
}
|
||||
|
||||
func (l *Location) Name() ResourceName {
|
||||
return ResourceName{l.ID, RTLocation}
|
||||
func (l *Location) Name() pkiadm.ResourceName {
|
||||
return pkiadm.ResourceName{l.ID, pkiadm.RTLocation}
|
||||
}
|
||||
|
||||
// Refresh writes all resources into the single file.
|
||||
|
@ -50,12 +58,25 @@ func (l *Location) Refresh(lookup *Storage) error {
|
|||
}
|
||||
raw = append(raw, output...)
|
||||
}
|
||||
// TODO write to file
|
||||
fmt.Printf("found %d characters for file: %s\n", len(raw), l.Path)
|
||||
if l.PreCommand != "" {
|
||||
cmd := exec.Command(l.PreCommand, l.Path)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := ioutil.WriteFile(l.Path, raw, 0600); err != nil {
|
||||
return err
|
||||
}
|
||||
if l.PostCommand != "" {
|
||||
cmd := exec.Command(l.PostCommand, l.Path)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (l *Location) DependsOn() []ResourceName { return l.Dependencies }
|
||||
func (l *Location) DependsOn() []pkiadm.ResourceName { return l.Dependencies }
|
||||
|
||||
// Pem is not used by location, as it does not contain any data.
|
||||
func (l *Location) Pem() ([]byte, error) { return []byte{}, nil }
|
||||
|
@ -63,9 +84,119 @@ func (l *Location) Pem() ([]byte, error) { return []byte{}, nil }
|
|||
// Checksum is not used by Location, as it does not contain any data.
|
||||
func (l *Location) Checksum() []byte { return []byte{} }
|
||||
|
||||
//func (l *Location) MarshalJSON() ([]byte, error) {
|
||||
// return json.Marshal(*l)
|
||||
//}
|
||||
//func (l *Location) UnmarshalJSON(raw []byte) error {
|
||||
// return json.Unmarshal(raw, l)
|
||||
//}
|
||||
func (s *Server) CreateLocation(inLoc pkiadm.Location, res *pkiadm.Result) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
deps := []pkiadm.ResourceName{}
|
||||
for _, dep := range inLoc.Dependencies {
|
||||
deps = append(deps, pkiadm.ResourceName{ID: dep.ID, Type: dep.Type})
|
||||
}
|
||||
loc, err := NewLocation(inLoc.ID, inLoc.Path, inLoc.PreCommand, inLoc.PostCommand, deps)
|
||||
if err != nil {
|
||||
res.SetError(err, "Could not create location '%s'", inLoc.ID)
|
||||
return nil
|
||||
}
|
||||
if err := s.storage.AddLocation(loc); err != nil {
|
||||
res.SetError(err, "Could not add location '%s'", inLoc.ID)
|
||||
return nil
|
||||
}
|
||||
return s.store(res)
|
||||
}
|
||||
|
||||
func (s *Server) SetLocation(changeset pkiadm.LocationChange, res *pkiadm.Result) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
changed := changeset.Location
|
||||
locName := pkiadm.ResourceName{changed.ID, pkiadm.RTLocation}
|
||||
loc, err := s.storage.GetLocation(locName)
|
||||
if err != nil {
|
||||
res.SetError(err, "could not find location '%s'", changeset.Location.ID)
|
||||
return nil
|
||||
}
|
||||
for _, field := range changeset.FieldList {
|
||||
switch field {
|
||||
case "path":
|
||||
// TODO remove old file?
|
||||
loc.Path = changed.Path
|
||||
case "pre-cmd":
|
||||
loc.PreCommand = changed.PreCommand
|
||||
case "post-cmd":
|
||||
loc.PostCommand = changed.PostCommand
|
||||
case "resources":
|
||||
loc.Dependencies = changed.Dependencies
|
||||
default:
|
||||
res.SetError(fmt.Errorf("unknown field"), "unknown field '%s'", field)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if err := s.storage.Update(locName); err != nil {
|
||||
res.SetError(err, "Could not update location '%s'", loc.ID)
|
||||
return nil
|
||||
}
|
||||
return s.store(res)
|
||||
}
|
||||
|
||||
func (s *Server) DeleteLocation(inLoc pkiadm.Location, res *pkiadm.Result) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
loc, err := s.storage.GetLocation(pkiadm.ResourceName{inLoc.ID, pkiadm.RTLocation})
|
||||
if err != nil {
|
||||
res.SetError(err, "could not find location '%s'", inLoc.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := os.Remove(loc.Path); err != nil {
|
||||
res.SetError(err, "Could not remove file '%s' for location '%s'", loc.Path, loc.ID)
|
||||
return nil
|
||||
}
|
||||
if err := s.storage.Remove(loc); err != nil {
|
||||
res.SetError(err, "Could not remove location '%s'", loc.ID)
|
||||
return nil
|
||||
}
|
||||
if loc.PostCommand != "" {
|
||||
cmd := exec.Command(loc.PostCommand, loc.Path)
|
||||
if err := cmd.Run(); err != nil {
|
||||
res.SetError(err, "Could not run post command after deleting '%s'", loc.ID)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return s.store(res)
|
||||
}
|
||||
|
||||
func (s *Server) ShowLocation(inLoc pkiadm.PrivateKey, res *pkiadm.ResultLocations) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
loc, err := s.storage.GetLocation(pkiadm.ResourceName{inLoc.ID, pkiadm.RTLocation})
|
||||
if err != nil {
|
||||
res.Result.SetError(err, "Could not find location '%s'", inLoc.ID)
|
||||
return nil
|
||||
}
|
||||
res.Locations = []pkiadm.Location{pkiadm.Location{
|
||||
ID: loc.ID,
|
||||
Path: loc.Path,
|
||||
PreCommand: loc.PreCommand,
|
||||
PostCommand: loc.PostCommand,
|
||||
Dependencies: loc.Dependencies,
|
||||
}}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) ListLocation(filter pkiadm.Filter, res *pkiadm.ResultLocations) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
for _, loc := range s.storage.Locations {
|
||||
res.Locations = append(res.Locations, pkiadm.Location{
|
||||
ID: loc.ID,
|
||||
Path: loc.Path,
|
||||
PreCommand: loc.PreCommand,
|
||||
PostCommand: loc.PostCommand,
|
||||
Dependencies: loc.Dependencies,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -10,15 +10,15 @@ import (
|
|||
"github.com/gibheer/pkiadm"
|
||||
)
|
||||
|
||||
const (
|
||||
RTPrivateKey ResourceType = iota
|
||||
RTPublicKey
|
||||
RTCSR
|
||||
RTCertificate
|
||||
RTLocation
|
||||
RTSerial
|
||||
RTSubject
|
||||
)
|
||||
//const (
|
||||
// RTPrivateKey ResourceType = iota
|
||||
// RTPublicKey
|
||||
// RTCSR
|
||||
// RTCertificate
|
||||
// RTLocation
|
||||
// RTSerial
|
||||
// RTSubject
|
||||
//)
|
||||
|
||||
const (
|
||||
ENoIDGiven = Error("no ID given")
|
||||
|
@ -32,7 +32,7 @@ const (
|
|||
type (
|
||||
Resource interface {
|
||||
// Return the unique ResourceName
|
||||
Name() ResourceName
|
||||
Name() pkiadm.ResourceName
|
||||
// AddDependency registers a depending resource to be retuened by Dependencies()
|
||||
// Refresh must trigger a rebuild of the resource.
|
||||
Refresh(*Storage) error
|
||||
|
@ -40,21 +40,22 @@ type (
|
|||
Pem() ([]byte, error)
|
||||
Checksum() []byte
|
||||
// DependsOn must return the resource names it is depending on.
|
||||
DependsOn() []ResourceName
|
||||
DependsOn() []pkiadm.ResourceName
|
||||
}
|
||||
|
||||
ResourceName struct {
|
||||
ID string
|
||||
Type ResourceType
|
||||
}
|
||||
// ResourceName struct {
|
||||
// ID string
|
||||
// Type ResourceType
|
||||
// }
|
||||
|
||||
ResourceType uint
|
||||
|
||||
Error string
|
||||
)
|
||||
|
||||
func (e Error) Error() string { return string(e) }
|
||||
func (r ResourceName) String() string { return r.Type.String() + "/" + r.ID }
|
||||
func (e Error) Error() string { return string(e) }
|
||||
|
||||
//func (r ResourceName) String() string { return r.Type.String() + "/" + r.ID }
|
||||
|
||||
func main() {
|
||||
os.Exit(_main())
|
||||
|
|
|
@ -39,8 +39,8 @@ func NewPrivateKey(id string, pkType pkiadm.PrivateKeyType, bits uint) (*Private
|
|||
return &pk, nil
|
||||
}
|
||||
|
||||
func (p *PrivateKey) Name() ResourceName {
|
||||
return ResourceName{p.ID, RTPrivateKey}
|
||||
func (p *PrivateKey) Name() pkiadm.ResourceName {
|
||||
return pkiadm.ResourceName{p.ID, pkiadm.RTPrivateKey}
|
||||
}
|
||||
|
||||
func (p *PrivateKey) Checksum() []byte {
|
||||
|
@ -51,8 +51,8 @@ func (p *PrivateKey) Pem() ([]byte, error) {
|
|||
return p.Key, nil
|
||||
}
|
||||
|
||||
func (p *PrivateKey) DependsOn() []ResourceName {
|
||||
return []ResourceName{}
|
||||
func (p *PrivateKey) DependsOn() []pkiadm.ResourceName {
|
||||
return []pkiadm.ResourceName{}
|
||||
}
|
||||
|
||||
func (p *PrivateKey) Refresh(_ *Storage) error {
|
||||
|
@ -149,13 +149,13 @@ func (s *Server) CreatePrivateKey(inPk pkiadm.PrivateKey, res *pkiadm.Result) er
|
|||
res.SetError(err, "Could not add private key '%s'", inPk.ID)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
return s.store(res)
|
||||
}
|
||||
func (s *Server) SetPrivateKey(changeset pkiadm.PrivateKeyChange, res *pkiadm.Result) error {
|
||||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
pk, err := s.storage.GetPrivateKey(ResourceName{ID: changeset.PrivateKey.ID, Type: RTPrivateKey})
|
||||
pk, err := s.storage.GetPrivateKey(pkiadm.ResourceName{ID: changeset.PrivateKey.ID, Type: pkiadm.RTPrivateKey})
|
||||
if err != nil {
|
||||
res.SetError(err, "Could not find private key '%s'", changeset.PrivateKey.ID)
|
||||
return nil
|
||||
|
@ -172,7 +172,7 @@ func (s *Server) SetPrivateKey(changeset pkiadm.PrivateKeyChange, res *pkiadm.Re
|
|||
return nil
|
||||
}
|
||||
}
|
||||
if err := s.storage.Update(ResourceName{ID: pk.ID, Type: RTPrivateKey}); err != nil {
|
||||
if err := s.storage.Update(pkiadm.ResourceName{ID: pk.ID, Type: pkiadm.RTPrivateKey}); err != nil {
|
||||
res.SetError(err, "Could not update private key '%s'", changeset.PrivateKey.ID)
|
||||
return nil
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ func (s *Server) DeletePrivateKey(inPk pkiadm.ResourceName, res *pkiadm.Result)
|
|||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
pk, err := s.storage.GetPrivateKey(ResourceName{ID: inPk.ID, Type: RTPrivateKey})
|
||||
pk, err := s.storage.GetPrivateKey(pkiadm.ResourceName{ID: inPk.ID, Type: pkiadm.RTPrivateKey})
|
||||
if err != nil {
|
||||
res.SetError(err, "Could not find private key '%s'", inPk.ID)
|
||||
return nil
|
||||
|
@ -198,7 +198,7 @@ func (s *Server) ShowPrivateKey(inPk pkiadm.ResourceName, res *pkiadm.ResultPriv
|
|||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
pk, err := s.storage.GetPrivateKey(ResourceName{ID: inPk.ID, Type: RTPrivateKey})
|
||||
pk, err := s.storage.GetPrivateKey(pkiadm.ResourceName{ID: inPk.ID, Type: pkiadm.RTPrivateKey})
|
||||
if err != nil {
|
||||
res.Result.SetError(err, "Could not find private key '%s'", inPk.ID)
|
||||
return nil
|
||||
|
|
|
@ -2,6 +2,8 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/pem"
|
||||
|
||||
"github.com/gibheer/pkiadm"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -14,7 +16,7 @@ type (
|
|||
PublicKey struct {
|
||||
ID string
|
||||
|
||||
PrivateKey ResourceName
|
||||
PrivateKey pkiadm.ResourceName
|
||||
Type PublicKeyType // mark the type of the public key
|
||||
Key []byte
|
||||
}
|
||||
|
@ -22,7 +24,7 @@ type (
|
|||
PublicKeyType uint
|
||||
)
|
||||
|
||||
func NewPublicKey(id string, pk ResourceName) (*PublicKey, error) {
|
||||
func NewPublicKey(id string, pk pkiadm.ResourceName) (*PublicKey, error) {
|
||||
pub := PublicKey{
|
||||
ID: id,
|
||||
PrivateKey: pk,
|
||||
|
@ -30,8 +32,8 @@ func NewPublicKey(id string, pk ResourceName) (*PublicKey, error) {
|
|||
return &pub, nil
|
||||
}
|
||||
|
||||
func (p *PublicKey) Name() ResourceName {
|
||||
return ResourceName{p.ID, RTPublicKey}
|
||||
func (p *PublicKey) Name() pkiadm.ResourceName {
|
||||
return pkiadm.ResourceName{p.ID, pkiadm.RTPublicKey}
|
||||
}
|
||||
|
||||
func (p *PublicKey) Refresh(lookup *Storage) error {
|
||||
|
@ -57,8 +59,8 @@ func (p *PublicKey) Refresh(lookup *Storage) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *PublicKey) DependsOn() []ResourceName {
|
||||
return []ResourceName{p.PrivateKey}
|
||||
func (p *PublicKey) DependsOn() []pkiadm.ResourceName {
|
||||
return []pkiadm.ResourceName{p.PrivateKey}
|
||||
}
|
||||
|
||||
func (p *PublicKey) Pem() ([]byte, error) {
|
||||
|
|
|
@ -3,6 +3,8 @@ package main
|
|||
import (
|
||||
"crypto/rand"
|
||||
"math/big"
|
||||
|
||||
"github.com/gibheer/pkiadm"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -28,7 +30,7 @@ func NewSerial(id string, min, max int64) (*Serial, error) {
|
|||
}
|
||||
|
||||
// Return the unique ResourceName
|
||||
func (s *Serial) Name() ResourceName { return ResourceName{s.ID, RTSerial} }
|
||||
func (s *Serial) Name() pkiadm.ResourceName { return pkiadm.ResourceName{s.ID, pkiadm.RTSerial} }
|
||||
|
||||
// AddDependency registers a depending resource to be retuened by Dependencies()
|
||||
// Refresh must trigger a rebuild of the resource.
|
||||
|
@ -43,7 +45,7 @@ func (s *Serial) Pem() ([]byte, error) { return []byte{}, nil }
|
|||
func (s *Serial) Checksum() []byte { return []byte{} }
|
||||
|
||||
// DependsOn must return the resource names it is depending on.
|
||||
func (s *Serial) DependsOn() []ResourceName { return []ResourceName{} }
|
||||
func (s *Serial) DependsOn() []pkiadm.ResourceName { return []pkiadm.ResourceName{} }
|
||||
|
||||
// Generate generates a new serial number and stores it to avoid double
|
||||
// assigning.
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/gibheer/pkiadm"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
@ -193,24 +194,24 @@ func (s *Storage) AddLocation(l *Location) error {
|
|||
}
|
||||
|
||||
// Get figures out the resource to the ResourceName if available.
|
||||
func (s *Storage) Get(r ResourceName) (Resource, error) {
|
||||
func (s *Storage) Get(r pkiadm.ResourceName) (Resource, error) {
|
||||
if r.ID == "" {
|
||||
return nil, ENoIDGiven
|
||||
}
|
||||
switch r.Type {
|
||||
case RTSerial:
|
||||
case pkiadm.RTSerial:
|
||||
return s.GetSerial(r)
|
||||
case RTSubject:
|
||||
case pkiadm.RTSubject:
|
||||
return s.GetSubject(r)
|
||||
case RTPrivateKey:
|
||||
case pkiadm.RTPrivateKey:
|
||||
return s.GetPrivateKey(r)
|
||||
case RTPublicKey:
|
||||
case pkiadm.RTPublicKey:
|
||||
return s.GetPublicKey(r)
|
||||
case RTCSR:
|
||||
case pkiadm.RTCSR:
|
||||
return s.GetCSR(r)
|
||||
case RTCertificate:
|
||||
case pkiadm.RTCertificate:
|
||||
return s.GetCertificate(r)
|
||||
case RTLocation:
|
||||
case pkiadm.RTLocation:
|
||||
return s.GetLocation(r)
|
||||
default:
|
||||
return nil, EUnknownType
|
||||
|
@ -218,7 +219,7 @@ func (s *Storage) Get(r ResourceName) (Resource, error) {
|
|||
}
|
||||
|
||||
// GetSerial returns the Serial matching the ResourceName.
|
||||
func (s *Storage) GetSerial(r ResourceName) (*Serial, error) {
|
||||
func (s *Storage) GetSerial(r pkiadm.ResourceName) (*Serial, error) {
|
||||
if se, found := s.Serials[r.ID]; found {
|
||||
return se, nil
|
||||
}
|
||||
|
@ -226,7 +227,7 @@ func (s *Storage) GetSerial(r ResourceName) (*Serial, error) {
|
|||
}
|
||||
|
||||
// GetSubject returns the Subject matching the ResourceName.
|
||||
func (s *Storage) GetSubject(r ResourceName) (*Subject, error) {
|
||||
func (s *Storage) GetSubject(r pkiadm.ResourceName) (*Subject, error) {
|
||||
if se, found := s.Subjects[r.ID]; found {
|
||||
return se, nil
|
||||
}
|
||||
|
@ -234,7 +235,7 @@ func (s *Storage) GetSubject(r ResourceName) (*Subject, error) {
|
|||
}
|
||||
|
||||
// GetPrivateKey returns the PrivateKey to the ResourceName.
|
||||
func (s *Storage) GetPrivateKey(r ResourceName) (*PrivateKey, error) {
|
||||
func (s *Storage) GetPrivateKey(r pkiadm.ResourceName) (*PrivateKey, error) {
|
||||
if pk, found := s.PrivateKeys[r.ID]; found {
|
||||
return pk, nil
|
||||
}
|
||||
|
@ -242,7 +243,7 @@ func (s *Storage) GetPrivateKey(r ResourceName) (*PrivateKey, error) {
|
|||
}
|
||||
|
||||
// GetPublicKey returns the PublicKey to the ResourceName.
|
||||
func (s *Storage) GetPublicKey(r ResourceName) (*PublicKey, error) {
|
||||
func (s *Storage) GetPublicKey(r pkiadm.ResourceName) (*PublicKey, error) {
|
||||
if res, found := s.PublicKeys[r.ID]; found {
|
||||
return res, nil
|
||||
}
|
||||
|
@ -250,7 +251,7 @@ func (s *Storage) GetPublicKey(r ResourceName) (*PublicKey, error) {
|
|||
}
|
||||
|
||||
// GetCSR returns the CSR to the CSR.
|
||||
func (s *Storage) GetCSR(r ResourceName) (*CSR, error) {
|
||||
func (s *Storage) GetCSR(r pkiadm.ResourceName) (*CSR, error) {
|
||||
if res, found := s.CSRs[r.ID]; found {
|
||||
return res, nil
|
||||
}
|
||||
|
@ -258,7 +259,7 @@ func (s *Storage) GetCSR(r ResourceName) (*CSR, error) {
|
|||
}
|
||||
|
||||
// GetCertificate returns the Certificate matching the ResourceName.
|
||||
func (s *Storage) GetCertificate(r ResourceName) (*Certificate, error) {
|
||||
func (s *Storage) GetCertificate(r pkiadm.ResourceName) (*Certificate, error) {
|
||||
if res, found := s.Certificates[r.ID]; found {
|
||||
return res, nil
|
||||
}
|
||||
|
@ -266,7 +267,7 @@ func (s *Storage) GetCertificate(r ResourceName) (*Certificate, error) {
|
|||
}
|
||||
|
||||
// GetLocation returns the Location matching the ResourceName.
|
||||
func (s *Storage) GetLocation(r ResourceName) (*Location, error) {
|
||||
func (s *Storage) GetLocation(r pkiadm.ResourceName) (*Location, error) {
|
||||
if res, found := s.Locations[r.ID]; found {
|
||||
return res, nil
|
||||
}
|
||||
|
@ -277,19 +278,19 @@ func (s *Storage) GetLocation(r ResourceName) (*Location, error) {
|
|||
func (s *Storage) Remove(r Resource) error {
|
||||
// TODO implement unable to remove when having dependencies
|
||||
switch r.Name().Type {
|
||||
case RTSerial:
|
||||
case pkiadm.RTSerial:
|
||||
delete(s.Serials, r.Name().ID)
|
||||
case RTSubject:
|
||||
case pkiadm.RTSubject:
|
||||
delete(s.Subjects, r.Name().ID)
|
||||
case RTPrivateKey:
|
||||
case pkiadm.RTPrivateKey:
|
||||
delete(s.PrivateKeys, r.Name().ID)
|
||||
case RTPublicKey:
|
||||
case pkiadm.RTPublicKey:
|
||||
delete(s.PublicKeys, r.Name().ID)
|
||||
case RTCSR:
|
||||
case pkiadm.RTCSR:
|
||||
delete(s.CSRs, r.Name().ID)
|
||||
case RTCertificate:
|
||||
case pkiadm.RTCertificate:
|
||||
delete(s.Certificates, r.Name().ID)
|
||||
case RTLocation:
|
||||
case pkiadm.RTLocation:
|
||||
delete(s.Locations, r.Name().ID)
|
||||
default:
|
||||
return EUnknownType
|
||||
|
@ -303,7 +304,7 @@ func (s *Storage) Remove(r Resource) error {
|
|||
}
|
||||
|
||||
// Update sends a refresh through all resources depending on the one given.
|
||||
func (s *Storage) Update(rn ResourceName) error {
|
||||
func (s *Storage) Update(rn pkiadm.ResourceName) error {
|
||||
r, err := s.Get(rn)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -24,7 +24,7 @@ func NewSubject(id string, name pkix.Name) (*Subject, error) {
|
|||
}
|
||||
|
||||
// Return the unique ResourceName
|
||||
func (sub *Subject) Name() ResourceName { return ResourceName{sub.ID, RTSubject} }
|
||||
func (sub *Subject) Name() pkiadm.ResourceName { return pkiadm.ResourceName{sub.ID, pkiadm.RTSubject} }
|
||||
|
||||
// AddDependency registers a depending resource to be retuened by Dependencies()
|
||||
// Refresh must trigger a rebuild of the resource.
|
||||
|
@ -36,7 +36,7 @@ func (sub *Subject) Pem() ([]byte, error) { return []byte{}, nil }
|
|||
func (sub *Subject) Checksum() []byte { return []byte{} }
|
||||
|
||||
// DependsOn must return the resource names it is depending on.
|
||||
func (sub *Subject) DependsOn() []ResourceName { return []ResourceName{} }
|
||||
func (sub *Subject) DependsOn() []pkiadm.ResourceName { return []pkiadm.ResourceName{} }
|
||||
|
||||
// GetName returns the stored name definition.
|
||||
func (sub *Subject) GetName() pkix.Name {
|
||||
|
@ -65,7 +65,7 @@ func (s *Server) SetSubject(changeset pkiadm.SubjectChange, res *pkiadm.Result)
|
|||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
subj, err := s.storage.GetSubject(ResourceName{ID: changeset.Subject.ID, Type: RTSubject})
|
||||
subj, err := s.storage.GetSubject(pkiadm.ResourceName{ID: changeset.Subject.ID, Type: pkiadm.RTSubject})
|
||||
if err != nil {
|
||||
res.SetError(err, "Could not find subject '%s'", changeset.Subject.ID)
|
||||
return nil
|
||||
|
@ -96,7 +96,7 @@ func (s *Server) SetSubject(changeset pkiadm.SubjectChange, res *pkiadm.Result)
|
|||
return nil
|
||||
}
|
||||
}
|
||||
if err := s.storage.Update(ResourceName{ID: subj.ID, Type: RTSubject}); err != nil {
|
||||
if err := s.storage.Update(pkiadm.ResourceName{ID: subj.ID, Type: pkiadm.RTSubject}); err != nil {
|
||||
res.SetError(err, "Could not update subject '%s'", changeset.Subject.ID)
|
||||
return nil
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ func (s *Server) DeleteSubject(inSubj pkiadm.ResourceName, res *pkiadm.Result) e
|
|||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
subj, err := s.storage.Get(ResourceName{ID: inSubj.ID, Type: RTSubject})
|
||||
subj, err := s.storage.Get(pkiadm.ResourceName{ID: inSubj.ID, Type: pkiadm.RTSubject})
|
||||
if err == ENotFound {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
|
@ -142,7 +142,7 @@ func (s *Server) ShowSubject(inSubj pkiadm.ResourceName, res *pkiadm.ResultSubje
|
|||
s.lock()
|
||||
defer s.unlock()
|
||||
|
||||
subj, err := s.storage.GetSubject(ResourceName{ID: inSubj.ID, Type: RTSubject})
|
||||
subj, err := s.storage.GetSubject(pkiadm.ResourceName{ID: inSubj.ID, Type: pkiadm.RTSubject})
|
||||
if err == ENotFound {
|
||||
return nil
|
||||
} else if err != nil {
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package pkiadm
|
||||
|
||||
type (
|
||||
Location struct {
|
||||
ID string
|
||||
Path string
|
||||
Dependencies []ResourceName
|
||||
PreCommand string
|
||||
PostCommand string
|
||||
Checksum []byte
|
||||
}
|
||||
LocationChange struct {
|
||||
Location Location
|
||||
FieldList []string
|
||||
}
|
||||
|
||||
ResultLocations struct {
|
||||
Result Result
|
||||
Locations []Location
|
||||
}
|
||||
)
|
||||
|
||||
func (c *Client) CreateLocation(loc Location) error {
|
||||
return c.exec("CreateLocation", loc)
|
||||
}
|
||||
|
||||
func (c *Client) DeleteLocation(id string) error {
|
||||
loc := ResourceName{ID: id, Type: RTLocation}
|
||||
return c.exec("DeleteLocation", loc)
|
||||
}
|
||||
|
||||
func (c *Client) SetLocation(loc Location, fieldList []string) error {
|
||||
changeset := LocationChange{loc, fieldList}
|
||||
return c.exec("SetLocation", changeset)
|
||||
}
|
||||
|
||||
func (c *Client) ShowLocation(id string) (Location, error) {
|
||||
loc := ResourceName{ID: id, Type: RTLocation}
|
||||
result := &ResultLocations{}
|
||||
if err := c.query("ShowLocation", loc, result); err != nil {
|
||||
return Location{}, err
|
||||
}
|
||||
if result.Result.HasError {
|
||||
return Location{}, result.Result.Error
|
||||
}
|
||||
for _, location := range result.Locations {
|
||||
return location, nil
|
||||
}
|
||||
return Location{}, nil
|
||||
}
|
||||
|
||||
func (c *Client) ListLocation() ([]Location, error) {
|
||||
result := &ResultLocations{}
|
||||
if err := c.query("ListLocation", Filter{}, result); err != nil {
|
||||
return []Location{}, err
|
||||
}
|
||||
if result.Result.HasError {
|
||||
return []Location{}, result.Result.Error
|
||||
}
|
||||
return result.Locations, nil
|
||||
}
|
|
@ -4,13 +4,46 @@ package pkiadm
|
|||
|
||||
import "fmt"
|
||||
|
||||
const _ResourceType_name = "RTPrivateKeyRTPublicKeyRTCSRRTCertificateRTLocationRTSerialRTSubject"
|
||||
|
||||
var _ResourceType_index = [...]uint8{0, 12, 23, 28, 41, 51, 59, 68}
|
||||
|
||||
func (i ResourceType) String() string {
|
||||
if i >= ResourceType(len(_ResourceType_index)-1) {
|
||||
switch i {
|
||||
case RTPrivateKey:
|
||||
return "private"
|
||||
case RTPublicKey:
|
||||
return "public"
|
||||
case RTCSR:
|
||||
return "csr"
|
||||
case RTCertificate:
|
||||
return "cert"
|
||||
case RTSubject:
|
||||
return "subject"
|
||||
case RTSerial:
|
||||
return "serial"
|
||||
case RTLocation:
|
||||
return "location"
|
||||
case RTUnknown:
|
||||
return "unknown"
|
||||
default:
|
||||
return fmt.Sprintf("ResourceType(%d)", i)
|
||||
}
|
||||
return _ResourceType_name[_ResourceType_index[i]:_ResourceType_index[i+1]]
|
||||
}
|
||||
|
||||
func StringToResourceType(in string) (ResourceType, error) {
|
||||
switch in {
|
||||
case "private":
|
||||
return RTPrivateKey, nil
|
||||
case "public":
|
||||
return RTPublicKey, nil
|
||||
case "csr":
|
||||
return RTCSR, nil
|
||||
case "cert":
|
||||
return RTCertificate, nil
|
||||
case "location":
|
||||
return RTLocation, nil
|
||||
case "subject":
|
||||
return RTSubject, nil
|
||||
case "serial":
|
||||
return RTSerial, nil
|
||||
default:
|
||||
return RTUnknown, fmt.Errorf("unknown resource type")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ const (
|
|||
RTLocation
|
||||
RTSerial
|
||||
RTSubject
|
||||
RTUnknown
|
||||
)
|
||||
|
||||
type ResourceName struct {
|
||||
|
|
Loading…
Reference in New Issue