-
Notifications
You must be signed in to change notification settings - Fork 295
Expand file tree
/
Copy pathadmin.go
More file actions
163 lines (139 loc) · 3.83 KB
/
admin.go
File metadata and controls
163 lines (139 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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.WithField("admin", "admin-subject"),
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
}