forked from TrueCloudLab/certificates
wip
This commit is contained in:
parent
af3cf7dae9
commit
98a6e54530
7 changed files with 194 additions and 126 deletions
|
@ -4,25 +4,21 @@ import "context"
|
||||||
|
|
||||||
// Admin type.
|
// Admin type.
|
||||||
type Admin struct {
|
type Admin struct {
|
||||||
ID string `json:"-"`
|
ID string `json:"id"`
|
||||||
AuthorityID string `json:"-"`
|
AuthorityID string `json:"-"`
|
||||||
ProvisionerID string `json:"provisionerID"`
|
ProvisionerID string `json:"provisionerID"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ProvisionerName string `json:"provisionerName"`
|
IsSuperAdmin bool `json:"isSuperAdmin"`
|
||||||
ProvisionerType string `json:"provisionerType"`
|
Status StatusType `json:"status"`
|
||||||
IsSuperAdmin bool `json:"isSuperAdmin"`
|
|
||||||
Status StatusType `json:"status"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateAdmin builds and stores an admin type in the DB.
|
// CreateAdmin builds and stores an admin type in the DB.
|
||||||
func CreateAdmin(ctx context.Context, db DB, name string, prov *Provisioner, isSuperAdmin bool) (*Admin, error) {
|
func CreateAdmin(ctx context.Context, db DB, name string, provID string, isSuperAdmin bool) (*Admin, error) {
|
||||||
adm := &Admin{
|
adm := &Admin{
|
||||||
Name: name,
|
Name: name,
|
||||||
ProvisionerID: prov.ID,
|
ProvisionerID: provID,
|
||||||
ProvisionerName: prov.Name,
|
IsSuperAdmin: isSuperAdmin,
|
||||||
ProvisionerType: prov.Type,
|
Status: StatusActive,
|
||||||
IsSuperAdmin: isSuperAdmin,
|
|
||||||
Status: StatusActive,
|
|
||||||
}
|
}
|
||||||
if err := db.CreateAdmin(ctx, adm); err != nil {
|
if err := db.CreateAdmin(ctx, adm); err != nil {
|
||||||
return nil, WrapErrorISE(err, "error creating admin")
|
return nil, WrapErrorISE(err, "error creating admin")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"github.com/go-chi/chi"
|
"github.com/go-chi/chi"
|
||||||
|
@ -10,12 +11,14 @@ import (
|
||||||
|
|
||||||
// CreateProvisionerRequest represents the body for a CreateProvisioner request.
|
// CreateProvisionerRequest represents the body for a CreateProvisioner request.
|
||||||
type CreateProvisionerRequest struct {
|
type CreateProvisionerRequest struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Claims *mgmt.Claims `json:"claims"`
|
Claims *mgmt.Claims `json:"claims"`
|
||||||
Details interface{} `json:"details"`
|
Details interface{} `json:"details"`
|
||||||
X509Template string `json:"x509Template"`
|
X509Template string `json:"x509Template"`
|
||||||
SSHTemplate string `json:"sshTemplate"`
|
X509TemplateData []byte `json:"x509TemplateData"`
|
||||||
|
SSHTemplate string `json:"sshTemplate"`
|
||||||
|
SSHTemplateData []byte `json:"sshTemplateData"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates a new-provisioner request body.
|
// Validate validates a new-provisioner request body.
|
||||||
|
@ -25,10 +28,12 @@ func (car *CreateProvisionerRequest) Validate() error {
|
||||||
|
|
||||||
// UpdateProvisionerRequest represents the body for a UpdateProvisioner request.
|
// UpdateProvisionerRequest represents the body for a UpdateProvisioner request.
|
||||||
type UpdateProvisionerRequest struct {
|
type UpdateProvisionerRequest struct {
|
||||||
Claims *mgmt.Claims `json:"claims"`
|
Claims *mgmt.Claims `json:"claims"`
|
||||||
Details interface{} `json:"details"`
|
Details interface{} `json:"details"`
|
||||||
X509Template string `json:"x509Template"`
|
X509Template string `json:"x509Template"`
|
||||||
SSHTemplate string `json:"sshTemplate"`
|
X509TemplateData []byte `json:"x509TemplateData"`
|
||||||
|
SSHTemplate string `json:"sshTemplate"`
|
||||||
|
SSHTemplateData []byte `json:"sshTemplateData"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates a new-provisioner request body.
|
// Validate validates a new-provisioner request body.
|
||||||
|
@ -58,6 +63,7 @@ func (h *Handler) GetProvisioners(w http.ResponseWriter, r *http.Request) {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
fmt.Printf("provs = %+v\n", provs)
|
||||||
api.JSON(w, provs)
|
api.JSON(w, provs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,12 +81,14 @@ func (h *Handler) CreateProvisioner(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
prov := &mgmt.Provisioner{
|
prov := &mgmt.Provisioner{
|
||||||
Type: body.Type,
|
Type: body.Type,
|
||||||
Name: body.Name,
|
Name: body.Name,
|
||||||
Claims: body.Claims,
|
Claims: body.Claims,
|
||||||
Details: body.Details,
|
Details: body.Details,
|
||||||
X509Template: body.X509Template,
|
X509Template: body.X509Template,
|
||||||
SSHTemplate: body.SSHTemplate,
|
X509TemplateData: body.X509TemplateData,
|
||||||
|
SSHTemplate: body.SSHTemplate,
|
||||||
|
SSHTemplateData: body.SSHTemplateData,
|
||||||
}
|
}
|
||||||
if err := h.db.CreateProvisioner(ctx, prov); err != nil {
|
if err := h.db.CreateProvisioner(ctx, prov); err != nil {
|
||||||
api.WriteError(w, err)
|
api.WriteError(w, err)
|
||||||
|
|
|
@ -2,6 +2,7 @@ package mgmt
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/smallstep/certificates/authority/config"
|
"github.com/smallstep/certificates/authority/config"
|
||||||
|
@ -24,6 +25,17 @@ const (
|
||||||
StatusDeleted
|
StatusDeleted
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (st StatusType) String() string {
|
||||||
|
switch st {
|
||||||
|
case StatusActive:
|
||||||
|
return "active"
|
||||||
|
case StatusDeleted:
|
||||||
|
return "deleted"
|
||||||
|
default:
|
||||||
|
return fmt.Sprintf("status %d not found", st)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Claims encapsulates all x509 and ssh claims applied to the authority
|
// Claims encapsulates all x509 and ssh claims applied to the authority
|
||||||
// configuration. E.g. maxTLSCertDuration, defaultSSHCertDuration, etc.
|
// configuration. E.g. maxTLSCertDuration, defaultSSHCertDuration, etc.
|
||||||
type Claims struct {
|
type Claims struct {
|
||||||
|
@ -111,7 +123,7 @@ func CreateAuthority(ctx context.Context, db DB, options ...AuthorityOption) (*A
|
||||||
return nil, WrapErrorISE(err, "error creating first provisioner")
|
return nil, WrapErrorISE(err, "error creating first provisioner")
|
||||||
}
|
}
|
||||||
|
|
||||||
admin, err := CreateAdmin(ctx, db, "Change Me", prov, true)
|
admin, err := CreateAdmin(ctx, db, "Change Me", prov.ID, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO should we try to clean up?
|
// TODO should we try to clean up?
|
||||||
return nil, WrapErrorISE(err, "error creating first provisioner")
|
return nil, WrapErrorISE(err, "error creating first provisioner")
|
||||||
|
|
|
@ -63,19 +63,13 @@ func (db *DB) GetAdmin(ctx context.Context, id string) (*mgmt.Admin, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if adm.Status == mgmt.StatusDeleted {
|
if adm.Status == mgmt.StatusDeleted {
|
||||||
return nil, mgmt.NewError(mgmt.ErrorDeletedType, "admin %s is deleted")
|
return nil, mgmt.NewError(mgmt.ErrorDeletedType, "admin %s is deleted", adm.ID)
|
||||||
}
|
}
|
||||||
if adm.AuthorityID != db.authorityID {
|
if adm.AuthorityID != db.authorityID {
|
||||||
return nil, mgmt.NewError(mgmt.ErrorAuthorityMismatchType,
|
return nil, mgmt.NewError(mgmt.ErrorAuthorityMismatchType,
|
||||||
"admin %s is not owned by authority %s", adm.ID, db.authorityID)
|
"admin %s is not owned by authority %s", adm.ID, db.authorityID)
|
||||||
}
|
}
|
||||||
|
|
||||||
prov, err := db.GetProvisioner(ctx, adm.ProvisionerID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
adm.ProvisionerName = prov.Name
|
|
||||||
adm.ProvisionerType = prov.Type
|
|
||||||
return adm, nil
|
return adm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package nosql
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
@ -12,16 +13,18 @@ import (
|
||||||
|
|
||||||
// dbProvisioner is the database representation of a Provisioner type.
|
// dbProvisioner is the database representation of a Provisioner type.
|
||||||
type dbProvisioner struct {
|
type dbProvisioner struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
AuthorityID string `json:"authorityID"`
|
AuthorityID string `json:"authorityID"`
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Claims *mgmt.Claims `json:"claims"`
|
Claims *mgmt.Claims `json:"claims"`
|
||||||
Details interface{} `json:"details"`
|
Details []byte `json:"details"`
|
||||||
X509Template string `json:"x509Template"`
|
X509Template string `json:"x509Template"`
|
||||||
SSHTemplate string `json:"sshTemplate"`
|
X509TemplateData []byte `json:"x509TemplateData"`
|
||||||
CreatedAt time.Time `json:"createdAt"`
|
SSHTemplate string `json:"sshTemplate"`
|
||||||
DeletedAt time.Time `json:"deletedAt"`
|
SSHTemplateData []byte `json:"sshTemplateData"`
|
||||||
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
|
DeletedAt time.Time `json:"deletedAt"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dbp *dbProvisioner) clone() *dbProvisioner {
|
func (dbp *dbProvisioner) clone() *dbProvisioner {
|
||||||
|
@ -84,19 +87,36 @@ func unmarshalDBProvisioner(data []byte, id string) (*dbProvisioner, error) {
|
||||||
return dbp, nil
|
return dbp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type detailsType struct {
|
||||||
|
Type mgmt.ProvisionerType
|
||||||
|
}
|
||||||
|
|
||||||
func unmarshalProvisioner(data []byte, id string) (*mgmt.Provisioner, error) {
|
func unmarshalProvisioner(data []byte, id string) (*mgmt.Provisioner, error) {
|
||||||
dbp, err := unmarshalDBProvisioner(data, id)
|
dbp, err := unmarshalDBProvisioner(data, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dt := new(detailsType)
|
||||||
|
if err := json.Unmarshal(dbp.Details, dt); err != nil {
|
||||||
|
return nil, mgmt.WrapErrorISE(err, "error unmarshaling details to detailsType for provisioner %s", id)
|
||||||
|
}
|
||||||
|
details, err := unmarshalDetails(dt.Type, dbp.Details)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
prov := &mgmt.Provisioner{
|
prov := &mgmt.Provisioner{
|
||||||
ID: dbp.ID,
|
ID: dbp.ID,
|
||||||
Type: dbp.Type,
|
AuthorityID: dbp.AuthorityID,
|
||||||
Name: dbp.Name,
|
Type: dbp.Type,
|
||||||
Claims: dbp.Claims,
|
Name: dbp.Name,
|
||||||
X509Template: dbp.X509Template,
|
Claims: dbp.Claims,
|
||||||
SSHTemplate: dbp.SSHTemplate,
|
Details: details,
|
||||||
|
X509Template: dbp.X509Template,
|
||||||
|
X509TemplateData: dbp.X509TemplateData,
|
||||||
|
SSHTemplate: dbp.SSHTemplate,
|
||||||
|
SSHTemplateData: dbp.SSHTemplateData,
|
||||||
}
|
}
|
||||||
if !dbp.DeletedAt.IsZero() {
|
if !dbp.DeletedAt.IsZero() {
|
||||||
prov.Status = mgmt.StatusDeleted
|
prov.Status = mgmt.StatusDeleted
|
||||||
|
@ -172,3 +192,66 @@ func (db *DB) UpdateProvisioner(ctx context.Context, prov *mgmt.Provisioner) err
|
||||||
|
|
||||||
return db.save(ctx, old.ID, nu, old, "provisioner", authorityProvisionersTable)
|
return db.save(ctx, old.ID, nu, old, "provisioner", authorityProvisionersTable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unmarshalDetails(typ ProvisionerType, details []byte) (interface{}, error) {
|
||||||
|
if !s.Valid {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
var v isProvisionerDetails_Data
|
||||||
|
switch typ {
|
||||||
|
case ProvisionerTypeJWK:
|
||||||
|
p := new(ProvisionerDetailsJWK)
|
||||||
|
if err := json.Unmarshal([]byte(s.String), p); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if p.JWK.Key.Key == nil {
|
||||||
|
key, err := LoadKey(ctx, db, p.JWK.Key.Id.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
p.JWK.Key = key
|
||||||
|
}
|
||||||
|
return &ProvisionerDetails{Data: p}, nil
|
||||||
|
case ProvisionerType_OIDC:
|
||||||
|
v = new(ProvisionerDetails_OIDC)
|
||||||
|
case ProvisionerType_GCP:
|
||||||
|
v = new(ProvisionerDetails_GCP)
|
||||||
|
case ProvisionerType_AWS:
|
||||||
|
v = new(ProvisionerDetails_AWS)
|
||||||
|
case ProvisionerType_AZURE:
|
||||||
|
v = new(ProvisionerDetails_Azure)
|
||||||
|
case ProvisionerType_ACME:
|
||||||
|
v = new(ProvisionerDetails_ACME)
|
||||||
|
case ProvisionerType_X5C:
|
||||||
|
p := new(ProvisionerDetails_X5C)
|
||||||
|
if err := json.Unmarshal([]byte(s.String), p); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, k := range p.X5C.GetRoots() {
|
||||||
|
if err := k.Select(ctx, db, k.Id.Id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &ProvisionerDetails{Data: p}, nil
|
||||||
|
case ProvisionerType_K8SSA:
|
||||||
|
p := new(ProvisionerDetails_K8SSA)
|
||||||
|
if err := json.Unmarshal([]byte(s.String), p); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, k := range p.K8SSA.GetPublicKeys() {
|
||||||
|
if err := k.Select(ctx, db, k.Id.Id); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &ProvisionerDetails{Data: p}, nil
|
||||||
|
case ProvisionerType_SSHPOP:
|
||||||
|
v = new(ProvisionerDetails_SSHPOP)
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported provisioner type %s", typ)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal([]byte(s.String), v); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &ProvisionerDetails{Data: v}, nil
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,17 @@ type ProvisionerCtx struct {
|
||||||
Password string
|
Password string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProvisionerType string
|
||||||
|
|
||||||
|
var (
|
||||||
|
ProvisionerTypeJWK = ProvisionerType("JWK")
|
||||||
|
ProvisionerTypeOIDC = ProvisionerType("OIDC")
|
||||||
|
ProvisionerTypeACME = ProvisionerType("ACME")
|
||||||
|
ProvisionerTypeX5C = ProvisionerType("X5C")
|
||||||
|
ProvisionerTypeK8S = ProvisionerType("K8S")
|
||||||
|
ProvisionerTypeSSHPOP = ProvisionerType("SSHPOP")
|
||||||
|
)
|
||||||
|
|
||||||
func NewProvisionerCtx(opts ...ProvisionerOption) *ProvisionerCtx {
|
func NewProvisionerCtx(opts ...ProvisionerOption) *ProvisionerCtx {
|
||||||
pc := &ProvisionerCtx{
|
pc := &ProvisionerCtx{
|
||||||
Claims: NewDefaultClaims(),
|
Claims: NewDefaultClaims(),
|
||||||
|
@ -97,12 +108,14 @@ func CreateProvisioner(ctx context.Context, db DB, typ, name string, opts ...Pro
|
||||||
return p, nil
|
return p, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProvisionerDetails_JWK struct {
|
// ProvisionerDetailsJWK represents the values required by a JWK provisioner.
|
||||||
PubKey []byte `json:"pubKey"`
|
type ProvisionerDetailsJWK struct {
|
||||||
PrivKey string `json:"privKey"`
|
Type ProvisionerType `json:"type"`
|
||||||
|
PubKey []byte `json:"pubKey"`
|
||||||
|
EncPrivKey string `json:"privKey"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func createJWKDetails(pc *ProvisionerCtx) (*ProvisionerDetails_JWK, error) {
|
func createJWKDetails(pc *ProvisionerCtx) (*ProvisionerDetailsJWK, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if pc.JWK != nil && pc.JWE == nil {
|
if pc.JWK != nil && pc.JWE == nil {
|
||||||
|
@ -131,9 +144,10 @@ func createJWKDetails(pc *ProvisionerCtx) (*ProvisionerDetails_JWK, error) {
|
||||||
return nil, WrapErrorISE(err, "error serializing JWE")
|
return nil, WrapErrorISE(err, "error serializing JWE")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ProvisionerDetails_JWK{
|
return &ProvisionerDetailsJWK{
|
||||||
PubKey: jwkPubBytes,
|
Type: ProvisionerTypeJWK,
|
||||||
PrivKey: jwePrivStr,
|
PubKey: jwkPubBytes,
|
||||||
|
EncPrivKey: jwePrivStr,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +164,7 @@ func (p *Provisioner) ToCertificates() (provisioner.Interface, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
switch details := p.Details.(type) {
|
switch details := p.Details.(type) {
|
||||||
case *ProvisionerDetails_JWK:
|
case *ProvisionerDetailsJWK:
|
||||||
jwk := new(jose.JSONWebKey)
|
jwk := new(jose.JSONWebKey)
|
||||||
if err := json.Unmarshal(details.PubKey, &jwk); err != nil {
|
if err := json.Unmarshal(details.PubKey, &jwk); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -159,7 +173,7 @@ func (p *Provisioner) ToCertificates() (provisioner.Interface, error) {
|
||||||
Type: p.Type,
|
Type: p.Type,
|
||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
Key: jwk,
|
Key: jwk,
|
||||||
EncryptedKey: details.PrivKey,
|
EncryptedKey: details.EncPrivKey,
|
||||||
Claims: claims,
|
Claims: claims,
|
||||||
Options: p.GetOptions(),
|
Options: p.GetOptions(),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -324,68 +338,6 @@ func marshalDetails(d *ProvisionerDetails) (sql.NullString, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func unmarshalDetails(ctx context.Context, db database.DB, typ ProvisionerType, s sql.NullString) (*ProvisionerDetails, error) {
|
|
||||||
if !s.Valid {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
var v isProvisionerDetails_Data
|
|
||||||
switch typ {
|
|
||||||
case ProvisionerType_JWK:
|
|
||||||
p := new(ProvisionerDetails_JWK)
|
|
||||||
if err := json.Unmarshal([]byte(s.String), p); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if p.JWK.Key.Key == nil {
|
|
||||||
key, err := LoadKey(ctx, db, p.JWK.Key.Id.Id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
p.JWK.Key = key
|
|
||||||
}
|
|
||||||
return &ProvisionerDetails{Data: p}, nil
|
|
||||||
case ProvisionerType_OIDC:
|
|
||||||
v = new(ProvisionerDetails_OIDC)
|
|
||||||
case ProvisionerType_GCP:
|
|
||||||
v = new(ProvisionerDetails_GCP)
|
|
||||||
case ProvisionerType_AWS:
|
|
||||||
v = new(ProvisionerDetails_AWS)
|
|
||||||
case ProvisionerType_AZURE:
|
|
||||||
v = new(ProvisionerDetails_Azure)
|
|
||||||
case ProvisionerType_ACME:
|
|
||||||
v = new(ProvisionerDetails_ACME)
|
|
||||||
case ProvisionerType_X5C:
|
|
||||||
p := new(ProvisionerDetails_X5C)
|
|
||||||
if err := json.Unmarshal([]byte(s.String), p); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, k := range p.X5C.GetRoots() {
|
|
||||||
if err := k.Select(ctx, db, k.Id.Id); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &ProvisionerDetails{Data: p}, nil
|
|
||||||
case ProvisionerType_K8SSA:
|
|
||||||
p := new(ProvisionerDetails_K8SSA)
|
|
||||||
if err := json.Unmarshal([]byte(s.String), p); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, k := range p.K8SSA.GetPublicKeys() {
|
|
||||||
if err := k.Select(ctx, db, k.Id.Id); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return &ProvisionerDetails{Data: p}, nil
|
|
||||||
case ProvisionerType_SSHPOP:
|
|
||||||
v = new(ProvisionerDetails_SSHPOP)
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("unsupported provisioner type %s", typ)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := json.Unmarshal([]byte(s.String), v); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &ProvisionerDetails{Data: v}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func marshalClaims(c *Claims) (sql.NullString, error) {
|
func marshalClaims(c *Claims) (sql.NullString, error) {
|
||||||
b, err := json.Marshal(c)
|
b, err := json.Marshal(c)
|
||||||
|
|
|
@ -105,3 +105,26 @@ retry:
|
||||||
}
|
}
|
||||||
return *admins, nil
|
return *admins, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetProvisioners performs the GET /mgmt/provisioners request to the CA.
|
||||||
|
func (c *MgmtClient) GetProvisioners() ([]*mgmt.Provisioner, error) {
|
||||||
|
var retried bool
|
||||||
|
u := c.endpoint.ResolveReference(&url.URL{Path: "/mgmt/provisioners"})
|
||||||
|
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, readError(resp.Body)
|
||||||
|
}
|
||||||
|
var provs = new([]*mgmt.Provisioner)
|
||||||
|
if err := readJSON(resp.Body, provs); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "error reading %s", u)
|
||||||
|
}
|
||||||
|
return *provs, nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue