diff --git a/authority/mgmt/api/handler.go b/authority/mgmt/api/handler.go index 11dcbd86..8b6f915b 100644 --- a/authority/mgmt/api/handler.go +++ b/authority/mgmt/api/handler.go @@ -32,20 +32,20 @@ func NewHandler(auth *authority.Authority) api.RouterHandler { // Route traffic and implement the Router interface. func (h *Handler) Route(r api.Router) { // Provisioners - r.MethodFunc("GET", "/provisioner/{name}", h.GetProvisioner) + r.MethodFunc("GET", "/provisioners/{name}", h.GetProvisioner) r.MethodFunc("GET", "/provisioners", h.GetProvisioners) - r.MethodFunc("POST", "/provisioner", h.CreateProvisioner) - r.MethodFunc("PUT", "/provisioner/{name}", h.UpdateProvisioner) - r.MethodFunc("DELETE", "/provisioner/{name}", h.DeleteProvisioner) + r.MethodFunc("POST", "/provisioners", h.CreateProvisioner) + r.MethodFunc("PUT", "/provisioners/{name}", h.UpdateProvisioner) + r.MethodFunc("DELETE", "/provisioners/{name}", h.DeleteProvisioner) // Admins - r.MethodFunc("GET", "/admin/{id}", h.GetAdmin) + r.MethodFunc("GET", "/admins/{id}", h.GetAdmin) r.MethodFunc("GET", "/admins", h.GetAdmins) - r.MethodFunc("POST", "/admin", h.CreateAdmin) - r.MethodFunc("PATCH", "/admin/{id}", h.UpdateAdmin) - r.MethodFunc("DELETE", "/admin/{id}", h.DeleteAdmin) + r.MethodFunc("POST", "/admins", h.CreateAdmin) + r.MethodFunc("PATCH", "/admins/{id}", h.UpdateAdmin) + r.MethodFunc("DELETE", "/admins/{id}", h.DeleteAdmin) // AuthConfig - r.MethodFunc("GET", "/authconfig/{id}", h.GetAuthConfig) - r.MethodFunc("PUT", "/authconfig/{id}", h.UpdateAuthConfig) + r.MethodFunc("GET", "/authconfigs/{id}", h.GetAuthConfig) + r.MethodFunc("PUT", "/authconfigs/{id}", h.UpdateAuthConfig) } diff --git a/authority/mgmt/provisioner.go b/authority/mgmt/provisioner.go index ea9d0da5..537b7fdd 100644 --- a/authority/mgmt/provisioner.go +++ b/authority/mgmt/provisioner.go @@ -58,6 +58,20 @@ func WithPassword(pass string) func(*ProvisionerCtx) { } } +type unmarshalProvisioner struct { + ID string `json:"-"` + AuthorityID string `json:"-"` + Type string `json:"type"` + Name string `json:"name"` + Claims *Claims `json:"claims"` + Details json.RawMessage `json:"details"` + X509Template string `json:"x509Template"` + X509TemplateData []byte `json:"x509TemplateData"` + SSHTemplate string `json:"sshTemplate"` + SSHTemplateData []byte `json:"sshTemplateData"` + Status status.Type `json:"status"` +} + // Provisioner type. type Provisioner struct { ID string `json:"-"` @@ -73,6 +87,38 @@ type Provisioner struct { Status status.Type `json:"status"` } +type typ struct { + Type ProvisionerType `json:"type"` +} + +// UnmarshalJSON implements the Unmarshal interface. +func (p *Provisioner) UnmarshalJSON(b []byte) error { + var ( + err error + up = new(unmarshalProvisioner) + ) + if err = json.Unmarshal(b, up); err != nil { + return WrapErrorISE(err, "error unmarshaling provisioner to intermediate type") + } + p.Details, err = UnmarshalProvisionerDetails(up.Details) + if err = json.Unmarshal(b, up); err != nil { + return WrapErrorISE(err, "error unmarshaling provisioner details") + } + + p.ID = up.ID + p.AuthorityID = up.AuthorityID + p.Type = up.Type + p.Name = up.Name + p.Claims = up.Claims + p.X509Template = up.X509Template + p.X509TemplateData = up.X509TemplateData + p.SSHTemplate = up.SSHTemplate + p.SSHTemplateData = up.SSHTemplateData + p.Status = up.Status + + return nil +} + func (p *Provisioner) GetOptions() *provisioner.Options { return &provisioner.Options{ X509: &provisioner.X509Options{ @@ -415,7 +461,7 @@ type detailsType struct { Type ProvisionerType } -func UnmarshalProvisionerDetails(data []byte) (ProvisionerDetails, error) { +func UnmarshalProvisionerDetails(data json.RawMessage) (ProvisionerDetails, error) { dt := new(detailsType) if err := json.Unmarshal(data, dt); err != nil { return nil, WrapErrorISE(err, "error unmarshaling provisioner details") diff --git a/ca/mgmtClient.go b/ca/adminClient.go similarity index 77% rename from ca/mgmtClient.go rename to ca/adminClient.go index 7c4207aa..5fc6a7d4 100644 --- a/ca/mgmtClient.go +++ b/ca/adminClient.go @@ -16,16 +16,16 @@ import ( "github.com/smallstep/certificates/errs" ) -// MgmtClient implements an HTTP client for the CA server. -type MgmtClient struct { +// AdminClient implements an HTTP client for the CA server. +type AdminClient struct { client *uaClient endpoint *url.URL retryFunc RetryFunc opts []ClientOption } -// NewMgmtClient creates a new MgmtClient with the given endpoint and options. -func NewMgmtClient(endpoint string, opts ...ClientOption) (*MgmtClient, error) { +// NewAdminClient creates a new AdminClient with the given endpoint and options. +func NewAdminClient(endpoint string, opts ...ClientOption) (*AdminClient, error) { u, err := parseEndpoint(endpoint) if err != nil { return nil, err @@ -40,7 +40,7 @@ func NewMgmtClient(endpoint string, opts ...ClientOption) (*MgmtClient, error) { return nil, err } - return &MgmtClient{ + return &AdminClient{ client: newClient(tr), endpoint: u, retryFunc: o.retryFunc, @@ -48,7 +48,7 @@ func NewMgmtClient(endpoint string, opts ...ClientOption) (*MgmtClient, error) { }, nil } -func (c *MgmtClient) retryOnError(r *http.Response) bool { +func (c *AdminClient) retryOnError(r *http.Response) bool { if c.retryFunc != nil { if c.retryFunc(r.StatusCode) { o := new(clientOptions) @@ -67,10 +67,10 @@ func (c *MgmtClient) retryOnError(r *http.Response) bool { return false } -// GetAdmin performs the GET /mgmt/admin/{id} request to the CA. -func (c *MgmtClient) GetAdmin(id string) (*mgmt.Admin, error) { +// GetAdmin performs the GET /admin/admin/{id} request to the CA. +func (c *AdminClient) GetAdmin(id string) (*mgmt.Admin, error) { var retried bool - u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/mgmt/admin", id)}) + u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/admin", id)}) retry: resp, err := c.client.Get(u.String()) if err != nil { @@ -81,7 +81,7 @@ retry: retried = true goto retry } - return nil, readMgmtError(resp.Body) + return nil, readAdminError(resp.Body) } var adm = new(mgmt.Admin) if err := readJSON(resp.Body, adm); err != nil { @@ -135,7 +135,7 @@ func WithAdminLimit(limit int) AdminOption { } // GetAdmins performs the GET /admin/admins request to the CA. -func (c *MgmtClient) GetAdmins(opts ...AdminOption) (*mgmtAPI.GetAdminsResponse, error) { +func (c *AdminClient) GetAdmins(opts ...AdminOption) (*mgmtAPI.GetAdminsResponse, error) { var retried bool o := new(adminOptions) if err := o.apply(opts); err != nil { @@ -155,7 +155,7 @@ retry: retried = true goto retry } - return nil, readMgmtError(resp.Body) + return nil, readAdminError(resp.Body) } var body = new(mgmtAPI.GetAdminsResponse) if err := readJSON(resp.Body, body); err != nil { @@ -164,14 +164,14 @@ retry: return body, nil } -// CreateAdmin performs the POST /admin/admin request to the CA. -func (c *MgmtClient) CreateAdmin(req *mgmtAPI.CreateAdminRequest) (*mgmt.Admin, error) { +// CreateAdmin performs the POST /admin/admins request to the CA. +func (c *AdminClient) CreateAdmin(req *mgmtAPI.CreateAdminRequest) (*mgmt.Admin, error) { var retried bool body, err := json.Marshal(req) if err != nil { return nil, errs.Wrap(http.StatusInternalServerError, err, "error marshaling request") } - u := c.endpoint.ResolveReference(&url.URL{Path: "/admin/admin"}) + u := c.endpoint.ResolveReference(&url.URL{Path: "/admin/admins"}) retry: resp, err := c.client.Post(u.String(), "application/json", bytes.NewReader(body)) if err != nil { @@ -182,7 +182,7 @@ retry: retried = true goto retry } - return nil, readMgmtError(resp.Body) + return nil, readAdminError(resp.Body) } var adm = new(mgmt.Admin) if err := readJSON(resp.Body, adm); err != nil { @@ -191,10 +191,10 @@ retry: return adm, nil } -// RemoveAdmin performs the DELETE /admin/admin/{id} request to the CA. -func (c *MgmtClient) RemoveAdmin(id string) error { +// RemoveAdmin performs the DELETE /admin/admins/{id} request to the CA. +func (c *AdminClient) RemoveAdmin(id string) error { var retried bool - u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/admin", id)}) + u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/admins", id)}) req, err := http.NewRequest("DELETE", u.String(), nil) if err != nil { return errors.Wrapf(err, "create DELETE %s request failed", u) @@ -209,19 +209,19 @@ retry: retried = true goto retry } - return readMgmtError(resp.Body) + return readAdminError(resp.Body) } return nil } -// UpdateAdmin performs the PUT /admin/admin/{id} request to the CA. -func (c *MgmtClient) UpdateAdmin(id string, uar *mgmtAPI.UpdateAdminRequest) (*admin.Admin, error) { +// UpdateAdmin performs the PUT /admin/admins/{id} request to the CA. +func (c *AdminClient) UpdateAdmin(id string, uar *mgmtAPI.UpdateAdminRequest) (*admin.Admin, error) { var retried bool body, err := json.Marshal(uar) if err != nil { return nil, errs.Wrap(http.StatusInternalServerError, err, "error marshaling request") } - u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/admin", id)}) + u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/admins", id)}) req, err := http.NewRequest("PATCH", u.String(), bytes.NewReader(body)) if err != nil { return nil, errors.Wrapf(err, "create PUT %s request failed", u) @@ -236,7 +236,7 @@ retry: retried = true goto retry } - return nil, readMgmtError(resp.Body) + return nil, readAdminError(resp.Body) } var adm = new(admin.Admin) if err := readJSON(resp.Body, adm); err != nil { @@ -245,10 +245,10 @@ retry: return adm, nil } -// GetProvisioner performs the GET /admin/provisioner/{name} request to the CA. -func (c *MgmtClient) GetProvisioner(name string) (*mgmt.Provisioner, error) { +// GetProvisioner performs the GET /admin/provisioners/{name} request to the CA. +func (c *AdminClient) GetProvisioner(name string) (*mgmt.Provisioner, error) { var retried bool - u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/provisioner", name)}) + u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/provisioners", name)}) retry: resp, err := c.client.Get(u.String()) if err != nil { @@ -259,7 +259,7 @@ retry: retried = true goto retry } - return nil, readMgmtError(resp.Body) + return nil, readAdminError(resp.Body) } var prov = new(mgmt.Provisioner) if err := readJSON(resp.Body, prov); err != nil { @@ -269,7 +269,7 @@ retry: } // GetProvisioners performs the GET /admin/provisioners request to the CA. -func (c *MgmtClient) GetProvisioners() ([]*mgmt.Provisioner, error) { +func (c *AdminClient) GetProvisioners() ([]*mgmt.Provisioner, error) { var retried bool u := c.endpoint.ResolveReference(&url.URL{Path: "/admin/provisioners"}) retry: @@ -282,7 +282,7 @@ retry: retried = true goto retry } - return nil, readMgmtError(resp.Body) + return nil, readAdminError(resp.Body) } var provs = new([]*mgmt.Provisioner) if err := readJSON(resp.Body, provs); err != nil { @@ -291,10 +291,10 @@ retry: return *provs, nil } -// RemoveProvisioner performs the DELETE /admin/provisioner/{name} request to the CA. -func (c *MgmtClient) RemoveProvisioner(name string) error { +// RemoveProvisioner performs the DELETE /admin/provisioners/{name} request to the CA. +func (c *AdminClient) RemoveProvisioner(name string) error { var retried bool - u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/provisioner", name)}) + u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/provisioners", name)}) req, err := http.NewRequest("DELETE", u.String(), nil) if err != nil { return errors.Wrapf(err, "create DELETE %s request failed", u) @@ -309,19 +309,19 @@ retry: retried = true goto retry } - return readMgmtError(resp.Body) + return readAdminError(resp.Body) } return nil } -// CreateProvisioner performs the POST /admin/provisioner request to the CA. -func (c *MgmtClient) CreateProvisioner(req *mgmtAPI.CreateProvisionerRequest) (*mgmt.Provisioner, error) { +// CreateProvisioner performs the POST /admin/provisioners request to the CA. +func (c *AdminClient) CreateProvisioner(req *mgmtAPI.CreateProvisionerRequest) (*mgmt.Provisioner, error) { var retried bool body, err := json.Marshal(req) if err != nil { return nil, errs.Wrap(http.StatusInternalServerError, err, "error marshaling request") } - u := c.endpoint.ResolveReference(&url.URL{Path: "/admin/provisioner"}) + u := c.endpoint.ResolveReference(&url.URL{Path: "/admin/provisioners"}) retry: resp, err := c.client.Post(u.String(), "application/json", bytes.NewReader(body)) if err != nil { @@ -332,7 +332,7 @@ retry: retried = true goto retry } - return nil, readMgmtError(resp.Body) + return nil, readAdminError(resp.Body) } var prov = new(mgmt.Provisioner) if err := readJSON(resp.Body, prov); err != nil { @@ -341,14 +341,14 @@ retry: return prov, nil } -// UpdateProvisioner performs the PUT /admin/provisioner/{id} request to the CA. -func (c *MgmtClient) UpdateProvisioner(id string, upr *mgmtAPI.UpdateProvisionerRequest) (*mgmt.Provisioner, error) { +// UpdateProvisioner performs the PUT /admin/provisioners/{id} request to the CA. +func (c *AdminClient) UpdateProvisioner(id string, upr *mgmtAPI.UpdateProvisionerRequest) (*mgmt.Provisioner, error) { var retried bool body, err := json.Marshal(upr) if err != nil { return nil, errs.Wrap(http.StatusInternalServerError, err, "error marshaling request") } - u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/provisioner", id)}) + u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/provisioners", id)}) req, err := http.NewRequest("PUT", u.String(), bytes.NewReader(body)) if err != nil { return nil, errors.Wrapf(err, "create PUT %s request failed", u) @@ -363,7 +363,7 @@ retry: retried = true goto retry } - return nil, readMgmtError(resp.Body) + return nil, readAdminError(resp.Body) } var prov = new(mgmt.Provisioner) if err := readJSON(resp.Body, prov); err != nil { @@ -373,7 +373,7 @@ retry: } // GetAuthConfig performs the GET /admin/authconfig/{id} request to the CA. -func (c *MgmtClient) GetAuthConfig(id string) (*mgmt.AuthConfig, error) { +func (c *AdminClient) GetAuthConfig(id string) (*mgmt.AuthConfig, error) { var retried bool u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/authconfig", id)}) retry: @@ -386,7 +386,7 @@ retry: retried = true goto retry } - return nil, readMgmtError(resp.Body) + return nil, readAdminError(resp.Body) } var ac = new(mgmt.AuthConfig) if err := readJSON(resp.Body, ac); err != nil { @@ -395,7 +395,7 @@ retry: return ac, nil } -func readMgmtError(r io.ReadCloser) error { +func readAdminError(r io.ReadCloser) error { defer r.Close() mgmtErr := new(mgmt.Error) if err := json.NewDecoder(r).Decode(mgmtErr); err != nil {