Skip to content

Commit 813bd86

Browse files
authored
customize object metadata for generated roles/clusterroles (#105)
Implements #92
1 parent 505d5c7 commit 813bd86

File tree

3 files changed

+55
-13
lines changed

3 files changed

+55
-13
lines changed

Diff for: cmd/generate_cmd.go

+24-12
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ import (
2020
)
2121

2222
func NewCommandGenerateClusterRole() *cobra.Command {
23-
2423
clusterContext := ""
2524
generateKind := ""
2625
allowedGroups := []string{}
2726
//expandGroups := []string{}
2827
allowedVerb := []string{}
2928
denyResources := []string{}
29+
metadataFlag := &MetadataFlag{metadata: metav1.ObjectMeta{Name: ""}}
3030

3131
// Support overrides
3232
cmd := &cobra.Command{
@@ -47,6 +47,8 @@ rbac-tool gen --generated-type=Role --deny-resources=secrets.,ingresses.extensio
4747
# Generate a Role with read-only (get,list) excluding secrets (core group) from core group, admissionregistration.k8s.io,storage.k8s.io,networking.k8s.io
4848
rbac-tool gen --generated-type=ClusterRole --deny-resources=secrets., --allowed-verbs=get,list --allowed-groups=,admissionregistration.k8s.io,storage.k8s.io,networking.k8s.io
4949
50+
# Generate a Role and customize the metadata of the generated object
51+
rbac-tool gen --generated-type=Role --deny-resources=secrets.,ingresses.extensions --allowed-verbs=get,list --metadata='{"name": "my-role", "namespace":"my-namespace", "labels": {"app": "myapp"}, "annotations": {"generated-by": "rbac-tool"}}'
5052
5153
`,
5254
Hidden: false,
@@ -61,7 +63,7 @@ rbac-tool gen --generated-type=ClusterRole --deny-resources=secrets., --allowed-
6163
return err
6264
}
6365

64-
obj, err := generateRole(generateKind, computedPolicyRules)
66+
obj, err := generateRole(generateKind, computedPolicyRules, &metadataFlag.metadata)
6567
if err != nil {
6668
return err
6769
}
@@ -80,36 +82,46 @@ rbac-tool gen --generated-type=ClusterRole --deny-resources=secrets., --allowed-
8082
flags.StringSliceVar(&allowedGroups, "allowed-groups", []string{"*"}, "Comma separated list of API groups we would like to allow '*'")
8183
flags.StringSliceVar(&allowedVerb, "allowed-verbs", []string{"*"}, "Comma separated list of verbs to include. To include all use '*'")
8284
flags.StringSliceVar(&denyResources, "deny-resources", []string{""}, "Comma separated list of resource.group - for example secret. to deny secret (core group) access")
85+
flags.Var(metadataFlag, "metadata", "Kubernetes object metadata as JSON")
8386

8487
return cmd
8588
}
8689

87-
func generateRole(generateKind string, rules []rbacv1.PolicyRule) (string, error) {
90+
func generateRole(generateKind string, rules []rbacv1.PolicyRule, metadata *metav1.ObjectMeta) (string, error) {
8891
var obj runtime.Object
92+
md := *metadata
8993

9094
if generateKind == "ClusterRole" {
95+
if md.Name == "" {
96+
md.Name = "custom-cluster-role"
97+
}
98+
md.Namespace = ""
99+
91100
obj = &rbacv1.ClusterRole{
92101
TypeMeta: metav1.TypeMeta{
93102
Kind: "ClusterRole",
94103
APIVersion: "rbac.authorization.k8s.io/v1",
95104
},
96-
ObjectMeta: metav1.ObjectMeta{
97-
Name: "custom-cluster-role",
98-
},
99-
Rules: rules,
105+
ObjectMeta: md,
106+
Rules: rules,
100107
}
101108
} else {
109+
if md.Name == "" {
110+
md.Name = "custom-role"
111+
}
112+
if md.Namespace == "" {
113+
md.Namespace = "mynamespace"
114+
}
115+
102116
obj = &rbacv1.Role{
103117
TypeMeta: metav1.TypeMeta{
104118
Kind: "Role",
105119
APIVersion: "rbac.authorization.k8s.io/v1",
106120
},
107-
ObjectMeta: metav1.ObjectMeta{
108-
Name: "custom-role",
109-
Namespace: "mynamespace",
110-
},
111-
Rules: rules,
121+
ObjectMeta: md,
122+
Rules: rules,
112123
}
124+
113125
}
114126

115127
serializer := k8sJson.NewSerializerWithOptions(k8sJson.DefaultMetaFactory, nil, nil, k8sJson.SerializerOptions{Yaml: true, Pretty: true, Strict: true})

Diff for: cmd/metadata_arg.go

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package cmd
2+
3+
import (
4+
"encoding/json"
5+
6+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
7+
)
8+
9+
type MetadataFlag struct {
10+
metadata metav1.ObjectMeta
11+
}
12+
13+
func (f *MetadataFlag) String() string {
14+
b, err := json.Marshal(f.metadata)
15+
if err != nil {
16+
return "failed to marshal metadata object"
17+
}
18+
return string(b)
19+
}
20+
21+
func (f *MetadataFlag) Set(v string) error {
22+
f.metadata = metav1.ObjectMeta{}
23+
return json.Unmarshal([]byte(v), &f.metadata)
24+
}
25+
26+
func (f *MetadataFlag) Type() string {
27+
return "json"
28+
}

Diff for: cmd/show_permissions_cmd.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ func NewCommandGenerateShowPermissions() *cobra.Command {
2828
scope := "cluster"
2929
denyVerb := []string{}
3030
denyResource := []string{}
31+
metadataFlag := &MetadataFlag{metadata: metav1.ObjectMeta{Name: ""}}
3132

3233
// Support overrides
3334
cmd := &cobra.Command{
@@ -87,7 +88,7 @@ rbac-tool show --scope=namespaced --without-verbs=create,update,patch,delete,del
8788
if scope == "namespaced" {
8889
generateKind = "Role"
8990
}
90-
obj, err := generateRole(generateKind, computedPolicyRules)
91+
obj, err := generateRole(generateKind, computedPolicyRules, &metadataFlag.metadata)
9192
if err != nil {
9293
return err
9394
}
@@ -106,6 +107,7 @@ rbac-tool show --scope=namespaced --without-verbs=create,update,patch,delete,del
106107
flags.StringSliceVar(&withVerb, "with-verbs", []string{"*"}, "Comma separated list of verbs to include. To include all use '*'")
107108
flags.StringSliceVar(&denyVerb, "without-verbs", []string{""}, "Comma separated list of verbs to exclude.")
108109
flags.StringSliceVar(&denyResource, "without-resources", []string{""}, "Comma separated list of resources to exclude. Syntax: <resourceName>.<apiGroup>")
110+
flags.Var(metadataFlag, "metadata", "Kubernetes object metadata as JSON")
109111

110112
return cmd
111113
}

0 commit comments

Comments
 (0)