forked from TrueCloudLab/certificates
exposing authority configuration for provisioner cli commands
This commit is contained in:
parent
3424442c50
commit
b91affdd34
6 changed files with 115 additions and 48 deletions
|
@ -71,6 +71,52 @@ type DB interface {
|
||||||
DeleteAdmin(ctx context.Context, id string) error
|
DeleteAdmin(ctx context.Context, id string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type NoDB struct{}
|
||||||
|
|
||||||
|
func NewNoDB() *NoDB {
|
||||||
|
return &NoDB{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoDB) CreateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoDB) GetProvisioner(ctx context.Context, id string) (*linkedca.Provisioner, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoDB) GetProvisioners(ctx context.Context) ([]*linkedca.Provisioner, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoDB) UpdateProvisioner(ctx context.Context, prov *linkedca.Provisioner) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoDB) DeleteProvisioner(ctx context.Context, id string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoDB) CreateAdmin(ctx context.Context, admin *linkedca.Admin) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoDB) GetAdmin(ctx context.Context, id string) (*linkedca.Admin, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoDB) GetAdmins(ctx context.Context) ([]*linkedca.Admin, error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoDB) UpdateAdmin(ctx context.Context, prov *linkedca.Admin) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *NoDB) DeleteAdmin(ctx context.Context, id string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// MockDB is an implementation of the DB interface that should only be used as
|
// MockDB is an implementation of the DB interface that should only be used as
|
||||||
// a mock in tests.
|
// a mock in tests.
|
||||||
type MockDB struct {
|
type MockDB struct {
|
||||||
|
|
|
@ -49,7 +49,7 @@ func (a *Authority) StoreAdmin(ctx context.Context, adm *linkedca.Admin, prov pr
|
||||||
return admin.WrapErrorISE(err, "error creating admin")
|
return admin.WrapErrorISE(err, "error creating admin")
|
||||||
}
|
}
|
||||||
if err := a.admins.Store(adm, prov); err != nil {
|
if err := a.admins.Store(adm, prov); err != nil {
|
||||||
if err := a.reloadAdminResources(ctx); err != nil {
|
if err := a.ReloadAdminResources(ctx); err != nil {
|
||||||
return admin.WrapErrorISE(err, "error reloading admin resources on failed admin store")
|
return admin.WrapErrorISE(err, "error reloading admin resources on failed admin store")
|
||||||
}
|
}
|
||||||
return admin.WrapErrorISE(err, "error storing admin in authority cache")
|
return admin.WrapErrorISE(err, "error storing admin in authority cache")
|
||||||
|
@ -66,7 +66,7 @@ func (a *Authority) UpdateAdmin(ctx context.Context, id string, nu *linkedca.Adm
|
||||||
return nil, admin.WrapErrorISE(err, "error updating cached admin %s", id)
|
return nil, admin.WrapErrorISE(err, "error updating cached admin %s", id)
|
||||||
}
|
}
|
||||||
if err := a.adminDB.UpdateAdmin(ctx, adm); err != nil {
|
if err := a.adminDB.UpdateAdmin(ctx, adm); err != nil {
|
||||||
if err := a.reloadAdminResources(ctx); err != nil {
|
if err := a.ReloadAdminResources(ctx); err != nil {
|
||||||
return nil, admin.WrapErrorISE(err, "error reloading admin resources on failed admin update")
|
return nil, admin.WrapErrorISE(err, "error reloading admin resources on failed admin update")
|
||||||
}
|
}
|
||||||
return nil, admin.WrapErrorISE(err, "error updating admin %s", id)
|
return nil, admin.WrapErrorISE(err, "error updating admin %s", id)
|
||||||
|
@ -88,7 +88,7 @@ func (a *Authority) removeAdmin(ctx context.Context, id string) error {
|
||||||
return admin.WrapErrorISE(err, "error removing admin %s from authority cache", id)
|
return admin.WrapErrorISE(err, "error removing admin %s from authority cache", id)
|
||||||
}
|
}
|
||||||
if err := a.adminDB.DeleteAdmin(ctx, id); err != nil {
|
if err := a.adminDB.DeleteAdmin(ctx, id); err != nil {
|
||||||
if err := a.reloadAdminResources(ctx); err != nil {
|
if err := a.ReloadAdminResources(ctx); err != nil {
|
||||||
return admin.WrapErrorISE(err, "error reloading admin resources on failed admin remove")
|
return admin.WrapErrorISE(err, "error reloading admin resources on failed admin remove")
|
||||||
}
|
}
|
||||||
return admin.WrapErrorISE(err, "error deleting admin %s", id)
|
return admin.WrapErrorISE(err, "error deleting admin %s", id)
|
||||||
|
|
|
@ -115,6 +115,20 @@ func New(cfg *config.Config, opts ...Option) (*Authority, error) {
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FromOptions creates an Authority exclusively using the passed in options
|
||||||
|
// and does not intialize the Authority.
|
||||||
|
func FromOptions(opts ...Option) (*Authority, error) {
|
||||||
|
var a = new(Authority)
|
||||||
|
|
||||||
|
// Apply options.
|
||||||
|
for _, fn := range opts {
|
||||||
|
if err := fn(a); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewEmbedded initializes an authority that can be embedded in a different
|
// NewEmbedded initializes an authority that can be embedded in a different
|
||||||
// project without the limitations of the config.
|
// project without the limitations of the config.
|
||||||
func NewEmbedded(opts ...Option) (*Authority, error) {
|
func NewEmbedded(opts ...Option) (*Authority, error) {
|
||||||
|
@ -153,8 +167,8 @@ func NewEmbedded(opts ...Option) (*Authority, error) {
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// reloadAdminResources reloads admins and provisioners from the DB.
|
// ReloadAdminResources reloads admins and provisioners from the DB.
|
||||||
func (a *Authority) reloadAdminResources(ctx context.Context) error {
|
func (a *Authority) ReloadAdminResources(ctx context.Context) error {
|
||||||
var (
|
var (
|
||||||
provList provisioner.List
|
provList provisioner.List
|
||||||
adminList []*linkedca.Admin
|
adminList []*linkedca.Admin
|
||||||
|
@ -551,7 +565,7 @@ func (a *Authority) init() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load Provisioners and Admins
|
// Load Provisioners and Admins
|
||||||
if err := a.reloadAdminResources(context.Background()); err != nil {
|
if err := a.ReloadAdminResources(context.Background()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,6 +601,12 @@ func (a *Authority) GetAdminDatabase() admin.DB {
|
||||||
return a.adminDB
|
return a.adminDB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetConfig returns the config.
|
||||||
|
func (a *Authority) GetConfig() *config.Config {
|
||||||
|
return a.config
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetInfo returns information about the authority.
|
||||||
func (a *Authority) GetInfo() Info {
|
func (a *Authority) GetInfo() Info {
|
||||||
ai := Info{
|
ai := Info{
|
||||||
StartTime: a.startTime,
|
StartTime: a.startTime,
|
||||||
|
|
|
@ -145,7 +145,7 @@ func (a *Authority) generateProvisionerConfig(ctx context.Context) (provisioner.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreProvisioner stores an provisioner.Interface to the authority.
|
// StoreProvisioner stores a provisioner to the authority.
|
||||||
func (a *Authority) StoreProvisioner(ctx context.Context, prov *linkedca.Provisioner) error {
|
func (a *Authority) StoreProvisioner(ctx context.Context, prov *linkedca.Provisioner) error {
|
||||||
a.adminMutex.Lock()
|
a.adminMutex.Lock()
|
||||||
defer a.adminMutex.Unlock()
|
defer a.adminMutex.Unlock()
|
||||||
|
@ -191,7 +191,7 @@ func (a *Authority) StoreProvisioner(ctx context.Context, prov *linkedca.Provisi
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := a.provisioners.Store(certProv); err != nil {
|
if err := a.provisioners.Store(certProv); err != nil {
|
||||||
if err := a.reloadAdminResources(ctx); err != nil {
|
if err := a.ReloadAdminResources(ctx); err != nil {
|
||||||
return admin.WrapErrorISE(err, "error reloading admin resources on failed provisioner store")
|
return admin.WrapErrorISE(err, "error reloading admin resources on failed provisioner store")
|
||||||
}
|
}
|
||||||
return admin.WrapErrorISE(err, "error storing provisioner in authority cache")
|
return admin.WrapErrorISE(err, "error storing provisioner in authority cache")
|
||||||
|
@ -223,7 +223,7 @@ func (a *Authority) UpdateProvisioner(ctx context.Context, nu *linkedca.Provisio
|
||||||
return admin.WrapErrorISE(err, "error updating provisioner '%s' in authority cache", nu.Name)
|
return admin.WrapErrorISE(err, "error updating provisioner '%s' in authority cache", nu.Name)
|
||||||
}
|
}
|
||||||
if err := a.adminDB.UpdateProvisioner(ctx, nu); err != nil {
|
if err := a.adminDB.UpdateProvisioner(ctx, nu); err != nil {
|
||||||
if err := a.reloadAdminResources(ctx); err != nil {
|
if err := a.ReloadAdminResources(ctx); err != nil {
|
||||||
return admin.WrapErrorISE(err, "error reloading admin resources on failed provisioner update")
|
return admin.WrapErrorISE(err, "error reloading admin resources on failed provisioner update")
|
||||||
}
|
}
|
||||||
return admin.WrapErrorISE(err, "error updating provisioner '%s'", nu.Name)
|
return admin.WrapErrorISE(err, "error updating provisioner '%s'", nu.Name)
|
||||||
|
@ -267,7 +267,7 @@ func (a *Authority) RemoveProvisioner(ctx context.Context, id string) error {
|
||||||
}
|
}
|
||||||
// Remove provisioner from database.
|
// Remove provisioner from database.
|
||||||
if err := a.adminDB.DeleteProvisioner(ctx, provID); err != nil {
|
if err := a.adminDB.DeleteProvisioner(ctx, provID); err != nil {
|
||||||
if err := a.reloadAdminResources(ctx); err != nil {
|
if err := a.ReloadAdminResources(ctx); err != nil {
|
||||||
return admin.WrapErrorISE(err, "error reloading admin resources on failed provisioner remove")
|
return admin.WrapErrorISE(err, "error reloading admin resources on failed provisioner remove")
|
||||||
}
|
}
|
||||||
return admin.WrapErrorISE(err, "error deleting provisioner %s", provName)
|
return admin.WrapErrorISE(err, "error deleting provisioner %s", provName)
|
||||||
|
|
|
@ -363,19 +363,19 @@ retry:
|
||||||
// GetProvisioner performs the GET /admin/provisioners/{name} request to the CA.
|
// GetProvisioner performs the GET /admin/provisioners/{name} request to the CA.
|
||||||
func (c *AdminClient) GetProvisioner(opts ...ProvisionerOption) (*linkedca.Provisioner, error) {
|
func (c *AdminClient) GetProvisioner(opts ...ProvisionerOption) (*linkedca.Provisioner, error) {
|
||||||
var retried bool
|
var retried bool
|
||||||
o := new(provisionerOptions)
|
o := new(ProvisionerOptions)
|
||||||
if err := o.apply(opts); err != nil {
|
if err := o.Apply(opts); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
var u *url.URL
|
var u *url.URL
|
||||||
switch {
|
switch {
|
||||||
case len(o.id) > 0:
|
case len(o.ID) > 0:
|
||||||
u = c.endpoint.ResolveReference(&url.URL{
|
u = c.endpoint.ResolveReference(&url.URL{
|
||||||
Path: "/admin/provisioners/id",
|
Path: "/admin/provisioners/id",
|
||||||
RawQuery: o.rawQuery(),
|
RawQuery: o.rawQuery(),
|
||||||
})
|
})
|
||||||
case len(o.name) > 0:
|
case len(o.Name) > 0:
|
||||||
u = c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "provisioners", o.name)})
|
u = c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "provisioners", o.Name)})
|
||||||
default:
|
default:
|
||||||
return nil, errors.New("must set either name or id in method options")
|
return nil, errors.New("must set either name or id in method options")
|
||||||
}
|
}
|
||||||
|
@ -410,8 +410,8 @@ retry:
|
||||||
// GetProvisionersPaginate performs the GET /admin/provisioners request to the CA.
|
// GetProvisionersPaginate performs the GET /admin/provisioners request to the CA.
|
||||||
func (c *AdminClient) GetProvisionersPaginate(opts ...ProvisionerOption) (*adminAPI.GetProvisionersResponse, error) {
|
func (c *AdminClient) GetProvisionersPaginate(opts ...ProvisionerOption) (*adminAPI.GetProvisionersResponse, error) {
|
||||||
var retried bool
|
var retried bool
|
||||||
o := new(provisionerOptions)
|
o := new(ProvisionerOptions)
|
||||||
if err := o.apply(opts); err != nil {
|
if err := o.Apply(opts); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
u := c.endpoint.ResolveReference(&url.URL{
|
u := c.endpoint.ResolveReference(&url.URL{
|
||||||
|
@ -472,19 +472,19 @@ func (c *AdminClient) RemoveProvisioner(opts ...ProvisionerOption) error {
|
||||||
retried bool
|
retried bool
|
||||||
)
|
)
|
||||||
|
|
||||||
o := new(provisionerOptions)
|
o := new(ProvisionerOptions)
|
||||||
if err := o.apply(opts); err != nil {
|
if err := o.Apply(opts); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case len(o.id) > 0:
|
case len(o.ID) > 0:
|
||||||
u = c.endpoint.ResolveReference(&url.URL{
|
u = c.endpoint.ResolveReference(&url.URL{
|
||||||
Path: path.Join(adminURLPrefix, "provisioners/id"),
|
Path: path.Join(adminURLPrefix, "provisioners/id"),
|
||||||
RawQuery: o.rawQuery(),
|
RawQuery: o.rawQuery(),
|
||||||
})
|
})
|
||||||
case len(o.name) > 0:
|
case len(o.Name) > 0:
|
||||||
u = c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "provisioners", o.name)})
|
u = c.endpoint.ResolveReference(&url.URL{Path: path.Join(adminURLPrefix, "provisioners", o.Name)})
|
||||||
default:
|
default:
|
||||||
return errors.New("must set either name or id in method options")
|
return errors.New("must set either name or id in method options")
|
||||||
}
|
}
|
||||||
|
|
53
ca/client.go
53
ca/client.go
|
@ -425,16 +425,17 @@ func parseEndpoint(endpoint string) (*url.URL, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProvisionerOption is the type of options passed to the Provisioner method.
|
// ProvisionerOption is the type of options passed to the Provisioner method.
|
||||||
type ProvisionerOption func(o *provisionerOptions) error
|
type ProvisionerOption func(o *ProvisionerOptions) error
|
||||||
|
|
||||||
type provisionerOptions struct {
|
// ProvisionerOptions stores options for the provisioner CRUD API.
|
||||||
cursor string
|
type ProvisionerOptions struct {
|
||||||
limit int
|
Cursor string
|
||||||
id string
|
Limit int
|
||||||
name string
|
ID string
|
||||||
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *provisionerOptions) apply(opts []ProvisionerOption) (err error) {
|
func (o *ProvisionerOptions) Apply(opts []ProvisionerOption) (err error) {
|
||||||
for _, fn := range opts {
|
for _, fn := range opts {
|
||||||
if err = fn(o); err != nil {
|
if err = fn(o); err != nil {
|
||||||
return
|
return
|
||||||
|
@ -443,51 +444,51 @@ func (o *provisionerOptions) apply(opts []ProvisionerOption) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *provisionerOptions) rawQuery() string {
|
func (o *ProvisionerOptions) rawQuery() string {
|
||||||
v := url.Values{}
|
v := url.Values{}
|
||||||
if len(o.cursor) > 0 {
|
if len(o.Cursor) > 0 {
|
||||||
v.Set("cursor", o.cursor)
|
v.Set("cursor", o.Cursor)
|
||||||
}
|
}
|
||||||
if o.limit > 0 {
|
if o.Limit > 0 {
|
||||||
v.Set("limit", strconv.Itoa(o.limit))
|
v.Set("limit", strconv.Itoa(o.Limit))
|
||||||
}
|
}
|
||||||
if len(o.id) > 0 {
|
if len(o.ID) > 0 {
|
||||||
v.Set("id", o.id)
|
v.Set("id", o.ID)
|
||||||
}
|
}
|
||||||
if len(o.name) > 0 {
|
if len(o.Name) > 0 {
|
||||||
v.Set("name", o.name)
|
v.Set("name", o.Name)
|
||||||
}
|
}
|
||||||
return v.Encode()
|
return v.Encode()
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithProvisionerCursor will request the provisioners starting with the given cursor.
|
// WithProvisionerCursor will request the provisioners starting with the given cursor.
|
||||||
func WithProvisionerCursor(cursor string) ProvisionerOption {
|
func WithProvisionerCursor(cursor string) ProvisionerOption {
|
||||||
return func(o *provisionerOptions) error {
|
return func(o *ProvisionerOptions) error {
|
||||||
o.cursor = cursor
|
o.Cursor = cursor
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithProvisionerLimit will request the given number of provisioners.
|
// WithProvisionerLimit will request the given number of provisioners.
|
||||||
func WithProvisionerLimit(limit int) ProvisionerOption {
|
func WithProvisionerLimit(limit int) ProvisionerOption {
|
||||||
return func(o *provisionerOptions) error {
|
return func(o *ProvisionerOptions) error {
|
||||||
o.limit = limit
|
o.Limit = limit
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithProvisionerID will request the given provisioner.
|
// WithProvisionerID will request the given provisioner.
|
||||||
func WithProvisionerID(id string) ProvisionerOption {
|
func WithProvisionerID(id string) ProvisionerOption {
|
||||||
return func(o *provisionerOptions) error {
|
return func(o *ProvisionerOptions) error {
|
||||||
o.id = id
|
o.ID = id
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithProvisionerName will request the given provisioner.
|
// WithProvisionerName will request the given provisioner.
|
||||||
func WithProvisionerName(name string) ProvisionerOption {
|
func WithProvisionerName(name string) ProvisionerOption {
|
||||||
return func(o *provisionerOptions) error {
|
return func(o *ProvisionerOptions) error {
|
||||||
o.name = name
|
o.Name = name
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -810,8 +811,8 @@ retry:
|
||||||
// paginate the provisioners.
|
// paginate the provisioners.
|
||||||
func (c *Client) Provisioners(opts ...ProvisionerOption) (*api.ProvisionersResponse, error) {
|
func (c *Client) Provisioners(opts ...ProvisionerOption) (*api.ProvisionersResponse, error) {
|
||||||
var retried bool
|
var retried bool
|
||||||
o := new(provisionerOptions)
|
o := new(ProvisionerOptions)
|
||||||
if err := o.apply(opts); err != nil {
|
if err := o.Apply(opts); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
u := c.endpoint.ResolveReference(&url.URL{
|
u := c.endpoint.ResolveReference(&url.URL{
|
||||||
|
|
Loading…
Reference in a new issue