Skip to content

Commit 78308e5

Browse files
committed
Add option to specify name, labels, and annotations for generated objects
1 parent af7a939 commit 78308e5

File tree

2 files changed

+67
-30
lines changed

2 files changed

+67
-30
lines changed

cmd/audit2rbac/audit2rbac.go

Lines changed: 61 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,12 @@ func checkErr(w io.Writer, err error) {
4141
}
4242

4343
func NewAudit2RBACCommand(stdout, stderr io.Writer) *cobra.Command {
44+
name := "audit2rbac:${user}"
45+
annotations := []string{"audit2rbac.liggitt.net/version=${version}"}
46+
labels := []string{"audit2rbac.liggitt.net/user=${user}", "audit2rbac.liggitt.net/generated=true"}
47+
4448
options := &Audit2RBACOptions{
45-
GeneratedPath: ".",
46-
GeneratedNamePrefix: "",
47-
GeneratedLabels: map[string]string{},
48-
GeneratedAnnotations: map[string]string{},
49+
GeneratedPath: ".",
4950

5051
ExpandMultipleNamespacesToClusterScoped: true,
5152
ExpandMultipleNamesToUnnamed: true,
@@ -68,7 +69,7 @@ func NewAudit2RBACCommand(stdout, stderr io.Writer) *cobra.Command {
6869
return
6970
}
7071

71-
checkErr(stderr, options.Complete(serviceAccount, args))
72+
checkErr(stderr, options.Complete(serviceAccount, args, name, annotations, labels))
7273

7374
if err := options.Validate(); err != nil {
7475
fmt.Fprintln(stderr, err)
@@ -82,11 +83,19 @@ func NewAudit2RBACCommand(stdout, stderr io.Writer) *cobra.Command {
8283
}
8384

8485
cmd.Flags().StringArrayVarP(&options.AuditSources, "filename", "f", options.AuditSources, "File, URL, or - for STDIN to read audit events from")
86+
8587
cmd.Flags().StringVar(&options.User, "user", options.User, "User to filter audit events to and generate role bindings for")
8688
cmd.Flags().StringVar(&serviceAccount, "serviceaccount", serviceAccount, "Service account to filter audit events to and generate role bindings for, in format <namespace>:<name>")
89+
8790
cmd.Flags().StringVarP(&options.Namespace, "namespace", "n", options.Namespace, "Namespace to filter audit events to")
91+
8892
cmd.Flags().BoolVar(&options.ExpandMultipleNamespacesToClusterScoped, "expand-multi-namespace", options.ExpandMultipleNamespacesToClusterScoped, "Allow identical operations performed in more than one namespace to be performed in any namespace")
8993
cmd.Flags().BoolVar(&options.ExpandMultipleNamesToUnnamed, "expand-multi-name", options.ExpandMultipleNamesToUnnamed, "Allow identical operations performed on more than one resource name (e.g. 'get pods pod1' and 'get pods pod2') to be allowed on any name")
94+
95+
cmd.Flags().StringVar(&name, "generate-name", name, "Name to use for generated objects")
96+
cmd.Flags().StringSliceVar(&annotations, "generate-annotations", annotations, "Annotations to add to generated objects")
97+
cmd.Flags().StringSliceVar(&labels, "generate-labels", labels, "Labels to add to generated objects")
98+
9099
cmd.Flags().BoolVar(&showVersion, "version", false, "Display version")
91100

92101
return cmd
@@ -109,12 +118,12 @@ type Audit2RBACOptions struct {
109118

110119
// Directory to write generated roles to. Defaults to current directory.
111120
GeneratedPath string
112-
// Prefix for generated object names. Defaults to "audit2rbac:<user>"
113-
GeneratedNamePrefix string
121+
// Name for generated objects. Defaults to "audit2rbac:<user>"
122+
Name string
114123
// Labels to apply to generated object names.
115-
GeneratedLabels map[string]string
124+
Labels map[string]string
116125
// Annotations to apply to generated object names.
117-
GeneratedAnnotations map[string]string
126+
Annotations map[string]string
118127

119128
// If the same operation is performed in multiple namespaces, expand the permission to allow it in any namespace
120129
ExpandMultipleNamespacesToClusterScoped bool
@@ -125,7 +134,7 @@ type Audit2RBACOptions struct {
125134
Stderr io.Writer
126135
}
127136

128-
func (a *Audit2RBACOptions) Complete(serviceAccount string, args []string) error {
137+
func (a *Audit2RBACOptions) Complete(serviceAccount string, args []string, name string, annotations, labels []string) error {
129138
if len(serviceAccount) > 0 && len(a.User) > 0 {
130139
return fmt.Errorf("cannot set both user and service account")
131140
}
@@ -137,20 +146,48 @@ func (a *Audit2RBACOptions) Complete(serviceAccount string, args []string) error
137146
a.User = serviceaccount.MakeUsername(parts[0], parts[1])
138147
}
139148

140-
if len(a.GeneratedLabels) == 0 {
141-
a.GeneratedLabels["audit2rbac.liggitt.net/user"] = sanitizeLabel(a.User)
142-
a.GeneratedLabels["audit2rbac.liggitt.net/generated"] = "true"
143-
}
144-
if len(a.GeneratedAnnotations) == 0 {
145-
a.GeneratedAnnotations["audit2rbac.liggitt.net/version"] = pkg.Version
149+
a.Annotations = nil
150+
for _, s := range annotations {
151+
s = strings.TrimSpace(s)
152+
if len(s) == 0 {
153+
continue
154+
}
155+
if a.Annotations == nil {
156+
a.Annotations = map[string]string{}
157+
}
158+
s = strings.Replace(s, "${user}", a.User, -1)
159+
s = strings.Replace(s, "${version}", pkg.Version, -1)
160+
parts := strings.SplitN(s, "=", 2)
161+
if len(parts) == 1 {
162+
a.Annotations[parts[0]] = ""
163+
} else {
164+
a.Annotations[parts[0]] = parts[1]
165+
}
146166
}
147167

148-
if len(a.GeneratedNamePrefix) == 0 {
149-
user := a.User
150-
if _, name, err := serviceaccount.SplitUsername(a.User); err == nil && name != "default" {
151-
user = name
168+
a.Labels = nil
169+
for _, s := range labels {
170+
s = strings.TrimSpace(s)
171+
if len(s) == 0 {
172+
continue
173+
}
174+
if a.Labels == nil {
175+
a.Labels = map[string]string{}
152176
}
153-
a.GeneratedNamePrefix = "audit2rbac:" + sanitizeName(user)
177+
s = strings.Replace(s, "${user}", sanitizeLabel(a.User), -1)
178+
s = strings.Replace(s, "${version}", sanitizeLabel(pkg.Version), -1)
179+
parts := strings.SplitN(s, "=", 2)
180+
if len(parts) == 1 {
181+
a.Labels[parts[0]] = ""
182+
} else {
183+
a.Labels[parts[0]] = parts[1]
184+
}
185+
}
186+
187+
if len(name) > 0 {
188+
name = strings.Replace(name, "${user}", sanitizeName(a.User), -1)
189+
name = strings.Replace(name, "${version}", sanitizeName(pkg.Version), -1)
190+
a.Name = name
154191
}
155192

156193
if a.Stderr == nil {
@@ -239,9 +276,9 @@ func (a *Audit2RBACOptions) Run() error {
239276
fmt.Fprintln(a.Stderr, "Evaluating API calls...")
240277

241278
opts := pkg.DefaultGenerateOptions()
242-
opts.Labels = a.GeneratedLabels
243-
opts.Annotations = a.GeneratedAnnotations
244-
opts.NamePrefix = a.GeneratedNamePrefix
279+
opts.Labels = a.Labels
280+
opts.Annotations = a.Annotations
281+
opts.Name = a.Name
245282
opts.ExpandMultipleNamespacesToClusterScoped = a.ExpandMultipleNamespacesToClusterScoped
246283
opts.ExpandMultipleNamesToUnnamed = a.ExpandMultipleNamesToUnnamed
247284

pkg/process.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type GenerateOptions struct {
2424
ExpandMultipleNamesToUnnamed bool
2525
ExpandMultipleNamespacesToClusterScoped bool
2626

27-
NamePrefix string
27+
Name string
2828
Labels map[string]string
2929
Annotations map[string]string
3030
}
@@ -41,7 +41,7 @@ func DefaultGenerateOptions() GenerateOptions {
4141
ExpandMultipleNamesToUnnamed: true,
4242
ExpandMultipleNamespacesToClusterScoped: true,
4343

44-
NamePrefix: "audit2rbac",
44+
Name: "audit2rbac",
4545
Labels: nil,
4646
Annotations: nil,
4747
}
@@ -162,10 +162,10 @@ func (g *Generator) ensureClusterRoleAndBinding(subject rbac.Subject) *rbac.Clus
162162
}
163163

164164
g.clusterRole = &rbac.ClusterRole{
165-
ObjectMeta: metav1.ObjectMeta{Name: g.Options.NamePrefix, Labels: g.Options.Labels, Annotations: g.Options.Annotations},
165+
ObjectMeta: metav1.ObjectMeta{Name: g.Options.Name, Labels: g.Options.Labels, Annotations: g.Options.Annotations},
166166
}
167167
g.clusterRoleBinding = &rbac.ClusterRoleBinding{
168-
ObjectMeta: metav1.ObjectMeta{Name: g.Options.NamePrefix, Labels: g.Options.Labels, Annotations: g.Options.Annotations},
168+
ObjectMeta: metav1.ObjectMeta{Name: g.Options.Name, Labels: g.Options.Labels, Annotations: g.Options.Annotations},
169169
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "ClusterRole", Name: g.clusterRole.Name},
170170
Subjects: []rbac.Subject{subject},
171171
}
@@ -185,10 +185,10 @@ func (g *Generator) ensureNamespacedRoleAndBinding(subject rbac.Subject, namespa
185185
}
186186

187187
g.namespacedRole[namespace] = &rbac.Role{
188-
ObjectMeta: metav1.ObjectMeta{Name: g.Options.NamePrefix, Namespace: namespace, Labels: g.Options.Labels, Annotations: g.Options.Annotations},
188+
ObjectMeta: metav1.ObjectMeta{Name: g.Options.Name, Namespace: namespace, Labels: g.Options.Labels, Annotations: g.Options.Annotations},
189189
}
190190
g.namespacedRoleBinding[namespace] = &rbac.RoleBinding{
191-
ObjectMeta: metav1.ObjectMeta{Name: g.Options.NamePrefix, Namespace: namespace, Labels: g.Options.Labels, Annotations: g.Options.Annotations},
191+
ObjectMeta: metav1.ObjectMeta{Name: g.Options.Name, Namespace: namespace, Labels: g.Options.Labels, Annotations: g.Options.Annotations},
192192
RoleRef: rbac.RoleRef{APIGroup: rbac.GroupName, Kind: "Role", Name: g.namespacedRole[namespace].Name},
193193
Subjects: []rbac.Subject{subject},
194194
}

0 commit comments

Comments
 (0)