forked from TrueCloudLab/certificates
wip
This commit is contained in:
parent
423942da44
commit
1726076ea2
9 changed files with 154 additions and 298 deletions
|
@ -178,12 +178,3 @@ func loadAdmin(m *sync.Map, key string) (*linkedca.Admin, bool) {
|
|||
}
|
||||
return adm, true
|
||||
}
|
||||
|
||||
/*
|
||||
// provisionerSum returns the SHA1 of the provisioners ID. From this we will
|
||||
// create the unique and sorted id.
|
||||
func provisionerSum(p Interface) []byte {
|
||||
sum := sha1.Sum([]byte(p.GetID()))
|
||||
return sum[:]
|
||||
}
|
||||
*/
|
||||
|
|
|
@ -8,11 +8,11 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/smallstep/certificates/authority/admin"
|
||||
"github.com/smallstep/certificates/authority/provisioner"
|
||||
cas "github.com/smallstep/certificates/cas/apiv1"
|
||||
"github.com/smallstep/certificates/db"
|
||||
kms "github.com/smallstep/certificates/kms/apiv1"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
"github.com/smallstep/certificates/templates"
|
||||
)
|
||||
|
||||
|
@ -96,7 +96,7 @@ type AuthConfig struct {
|
|||
*cas.Options
|
||||
AuthorityID string `json:"authorityID,omitempty"`
|
||||
Provisioners provisioner.List `json:"provisioners"`
|
||||
Admins []*admin.Admin `json:"-"`
|
||||
Admins []*linkedca.Admin `json:"-"`
|
||||
Template *ASN1DN `json:"template,omitempty"`
|
||||
Claims *provisioner.Claims `json:"claims,omitempty"`
|
||||
DisableIssuedAtCheck bool `json:"disableIssuedAtCheck,omitempty"`
|
||||
|
|
|
@ -2,6 +2,7 @@ package mgmt
|
|||
|
||||
import (
|
||||
"github.com/smallstep/certificates/authority/config"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -11,49 +12,22 @@ const (
|
|||
DefaultAuthorityID = "00000000-0000-0000-0000-000000000000"
|
||||
)
|
||||
|
||||
// Claims encapsulates all x509 and ssh claims applied to the authority
|
||||
// configuration. E.g. maxTLSCertDuration, defaultSSHCertDuration, etc.
|
||||
type Claims struct {
|
||||
X509 *X509Claims `json:"x509Claims"`
|
||||
SSH *SSHClaims `json:"sshClaims"`
|
||||
DisableRenewal bool `json:"disableRenewal"`
|
||||
}
|
||||
|
||||
// X509Claims are the x509 claims applied to the authority.
|
||||
type X509Claims struct {
|
||||
Durations *Durations `json:"durations"`
|
||||
}
|
||||
|
||||
// SSHClaims are the ssh claims applied to the authority.
|
||||
type SSHClaims struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
UserDurations *Durations `json:"userDurations"`
|
||||
HostDurations *Durations `json:"hostDurations"`
|
||||
}
|
||||
|
||||
// Durations represents min, max, default, duration.
|
||||
type Durations struct {
|
||||
Min string `json:"min"`
|
||||
Max string `json:"max"`
|
||||
Default string `json:"default"`
|
||||
}
|
||||
|
||||
func NewDefaultClaims() *Claims {
|
||||
return &Claims{
|
||||
X509: &X509Claims{
|
||||
Durations: &Durations{
|
||||
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: &SSHClaims{
|
||||
UserDurations: &Durations{
|
||||
Ssh: &linkedca.SSHClaims{
|
||||
UserDurations: &linkedca.Durations{
|
||||
Min: config.GlobalProvisionerClaims.MinUserSSHDur.String(),
|
||||
Max: config.GlobalProvisionerClaims.MaxUserSSHDur.String(),
|
||||
Default: config.GlobalProvisionerClaims.DefaultUserSSHDur.String(),
|
||||
},
|
||||
HostDurations: &Durations{
|
||||
HostDurations: &linkedca.Durations{
|
||||
Min: config.GlobalProvisionerClaims.MinHostSSHDur.String(),
|
||||
Max: config.GlobalProvisionerClaims.MaxHostSSHDur.String(),
|
||||
Default: config.GlobalProvisionerClaims.DefaultHostSSHDur.String(),
|
||||
|
|
|
@ -17,11 +17,13 @@ type DB interface {
|
|||
GetProvisioner(ctx context.Context, id string) (*linkedca.Provisioner, error)
|
||||
GetProvisioners(ctx context.Context) ([]*linkedca.Provisioner, error)
|
||||
UpdateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error
|
||||
DeleteProvisioner(ctx context.Context, id string) error
|
||||
|
||||
CreateAdmin(ctx context.Context, admin *linkedca.Admin) error
|
||||
GetAdmin(ctx context.Context, id string) (*linkedca.Admin, error)
|
||||
GetAdmins(ctx context.Context) ([]*linkedca.Admin, error)
|
||||
UpdateAdmin(ctx context.Context, admin *linkedca.Admin) error
|
||||
DeleteAdmin(ctx context.Context, id string) error
|
||||
}
|
||||
|
||||
// MockDB is an implementation of the DB interface that should only be used as
|
||||
|
@ -31,11 +33,13 @@ type MockDB struct {
|
|||
MockGetProvisioner func(ctx context.Context, id string) (*linkedca.Provisioner, error)
|
||||
MockGetProvisioners func(ctx context.Context) ([]*linkedca.Provisioner, error)
|
||||
MockUpdateProvisioner func(ctx context.Context, prov *linkedca.Provisioner) error
|
||||
MockDeleteProvisioner func(ctx context.Context, id string) error
|
||||
|
||||
MockCreateAdmin func(ctx context.Context, adm *linkedca.Admin) error
|
||||
MockGetAdmin func(ctx context.Context, id string) (*linkedca.Admin, error)
|
||||
MockGetAdmins func(ctx context.Context) ([]*linkedca.Admin, error)
|
||||
MockUpdateAdmin func(ctx context.Context, adm *linkedca.Admin) error
|
||||
MockDeleteAdmin func(ctx context.Context, id string) error
|
||||
|
||||
MockError error
|
||||
MockRet1 interface{}
|
||||
|
@ -79,6 +83,14 @@ func (m *MockDB) UpdateProvisioner(ctx context.Context, prov *linkedca.Provision
|
|||
return m.MockError
|
||||
}
|
||||
|
||||
// DeleteProvisioner mock
|
||||
func (m *MockDB) DeleteProvisioner(ctx context.Context, id string) error {
|
||||
if m.MockDeleteProvisioner != nil {
|
||||
return m.MockDeleteProvisioner(ctx, id)
|
||||
}
|
||||
return m.MockError
|
||||
}
|
||||
|
||||
// CreateAdmin mock
|
||||
func (m *MockDB) CreateAdmin(ctx context.Context, admin *linkedca.Admin) error {
|
||||
if m.MockCreateAdmin != nil {
|
||||
|
@ -114,3 +126,11 @@ func (m *MockDB) UpdateAdmin(ctx context.Context, adm *linkedca.Admin) error {
|
|||
}
|
||||
return m.MockError
|
||||
}
|
||||
|
||||
// DeleteAdmin mock
|
||||
func (m *MockDB) DeleteAdmin(ctx context.Context, id string) error {
|
||||
if m.MockDeleteAdmin != nil {
|
||||
return m.MockDeleteAdmin(ctx, id)
|
||||
}
|
||||
return m.MockError
|
||||
}
|
||||
|
|
|
@ -6,21 +6,20 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/smallstep/certificates/authority/admin"
|
||||
"github.com/smallstep/certificates/authority/mgmt"
|
||||
"github.com/smallstep/certificates/authority/status"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
"github.com/smallstep/nosql"
|
||||
)
|
||||
|
||||
// dbAdmin is the database representation of the Admin type.
|
||||
type dbAdmin struct {
|
||||
ID string `json:"id"`
|
||||
AuthorityID string `json:"authorityID"`
|
||||
ProvisionerID string `json:"provisionerID"`
|
||||
Subject string `json:"subject"`
|
||||
Type admin.Type `json:"type"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
DeletedAt time.Time `json:"deletedAt"`
|
||||
ID string `json:"id"`
|
||||
AuthorityID string `json:"authorityID"`
|
||||
ProvisionerID string `json:"provisionerID"`
|
||||
Subject string `json:"subject"`
|
||||
Type linkedca.Admin_Type `json:"type"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
DeletedAt time.Time `json:"deletedAt"`
|
||||
}
|
||||
|
||||
func (dbp *dbAdmin) clone() *dbAdmin {
|
||||
|
@ -59,30 +58,28 @@ func unmarshalDBAdmin(data []byte, id string) (*dbAdmin, error) {
|
|||
if err := json.Unmarshal(data, dba); err != nil {
|
||||
return nil, errors.Wrapf(err, "error unmarshaling admin %s into dbAdmin", id)
|
||||
}
|
||||
if !dba.DeletedAt.IsZero() {
|
||||
return nil, mgmt.NewError(mgmt.ErrorDeletedType, "admin %s is deleted", id)
|
||||
}
|
||||
return dba, nil
|
||||
}
|
||||
|
||||
func unmarshalAdmin(data []byte, id string) (*mgmt.Admin, error) {
|
||||
var dba = new(dbAdmin)
|
||||
if err := json.Unmarshal(data, dba); err != nil {
|
||||
return nil, errors.Wrapf(err, "error unmarshaling admin %s into dbAdmin", id)
|
||||
func unmarshalAdmin(data []byte, id string) (*linkedca.Admin, error) {
|
||||
dba, err := unmarshalDBAdmin(data, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
adm := &mgmt.Admin{
|
||||
ID: dba.ID,
|
||||
AuthorityID: dba.AuthorityID,
|
||||
ProvisionerID: dba.ProvisionerID,
|
||||
return &linkedca.Admin{
|
||||
Id: dba.ID,
|
||||
AuthorityId: dba.AuthorityID,
|
||||
ProvisionerId: dba.ProvisionerID,
|
||||
Subject: dba.Subject,
|
||||
Type: dba.Type,
|
||||
Status: status.Active,
|
||||
}
|
||||
if !dba.DeletedAt.IsZero() {
|
||||
adm.Status = status.Deleted
|
||||
}
|
||||
return adm, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
// GetAdmin retrieves and unmarshals a admin from the database.
|
||||
func (db *DB) GetAdmin(ctx context.Context, id string) (*mgmt.Admin, error) {
|
||||
func (db *DB) GetAdmin(ctx context.Context, id string) (*linkedca.Admin, error) {
|
||||
data, err := db.getDBAdminBytes(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -91,12 +88,9 @@ func (db *DB) GetAdmin(ctx context.Context, id string) (*mgmt.Admin, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if adm.Status == status.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,
|
||||
"admin %s is not owned by authority %s", adm.ID, db.authorityID)
|
||||
"admin %s is not owned by authority %s", adm.Id, db.authorityID)
|
||||
}
|
||||
|
||||
return adm, nil
|
||||
|
@ -105,21 +99,18 @@ func (db *DB) GetAdmin(ctx context.Context, id string) (*mgmt.Admin, error) {
|
|||
// GetAdmins retrieves and unmarshals all active (not deleted) admins
|
||||
// from the database.
|
||||
// TODO should we be paginating?
|
||||
func (db *DB) GetAdmins(ctx context.Context) ([]*mgmt.Admin, error) {
|
||||
func (db *DB) GetAdmins(ctx context.Context) ([]*linkedca.Admin, error) {
|
||||
dbEntries, err := db.db.List(authorityAdminsTable)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "error loading admins")
|
||||
}
|
||||
var admins = []*mgmt.Admin{}
|
||||
var admins = []*linkedca.Admin{}
|
||||
for _, entry := range dbEntries {
|
||||
adm, err := unmarshalAdmin(entry.Value, string(entry.Key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if adm.Status == status.Deleted {
|
||||
continue
|
||||
}
|
||||
if adm.AuthorityID != db.authorityID {
|
||||
if adm.AuthorityId != db.authorityID {
|
||||
continue
|
||||
}
|
||||
admins = append(admins, adm)
|
||||
|
@ -128,18 +119,18 @@ func (db *DB) GetAdmins(ctx context.Context) ([]*mgmt.Admin, error) {
|
|||
}
|
||||
|
||||
// CreateAdmin stores a new admin to the database.
|
||||
func (db *DB) CreateAdmin(ctx context.Context, adm *mgmt.Admin) error {
|
||||
func (db *DB) CreateAdmin(ctx context.Context, adm *linkedca.Admin) error {
|
||||
var err error
|
||||
adm.ID, err = randID()
|
||||
adm.Id, err = randID()
|
||||
if err != nil {
|
||||
return mgmt.WrapErrorISE(err, "error generating random id for admin")
|
||||
}
|
||||
adm.AuthorityID = db.authorityID
|
||||
adm.AuthorityId = db.authorityID
|
||||
|
||||
dba := &dbAdmin{
|
||||
ID: adm.ID,
|
||||
ID: adm.Id,
|
||||
AuthorityID: db.authorityID,
|
||||
ProvisionerID: adm.ProvisionerID,
|
||||
ProvisionerID: adm.ProvisionerId,
|
||||
Subject: adm.Subject,
|
||||
Type: adm.Type,
|
||||
CreatedAt: clock.Now(),
|
||||
|
@ -149,19 +140,27 @@ func (db *DB) CreateAdmin(ctx context.Context, adm *mgmt.Admin) error {
|
|||
}
|
||||
|
||||
// UpdateAdmin saves an updated admin to the database.
|
||||
func (db *DB) UpdateAdmin(ctx context.Context, adm *mgmt.Admin) error {
|
||||
old, err := db.getDBAdmin(ctx, adm.ID)
|
||||
func (db *DB) UpdateAdmin(ctx context.Context, adm *linkedca.Admin) error {
|
||||
old, err := db.getDBAdmin(ctx, adm.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nu := old.clone()
|
||||
|
||||
// If the admin was active but is now deleted ...
|
||||
if old.DeletedAt.IsZero() && adm.Status == status.Deleted {
|
||||
nu.DeletedAt = clock.Now()
|
||||
}
|
||||
nu.Type = adm.Type
|
||||
|
||||
return db.save(ctx, old.ID, nu, old, "admin", authorityAdminsTable)
|
||||
}
|
||||
|
||||
// DeleteAdmin saves an updated admin to the database.
|
||||
func (db *DB) DeleteAdmin(ctx context.Context, id string) error {
|
||||
old, err := db.getDBAdmin(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nu := old.clone()
|
||||
nu.DeletedAt = clock.Now()
|
||||
|
||||
return db.save(ctx, old.ID, nu, old, "admin", authorityAdminsTable)
|
||||
}
|
||||
|
|
|
@ -1,117 +0,0 @@
|
|||
package nosql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/smallstep/certificates/authority/config"
|
||||
"github.com/smallstep/certificates/authority/mgmt"
|
||||
"github.com/smallstep/certificates/authority/status"
|
||||
"github.com/smallstep/nosql"
|
||||
)
|
||||
|
||||
type dbAuthConfig struct {
|
||||
ID string `json:"id"`
|
||||
ASN1DN *config.ASN1DN `json:"asn1dn"`
|
||||
Claims *mgmt.Claims `json:"claims"`
|
||||
Backdate string `json:"backdate,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
DeletedAt time.Time `json:"deletedAt"`
|
||||
}
|
||||
|
||||
func (dbp *dbAuthConfig) clone() *dbAuthConfig {
|
||||
u := *dbp
|
||||
return &u
|
||||
}
|
||||
|
||||
func (db *DB) getDBAuthConfigBytes(ctx context.Context, id string) ([]byte, error) {
|
||||
data, err := db.db.Get(authorityConfigsTable, []byte(id))
|
||||
if nosql.IsErrNotFound(err) {
|
||||
return nil, mgmt.NewError(mgmt.ErrorNotFoundType, "authConfig %s not found", id)
|
||||
} else if err != nil {
|
||||
return nil, errors.Wrapf(err, "error loading authConfig %s", id)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func (db *DB) getDBAuthConfig(ctx context.Context, id string) (*dbAuthConfig, error) {
|
||||
data, err := db.getDBAuthConfigBytes(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var dba = new(dbAuthConfig)
|
||||
if err = json.Unmarshal(data, dba); err != nil {
|
||||
return nil, errors.Wrapf(err, "error unmarshaling authority %s into dbAuthConfig", id)
|
||||
}
|
||||
|
||||
return dba, nil
|
||||
}
|
||||
|
||||
// GetAuthConfig retrieves an AuthConfig configuration from the DB.
|
||||
func (db *DB) GetAuthConfig(ctx context.Context, id string) (*mgmt.AuthConfig, error) {
|
||||
dba, err := db.getDBAuthConfig(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
provs, err := db.GetProvisioners(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
admins, err := db.GetAdmins(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &mgmt.AuthConfig{
|
||||
ID: dba.ID,
|
||||
Admins: admins,
|
||||
Provisioners: provs,
|
||||
ASN1DN: dba.ASN1DN,
|
||||
Backdate: dba.Backdate,
|
||||
Claims: dba.Claims,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateAuthConfig stores a new provisioner to the database.
|
||||
func (db *DB) CreateAuthConfig(ctx context.Context, ac *mgmt.AuthConfig) error {
|
||||
var err error
|
||||
if ac.ID == "" {
|
||||
ac.ID, err = randID()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error generating random id for provisioner")
|
||||
}
|
||||
}
|
||||
|
||||
dba := &dbAuthConfig{
|
||||
ID: ac.ID,
|
||||
ASN1DN: ac.ASN1DN,
|
||||
Claims: ac.Claims,
|
||||
Backdate: ac.Backdate,
|
||||
CreatedAt: clock.Now(),
|
||||
}
|
||||
|
||||
return db.save(ctx, dba.ID, dba, nil, "authConfig", authorityConfigsTable)
|
||||
}
|
||||
|
||||
// UpdateAuthConfig saves an updated provisioner to the database.
|
||||
func (db *DB) UpdateAuthConfig(ctx context.Context, ac *mgmt.AuthConfig) error {
|
||||
old, err := db.getDBAuthConfig(ctx, ac.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nu := old.clone()
|
||||
|
||||
// If the authority was active but is now deleted ...
|
||||
if old.DeletedAt.IsZero() && ac.Status == status.Deleted {
|
||||
nu.DeletedAt = clock.Now()
|
||||
}
|
||||
nu.Claims = ac.Claims
|
||||
nu.Backdate = ac.Backdate
|
||||
|
||||
return db.save(ctx, old.ID, nu, old, "authConfig", authorityProvisionersTable)
|
||||
}
|
|
@ -7,25 +7,25 @@ import (
|
|||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/smallstep/certificates/authority/mgmt"
|
||||
"github.com/smallstep/certificates/authority/status"
|
||||
"github.com/smallstep/certificates/linkedca"
|
||||
"github.com/smallstep/nosql"
|
||||
)
|
||||
|
||||
// dbProvisioner is the database representation of a Provisioner type.
|
||||
type dbProvisioner struct {
|
||||
ID string `json:"id"`
|
||||
AuthorityID string `json:"authorityID"`
|
||||
Type string `json:"type"`
|
||||
ID string `json:"id"`
|
||||
AuthorityID string `json:"authorityID"`
|
||||
Type linkedca.Provisioner_Type `json:"type"`
|
||||
// Name is the key
|
||||
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"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
DeletedAt time.Time `json:"deletedAt"`
|
||||
Name string `json:"name"`
|
||||
Claims *linkedca.Claims `json:"claims"`
|
||||
Details []byte `json:"details"`
|
||||
X509Template []byte `json:"x509Template"`
|
||||
X509TemplateData []byte `json:"x509TemplateData"`
|
||||
SSHTemplate []byte `json:"sshTemplate"`
|
||||
SSHTemplateData []byte `json:"sshTemplateData"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
DeletedAt time.Time `json:"deletedAt"`
|
||||
}
|
||||
|
||||
type provisionerNameID struct {
|
||||
|
@ -68,7 +68,7 @@ func (db *DB) getDBProvisioner(ctx context.Context, id string) (*dbProvisioner,
|
|||
}
|
||||
|
||||
// GetProvisioner retrieves and unmarshals a provisioner from the database.
|
||||
func (db *DB) GetProvisioner(ctx context.Context, id string) (*mgmt.Provisioner, error) {
|
||||
func (db *DB) GetProvisioner(ctx context.Context, id string) (*linkedca.Provisioner, error) {
|
||||
data, err := db.getDBProvisionerBytes(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -78,12 +78,9 @@ func (db *DB) GetProvisioner(ctx context.Context, id string) (*mgmt.Provisioner,
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if prov.Status == status.Deleted {
|
||||
return nil, mgmt.NewError(mgmt.ErrorDeletedType, "provisioner %s is deleted", prov.ID)
|
||||
}
|
||||
if prov.AuthorityID != db.authorityID {
|
||||
if prov.AuthorityId != db.authorityID {
|
||||
return nil, mgmt.NewError(mgmt.ErrorAuthorityMismatchType,
|
||||
"provisioner %s is not owned by authority %s", prov.ID, db.authorityID)
|
||||
"provisioner %s is not owned by authority %s", prov.Id, db.authorityID)
|
||||
}
|
||||
return prov, nil
|
||||
}
|
||||
|
@ -93,56 +90,52 @@ func unmarshalDBProvisioner(data []byte, name string) (*dbProvisioner, error) {
|
|||
if err := json.Unmarshal(data, dbp); err != nil {
|
||||
return nil, errors.Wrapf(err, "error unmarshaling provisioner %s into dbProvisioner", name)
|
||||
}
|
||||
if !dbp.DeletedAt.IsZero() {
|
||||
return nil, mgmt.NewError(mgmt.ErrorDeletedType, "provisioner %s is deleted", name)
|
||||
}
|
||||
return dbp, nil
|
||||
}
|
||||
|
||||
func unmarshalProvisioner(data []byte, name string) (*mgmt.Provisioner, error) {
|
||||
func unmarshalProvisioner(data []byte, name string) (*linkedca.Provisioner, error) {
|
||||
dbp, err := unmarshalDBProvisioner(data, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
details, err := mgmt.UnmarshalProvisionerDetails(dbp.Details)
|
||||
details, err := linkedca.UnmarshalProvisionerDetails(dbp.Type, dbp.Details)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
prov := &mgmt.Provisioner{
|
||||
ID: dbp.ID,
|
||||
AuthorityID: dbp.AuthorityID,
|
||||
prov := &linkedca.Provisioner{
|
||||
Id: dbp.ID,
|
||||
AuthorityId: dbp.AuthorityID,
|
||||
Type: dbp.Type,
|
||||
Name: dbp.Name,
|
||||
Claims: dbp.Claims,
|
||||
Details: details,
|
||||
Status: status.Active,
|
||||
X509Template: dbp.X509Template,
|
||||
X509TemplateData: dbp.X509TemplateData,
|
||||
SSHTemplate: dbp.SSHTemplate,
|
||||
SSHTemplateData: dbp.SSHTemplateData,
|
||||
}
|
||||
if !dbp.DeletedAt.IsZero() {
|
||||
prov.Status = status.Deleted
|
||||
SshTemplate: dbp.SSHTemplate,
|
||||
SshTemplateData: dbp.SSHTemplateData,
|
||||
}
|
||||
return prov, nil
|
||||
}
|
||||
|
||||
// GetProvisioners retrieves and unmarshals all active (not deleted) provisioners
|
||||
// from the database.
|
||||
func (db *DB) GetProvisioners(ctx context.Context) ([]*mgmt.Provisioner, error) {
|
||||
func (db *DB) GetProvisioners(ctx context.Context) ([]*linkedca.Provisioner, error) {
|
||||
dbEntries, err := db.db.List(authorityProvisionersTable)
|
||||
if err != nil {
|
||||
return nil, mgmt.WrapErrorISE(err, "error loading provisioners")
|
||||
}
|
||||
var provs []*mgmt.Provisioner
|
||||
var provs []*linkedca.Provisioner
|
||||
for _, entry := range dbEntries {
|
||||
prov, err := unmarshalProvisioner(entry.Value, string(entry.Key))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if prov.Status == status.Deleted {
|
||||
continue
|
||||
}
|
||||
if prov.AuthorityID != db.authorityID {
|
||||
if prov.AuthorityId != db.authorityID {
|
||||
continue
|
||||
}
|
||||
provs = append(provs, prov)
|
||||
|
@ -151,9 +144,9 @@ func (db *DB) GetProvisioners(ctx context.Context) ([]*mgmt.Provisioner, error)
|
|||
}
|
||||
|
||||
// CreateProvisioner stores a new provisioner to the database.
|
||||
func (db *DB) CreateProvisioner(ctx context.Context, prov *mgmt.Provisioner) error {
|
||||
func (db *DB) CreateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error {
|
||||
var err error
|
||||
prov.ID, err = randID()
|
||||
prov.Id, err = randID()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "error generating random id for provisioner")
|
||||
}
|
||||
|
@ -164,7 +157,7 @@ func (db *DB) CreateProvisioner(ctx context.Context, prov *mgmt.Provisioner) err
|
|||
}
|
||||
|
||||
dbp := &dbProvisioner{
|
||||
ID: prov.ID,
|
||||
ID: prov.Id,
|
||||
AuthorityID: db.authorityID,
|
||||
Type: prov.Type,
|
||||
Name: prov.Name,
|
||||
|
@ -172,12 +165,12 @@ func (db *DB) CreateProvisioner(ctx context.Context, prov *mgmt.Provisioner) err
|
|||
Details: details,
|
||||
X509Template: prov.X509Template,
|
||||
X509TemplateData: prov.X509TemplateData,
|
||||
SSHTemplate: prov.SSHTemplate,
|
||||
SSHTemplateData: prov.SSHTemplateData,
|
||||
SSHTemplate: prov.SshTemplate,
|
||||
SSHTemplateData: prov.SshTemplateData,
|
||||
CreatedAt: clock.Now(),
|
||||
}
|
||||
|
||||
if err := db.save(ctx, prov.ID, dbp, nil, "provisioner", authorityProvisionersTable); err != nil {
|
||||
if err := db.save(ctx, prov.Id, dbp, nil, "provisioner", authorityProvisionersTable); err != nil {
|
||||
return mgmt.WrapErrorISE(err, "error creating provisioner %s", prov.Name)
|
||||
}
|
||||
|
||||
|
@ -185,8 +178,8 @@ func (db *DB) CreateProvisioner(ctx context.Context, prov *mgmt.Provisioner) err
|
|||
}
|
||||
|
||||
// UpdateProvisioner saves an updated provisioner to the database.
|
||||
func (db *DB) UpdateProvisioner(ctx context.Context, prov *mgmt.Provisioner) error {
|
||||
old, err := db.getDBProvisioner(ctx, prov.ID)
|
||||
func (db *DB) UpdateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error {
|
||||
old, err := db.getDBProvisioner(ctx, prov.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -202,9 +195,10 @@ func (db *DB) UpdateProvisioner(ctx context.Context, prov *mgmt.Provisioner) err
|
|||
}
|
||||
nu.X509Template = prov.X509Template
|
||||
nu.X509TemplateData = prov.X509TemplateData
|
||||
nu.SSHTemplateData = prov.SSHTemplateData
|
||||
nu.SSHTemplate = prov.SshTemplate
|
||||
nu.SSHTemplateData = prov.SshTemplateData
|
||||
|
||||
if err := db.save(ctx, prov.ID, nu, old, "provisioner", authorityProvisionersTable); err != nil {
|
||||
if err := db.save(ctx, prov.Id, nu, old, "provisioner", authorityProvisionersTable); err != nil {
|
||||
return mgmt.WrapErrorISE(err, "error updating provisioner %s", prov.Name)
|
||||
}
|
||||
|
||||
|
|
|
@ -246,46 +246,3 @@ func claimsToCertificates(c *linkedca.Claims) (*provisioner.Claims, error) {
|
|||
EnableSSHCA: &c.Ssh.Enabled,
|
||||
}, nil
|
||||
}
|
||||
|
||||
/*
|
||||
type detailsType struct {
|
||||
Type ProvisionerType
|
||||
}
|
||||
|
||||
// UnmarshalProvisionerDetails unmarshals bytes into the proper details type.
|
||||
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")
|
||||
}
|
||||
|
||||
var v ProvisionerDetails
|
||||
switch dt.Type {
|
||||
case ProvisionerTypeJWK:
|
||||
v = new(ProvisionerDetailsJWK)
|
||||
case ProvisionerTypeOIDC:
|
||||
v = new(ProvisionerDetailsOIDC)
|
||||
case ProvisionerTypeGCP:
|
||||
v = new(ProvisionerDetailsGCP)
|
||||
case ProvisionerTypeAWS:
|
||||
v = new(ProvisionerDetailsAWS)
|
||||
case ProvisionerTypeAZURE:
|
||||
v = new(ProvisionerDetailsAzure)
|
||||
case ProvisionerTypeACME:
|
||||
v = new(ProvisionerDetailsACME)
|
||||
case ProvisionerTypeX5C:
|
||||
v = new(ProvisionerDetailsX5C)
|
||||
case ProvisionerTypeK8SSA:
|
||||
v = new(ProvisionerDetailsK8SSA)
|
||||
case ProvisionerTypeSSHPOP:
|
||||
v = new(ProvisionerDetailsSSHPOP)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported provisioner type %s", dt.Type)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
*/
|
||||
|
|
38
linkedca/provisioners.go
Normal file
38
linkedca/provisioners.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
package linkedca
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// UnmarshalProvisionerDetails unmarshals details type to the specific provisioner details.
|
||||
func UnmarshalProvisionerDetails(typ Provisioner_Type, data []byte) (*ProvisionerDetails, error) {
|
||||
var v isProvisionerDetails_Data
|
||||
switch typ {
|
||||
case Provisioner_JWK:
|
||||
v = new(ProvisionerDetails_JWK)
|
||||
case Provisioner_OIDC:
|
||||
v = new(ProvisionerDetails_OIDC)
|
||||
case Provisioner_GCP:
|
||||
v = new(ProvisionerDetails_GCP)
|
||||
case Provisioner_AWS:
|
||||
v = new(ProvisionerDetails_AWS)
|
||||
case Provisioner_AZURE:
|
||||
v = new(ProvisionerDetails_Azure)
|
||||
case Provisioner_ACME:
|
||||
v = new(ProvisionerDetails_ACME)
|
||||
case Provisioner_X5C:
|
||||
v = new(ProvisionerDetails_X5C)
|
||||
case Provisioner_K8SSA:
|
||||
v = new(ProvisionerDetails_K8SSA)
|
||||
case Provisioner_SSHPOP:
|
||||
v = new(ProvisionerDetails_SSHPOP)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported provisioner type %s", typ)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(data, v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ProvisionerDetails{Data: v}, nil
|
||||
}
|
Loading…
Reference in a new issue