Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

customize object metadata for generated roles/clusterroles #105

Merged
merged 1 commit into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading