forked from TrueCloudLab/certificates
wip
This commit is contained in:
parent
1726076ea2
commit
01a4460812
10 changed files with 377 additions and 429 deletions
|
@ -11,6 +11,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/smallstep/certificates/cas"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/smallstep/certificates/authority/admin"
|
||||
|
@ -129,15 +130,18 @@ func NewEmbedded(opts ...Option) (*Authority, error) {
|
|||
return a, nil
|
||||
}
|
||||
|
||||
func (a *Authority) ReloadAuthConfig() error {
|
||||
mgmtAuthConfig, err := a.adminDB.GetAuthConfig(context.Background(), mgmt.DefaultAuthorityID)
|
||||
func (a *Authority) ReloadAuthConfig(ctx context.Context) error {
|
||||
provs, err := a.adminDB.GetProvisioners(ctx)
|
||||
if err != nil {
|
||||
return mgmt.WrapErrorISE(err, "error getting authConfig from db")
|
||||
return mgmt.WrapErrorISE(err, "error getting provisioners to initialize authority")
|
||||
}
|
||||
|
||||
a.config.AuthorityConfig, err = mgmtAuthConfig.ToCertificates()
|
||||
a.config.AuthorityConfig.Provisioners, err = provisionerListToCertificates(provs)
|
||||
if err != nil {
|
||||
return mgmt.WrapErrorISE(err, "error converting mgmt authConfig to certificates authConfig")
|
||||
return mgmt.WrapErrorISE(err, "error converting provisioner list to certificates")
|
||||
}
|
||||
a.config.AuthorityConfig.Admins, err = a.adminDB.GetAdmins(ctx)
|
||||
if err != nil {
|
||||
return mgmt.WrapErrorISE(err, "error getting provisioners to initialize authority")
|
||||
}
|
||||
|
||||
// Merge global and configuration claims
|
||||
|
@ -148,7 +152,7 @@ func (a *Authority) ReloadAuthConfig() error {
|
|||
// TODO: should we also be combining the ssh federated roots here?
|
||||
// If we rotate ssh roots keys, sshpop provisioner will lose ability to
|
||||
// validate old SSH certificates, unless they are added as federated certs.
|
||||
sshKeys, err := a.GetSSHRoots(context.Background())
|
||||
sshKeys, err := a.GetSSHRoots(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -201,30 +205,52 @@ func (a *Authority) init() error {
|
|||
}
|
||||
}
|
||||
|
||||
// Initialize step-ca Admin Database if it's not already initialized using
|
||||
// WithAdminDB.
|
||||
if a.adminDB == nil {
|
||||
// Check if AuthConfig already exists
|
||||
a.adminDB, err = authMgmtNosql.New(a.db.(nosql.DB), mgmt.DefaultAuthorityID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
mgmtAuthConfig, err := a.adminDB.GetAuthConfig(context.Background(), mgmt.DefaultAuthorityID)
|
||||
if err != nil {
|
||||
if k, ok := err.(*mgmt.Error); ok && k.IsType(mgmt.ErrorNotFoundType) {
|
||||
mgmtAuthConfig, err = mgmt.CreateAuthority(context.Background(), a.adminDB, mgmt.WithDefaultAuthorityID)
|
||||
if err != nil {
|
||||
return mgmt.WrapErrorISE(err, "error creating authConfig")
|
||||
}
|
||||
} else {
|
||||
return mgmt.WrapErrorISE(err, "error getting authConfig from db")
|
||||
if len(a.config.AuthorityConfig.Provisioners) == 0 {
|
||||
// Initialize step-ca Admin Database if it's not already initialized using
|
||||
// WithAdminDB.
|
||||
if a.adminDB == nil {
|
||||
// Check if AuthConfig already exists
|
||||
a.adminDB, err = authMgmtNosql.New(a.db.(nosql.DB), mgmt.DefaultAuthorityID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
a.config.AuthorityConfig, err = mgmtAuthConfig.ToCertificates()
|
||||
provs, err := a.adminDB.GetProvisioners(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(provs) == 0 {
|
||||
// Create First Provisioner
|
||||
prov, err := mgmt.CreateFirstProvisioner(context.Background(), a.adminDB, a.config.Password)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Create First Admin
|
||||
adm := &linkedca.Admin{
|
||||
ProvisionerId: prov.Id,
|
||||
Subject: "step",
|
||||
Type: linkedca.Admin_SUPER_ADMIN,
|
||||
}
|
||||
if err := a.adminDB.CreateAdmin(context.Background(), adm); err != nil {
|
||||
// TODO should we try to clean up?
|
||||
return mgmt.WrapErrorISE(err, "error creating first admin")
|
||||
}
|
||||
a.config.AuthorityConfig.Admins = []*linkedca.Admin{adm}
|
||||
} else {
|
||||
provs, err := a.adminDB.GetProvisioners(context.Background())
|
||||
if err != nil {
|
||||
return mgmt.WrapErrorISE(err, "error getting provisioners to initialize authority")
|
||||
}
|
||||
a.config.AuthorityConfig.Provisioners, err = provisionerListToCertificates(provs)
|
||||
if err != nil {
|
||||
return mgmt.WrapErrorISE(err, "error converting provisioner list to certificates")
|
||||
}
|
||||
a.config.AuthorityConfig.Admins, err = a.adminDB.GetAdmins(context.Background())
|
||||
if err != nil {
|
||||
return mgmt.WrapErrorISE(err, "error getting provisioners to initialize authority")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize key manager if it has not been set in the options.
|
||||
|
|
|
@ -8,14 +8,14 @@ import (
|
|||
"github.com/smallstep/certificates/api"
|
||||
"github.com/smallstep/certificates/authority/admin"
|
||||
"github.com/smallstep/certificates/authority/mgmt"
|
||||
"github.com/smallstep/certificates/authority/status"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
)
|
||||
|
||||
// CreateAdminRequest represents the body for a CreateAdmin request.
|
||||
type CreateAdminRequest struct {
|
||||
Subject string `json:"subject"`
|
||||
Provisioner string `json:"provisioner"`
|
||||
Type admin.Type `json:"type"`
|
||||
Subject string `json:"subject"`
|
||||
Provisioner string `json:"provisioner"`
|
||||
Type linkedca.Admin_Type `json:"type"`
|
||||
}
|
||||
|
||||
// Validate validates a new-admin request body.
|
||||
|
@ -29,13 +29,13 @@ func (car *CreateAdminRequest) Validate(c *admin.Collection) error {
|
|||
|
||||
// GetAdminsResponse for returning a list of admins.
|
||||
type GetAdminsResponse struct {
|
||||
Admins []*admin.Admin `json:"admins"`
|
||||
NextCursor string `json:"nextCursor"`
|
||||
Admins []*linkedca.Admin `json:"admins"`
|
||||
NextCursor string `json:"nextCursor"`
|
||||
}
|
||||
|
||||
// UpdateAdminRequest represents the body for a UpdateAdmin request.
|
||||
type UpdateAdminRequest struct {
|
||||
Type admin.Type `json:"type"`
|
||||
Type linkedca.Admin_Type `json:"type"`
|
||||
}
|
||||
|
||||
// Validate validates a new-admin request body.
|
||||
|
@ -98,20 +98,17 @@ func (h *Handler) CreateAdmin(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
adm := &mgmt.Admin{
|
||||
ProvisionerID: p.GetID(),
|
||||
adm := &linkedca.Admin{
|
||||
ProvisionerId: p.GetID(),
|
||||
Subject: body.Subject,
|
||||
Type: body.Type,
|
||||
Status: status.Active,
|
||||
}
|
||||
if err := h.db.CreateAdmin(ctx, adm); err != nil {
|
||||
api.WriteError(w, mgmt.WrapErrorISE(err, "error creating admin"))
|
||||
return
|
||||
}
|
||||
adm.ProvisionerName = p.GetName()
|
||||
adm.ProvisionerType = p.GetType().String()
|
||||
api.JSON(w, adm)
|
||||
if err := h.auth.ReloadAuthConfig(); err != nil {
|
||||
if err := h.auth.ReloadAuthConfig(ctx); err != nil {
|
||||
fmt.Printf("err = %+v\n", err)
|
||||
}
|
||||
}
|
||||
|
@ -126,18 +123,13 @@ func (h *Handler) DeleteAdmin(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
ctx := r.Context()
|
||||
adm, err := h.db.GetAdmin(ctx, id)
|
||||
if err != nil {
|
||||
api.WriteError(w, mgmt.WrapErrorISE(err, "error retrieiving admin %s", id))
|
||||
return
|
||||
}
|
||||
adm.Status = status.Deleted
|
||||
if err := h.db.UpdateAdmin(ctx, adm); err != nil {
|
||||
api.WriteError(w, mgmt.WrapErrorISE(err, "error updating admin %s", id))
|
||||
if err := h.db.DeleteAdmin(ctx, id); err != nil {
|
||||
api.WriteError(w, mgmt.WrapErrorISE(err, "error deleting admin %s", id))
|
||||
return
|
||||
}
|
||||
api.JSON(w, &DeleteResponse{Status: "ok"})
|
||||
if err := h.auth.ReloadAuthConfig(); err != nil {
|
||||
|
||||
if err := h.auth.ReloadAuthConfig(ctx); err != nil {
|
||||
fmt.Printf("err = %+v\n", err)
|
||||
}
|
||||
}
|
||||
|
@ -166,12 +158,12 @@ func (h *Handler) UpdateAdmin(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
adm.Type = body.Type
|
||||
|
||||
if err := h.db.UpdateAdmin(ctx, (*mgmt.Admin)(adm)); err != nil {
|
||||
if err := h.db.UpdateAdmin(ctx, (*linkedca.Admin)(adm)); err != nil {
|
||||
api.WriteError(w, mgmt.WrapErrorISE(err, "error updating admin %s", id))
|
||||
return
|
||||
}
|
||||
api.JSON(w, adm)
|
||||
if err := h.auth.ReloadAuthConfig(); err != nil {
|
||||
if err := h.auth.ReloadAuthConfig(ctx); err != nil {
|
||||
fmt.Printf("err = %+v\n", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/smallstep/certificates/api"
|
||||
"github.com/smallstep/certificates/authority/config"
|
||||
"github.com/smallstep/certificates/authority/mgmt"
|
||||
)
|
||||
|
||||
// CreateAuthConfigRequest represents the body for a CreateAuthConfig request.
|
||||
type CreateAuthConfigRequest struct {
|
||||
ASN1DN *config.ASN1DN `json:"asn1dn,omitempty"`
|
||||
Claims *mgmt.Claims `json:"claims,omitempty"`
|
||||
Backdate string `json:"backdate,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates a CreateAuthConfig request body.
|
||||
func (car *CreateAuthConfigRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateAuthConfigRequest represents the body for a UpdateAuthConfig request.
|
||||
type UpdateAuthConfigRequest struct {
|
||||
ASN1DN *config.ASN1DN `json:"asn1dn"`
|
||||
Claims *mgmt.Claims `json:"claims"`
|
||||
Backdate string `json:"backdate,omitempty"`
|
||||
}
|
||||
|
||||
// Validate validates a new-admin request body.
|
||||
func (uar *UpdateAuthConfigRequest) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAuthConfig returns the requested admin, or an error.
|
||||
func (h *Handler) GetAuthConfig(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
id := chi.URLParam(r, "id")
|
||||
|
||||
ac, err := h.db.GetAuthConfig(ctx, id)
|
||||
if err != nil {
|
||||
api.WriteError(w, err)
|
||||
return
|
||||
}
|
||||
api.JSON(w, ac)
|
||||
}
|
||||
|
||||
// UpdateAuthConfig updates an existing AuthConfig.
|
||||
func (h *Handler) UpdateAuthConfig(w http.ResponseWriter, r *http.Request) {
|
||||
/*
|
||||
ctx := r.Context()
|
||||
id := chi.URLParam(r, "id")
|
||||
|
||||
var body UpdateAuthConfigRequest
|
||||
if err := api.ReadJSON(r.Body, &body); err != nil {
|
||||
api.WriteError(w, err)
|
||||
return
|
||||
}
|
||||
if err := body.Validate(); err != nil {
|
||||
api.WriteError(w, err)
|
||||
return
|
||||
}
|
||||
ac, err := h.db.GetAuthConfig(ctx, id)
|
||||
if err != nil {
|
||||
api.WriteError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
ac.Status = body.Status
|
||||
if body.ASN1DN != nil {
|
||||
ac.ASN1DN = body.ASN1DN
|
||||
}
|
||||
if body.Claims != nil {
|
||||
ac.Claims = body.Claims
|
||||
}
|
||||
if body.Backdate != "" {
|
||||
ac.Backdate = body.Backdate
|
||||
}
|
||||
|
||||
if err := h.db.UpdateAuthConfig(ctx, ac); err != nil {
|
||||
api.WriteError(w, err)
|
||||
return
|
||||
}
|
||||
api.JSON(w, ac)
|
||||
*/
|
||||
}
|
|
@ -44,8 +44,4 @@ func (h *Handler) Route(r api.Router) {
|
|||
r.MethodFunc("POST", "/admins", h.CreateAdmin)
|
||||
r.MethodFunc("PATCH", "/admins/{id}", h.UpdateAdmin)
|
||||
r.MethodFunc("DELETE", "/admins/{id}", h.DeleteAdmin)
|
||||
|
||||
// AuthConfig
|
||||
r.MethodFunc("GET", "/authconfigs/{id}", h.GetAuthConfig)
|
||||
r.MethodFunc("PUT", "/authconfigs/{id}", h.UpdateAuthConfig)
|
||||
}
|
||||
|
|
|
@ -8,20 +8,20 @@ import (
|
|||
"github.com/smallstep/certificates/api"
|
||||
"github.com/smallstep/certificates/authority/mgmt"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
"github.com/smallstep/certificates/authority/status"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
)
|
||||
|
||||
// CreateProvisionerRequest represents the body for a CreateProvisioner request.
|
||||
type CreateProvisionerRequest struct {
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Claims *mgmt.Claims `json:"claims"`
|
||||
Details []byte `json:"details"`
|
||||
X509Template string `json:"x509Template"`
|
||||
X509TemplateData []byte `json:"x509TemplateData"`
|
||||
SSHTemplate string `json:"sshTemplate"`
|
||||
SSHTemplateData []byte `json:"sshTemplateData"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Claims *linkedca.Claims `json:"claims"`
|
||||
Details []byte `json:"details"`
|
||||
X509Template string `json:"x509Template"`
|
||||
X509TemplateData []byte `json:"x509TemplateData"`
|
||||
SSHTemplate string `json:"sshTemplate"`
|
||||
SSHTemplateData []byte `json:"sshTemplateData"`
|
||||
}
|
||||
|
||||
// Validate validates a new-provisioner request body.
|
||||
|
@ -40,14 +40,14 @@ type GetProvisionersResponse struct {
|
|||
|
||||
// UpdateProvisionerRequest represents the body for a UpdateProvisioner request.
|
||||
type UpdateProvisionerRequest struct {
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Claims *mgmt.Claims `json:"claims"`
|
||||
Details []byte `json:"details"`
|
||||
X509Template string `json:"x509Template"`
|
||||
X509TemplateData []byte `json:"x509TemplateData"`
|
||||
SSHTemplate string `json:"sshTemplate"`
|
||||
SSHTemplateData []byte `json:"sshTemplateData"`
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Claims *linkedca.Claims `json:"claims"`
|
||||
Details []byte `json:"details"`
|
||||
X509Template string `json:"x509Template"`
|
||||
X509TemplateData []byte `json:"x509TemplateData"`
|
||||
SSHTemplate string `json:"sshTemplate"`
|
||||
SSHTemplateData []byte `json:"sshTemplateData"`
|
||||
}
|
||||
|
||||
// Validate validates a update-provisioner request body.
|
||||
|
@ -101,7 +101,7 @@ func (h *Handler) GetProvisioners(w http.ResponseWriter, r *http.Request) {
|
|||
func (h *Handler) CreateProvisioner(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
|
||||
var prov = new(mgmt.Provisioner)
|
||||
var prov = new(linkedca.Provisioner)
|
||||
if err := api.ReadJSON(r.Body, prov); err != nil {
|
||||
api.WriteError(w, err)
|
||||
return
|
||||
|
@ -118,7 +118,7 @@ func (h *Handler) CreateProvisioner(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
api.JSONStatus(w, prov, http.StatusCreated)
|
||||
|
||||
if err := h.auth.ReloadAuthConfig(); err != nil {
|
||||
if err := h.auth.ReloadAuthConfig(ctx); err != nil {
|
||||
fmt.Printf("err = %+v\n", err)
|
||||
}
|
||||
}
|
||||
|
@ -141,14 +141,8 @@ func (h *Handler) DeleteProvisioner(w http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
|
||||
ctx := r.Context()
|
||||
prov, err := h.db.GetProvisioner(ctx, p.GetID())
|
||||
if err != nil {
|
||||
api.WriteError(w, mgmt.WrapErrorISE(err, "error loading provisioner %s from db", name))
|
||||
return
|
||||
}
|
||||
prov.Status = status.Deleted
|
||||
if err := h.db.UpdateProvisioner(ctx, prov); err != nil {
|
||||
api.WriteError(w, mgmt.WrapErrorISE(err, "error updating provisioner %s", name))
|
||||
if err := h.db.DeleteProvisioner(ctx, p.GetID()); err != nil {
|
||||
api.WriteError(w, mgmt.WrapErrorISE(err, "error deleting provisioner %s", name))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -156,13 +150,7 @@ func (h *Handler) DeleteProvisioner(w http.ResponseWriter, r *http.Request) {
|
|||
admins, ok := c.LoadByProvisioner(name)
|
||||
if ok {
|
||||
for _, adm := range admins {
|
||||
if err := h.db.UpdateAdmin(ctx, &mgmt.Admin{
|
||||
ID: adm.ID,
|
||||
ProvisionerID: adm.ProvisionerID,
|
||||
Subject: adm.Subject,
|
||||
Type: adm.Type,
|
||||
Status: status.Deleted,
|
||||
}); err != nil {
|
||||
if err := h.db.DeleteAdmin(ctx, adm.Id); err != nil {
|
||||
api.WriteError(w, mgmt.WrapErrorISE(err, "error deleting admin %s, as part of provisioner %s deletion", adm.Subject, name))
|
||||
return
|
||||
}
|
||||
|
@ -171,7 +159,7 @@ func (h *Handler) DeleteProvisioner(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
api.JSON(w, &DeleteResponse{Status: "ok"})
|
||||
|
||||
if err := h.auth.ReloadAuthConfig(); err != nil {
|
||||
if err := h.auth.ReloadAuthConfig(ctx); err != nil {
|
||||
fmt.Printf("err = %+v\n", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
package mgmt
|
||||
|
||||
import (
|
||||
"github.com/smallstep/certificates/authority/config"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
)
|
||||
|
||||
const (
|
||||
// DefaultAuthorityID is the default AuthorityID. This will be the ID
|
||||
// of the first Authority created, as well as the default AuthorityID
|
||||
|
@ -12,31 +7,6 @@ const (
|
|||
DefaultAuthorityID = "00000000-0000-0000-0000-000000000000"
|
||||
)
|
||||
|
||||
func NewDefaultClaims() *linkedca.Claims {
|
||||
return &linkedca.Claims{
|
||||
X509: &linkedca.X509Claims{
|
||||
Durations: &linkedca.Durations{
|
||||
Min: config.GlobalProvisionerClaims.MinTLSDur.String(),
|
||||
Max: config.GlobalProvisionerClaims.MaxTLSDur.String(),
|
||||
Default: config.GlobalProvisionerClaims.DefaultTLSDur.String(),
|
||||
},
|
||||
},
|
||||
Ssh: &linkedca.SSHClaims{
|
||||
UserDurations: &linkedca.Durations{
|
||||
Min: config.GlobalProvisionerClaims.MinUserSSHDur.String(),
|
||||
Max: config.GlobalProvisionerClaims.MaxUserSSHDur.String(),
|
||||
Default: config.GlobalProvisionerClaims.DefaultUserSSHDur.String(),
|
||||
},
|
||||
HostDurations: &linkedca.Durations{
|
||||
Min: config.GlobalProvisionerClaims.MinHostSSHDur.String(),
|
||||
Max: config.GlobalProvisionerClaims.MaxHostSSHDur.String(),
|
||||
Default: config.GlobalProvisionerClaims.DefaultHostSSHDur.String(),
|
||||
},
|
||||
},
|
||||
DisableRenewal: config.DefaultDisableRenewal,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func CreateAuthority(ctx context.Context, db DB, options ...AuthorityOption) (*AuthConfig, error) {
|
||||
ac := NewDefaultAuthConfig()
|
||||
|
|
|
@ -204,3 +204,16 @@ func (db *DB) UpdateProvisioner(ctx context.Context, prov *linkedca.Provisioner)
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteProvisioner saves an updated admin to the database.
|
||||
func (db *DB) DeleteProvisioner(ctx context.Context, id string) error {
|
||||
old, err := db.getDBProvisioner(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nu := old.clone()
|
||||
nu.DeletedAt = clock.Now()
|
||||
|
||||
return db.save(ctx, old.ID, nu, old, "provisioner", authorityProvisionersTable)
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package mgmt
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"context"
|
||||
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
"github.com/smallstep/certificates/authority/config"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
"go.step.sm/crypto/jose"
|
||||
)
|
||||
|
@ -57,192 +56,57 @@ func (p *Provisioner) UnmarshalJSON(b []byte) error {
|
|||
}
|
||||
*/
|
||||
|
||||
func provisionerGetOptions(p *linkedca.Provisioner) *provisioner.Options {
|
||||
return &provisioner.Options{
|
||||
X509: &provisioner.X509Options{
|
||||
Template: string(p.X509Template),
|
||||
TemplateData: p.X509TemplateData,
|
||||
func NewDefaultClaims() *linkedca.Claims {
|
||||
return &linkedca.Claims{
|
||||
X509: &linkedca.X509Claims{
|
||||
Durations: &linkedca.Durations{
|
||||
Min: config.GlobalProvisionerClaims.MinTLSDur.String(),
|
||||
Max: config.GlobalProvisionerClaims.MaxTLSDur.String(),
|
||||
Default: config.GlobalProvisionerClaims.DefaultTLSDur.String(),
|
||||
},
|
||||
},
|
||||
SSH: &provisioner.SSHOptions{
|
||||
Template: string(p.SshTemplate),
|
||||
TemplateData: p.SshTemplateData,
|
||||
Ssh: &linkedca.SSHClaims{
|
||||
UserDurations: &linkedca.Durations{
|
||||
Min: config.GlobalProvisionerClaims.MinUserSSHDur.String(),
|
||||
Max: config.GlobalProvisionerClaims.MaxUserSSHDur.String(),
|
||||
Default: config.GlobalProvisionerClaims.DefaultUserSSHDur.String(),
|
||||
},
|
||||
HostDurations: &linkedca.Durations{
|
||||
Min: config.GlobalProvisionerClaims.MinHostSSHDur.String(),
|
||||
Max: config.GlobalProvisionerClaims.MaxHostSSHDur.String(),
|
||||
Default: config.GlobalProvisionerClaims.DefaultHostSSHDur.String(),
|
||||
},
|
||||
},
|
||||
DisableRenewal: config.DefaultDisableRenewal,
|
||||
}
|
||||
}
|
||||
|
||||
// provisionerToCertificates converts the landlord provisioner type to the open source
|
||||
// provisioner type.
|
||||
func provisionerToCertificates(p *linkedca.Provisioner) (provisioner.Interface, error) {
|
||||
claims, err := claimsToCertificates(p.Claims)
|
||||
func CreateFirstProvisioner(ctx context.Context, db DB, password string) (*linkedca.Provisioner, error) {
|
||||
jwk, jwe, err := jose.GenerateDefaultKeyPair([]byte(password))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, WrapErrorISE(err, "error generating JWK key pair")
|
||||
}
|
||||
|
||||
details := p.Details.GetData()
|
||||
if details == nil {
|
||||
return nil, fmt.Errorf("provisioner does not have any details")
|
||||
jwkPubBytes, err := jwk.MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, WrapErrorISE(err, "error marshaling JWK")
|
||||
}
|
||||
jwePrivStr, err := jwe.CompactSerialize()
|
||||
if err != nil {
|
||||
return nil, WrapErrorISE(err, "error serializing JWE")
|
||||
}
|
||||
|
||||
switch d := details.(type) {
|
||||
case *linkedca.ProvisionerDetails_JWK:
|
||||
jwk := new(jose.JSONWebKey)
|
||||
if err := json.Unmarshal(d.JWK.PublicKey, &jwk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &provisioner.JWK{
|
||||
ID: p.Id,
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
Key: jwk,
|
||||
EncryptedKey: string(d.JWK.EncryptedPrivateKey),
|
||||
Claims: claims,
|
||||
Options: provisionerGetOptions(p),
|
||||
}, nil
|
||||
/*
|
||||
case *ProvisionerDetails_OIDC:
|
||||
cfg := d.OIDC
|
||||
return &provisioner.OIDC{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
TenantID: cfg.TenantId,
|
||||
ClientID: cfg.ClientId,
|
||||
ClientSecret: cfg.ClientSecret,
|
||||
ConfigurationEndpoint: cfg.ConfigurationEndpoint,
|
||||
Admins: cfg.Admins,
|
||||
Domains: cfg.Domains,
|
||||
Groups: cfg.Groups,
|
||||
ListenAddress: cfg.ListenAddress,
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_GCP:
|
||||
cfg := d.GCP
|
||||
return &provisioner.GCP{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
ServiceAccounts: cfg.ServiceAccounts,
|
||||
ProjectIDs: cfg.ProjectIds,
|
||||
DisableCustomSANs: cfg.DisableCustomSans,
|
||||
DisableTrustOnFirstUse: cfg.DisableTrustOnFirstUse,
|
||||
InstanceAge: durationValue(cfg.InstanceAge),
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_AWS:
|
||||
cfg := d.AWS
|
||||
return &provisioner.AWS{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
Accounts: cfg.Accounts,
|
||||
DisableCustomSANs: cfg.DisableCustomSans,
|
||||
DisableTrustOnFirstUse: cfg.DisableTrustOnFirstUse,
|
||||
InstanceAge: durationValue(cfg.InstanceAge),
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_Azure:
|
||||
cfg := d.Azure
|
||||
return &provisioner.Azure{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
TenantID: cfg.TenantId,
|
||||
ResourceGroups: cfg.ResourceGroups,
|
||||
Audience: cfg.Audience,
|
||||
DisableCustomSANs: cfg.DisableCustomSans,
|
||||
DisableTrustOnFirstUse: cfg.DisableTrustOnFirstUse,
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_X5C:
|
||||
var roots []byte
|
||||
for i, k := range d.X5C.GetRoots() {
|
||||
if b := k.GetKey().GetPublic(); b != nil {
|
||||
if i > 0 {
|
||||
roots = append(roots, '\n')
|
||||
}
|
||||
roots = append(roots, b...)
|
||||
}
|
||||
}
|
||||
return &provisioner.X5C{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
Roots: roots,
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_K8SSA:
|
||||
var publicKeys []byte
|
||||
for i, k := range d.K8SSA.GetPublicKeys() {
|
||||
if b := k.GetKey().GetPublic(); b != nil {
|
||||
if i > 0 {
|
||||
publicKeys = append(publicKeys, '\n')
|
||||
}
|
||||
publicKeys = append(publicKeys, k.Key.Public...)
|
||||
}
|
||||
}
|
||||
return &provisioner.K8sSA{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
PubKeys: publicKeys,
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_SSHPOP:
|
||||
return &provisioner.SSHPOP{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
Claims: claims,
|
||||
}, nil
|
||||
case *ProvisionerDetails_ACME:
|
||||
cfg := d.ACME
|
||||
return &provisioner.ACME{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
ForceCN: cfg.ForceCn,
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
*/
|
||||
default:
|
||||
return nil, fmt.Errorf("provisioner %s not implemented", p.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// claimsToCertificates converts the landlord provisioner claims type to the open source
|
||||
// (step-ca) claims type.
|
||||
func claimsToCertificates(c *linkedca.Claims) (*provisioner.Claims, error) {
|
||||
var durs = map[string]struct {
|
||||
durStr string
|
||||
dur *provisioner.Duration
|
||||
}{
|
||||
"minTLSDur": {durStr: c.X509.Durations.Min},
|
||||
"maxTLSDur": {durStr: c.X509.Durations.Max},
|
||||
"defaultTLSDur": {durStr: c.X509.Durations.Default},
|
||||
"minSSHUserDur": {durStr: c.Ssh.UserDurations.Min},
|
||||
"maxSSHUserDur": {durStr: c.Ssh.UserDurations.Max},
|
||||
"defaultSSHUserDur": {durStr: c.Ssh.UserDurations.Default},
|
||||
"minSSHHostDur": {durStr: c.Ssh.HostDurations.Min},
|
||||
"maxSSHHostDur": {durStr: c.Ssh.HostDurations.Max},
|
||||
"defaultSSHHostDur": {durStr: c.Ssh.HostDurations.Default},
|
||||
}
|
||||
var err error
|
||||
for k, v := range durs {
|
||||
v.dur, err = provisioner.NewDuration(v.durStr)
|
||||
if err != nil {
|
||||
return nil, WrapErrorISE(err, "error parsing %s %s from claims", k, v.durStr)
|
||||
}
|
||||
}
|
||||
return &provisioner.Claims{
|
||||
MinTLSDur: durs["minTLSDur"].dur,
|
||||
MaxTLSDur: durs["maxTLSDur"].dur,
|
||||
DefaultTLSDur: durs["defaultTLSDur"].dur,
|
||||
DisableRenewal: &c.DisableRenewal,
|
||||
MinUserSSHDur: durs["minSSHUserDur"].dur,
|
||||
MaxUserSSHDur: durs["maxSSHUserDur"].dur,
|
||||
DefaultUserSSHDur: durs["defaultSSHUserDur"].dur,
|
||||
MinHostSSHDur: durs["minSSHHostDur"].dur,
|
||||
MaxHostSSHDur: durs["maxSSHHostDur"].dur,
|
||||
DefaultHostSSHDur: durs["defaultSSHHostDur"].dur,
|
||||
EnableSSHCA: &c.Ssh.Enabled,
|
||||
return &linkedca.Provisioner{
|
||||
Name: "Admin JWK",
|
||||
Type: linkedca.Provisioner_JWK,
|
||||
Claims: NewDefaultClaims(),
|
||||
Details: &linkedca.ProvisionerDetails{
|
||||
Data: &linkedca.ProvisionerDetails_JWK{
|
||||
JWK: &linkedca.JWKProvisioner{
|
||||
PublicKey: jwkPubBytes,
|
||||
EncryptedPrivateKey: []byte(jwePrivStr),
|
||||
},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -2,9 +2,14 @@ package authority
|
|||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/smallstep/certificates/authority/mgmt"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
"go.step.sm/crypto/jose"
|
||||
)
|
||||
|
||||
// GetEncryptedKey returns the JWE key corresponding to the given kid argument.
|
||||
|
@ -41,3 +46,205 @@ func (a *Authority) LoadProvisionerByID(id string) (provisioner.Interface, error
|
|||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func provisionerGetOptions(p *linkedca.Provisioner) *provisioner.Options {
|
||||
return &provisioner.Options{
|
||||
X509: &provisioner.X509Options{
|
||||
Template: string(p.X509Template),
|
||||
TemplateData: p.X509TemplateData,
|
||||
},
|
||||
SSH: &provisioner.SSHOptions{
|
||||
Template: string(p.SshTemplate),
|
||||
TemplateData: p.SshTemplateData,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func provisionerListToCertificates(l []*linkedca.Provisioner) (provisioner.List, error) {
|
||||
var nu provisioner.List
|
||||
for _, p := range l {
|
||||
certProv, err := provisionerToCertificates(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nu = append(nu, certProv)
|
||||
}
|
||||
return nu, nil
|
||||
}
|
||||
|
||||
// provisionerToCertificates converts the landlord provisioner type to the open source
|
||||
// provisioner type.
|
||||
func provisionerToCertificates(p *linkedca.Provisioner) (provisioner.Interface, error) {
|
||||
claims, err := claimsToCertificates(p.Claims)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
details := p.Details.GetData()
|
||||
if details == nil {
|
||||
return nil, fmt.Errorf("provisioner does not have any details")
|
||||
}
|
||||
|
||||
switch d := details.(type) {
|
||||
case *linkedca.ProvisionerDetails_JWK:
|
||||
jwk := new(jose.JSONWebKey)
|
||||
if err := json.Unmarshal(d.JWK.PublicKey, &jwk); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &provisioner.JWK{
|
||||
ID: p.Id,
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
Key: jwk,
|
||||
EncryptedKey: string(d.JWK.EncryptedPrivateKey),
|
||||
Claims: claims,
|
||||
Options: provisionerGetOptions(p),
|
||||
}, nil
|
||||
/*
|
||||
case *ProvisionerDetails_OIDC:
|
||||
cfg := d.OIDC
|
||||
return &provisioner.OIDC{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
TenantID: cfg.TenantId,
|
||||
ClientID: cfg.ClientId,
|
||||
ClientSecret: cfg.ClientSecret,
|
||||
ConfigurationEndpoint: cfg.ConfigurationEndpoint,
|
||||
Admins: cfg.Admins,
|
||||
Domains: cfg.Domains,
|
||||
Groups: cfg.Groups,
|
||||
ListenAddress: cfg.ListenAddress,
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_GCP:
|
||||
cfg := d.GCP
|
||||
return &provisioner.GCP{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
ServiceAccounts: cfg.ServiceAccounts,
|
||||
ProjectIDs: cfg.ProjectIds,
|
||||
DisableCustomSANs: cfg.DisableCustomSans,
|
||||
DisableTrustOnFirstUse: cfg.DisableTrustOnFirstUse,
|
||||
InstanceAge: durationValue(cfg.InstanceAge),
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_AWS:
|
||||
cfg := d.AWS
|
||||
return &provisioner.AWS{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
Accounts: cfg.Accounts,
|
||||
DisableCustomSANs: cfg.DisableCustomSans,
|
||||
DisableTrustOnFirstUse: cfg.DisableTrustOnFirstUse,
|
||||
InstanceAge: durationValue(cfg.InstanceAge),
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_Azure:
|
||||
cfg := d.Azure
|
||||
return &provisioner.Azure{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
TenantID: cfg.TenantId,
|
||||
ResourceGroups: cfg.ResourceGroups,
|
||||
Audience: cfg.Audience,
|
||||
DisableCustomSANs: cfg.DisableCustomSans,
|
||||
DisableTrustOnFirstUse: cfg.DisableTrustOnFirstUse,
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_X5C:
|
||||
var roots []byte
|
||||
for i, k := range d.X5C.GetRoots() {
|
||||
if b := k.GetKey().GetPublic(); b != nil {
|
||||
if i > 0 {
|
||||
roots = append(roots, '\n')
|
||||
}
|
||||
roots = append(roots, b...)
|
||||
}
|
||||
}
|
||||
return &provisioner.X5C{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
Roots: roots,
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_K8SSA:
|
||||
var publicKeys []byte
|
||||
for i, k := range d.K8SSA.GetPublicKeys() {
|
||||
if b := k.GetKey().GetPublic(); b != nil {
|
||||
if i > 0 {
|
||||
publicKeys = append(publicKeys, '\n')
|
||||
}
|
||||
publicKeys = append(publicKeys, k.Key.Public...)
|
||||
}
|
||||
}
|
||||
return &provisioner.K8sSA{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
PubKeys: publicKeys,
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
case *ProvisionerDetails_SSHPOP:
|
||||
return &provisioner.SSHPOP{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
Claims: claims,
|
||||
}, nil
|
||||
case *ProvisionerDetails_ACME:
|
||||
cfg := d.ACME
|
||||
return &provisioner.ACME{
|
||||
Type: p.Type.String(),
|
||||
Name: p.Name,
|
||||
ForceCN: cfg.ForceCn,
|
||||
Claims: claims,
|
||||
Options: options,
|
||||
}, nil
|
||||
*/
|
||||
default:
|
||||
return nil, fmt.Errorf("provisioner %s not implemented", p.Type)
|
||||
}
|
||||
}
|
||||
|
||||
// claimsToCertificates converts the landlord provisioner claims type to the open source
|
||||
// (step-ca) claims type.
|
||||
func claimsToCertificates(c *linkedca.Claims) (*provisioner.Claims, error) {
|
||||
var durs = map[string]struct {
|
||||
durStr string
|
||||
dur *provisioner.Duration
|
||||
}{
|
||||
"minTLSDur": {durStr: c.X509.Durations.Min},
|
||||
"maxTLSDur": {durStr: c.X509.Durations.Max},
|
||||
"defaultTLSDur": {durStr: c.X509.Durations.Default},
|
||||
"minSSHUserDur": {durStr: c.Ssh.UserDurations.Min},
|
||||
"maxSSHUserDur": {durStr: c.Ssh.UserDurations.Max},
|
||||
"defaultSSHUserDur": {durStr: c.Ssh.UserDurations.Default},
|
||||
"minSSHHostDur": {durStr: c.Ssh.HostDurations.Min},
|
||||
"maxSSHHostDur": {durStr: c.Ssh.HostDurations.Max},
|
||||
"defaultSSHHostDur": {durStr: c.Ssh.HostDurations.Default},
|
||||
}
|
||||
var err error
|
||||
for k, v := range durs {
|
||||
v.dur, err = provisioner.NewDuration(v.durStr)
|
||||
if err != nil {
|
||||
return nil, mgmt.WrapErrorISE(err, "error parsing %s %s from claims", k, v.durStr)
|
||||
}
|
||||
}
|
||||
return &provisioner.Claims{
|
||||
MinTLSDur: durs["minTLSDur"].dur,
|
||||
MaxTLSDur: durs["maxTLSDur"].dur,
|
||||
DefaultTLSDur: durs["defaultTLSDur"].dur,
|
||||
DisableRenewal: &c.DisableRenewal,
|
||||
MinUserSSHDur: durs["minSSHUserDur"].dur,
|
||||
MaxUserSSHDur: durs["maxSSHUserDur"].dur,
|
||||
DefaultUserSSHDur: durs["defaultSSHUserDur"].dur,
|
||||
MinHostSSHDur: durs["minSSHHostDur"].dur,
|
||||
MaxHostSSHDur: durs["maxSSHHostDur"].dur,
|
||||
DefaultHostSSHDur: durs["defaultSSHHostDur"].dur,
|
||||
EnableSSHCA: &c.Ssh.Enabled,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -10,12 +10,14 @@ import (
|
|||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/smallstep/certificates/authority/admin"
|
||||
"github.com/smallstep/certificates/authority/mgmt"
|
||||
mgmtAPI "github.com/smallstep/certificates/authority/mgmt/api"
|
||||
"github.com/smallstep/certificates/errs"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
)
|
||||
|
||||
var adminURLPrefix = "admin"
|
||||
|
||||
// AdminClient implements an HTTP client for the CA server.
|
||||
type AdminClient struct {
|
||||
client *uaClient
|
||||
|
@ -68,9 +70,9 @@ func (c *AdminClient) retryOnError(r *http.Response) bool {
|
|||
}
|
||||
|
||||
// GetAdmin performs the GET /admin/admin/{id} request to the CA.
|
||||
func (c *AdminClient) GetAdmin(id string) (*mgmt.Admin, error) {
|
||||
func (c *AdminClient) GetAdmin(id string) (*linkedca.Admin, 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(adminURLPrefix, "admins", id)})
|
||||
retry:
|
||||
resp, err := c.client.Get(u.String())
|
||||
if err != nil {
|
||||
|
@ -83,7 +85,7 @@ retry:
|
|||
}
|
||||
return nil, readAdminError(resp.Body)
|
||||
}
|
||||
var adm = new(mgmt.Admin)
|
||||
var adm = new(linkedca.Admin)
|
||||
if err := readJSON(resp.Body, adm); err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||
}
|
||||
|
@ -165,7 +167,7 @@ retry:
|
|||
}
|
||||
|
||||
// CreateAdmin performs the POST /admin/admins request to the CA.
|
||||
func (c *AdminClient) CreateAdmin(req *mgmtAPI.CreateAdminRequest) (*mgmt.Admin, error) {
|
||||
func (c *AdminClient) CreateAdmin(req *mgmtAPI.CreateAdminRequest) (*linkedca.Admin, error) {
|
||||
var retried bool
|
||||
body, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
|
@ -184,7 +186,7 @@ retry:
|
|||
}
|
||||
return nil, readAdminError(resp.Body)
|
||||
}
|
||||
var adm = new(mgmt.Admin)
|
||||
var adm = new(linkedca.Admin)
|
||||
if err := readJSON(resp.Body, adm); err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||
}
|
||||
|
@ -194,7 +196,7 @@ retry:
|
|||
// 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/admins", id)})
|
||||
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "admins", id)})
|
||||
req, err := http.NewRequest("DELETE", u.String(), nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "create DELETE %s request failed", u)
|
||||
|
@ -215,13 +217,13 @@ retry:
|
|||
}
|
||||
|
||||
// UpdateAdmin performs the PUT /admin/admins/{id} request to the CA.
|
||||
func (c *AdminClient) UpdateAdmin(id string, uar *mgmtAPI.UpdateAdminRequest) (*admin.Admin, error) {
|
||||
func (c *AdminClient) UpdateAdmin(id string, uar *mgmtAPI.UpdateAdminRequest) (*linkedca.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/admins", id)})
|
||||
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "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)
|
||||
|
@ -238,7 +240,7 @@ retry:
|
|||
}
|
||||
return nil, readAdminError(resp.Body)
|
||||
}
|
||||
var adm = new(admin.Admin)
|
||||
var adm = new(linkedca.Admin)
|
||||
if err := readJSON(resp.Body, adm); err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||
}
|
||||
|
@ -246,9 +248,9 @@ retry:
|
|||
}
|
||||
|
||||
// GetProvisioner performs the GET /admin/provisioners/{name} request to the CA.
|
||||
func (c *AdminClient) GetProvisioner(name string) (*mgmt.Provisioner, error) {
|
||||
func (c *AdminClient) GetProvisioner(name string) (*linkedca.Provisioner, error) {
|
||||
var retried bool
|
||||
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join("/admin/provisioners", name)})
|
||||
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "provisioners", name)})
|
||||
retry:
|
||||
resp, err := c.client.Get(u.String())
|
||||
if err != nil {
|
||||
|
@ -261,7 +263,7 @@ retry:
|
|||
}
|
||||
return nil, readAdminError(resp.Body)
|
||||
}
|
||||
var prov = new(mgmt.Provisioner)
|
||||
var prov = new(linkedca.Provisioner)
|
||||
if err := readJSON(resp.Body, prov); err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||
}
|
||||
|
@ -269,7 +271,7 @@ retry:
|
|||
}
|
||||
|
||||
// GetProvisioners performs the GET /admin/provisioners request to the CA.
|
||||
func (c *AdminClient) GetProvisioners() ([]*mgmt.Provisioner, error) {
|
||||
func (c *AdminClient) GetProvisioners() ([]*linkedca.Provisioner, error) {
|
||||
var retried bool
|
||||
u := c.endpoint.ResolveReference(&url.URL{Path: "/admin/provisioners"})
|
||||
retry:
|
||||
|
@ -284,7 +286,7 @@ retry:
|
|||
}
|
||||
return nil, readAdminError(resp.Body)
|
||||
}
|
||||
var provs = new([]*mgmt.Provisioner)
|
||||
var provs = new([]*linkedca.Provisioner)
|
||||
if err := readJSON(resp.Body, provs); err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||
}
|
||||
|
@ -294,7 +296,7 @@ retry:
|
|||
// 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/provisioners", name)})
|
||||
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "provisioners", name)})
|
||||
req, err := http.NewRequest("DELETE", u.String(), nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "create DELETE %s request failed", u)
|
||||
|
@ -315,7 +317,7 @@ retry:
|
|||
}
|
||||
|
||||
// CreateProvisioner performs the POST /admin/provisioners request to the CA.
|
||||
func (c *AdminClient) CreateProvisioner(prov *mgmt.Provisioner) (*mgmt.Provisioner, error) {
|
||||
func (c *AdminClient) CreateProvisioner(prov *linkedca.Provisioner) (*linkedca.Provisioner, error) {
|
||||
var retried bool
|
||||
body, err := json.Marshal(prov)
|
||||
if err != nil {
|
||||
|
@ -334,7 +336,7 @@ retry:
|
|||
}
|
||||
return nil, readAdminError(resp.Body)
|
||||
}
|
||||
var nuProv = new(mgmt.Provisioner)
|
||||
var nuProv = new(linkedca.Provisioner)
|
||||
if err := readJSON(resp.Body, nuProv); err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||
}
|
||||
|
@ -342,13 +344,13 @@ retry:
|
|||
}
|
||||
|
||||
// UpdateProvisioner performs the PUT /admin/provisioners/{id} request to the CA.
|
||||
func (c *AdminClient) UpdateProvisioner(id string, upr *mgmtAPI.UpdateProvisionerRequest) (*mgmt.Provisioner, error) {
|
||||
func (c *AdminClient) UpdateProvisioner(id string, upr *mgmtAPI.UpdateProvisionerRequest) (*linkedca.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/provisioners", id)})
|
||||
u := c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "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)
|
||||
|
@ -365,36 +367,13 @@ retry:
|
|||
}
|
||||
return nil, readAdminError(resp.Body)
|
||||
}
|
||||
var prov = new(mgmt.Provisioner)
|
||||
var prov = new(linkedca.Provisioner)
|
||||
if err := readJSON(resp.Body, prov); err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||
}
|
||||
return prov, nil
|
||||
}
|
||||
|
||||
// GetAuthConfig performs the GET /admin/authconfig/{id} request to the CA.
|
||||
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:
|
||||
resp, err := c.client.Get(u.String())
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "client GET %s failed", u)
|
||||
}
|
||||
if resp.StatusCode >= 400 {
|
||||
if !retried && c.retryOnError(resp) {
|
||||
retried = true
|
||||
goto retry
|
||||
}
|
||||
return nil, readAdminError(resp.Body)
|
||||
}
|
||||
var ac = new(mgmt.AuthConfig)
|
||||
if err := readJSON(resp.Body, ac); err != nil {
|
||||
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||
}
|
||||
return ac, nil
|
||||
}
|
||||
|
||||
func readAdminError(r io.ReadCloser) error {
|
||||
defer r.Close()
|
||||
mgmtErr := new(mgmt.Error)
|
||||
|
|
Loading…
Reference in a new issue