|
| 1 | +# Addon Template ClusterRoleBinding |
| 2 | + |
| 3 | +## Release Signoff Checklist |
| 4 | + |
| 5 | +- [ ] Enhancement is `provisional` |
| 6 | +- [ ] Design details are appropriately documented from clear requirements |
| 7 | +- [ ] Test plan is defined |
| 8 | +- [ ] Graduation criteria for dev preview, tech preview, GA |
| 9 | +- [ ] User-facing documentation is created in [website](https://github.com/open-cluster-management-io/open-cluster-management-io.github.io/) |
| 10 | + |
| 11 | +## Summary |
| 12 | +Extend AddonTemplate kubeClient registration to support ClusterRoleBindings for addon agent service accounts. A new hubPermission type called "AllNamespaces" will be added along with an associated AllNamespacesBindingConfig which references a ClusterRole in the hub. The addon manager will create a ClusterRoleBinding for each ManagedClusterAddon that binds the ClusterRole to the subject associated with the spoke addon agent. |
| 13 | + |
| 14 | +## Motivation |
| 15 | +Currently hubPermissions only supports creating a RoleBinding for CurrentCluster or SingleNamespace. This means that spoke addon agents can't be granted permissions on non-namespaced resources/custom-resources without a hub addon controller that manages the ClusterRoleBinding for ManagedClusterAddons. |
| 16 | + |
| 17 | +My use-case is for a non-namespaced CRD that describes shared state for the fleet which needs to be distributed out to spoke clusters. The only way for me to do this right now is to add a custom controller in the addon's hub manager that watches ManagedClusterAddons and creates the ClusterRoleBindings itself. |
| 18 | + |
| 19 | +## Proposal |
| 20 | +- Add "AllNamespaces" hub permission type, which references a single ClusterRole in the hub |
| 21 | +- Addon Manager will manage ClusterRoleBindings for spoke agent addons with AllNamespaces permissions |
| 22 | + - Each ManagedClusterAddon has its own ClusterRoleBinding named `open-cluster-management:<addon-name>:clusterrole:<cluster-name>:agent` |
| 23 | + |
| 24 | +### Design Details |
| 25 | + |
| 26 | +### Permission change |
| 27 | + |
| 28 | +Add `clusterrolebindings` to the `open-cluster-management:{{ .ClusterManagerName }}-addon-manager:controller` ClusterRole |
| 29 | + |
| 30 | +#### API change |
| 31 | + |
| 32 | +Add new HubPermissionsBindingType |
| 33 | + |
| 34 | +```go |
| 35 | + |
| 36 | +const ( |
| 37 | + ... |
| 38 | + |
| 39 | + // HubPermissionsBindingAllNamespaces means the addon agent will have access to resources in any namespace, |
| 40 | + // or to non-namespaced resources on the hub cluster. |
| 41 | + HubPermissionsBindingAllNamespaces HubPermissionsBindingType = "AllNamespaces" |
| 42 | +) |
| 43 | +``` |
| 44 | + |
| 45 | +Add config for AllNamespaces permissions |
| 46 | + |
| 47 | +```go |
| 48 | +type HubPermissionConfig struct { |
| 49 | + // Type of the permissions setting. It defines how to bind the roleRef on the hub cluster. It can be: |
| 50 | + // - CurrentCluster: Bind the roleRef to the namespace with the same name as the managedCluster. |
| 51 | + // - SingleNamespace: Bind the roleRef to the namespace specified by SingleNamespaceBindingConfig. |
| 52 | + // - AllNamespaces: Bind the clusterRoleRef to the subject for the managedCluster. |
| 53 | + // |
| 54 | + // +kubebuilder:validation:Required |
| 55 | + // +kubebuilder:validation:Enum:=CurrentCluster;SingleNamespace;AllNamespaces |
| 56 | + Type HubPermissionsBindingType `json:"type"` |
| 57 | + |
| 58 | + ... |
| 59 | + |
| 60 | + // AllNamespaces contains the configuration of AllNamespaces type binding. |
| 61 | + // It is required when the type is AllNamespaces |
| 62 | + AllNamespaces *AllNamespacesBindingConfig `json:"allNamespaces,omitempty"` |
| 63 | +} |
| 64 | + |
| 65 | +type AllNamespacesBindingConfig struct { |
| 66 | + // ClusterRoleName is the name of the clusterrole the addon agent is bound. A clusterrolebinding |
| 67 | + // will be created referring to this cluster role with subjects for each cluster namespace. |
| 68 | + // The user must make sure the clusterrole exists on the hub cluster. |
| 69 | + // +kubebuilder:validation:Required |
| 70 | + ClusterRoleName string `json:"clusterRoleName"` |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +#### hub implementation |
| 75 | +Update `createKubeClientPermissions` in `pkg/addon/templateagent/registration.go` to handle the additional hub permission case `addonapiv1alpha1.HubPermissionsBindingAllNamespaces`. This will call a new method `createPermissionClusterRoleBinding` which is nearly the same as the existing `createPermissionRoleBinding` except that it creates a ClusterRoleBinding instead of a RoleBinding. |
| 76 | + |
| 77 | +#### examples |
| 78 | + |
| 79 | +```yaml |
| 80 | +apiVersion: addon.open-cluster-management.io/v1beta1 |
| 81 | +kind: AddOnTemplate |
| 82 | +metadata: |
| 83 | + name: my-agent |
| 84 | +spec: |
| 85 | + addonName: my-agent |
| 86 | + agentSpec: |
| 87 | + workload: |
| 88 | + manifests: |
| 89 | + - apiVersion: apps/v1 |
| 90 | + kind: Deployment |
| 91 | + metadata: |
| 92 | + name: my-agent-addon |
| 93 | + namespace: open-cluster-management-agent-addon |
| 94 | + spec: |
| 95 | + replicas: 1 |
| 96 | + selector: |
| 97 | + matchLabels: |
| 98 | + addon-agent: my-agent |
| 99 | + template: |
| 100 | + metadata: |
| 101 | + labels: |
| 102 | + addon-agent: my-agent |
| 103 | + spec: |
| 104 | + containers: |
| 105 | + - name: addon-agent |
| 106 | + image: registry.example.com/my-agent:latest |
| 107 | + registration: |
| 108 | + - type: KubeClient |
| 109 | + kubeClient: |
| 110 | + hubPermissions: |
| 111 | + - type: AllNamespaces |
| 112 | + allNamespaces: |
| 113 | + clusterRoleName: my-agent-hub-permissions |
| 114 | +``` |
| 115 | +
|
| 116 | +### Test Plan |
| 117 | +- Verify existing AddonTemplates with hub permissions continue to work as before |
| 118 | +- Add AllNamespaces binding for a hub ClusterRole, verify ClusterRoleBinding is created for each ManagedClusterAddon |
| 119 | +
|
| 120 | +### Graduation Criteria |
| 121 | +N/A |
| 122 | +
|
| 123 | +### Upgrade Strategy |
| 124 | +Upgrade AddonTemplate CRD. Existing AddonTemplates will not need to be changed. |
| 125 | +
|
| 126 | +### Version Skew Strategy |
| 127 | +The AllNamespaces hubPermissions type is added on top of existing types. No migration required. |
0 commit comments