Skip to content

Commit

Permalink
Generate RBAC settings declaratively
Browse files Browse the repository at this point in the history
This allows RBAC settings to be declared as close as possible to their
point of use, which means that, as functions are added and deleted,
permissions will be adjusted "automatically" and we'll avoid keeping
no-longer-needed permissions.

As generated by the operator SDK, the operator ends up with only
cluster roles, but this makes sense since the operator is supposed to
be able to act in any namespace.

Fixes: submariner-io#1105
Signed-off-by: Stephen Kitt <[email protected]>
  • Loading branch information
skitt committed Mar 18, 2021
1 parent 6139040 commit 257ad3e
Show file tree
Hide file tree
Showing 14 changed files with 201 additions and 60 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ generate: vendor/modules.txt

# Generate manifests e.g. CRD, RBAC etc
manifests: generate vendor/modules.txt
controller-gen $(CRD_OPTIONS) rbac:roleName=manager-role webhook paths="./..." output:crd:artifacts:config=config/crd/bases
controller-gen $(CRD_OPTIONS) rbac:roleName=submariner-operator webhook paths="./..." output:crd:artifacts:config=config/crd/bases output:rbac:artifacts:config=config/rbac/submariner-operator

# test if VERSION matches the semantic versioning rule
is-semantic-version:
Expand Down
206 changes: 149 additions & 57 deletions config/rbac/submariner-operator/role.yaml
Original file line number Diff line number Diff line change
@@ -1,63 +1,155 @@

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
kind: ClusterRole
metadata:
creationTimestamp: null
name: submariner-operator
rules:
- apiGroups:
- ""
resources:
- pods
- services
- services/finalizers
- endpoints
- persistentvolumeclaims
- events
- configmaps
- secrets
verbs:
- '*'
- apiGroups:
- apps
resources:
- deployments
- daemonsets
- replicasets
- statefulsets
verbs:
- '*'
- apiGroups:
- monitoring.coreos.com
resources:
- servicemonitors
verbs:
- get
- create
- apiGroups:
- apps
resourceNames:
- submariner-operator
resources:
- deployments/finalizers
verbs:
- update
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- apps
resources:
- replicasets
verbs:
- get
- apiGroups:
- submariner.io
resources:
- '*'
- servicediscoveries
verbs:
- '*'
- resources:
- configmaps
verbs:
- create
- get
- update
- resources:
- namespaces
verbs:
- create
- resources:
- nodes
verbs:
- list
- resources:
- pods
verbs:
- list
- resources:
- secrets
verbs:
- get
- resources:
- serviceaccounts
verbs:
- create
- get
- update
- resources:
- services
verbs:
- create
- get
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- create
- get
- update
- apiGroups:
- apps
resources:
- deployments
verbs:
- create
- get
- update
- apiGroups:
- rbac
resources:
- clusterrolebindings
verbs:
- create
- get
- update
- apiGroups:
- rbac
resources:
- clusterroles
verbs:
- create
- get
- update
- apiGroups:
- rbac
resources:
- rolebindings
verbs:
- create
- get
- update
- apiGroups:
- rbac
resources:
- roles
verbs:
- create
- get
- update
- apiGroups:
- rbac
resources:
- serviceaccounts
verbs:
- create
- apiGroups:
- submariner.io
resources:
- brokers
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- submariner.io
resources:
- brokers/status
verbs:
- get
- patch
- update
- apiGroups:
- submariner.io
resources:
- servicediscoveries
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- submariner.io
resources:
- servicediscoveries/status
verbs:
- get
- patch
- update
- apiGroups:
- submariner.io
resources:
- submariners
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- submariner.io
resources:
- submariners/status
verbs:
- get
- patch
- update
7 changes: 7 additions & 0 deletions controllers/servicediscovery/servicediscovery_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ type ServiceDiscoveryReconciler struct {

// +kubebuilder:rbac:groups=submariner.io,resources=servicediscoveries,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=submariner.io,resources=servicediscoveries/status,verbs=get;update;patch

func (r *ServiceDiscoveryReconciler) Reconcile(request reconcile.Request) (reconcile.Result, error) {
reqLogger := log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name)
reqLogger.Info("Reconciling ServiceDiscovery")
Expand Down Expand Up @@ -377,6 +378,9 @@ func newLighthouseCoreDNSService(cr *submarinerv1alpha1.ServiceDiscovery) *corev
}
}

