Skip to content

Commit

Permalink
Inital rbac commit:
Browse files Browse the repository at this point in the history
Signed-off-by: lubronzhan <lubronzhan@gmail.com>
  • Loading branch information
lubronzhan committed Jan 14, 2024
1 parent dc6707a commit 680c1d7
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 7 deletions.
25 changes: 22 additions & 3 deletions internal/provisioner/objects/rbac/clusterrole/cluster_role.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ const (

// EnsureClusterRole ensures a ClusterRole resource exists with the provided name
// and contour namespace/name for the owning contour labels.
func EnsureClusterRole(ctx context.Context, cli client.Client, name string, contour *model.Contour) error {
desired := desiredClusterRole(name, contour)
func EnsureClusterRole(ctx context.Context, cli client.Client, name string, contour *model.Contour, gatewayClassOnly bool) error {
desired := desiredClusterRole(name, contour, gatewayClassOnly)

// Enclose contour.
updater := func(ctx context.Context, cli client.Client, current, desired *rbacv1.ClusterRole) error {
Expand All @@ -49,7 +49,7 @@ func EnsureClusterRole(ctx context.Context, cli client.Client, name string, cont

// desiredClusterRole constructs an instance of the desired ClusterRole resource with
// the provided name and contour namespace/name for the owning contour labels.
func desiredClusterRole(name string, contour *model.Contour) *rbacv1.ClusterRole {
func desiredClusterRole(name string, contour *model.Contour, gatewayClassOnly bool) *rbacv1.ClusterRole {
var (
createGetUpdate = []string{"create", "get", "update"}
getListWatch = []string{"get", "list", "watch"}
Expand All @@ -64,6 +64,25 @@ func desiredClusterRole(name string, contour *model.Contour) *rbacv1.ClusterRole
}
}

if gatewayClassOnly {
return &rbacv1.ClusterRole{
TypeMeta: metav1.TypeMeta{
Kind: "Role",
},
ObjectMeta: metav1.ObjectMeta{
Name: name,
Labels: contour.CommonLabels(),
Annotations: contour.CommonAnnotations(),
},
Rules: []rbacv1.PolicyRule{
// Gateway API resources.
// Note, ReferenceGrant does not currently have a .status field so it's omitted from the status rule.
policyRuleFor(gatewayv1alpha2.GroupName, getListWatch, "gatewayclasses"),
policyRuleFor(gatewayv1alpha2.GroupName, update, "gatewayclasses/status"),
},
}
}

return &rbacv1.ClusterRole{
TypeMeta: metav1.TypeMeta{
Kind: "Role",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func checkClusterRoleLabels(t *testing.T, cr *rbacv1.ClusterRole, expected map[s
func TestDesiredClusterRole(t *testing.T) {
name := "test-cr"
cntr := model.Default(fmt.Sprintf("%s-ns", name), name)
cr := desiredClusterRole(name, cntr)
cr := desiredClusterRole(name, cntr, false)
checkClusterRoleName(t, cr, name)
ownerLabels := map[string]string{
model.ContourOwningGatewayNameLabel: cntr.Name,
Expand Down
26 changes: 23 additions & 3 deletions internal/provisioner/objects/rbac/rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,30 @@ func ensureContourRBAC(ctx context.Context, cli client.Client, contour *model.Co
return fmt.Errorf("failed to ensure service account %s/%s: %w", contour.Namespace, names.ServiceAccount, err)
}

// Ensure cluster role & binding.
if err := clusterrole.EnsureClusterRole(ctx, cli, names.ClusterRole, contour); err != nil {
return fmt.Errorf("failed to ensure cluster role %s: %w", names.ClusterRole, err)
// By default, Contour watches all namespaces, use default cluster role and rolebinding
if contour.WatchAllNamespaces() {
// Ensure cluster role & binding.
if err := clusterrole.EnsureClusterRole(ctx, cli, names.ClusterRole, contour, false); err != nil {
return fmt.Errorf("failed to ensure cluster role %s: %w", names.ClusterRole, err)
}
} else {
// Ensure cluster role & cluster binding for gatewayclass first since it's cluster scope variables
if err := clusterrole.EnsureClusterRole(ctx, cli, names.ClusterRole, contour, true); err != nil {
return fmt.Errorf("failed to ensure cluster role %s: %w", names.ClusterRole, err)
}

// Ensures role and rolebinding for set of namespaces in contour.spec.watchNamespaces variable
// Ensure cluster role & cluster binding for gatewayclass first since it's cluster scope variables
if err := role.EnsureRolesForNamespaces(ctx, cli, names.Role, contour); err != nil {
return fmt.Errorf("failed to ensure cluster role %s: %w", names.ClusterRole, err)
}
// Ensures role and rolebinding for set of namespaces in contour.spec.watchNamespaces variable
// Ensure cluster role & cluster binding for gatewayclass first since it's cluster scope variables
if err := rolebinding.EnsureRoleBindingsForNamespaces(ctx, cli, names.RoleBinding, names.ServiceAccount, names.Role, contour); err != nil {
return fmt.Errorf("failed to ensure cluster role %s: %w", names.ClusterRole, err)
}
}

if err := clusterrolebinding.EnsureClusterRoleBinding(ctx, cli, names.ClusterRoleBinding, names.ClusterRole, names.ServiceAccount, contour); err != nil {
return fmt.Errorf("failed to ensure cluster role binding %s: %w", names.ClusterRoleBinding, err)
}
Expand Down
13 changes: 13 additions & 0 deletions internal/provisioner/objects/rbac/role/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,19 @@ func EnsureControllerRole(ctx context.Context, cli client.Client, name string, c
return objects.EnsureObject(ctx, cli, desired, updater, &rbacv1.Role{})
}

// EnsureRolesForNamespaces ensures a Role resource exists with the for the Contour
// controller.
func EnsureRolesForNamespaces(ctx context.Context, cli client.Client, name string, contour *model.Contour) error {
desired := desiredControllerRole(name, contour)

updater := func(ctx context.Context, cli client.Client, current, desired *rbacv1.Role) error {
_, err := updateRoleIfNeeded(ctx, cli, contour, current, desired)
return err
}

return objects.EnsureObject(ctx, cli, desired, updater, &rbacv1.Role{})
}

// desiredControllerRole constructs an instance of the desired Role resource with the
// provided ns/name and contour namespace/name for the owning contour labels for
// the Contour controller.
Expand Down
14 changes: 14 additions & 0 deletions internal/provisioner/objects/rbac/rolebinding/role_binding.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,20 @@ func EnsureRoleBinding(ctx context.Context, cli client.Client, name, svcAct, rol
return objects.EnsureObject(ctx, cli, desired, updater, &rbacv1.RoleBinding{})
}

// EnsureRoleBindingsForNamespaces ensures a RoleBinding resource exists with the provided
// ns/name and contour namespace/name for the owning contour labels.
// The RoleBinding will use svcAct for the subject and role for the role reference.
func EnsureRoleBindingsForNamespaces(ctx context.Context, cli client.Client, name, svcAct, role string, contour *model.Contour) error {
desired := desiredRoleBinding(name, svcAct, role, contour)

// Enclose contour.
updater := func(ctx context.Context, cli client.Client, current, desired *rbacv1.RoleBinding) error {
return updateRoleBindingIfNeeded(ctx, cli, contour, current, desired)
}

return objects.EnsureObject(ctx, cli, desired, updater, &rbacv1.RoleBinding{})
}

// desiredRoleBinding constructs an instance of the desired RoleBinding resource
// with the provided name in Contour spec Namespace, using contour namespace/name
// for the owning contour labels. The RoleBinding will use svcAct for the subject
Expand Down

0 comments on commit 680c1d7

Please sign in to comment.