Skip to content

Commit

Permalink
generate role binding according to the role
Browse files Browse the repository at this point in the history
  • Loading branch information
Anddd7 committed Aug 1, 2023
1 parent c94980b commit 11272ce
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 8 deletions.
100 changes: 97 additions & 3 deletions pkg/rbac/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,107 @@ func GenerateRoles(ctx *genall.GenerationContext, roleName string) ([]interface{
return objs, nil
}

// GenerateRoleBindings generate a slice of objs representing either a ClusterRoleBinding or a RoleBinding object
// according to the given roles
func GenerateRoleBindings(roles []interface{}, roleName string) ([]interface{}, error) {
var objs []interface{}
for _, role := range roles {
if role, ok := role.(rbacv1.ClusterRole); ok {
objs = append(objs, rbacv1.ClusterRoleBinding{
TypeMeta: metav1.TypeMeta{
Kind: "ClusterRoleBinding",
APIVersion: rbacv1.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%sbinding", roleName),
},
Subjects: []rbacv1.Subject{
{
// keep consistent with kubebuilder's default
Kind: rbacv1.ServiceAccountKind,
Name: "controller-manager",
Namespace: "system",
},
},
RoleRef: rbacv1.RoleRef{
Kind: role.Kind,
Name: role.Name,
APIGroup: rbacv1.SchemeGroupVersion.Group,
},
})
}

if role, ok := role.(rbacv1.Role); ok {
objs = append(objs, rbacv1.RoleBinding{
TypeMeta: metav1.TypeMeta{
Kind: "RoleBinding",
APIVersion: rbacv1.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%sbinding", roleName),
Namespace: role.Namespace,
},
Subjects: []rbacv1.Subject{
{
// keep consistent with kubebuilder's default
Kind: rbacv1.ServiceAccountKind,
Name: "controller-manager",
Namespace: "system",
},
},
RoleRef: rbacv1.RoleRef{
Kind: role.Kind,
Name: role.Name,
APIGroup: rbacv1.SchemeGroupVersion.Group,
},
})
}
}
return objs, nil
}

// Generate generates RBAC manifests.
func (g Generator) Generate(ctx *genall.GenerationContext) error {
objs, err := GenerateRoles(ctx, g.RoleName)
roles, err := GenerateRoles(ctx, g.RoleName)
if err != nil {
return err
}

if len(objs) == 0 {
err = g.writeRoles(ctx, roles)
if err != nil {
return err
}

roleBindings, err := GenerateRoleBindings(roles, g.RoleName)
if err != nil {
return err
}

return g.writeRoleBindings(ctx, roleBindings)
}

// writeRoles writes the given roles to the file "role.yaml".
func (g Generator) writeRoles(ctx *genall.GenerationContext, roles []interface{}) error {
if len(roles) == 0 {
return nil
}

var headerText string
if g.HeaderFile != "" {
headerBytes, err := ctx.ReadFile(g.HeaderFile)
if err != nil {
return err
}
headerText = string(headerBytes)
}
headerText = strings.ReplaceAll(headerText, " YEAR", " "+g.Year)

return ctx.WriteYAML("role.yaml", headerText, roles, genall.WithTransform(genall.TransformRemoveCreationTimestamp))
}

// writeRoleBindings writes the given roleBindings to the file "role_binding.yaml".
func (g Generator) writeRoleBindings(ctx *genall.GenerationContext, roleBindings []interface{}) error {
if len(roleBindings) == 0 {
return nil
}

Expand All @@ -279,5 +373,5 @@ func (g Generator) Generate(ctx *genall.GenerationContext) error {
}
headerText = strings.ReplaceAll(headerText, " YEAR", " "+g.Year)

return ctx.WriteYAML("role.yaml", headerText, objs, genall.WithTransform(genall.TransformRemoveCreationTimestamp))
return ctx.WriteYAML("role_binding.yaml", headerText, roleBindings, genall.WithTransform(genall.TransformRemoveCreationTimestamp))
}
33 changes: 28 additions & 5 deletions pkg/rbac/parser_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,18 @@ var _ = Describe("ClusterRole generated by the RBAC Generator", func() {
Roots: pkgs,
}

By("generating a ClusterRole")
objs, err := rbac.GenerateRoles(ctx, "manager-role")
By("generating ClusterRoles and Roles")
roles, err := rbac.GenerateRoles(ctx, "manager-role")
Expect(err).NotTo(HaveOccurred())

By("loading the desired YAML")
By("loading the desired role YAML")
expectedFile, err := ioutil.ReadFile("role.yaml")
Expect(err).NotTo(HaveOccurred())

By("parsing the desired YAML")
By("parsing the desired role YAML")
for i, expectedRoleBytes := range bytes.Split(expectedFile, []byte("\n---\n"))[1:] {
By(fmt.Sprintf("comparing the generated Role and expected Role (Pair %d)", i))
obj := objs[i]
obj := roles[i]
switch obj := obj.(type) {
case rbacv1.ClusterRole:
var expectedClusterRole rbacv1.ClusterRole
Expand All @@ -68,6 +68,29 @@ var _ = Describe("ClusterRole generated by the RBAC Generator", func() {
}
}

By("generating ClusterRoleBindings and RoleBindings")
roleBindings, err := rbac.GenerateRoleBindings(roles, "manager-role")
Expect(err).NotTo(HaveOccurred())

By("loading the desired role binding YAML")
expectedFile, err = ioutil.ReadFile("role_binding.yaml")
Expect(err).NotTo(HaveOccurred())

By("parsing the desired role binding YAML")
for i, expectedRoleBindingBytes := range bytes.Split(expectedFile, []byte("\n---\n"))[1:] {
By(fmt.Sprintf("comparing the generated RoleBinding and expected RoleBinding (Pair %d)", i))
obj := roleBindings[i]
switch obj := obj.(type) {
case rbacv1.ClusterRoleBinding:
var expectedClusterRoleBinding rbacv1.ClusterRoleBinding
Expect(yaml.Unmarshal(expectedRoleBindingBytes, &expectedClusterRoleBinding)).To(Succeed())
Expect(obj).To(Equal(expectedClusterRoleBinding), "type not as expected, check pkg/rbac/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(obj, expectedClusterRoleBinding))
default:
var expectedRoleBinding rbacv1.RoleBinding
Expect(yaml.Unmarshal(expectedRoleBindingBytes, &expectedRoleBinding)).To(Succeed())
Expect(obj).To(Equal(expectedRoleBinding), "type not as expected, check pkg/rbac/testdata/README.md for more details.\n\nDiff:\n\n%s", cmp.Diff(obj, expectedRoleBinding))
}
}
})
}
})
Binary file added pkg/rbac/testdata/controller-gen
Binary file not shown.
44 changes: 44 additions & 0 deletions pkg/rbac/testdata/role_binding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: manager-role
subjects:
- kind: ServiceAccount
name: controller-manager
namespace: system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: manager-rolebinding
namespace: park
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: manager-role
subjects:
- kind: ServiceAccount
name: controller-manager
namespace: system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: manager-rolebinding
namespace: zoo
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: manager-role
subjects:
- kind: ServiceAccount
name: controller-manager
namespace: system

0 comments on commit 11272ce

Please sign in to comment.