You've already forked step-ca-cli
mirror of
https://github.com/smallstep/cli.git
synced 2026-10-24 11:19:19 +03:00
163 lines
3.8 KiB
Go
163 lines
3.8 KiB
Go
package admin
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/urfave/cli"
|
|
|
|
"github.com/smallstep/certificates/ca"
|
|
"github.com/smallstep/cli-utils/errs"
|
|
"github.com/smallstep/cli-utils/ui"
|
|
"github.com/smallstep/linkedca"
|
|
)
|
|
|
|
// Command returns the jwk subcommand.
|
|
func Command() cli.Command {
|
|
return cli.Command{
|
|
Name: "admin",
|
|
Usage: "create and manage the certificate authority admins",
|
|
UsageText: "**step ca admin** <subcommand> [arguments] [global-flags] [subcommand-flags]",
|
|
Subcommands: cli.Commands{
|
|
listCommand(),
|
|
addCommand(),
|
|
removeCommand(),
|
|
updateCommand(),
|
|
},
|
|
Description: `**step ca admin** command group provides facilities for managing the
|
|
certificate authority admins.
|
|
|
|
An admin is an entity that manages administrative resources (like authority
|
|
configuration, provisioner configuration, and other admins) within a certificate
|
|
authority.
|
|
|
|
## EXAMPLES
|
|
|
|
List the active admins:
|
|
'''
|
|
$ step ca admin list
|
|
'''
|
|
|
|
Add an admin:
|
|
'''
|
|
$ step ca admin add max@smallstep.com my-jwk-provisioner --super
|
|
'''
|
|
|
|
Update an admin:
|
|
'''
|
|
$ step ca admin update max@smallstep.com --super=false
|
|
'''
|
|
|
|
Remove an admin:
|
|
'''
|
|
$ step ca admin remove max@smallstep.com
|
|
'''`,
|
|
}
|
|
}
|
|
|
|
var provisionerFilterFlag = cli.StringFlag{
|
|
Name: "provisioner",
|
|
Usage: `The provisioner <name> by which to filter admins.`,
|
|
}
|
|
|
|
type adminSelect struct {
|
|
Name string
|
|
CLIAdmin *cliAdmin
|
|
}
|
|
|
|
type cliAdmin struct {
|
|
*linkedca.Admin
|
|
ProvisionerName string
|
|
ProvisionerType string
|
|
}
|
|
|
|
func toCLI(_ *cli.Context, client *ca.AdminClient, adm *linkedca.Admin) (*cliAdmin, error) {
|
|
p, err := client.GetProvisioner(ca.WithProvisionerID(adm.ProvisionerId))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &cliAdmin{Admin: adm, ProvisionerName: p.GetName(), ProvisionerType: p.GetType().String()}, nil
|
|
}
|
|
|
|
func listToCLI(ctx *cli.Context, client *ca.AdminClient, admins []*linkedca.Admin) ([]*cliAdmin, error) {
|
|
var (
|
|
err error
|
|
cliAdmins = make([]*cliAdmin, len(admins))
|
|
)
|
|
for i, adm := range admins {
|
|
cliAdmins[i], err = toCLI(ctx, client, adm)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return cliAdmins, nil
|
|
}
|
|
|
|
func adminPrompt(ctx *cli.Context, client *ca.AdminClient, admins []*linkedca.Admin) (*cliAdmin, error) {
|
|
if len(admins) == 0 {
|
|
return nil, errors.New("no admins to update")
|
|
}
|
|
args := ctx.Args()
|
|
subject := args[0]
|
|
|
|
cliAdmins, err := listToCLI(ctx, client, admins)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Filter by subject
|
|
cliAdmins = adminFilter(cliAdmins, func(adm *cliAdmin) bool {
|
|
return adm.Subject == subject
|
|
})
|
|
if len(cliAdmins) == 0 {
|
|
return nil, fmt.Errorf("no admins with subject %s", subject)
|
|
}
|
|
|
|
// Filter by provisionerName
|
|
if provName := ctx.String("provisioner"); provName != "" {
|
|
cliAdmins = adminFilter(cliAdmins, func(a *cliAdmin) bool {
|
|
return a.ProvisionerName == provName
|
|
})
|
|
if len(cliAdmins) == 0 {
|
|
return nil, errs.InvalidFlagValue(ctx, "provisioner", provName, "")
|
|
}
|
|
}
|
|
|
|
// Select admin
|
|
var items []*adminSelect
|
|
for _, adm := range cliAdmins {
|
|
items = append(items, &adminSelect{
|
|
//Name: fmt.Sprintf("%s\t%s (%s)\t%s", adm.Subject,
|
|
Name: fmt.Sprintf("subject: %s, provisioner: %s(%s), type: %s", adm.Subject,
|
|
adm.ProvisionerName, adm.ProvisionerType, adm.Type),
|
|
CLIAdmin: adm,
|
|
})
|
|
}
|
|
|
|
if len(items) == 1 {
|
|
if err := ui.PrintSelected("Admin", items[0].Name); err != nil {
|
|
return nil, err
|
|
}
|
|
return items[0].CLIAdmin, nil
|
|
}
|
|
|
|
i, _, err := ui.Select("Select an admin:", items,
|
|
ui.WithSelectTemplates(ui.NamedSelectTemplates("Admin")))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return items[i].CLIAdmin, nil
|
|
}
|
|
|
|
// adminFilter returns a slice of admins that pass the given filter.
|
|
func adminFilter(cliAdmins []*cliAdmin, f func(*cliAdmin) bool) []*cliAdmin {
|
|
var result []*cliAdmin
|
|
for _, a := range cliAdmins {
|
|
if f(a) {
|
|
result = append(result, a)
|
|
}
|
|
}
|
|
return result
|
|
}
|