Skip to content

Commit

Permalink
customize object metadata for generated roles/clusterroles (#105)
Browse files Browse the repository at this point in the history
Implements #92
  • Loading branch information
gadinaor-r7 authored May 6, 2024
1 parent 505d5c7 commit 813bd86
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 13 deletions.
36 changes: 24 additions & 12 deletions cmd/generate_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ import (
)

func NewCommandGenerateClusterRole() *cobra.Command {

clusterContext := ""
generateKind := ""
allowedGroups := []string{}
//expandGroups := []string{}
allowedVerb := []string{}
denyResources := []string{}
metadataFlag := &MetadataFlag{metadata: metav1.ObjectMeta{Name: ""}}

// Support overrides
cmd := &cobra.Command{
Expand All @@ -47,6 +47,8 @@ rbac-tool gen --generated-type=Role --deny-resources=secrets.,ingresses.extensio
# Generate a Role with read-only (get,list) excluding secrets (core group) from core group, admissionregistration.k8s.io,storage.k8s.io,networking.k8s.io
rbac-tool gen --generated-type=ClusterRole --deny-resources=secrets., --allowed-verbs=get,list --allowed-groups=,admissionregistration.k8s.io,storage.k8s.io,networking.k8s.io
# Generate a Role and customize the metadata of the generated object
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"}}'
`,
Hidden: false,
Expand All @@ -61,7 +63,7 @@ rbac-tool gen --generated-type=ClusterRole --deny-resources=secrets., --allowed-
return err
}

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

return cmd
}

func generateRole(generateKind string, rules []rbacv1.PolicyRule) (string, error) {
func generateRole(generateKind string, rules []rbacv1.PolicyRule, metadata *metav1.ObjectMeta) (string, error) {
var obj runtime.Object
md := *metadata

if generateKind == "ClusterRole" {
if md.Name == "" {
md.Name = "custom-cluster-role"
}
md.Namespace = ""

obj = &rbacv1.ClusterRole{
TypeMeta: metav1.TypeMeta{
Kind: "ClusterRole",
APIVersion: "rbac.authorization.k8s.io/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "custom-cluster-role",
},
Rules: rules,
ObjectMeta: md,
Rules: rules,
}
} else {
if md.Name == "" {
md.Name = "custom-role"
}
if md.Namespace == "" {
md.Namespace = "mynamespace"
}

obj = &rbacv1.Role{
TypeMeta: metav1.TypeMeta{
Kind: "Role",
APIVersion: "rbac.authorization.k8s.io/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "custom-role",
Namespace: "mynamespace",
},
Rules: rules,
ObjectMeta: md,
Rules: rules,
}

}

serializer := k8sJson.NewSerializerWithOptions(k8sJson.DefaultMetaFactory, nil, nil, k8sJson.SerializerOptions{Yaml: true, Pretty: true, Strict: true})
Expand Down
28 changes: 28 additions & 0 deletions cmd/metadata_arg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package cmd

import (
"encoding/json"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type MetadataFlag struct {
metadata metav1.ObjectMeta
}

func (f *MetadataFlag) String() string {
b, err := json.Marshal(f.metadata)
if err != nil {
return "failed to marshal metadata object"
}
return string(b)
}

func (f *MetadataFlag) Set(v string) error {
f.metadata = metav1.ObjectMeta{}
return json.Unmarshal([]byte(v), &f.metadata)
}

func (f *MetadataFlag) Type() string {
return "json"
}
4 changes: 3 additions & 1 deletion cmd/show_permissions_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func NewCommandGenerateShowPermissions() *cobra.Command {
scope := "cluster"
denyVerb := []string{}
denyResource := []string{}
metadataFlag := &MetadataFlag{metadata: metav1.ObjectMeta{Name: ""}}

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

return cmd
}
Expand Down

0 comments on commit 813bd86

Please sign in to comment.