// +kubebuilder:rbac:resources=configmaps,verbs=get;update
// +kubebuilder:rbac:resources=services,verbs=get

func updateDNSCustomConfigMap(client controllerClient.Client, k8sclientSet clientset.Interface, cr *submarinerv1alpha1.ServiceDiscovery,
reqLogger logr.Logger) error {
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
Expand Down Expand Up @@ -415,6 +419,9 @@ func updateDNSCustomConfigMap(client controllerClient.Client, k8sclientSet clien
return retryErr
}

// +kubebuilder:rbac:resources=configmaps,verbs=get;update
// +kubebuilder:rbac:resources=services,verbs=get

func updateDNSConfigMap(client controllerClient.Client, k8sclientSet clientset.Interface, cr *submarinerv1alpha1.ServiceDiscovery,
reqLogger logr.Logger) error {
retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error {
Expand Down
3 changes: 1 addition & 2 deletions controllers/submariner/broker_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,9 @@ type BrokerReconciler struct {
Scheme *runtime.Scheme
}

// TODO skitt: these rbac declarations (and others, see submariner_controller.go) need to be separated
// from methods in order to be taken into account; but they produce ClusterRoles, not the Roles we want
// +kubebuilder:rbac:groups=submariner.io,resources=brokers,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=submariner.io,resources=brokers/status,verbs=get;update;patch

func (r *BrokerReconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) {
_ = context.Background()
_ = r.Log.WithValues("broker", request.NamespacedName)
Expand Down
1 change: 1 addition & 0 deletions controllers/submariner/submariner_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ type SubmarinerReconciler struct {

// +kubebuilder:rbac:groups=submariner.io,resources=submariners,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=submariner.io,resources=submariners/status,verbs=get;update;patch

func (r *SubmarinerReconciler) Reconcile(request reconcile.Request) (reconcile.Result, error) {
reqLogger := log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name)
reqLogger.Info("Reconciling Submariner")
Expand Down
6 changes: 6 additions & 0 deletions pkg/broker/ensure.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ func WaitForClientToken(clientset *kubernetes.Clientset, submarinerBrokerSA stri
return secret, err
}

// +kubebuilder:rbac:resources=namespaces,verbs=create

func CreateNewBrokerNamespace(clientset *kubernetes.Clientset) (brokernamespace *v1.Namespace, err error) {
return clientset.CoreV1().Namespaces().Create(NewBrokerNamespace())
}
Expand All @@ -189,13 +191,17 @@ func CreateOrUpdateBrokerAdminRole(clientset *kubernetes.Clientset) (created boo
return utils.CreateOrUpdateRole(clientset, SubmarinerBrokerNamespace, NewBrokerAdminRole())
}

// +kubebuilder:rbac:groups=rbac,resources=serviceaccounts,verbs=create

func CreateNewBrokerRoleBinding(clientset *kubernetes.Clientset, serviceAccount, role string) (brokerRoleBinding *rbac.RoleBinding,
err error) {
return clientset.RbacV1().RoleBindings(SubmarinerBrokerNamespace).Create(
NewBrokerRoleBinding(serviceAccount, role),
)
}

// +kubebuilder:rbac:resources=serviceaccounts,verbs=create

func CreateNewBrokerSA(clientset *kubernetes.Clientset, submarinerBrokerSA string) (brokerSA *v1.ServiceAccount, err error) {
return clientset.CoreV1().ServiceAccounts(SubmarinerBrokerNamespace).Create(NewBrokerSA(submarinerBrokerSA))
}
6 changes: 6 additions & 0 deletions pkg/broker/globalcidr_cm.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ type ClusterInfo struct {
GlobalCidr []string `json:"global_cidr"`
}

// +kubebuilder:rbac:resources=configmaps,verbs=create

func CreateGlobalnetConfigMap(config *rest.Config, globalnetEnabled bool, defaultGlobalCidrRange string,
defaultGlobalClusterSize uint, namespace string) error {
clientset, err := kubernetes.NewForConfig(config)
Expand Down Expand Up @@ -95,6 +97,8 @@ func NewGlobalnetConfigMap(globalnetEnabled bool, defaultGlobalCidrRange string,
return cm, nil
}

// +kubebuilder:rbac:resources=configmaps,verbs=update

func UpdateGlobalnetConfigMap(k8sClientset *kubernetes.Clientset, namespace string,
configMap *v1.ConfigMap, newCluster ClusterInfo) error {
var clusterInfo []ClusterInfo
Expand Down Expand Up @@ -128,6 +132,8 @@ func UpdateGlobalnetConfigMap(k8sClientset *kubernetes.Clientset, namespace stri
return err
}

// +kubebuilder:rbac:resources=configmaps,verbs=get

func GetGlobalnetConfigMap(k8sClientset *kubernetes.Clientset, namespace string) (*v1.ConfigMap, error) {
cm, err := k8sClientset.CoreV1().ConfigMaps(namespace).Get(GlobalCIDRConfigMapName, metav1.GetOptions{})
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions pkg/broker/rbac.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ func NewBrokerRoleBinding(serviceAccount, role string) *rbacv1.RoleBinding {
return binding
}

// +kubebuilder:rbac:resources=serviceaccounts,verbs=get
// +kubebuilder:rbac:resources=secrets,verbs=get

func GetClientTokenSecret(clientSet clientset.Interface, brokerNamespace, submarinerBrokerSA string) (*v1.Secret, error) {
sa, err := clientSet.CoreV1().ServiceAccounts(brokerNamespace).Get(submarinerBrokerSA, metav1.GetOptions{})
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions pkg/discovery/network/canal.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"k8s.io/client-go/kubernetes"
)

// +kubebuilder:rbac:resources=configmaps,verbs=get

func discoverCanalFlannelNetwork(clientSet kubernetes.Interface) (*ClusterNetwork, error) {
// TODO: this must be smarter, looking for the canal daemonset, with labels k8s-app=canal
// and then the reference on the container volumes:
Expand Down
4 changes: 4 additions & 0 deletions pkg/discovery/network/generic.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ func findClusterIPRangeFromApiserver(clientSet kubernetes.Interface) (string, er
return findPodCommandParameter(clientSet, "component=kube-apiserver", "--service-cluster-ip-range")
}

// +kubebuilder:rbac:resources=services,verbs=create

func findClusterIPRangeFromServiceCreation(clientSet kubernetes.Interface) (string, error) {
// find service cidr based on https://stackoverflow.com/questions/44190607/how-do-you-find-the-cluster-service-cidr-of-a-kubernetes-cluster
invalidSvcSpec := &v1.Service{
Expand Down Expand Up @@ -160,6 +162,8 @@ func findPodIPRangeKubeProxy(clientSet kubernetes.Interface) (string, error) {
return findPodCommandParameter(clientSet, "component=kube-proxy", "--cluster-cidr")
}

// +kubebuilder:rbac:resources=nodes,verbs=list

func findPodIPRangeFromNodeSpec(clientSet kubernetes.Interface) (string, error) {
nodes, err := clientSet.CoreV1().Nodes().List(v1meta.ListOptions{})

Expand Down
3 changes: 3 additions & 0 deletions pkg/discovery/network/ovnkubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ const (
OvnKubernetes = "OVNKubernetes"
)

// +kubebuilder:rbac:resources=services,verbs=get
// +kubebuilder:rbac:resources=configmaps,verbs=get

func discoverOvnKubernetesNetwork(clientSet kubernetes.Interface) (*ClusterNetwork, error) {
ovnDBPod, err := findPod(clientSet, "name=ovnkube-db")

Expand Down
2 changes: 2 additions & 0 deletions pkg/discovery/network/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ func findPodCommandParameter(clientSet kubernetes.Interface, labelSelector, para
return "", nil
}

// +kubebuilder:rbac:resources=pods,verbs=list

func findPod(clientSet kubernetes.Interface, labelSelector string) (*v1.Pod, error) {
pods, err := clientSet.CoreV1().Pods("").List(v1meta.ListOptions{
LabelSelector: labelSelector,
Expand Down
2 changes: 2 additions & 0 deletions pkg/subctl/operator/common/namespace/ensure.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import (
"k8s.io/client-go/rest"
)

// +kubebuilder:rbac:resources=namespaces,verbs=create

// Ensure functions updates or installs the operator CRDs in the cluster
func Ensure(restConfig *rest.Config, namespace string) (bool, error) {
clientSet, err := clientset.NewForConfig(restConfig)
Expand Down
Loading

0 comments on commit 257ad3e

Please sign in to comment.