From 959b71b8841ee5206d7a0bc80f51b81388c42fe8 Mon Sep 17 00:00:00 2001 From: Stephen Kitt Date: Wed, 24 Feb 2021 10:07:43 +0100 Subject: [PATCH] Generate RBAC settings declaratively 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: #1105 Signed-off-by: Stephen Kitt --- .yamllint.yml | 1 + Makefile | 2 +- config/rbac/kustomization.yaml | 2 - .../submariner-operator/cluster_role.yaml | 55 ---- .../cluster_role_binding.yaml | 13 - config/rbac/submariner-operator/role.yaml | 249 ++++++++++++++---- .../submariner-operator/role_binding.yaml | 7 +- controllers/helpers/helpers.go | 8 + .../servicediscovery_controller.go | 11 + controllers/submariner/broker_controller.go | 3 +- .../submariner/submariner_controller.go | 9 + main.go | 3 + pkg/broker/ensure.go | 6 + pkg/broker/globalcidr_cm.go | 6 + pkg/broker/rbac.go | 3 + pkg/discovery/network/canal.go | 2 + pkg/discovery/network/generic.go | 4 + pkg/discovery/network/ovnkubernetes.go | 3 + pkg/discovery/network/pods.go | 2 + pkg/subctl/cmd/root.go | 6 + .../embeddedyamls/generators/yamls2go.go | 2 - .../operator/common/namespace/ensure.go | 2 + .../submarinerop/serviceaccount/ensure.go | 20 +- pkg/utils/createorupdate.go | 14 + 24 files changed, 282 insertions(+), 151 deletions(-) delete mode 100644 config/rbac/submariner-operator/cluster_role.yaml delete mode 100644 config/rbac/submariner-operator/cluster_role_binding.yaml diff --git a/.yamllint.yml b/.yamllint.yml index b6821603c..303ddf459 100644 --- a/.yamllint.yml +++ b/.yamllint.yml @@ -21,6 +21,7 @@ ignore: | /config/crd/bases/submariner.io_brokers.yaml /config/crd/bases/submariner.io_submariners.yaml /config/crd/bases/submariner.io_servicediscoveries.yaml + /config/rbac/submariner-operator/role.yaml /config/manager/kustomization.yaml /config/manifests/bases/submariner.clusterserviceversion.yaml /bundle diff --git a/Makefile b/Makefile index 600f607f0..bba792244 100644 --- a/Makefile +++ b/Makefile @@ -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: diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml index 357306f63..ba07e97a4 100644 --- a/config/rbac/kustomization.yaml +++ b/config/rbac/kustomization.yaml @@ -3,8 +3,6 @@ resources: - submariner-operator/service_account.yaml - submariner-operator/role.yaml - submariner-operator/role_binding.yaml - - submariner-operator/cluster_role.yaml - - submariner-operator/cluster_role_binding.yaml - submariner-gateway/service_account.yaml - submariner-gateway/role.yaml - submariner-gateway/role_binding.yaml diff --git a/config/rbac/submariner-operator/cluster_role.yaml b/config/rbac/submariner-operator/cluster_role.yaml deleted file mode 100644 index 9046b5631..000000000 --- a/config/rbac/submariner-operator/cluster_role.yaml +++ /dev/null @@ -1,55 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: submariner-operator -rules: - # submariner-operator updates the config map of core-dns to forward requests to - # clusterset.local to Lighthouse DNS, also looks at existing configmaps - # to figure out network settings - - apiGroups: - - "" - resources: - - configmaps - verbs: - - create - - get - - list - - watch - - update - - apiGroups: - - apiextensions.k8s.io - resources: - - customresourcedefinitions - verbs: - - get - - list - - create - - update - - delete - - apiGroups: # pods, services and nodes are looked up to figure out network settings - - "" - resources: - - pods - - services - - nodes - verbs: - - get - - list - - watch - - apiGroups: - - operator.openshift.io - resources: - - dnses - verbs: - - get - - list - - watch - - update - - apiGroups: - - config.openshift.io - resources: - - networks - verbs: - - get - - list diff --git a/config/rbac/submariner-operator/cluster_role_binding.yaml b/config/rbac/submariner-operator/cluster_role_binding.yaml deleted file mode 100644 index 401ab7ecd..000000000 --- a/config/rbac/submariner-operator/cluster_role_binding.yaml +++ /dev/null @@ -1,13 +0,0 @@ ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: submariner-operator -subjects: - - kind: ServiceAccount - name: submariner-operator - namespace: placeholder -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: submariner-operator diff --git a/config/rbac/submariner-operator/role.yaml b/config/rbac/submariner-operator/role.yaml index 2e44cd617..7c85379a5 100644 --- a/config/rbac/submariner-operator/role.yaml +++ b/config/rbac/submariner-operator/role.yaml @@ -1,63 +1,198 @@ + --- 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: - - '*' +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - get + - update +- apiGroups: + - "" + resources: + - namespaces + verbs: + - create +- apiGroups: + - "" + resources: + - nodes + verbs: + - list + - patch +- apiGroups: + - "" + resources: + - pods + verbs: + - list +- apiGroups: + - "" + resources: + - secrets + verbs: + - get +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - create + - get + - update +- apiGroups: + - "" + resources: + - services + verbs: + - create + - get + - update +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - create + - get + - update +- apiGroups: + - apps + resources: + - daemonsets + verbs: + - create + - delete + - get + - list + - update + - watch +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - apps + resources: + - replicasets + verbs: + - get +- 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: + - 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: + - gateways + verbs: + - list +- apiGroups: + - submariner.io + resources: + - gateways + - submariners + verbs: + - list + - watch +- 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 diff --git a/config/rbac/submariner-operator/role_binding.yaml b/config/rbac/submariner-operator/role_binding.yaml index 9613958ae..401ab7ecd 100644 --- a/config/rbac/submariner-operator/role_binding.yaml +++ b/config/rbac/submariner-operator/role_binding.yaml @@ -1,12 +1,13 @@ --- -kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding metadata: name: submariner-operator subjects: - kind: ServiceAccount name: submariner-operator + namespace: placeholder roleRef: - kind: Role - name: submariner-operator apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: submariner-operator diff --git a/controllers/helpers/helpers.go b/controllers/helpers/helpers.go index 1007de826..eaa7a2529 100644 --- a/controllers/helpers/helpers.go +++ b/controllers/helpers/helpers.go @@ -34,6 +34,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) +// +kubebuilder:rbac:groups=apps,resources=daemonsets,verbs=create;delete;get;update + func ReconcileDaemonSet(owner metav1.Object, daemonSet *appsv1.DaemonSet, reqLogger logr.Logger, client controllerClient.Client, scheme *runtime.Scheme) (*appsv1.DaemonSet, error) { var err error @@ -94,6 +96,8 @@ func ReconcileDaemonSet(owner metav1.Object, daemonSet *appsv1.DaemonSet, reqLog return daemonSet, errorutil.WithMessagef(err, "error creating or updating DaemonSet %s/%s", daemonSet.Namespace, daemonSet.Name) } +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=create;get;update + func ReconcileDeployment(owner metav1.Object, deployment *appsv1.Deployment, reqLogger logr.Logger, client controllerClient.Client, scheme *runtime.Scheme) (*appsv1.Deployment, error) { var err error @@ -140,6 +144,8 @@ func ReconcileDeployment(owner metav1.Object, deployment *appsv1.Deployment, req return deployment, errorutil.WithMessagef(err, "error creating or updating Deployment %s/%s", deployment.Namespace, deployment.Name) } +// +kubebuilder:rbac:groups="",resources=configmaps,verbs=create;get;update + func ReconcileConfigMap(owner metav1.Object, configMap *corev1.ConfigMap, reqLogger logr.Logger, client controllerClient.Client, scheme *runtime.Scheme) (*corev1.ConfigMap, error) { var err error @@ -186,6 +192,8 @@ func ReconcileConfigMap(owner metav1.Object, configMap *corev1.ConfigMap, reqLog return configMap, errorutil.WithMessagef(err, "error creating or updating ConfigMap %s/%s", configMap.Namespace, configMap.Name) } +// +kubebuilder:rbac:groups="",resources=services,verbs=create;get;update + func ReconcileService(owner metav1.Object, service *corev1.Service, reqLogger logr.Logger, client controllerClient.Client, scheme *runtime.Scheme) (*corev1.Service, error) { var err error diff --git a/controllers/servicediscovery/servicediscovery_controller.go b/controllers/servicediscovery/servicediscovery_controller.go index 20c2814b3..da4cabab5 100644 --- a/controllers/servicediscovery/servicediscovery_controller.go +++ b/controllers/servicediscovery/servicediscovery_controller.go @@ -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") @@ -377,6 +378,9 @@ func newLighthouseCoreDNSService(cr *submarinerv1alpha1.ServiceDiscovery) *corev } } +// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;update +// +kubebuilder:rbac:groups="",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 { @@ -415,6 +419,9 @@ func updateDNSCustomConfigMap(client controllerClient.Client, k8sclientSet clien return retryErr } +// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;update +// +kubebuilder:rbac:groups="",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 { @@ -556,6 +563,10 @@ func getImagePath(submariner *submarinerv1alpha1.ServiceDiscovery, componentImag submariner.Spec.ImageOverrides) } +// Resources need to be listable as well as watchable (for the informer) +// +kubebuilder:rbac:groups=submariner.io,resources=servicediscoveries,verbs=list;watch +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=list;watch + func (r *ServiceDiscoveryReconciler) SetupWithManager(mgr ctrl.Manager) error { // These are required so that we can manipulate DNS ConfigMap if err := operatorv1.Install(mgr.GetScheme()); err != nil { diff --git a/controllers/submariner/broker_controller.go b/controllers/submariner/broker_controller.go index aeb4c6b82..be84e6c00 100644 --- a/controllers/submariner/broker_controller.go +++ b/controllers/submariner/broker_controller.go @@ -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) diff --git a/controllers/submariner/submariner_controller.go b/controllers/submariner/submariner_controller.go index 302834f5a..b0c305271 100644 --- a/controllers/submariner/submariner_controller.go +++ b/controllers/submariner/submariner_controller.go @@ -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") @@ -277,6 +278,8 @@ func (r *SubmarinerReconciler) checkDaemonSetContainers(daemonSet *appsv1.Daemon return mismatchedContainerImages, &nonReadyContainerStates, nil } +// +kubebuilder:rbac:groups="",resources=pods,verbs=list + func (r *SubmarinerReconciler) retrieveDaemonSetContainerStatuses(daemonSet *appsv1.DaemonSet, namespace string) (*[]corev1.ContainerStatus, error) { pods := &corev1.PodList{} @@ -295,6 +298,8 @@ func (r *SubmarinerReconciler) retrieveDaemonSetContainerStatuses(daemonSet *app return &containerStatuses, nil } +// +kubebuilder:rbac:groups=submariner.io,resources=gateways,verbs=list + func (r *SubmarinerReconciler) retrieveGateways(owner metav1.Object, namespace string) (*[]submv1.Gateway, error) { foundGateways := &submv1.GatewayList{} err := r.client.List(context.TODO(), foundGateways, client.InNamespace(namespace)) @@ -702,6 +707,10 @@ func getImagePath(submariner *submopv1a1.Submariner, componentImage string) stri submariner.Spec.ImageOverrides) } +// Resources need to be listable as well as watchable (for the informer) +// +kubebuilder:rbac:groups=submariner.io,resources=gateways;submariners,verbs=list;watch +// +kubebuilder:rbac:groups=apps,resources=daemonsets,verbs=list;watch + func (r *SubmarinerReconciler) SetupWithManager(mgr ctrl.Manager) error { // Set up the CRDs we need crdUpdater, err := crdutils.NewFromRestConfig(mgr.GetConfig()) diff --git a/main.go b/main.go index 68e88a354..f14c34ad5 100644 --- a/main.go +++ b/main.go @@ -87,6 +87,9 @@ func init() { // +kubebuilder:scaffold:scheme } +// The metrics setup requires access to replicasets +// +kubebuilder:rbac:groups=apps,resources=replicasets,verbs=get + func main() { // Add the zap logger flag set to the CLI. The flag set must // be added before calling pflag.Parse(). diff --git a/pkg/broker/ensure.go b/pkg/broker/ensure.go index a41627c62..d0cc0ff8a 100644 --- a/pkg/broker/ensure.go +++ b/pkg/broker/ensure.go @@ -177,6 +177,8 @@ func WaitForClientToken(clientset *kubernetes.Clientset, submarinerBrokerSA stri return secret, err } +// +kubebuilder:rbac:groups="",resources=namespaces,verbs=create + func CreateNewBrokerNamespace(clientset *kubernetes.Clientset) (brokernamespace *v1.Namespace, err error) { return clientset.CoreV1().Namespaces().Create(NewBrokerNamespace()) } @@ -189,6 +191,8 @@ func CreateOrUpdateBrokerAdminRole(clientset *kubernetes.Clientset) (created boo return utils.CreateOrUpdateRole(clientset, SubmarinerBrokerNamespace, NewBrokerAdminRole()) } +// +kubebuilder:rbac:groups=rbac,resources=rolebindings,verbs=create + func CreateNewBrokerRoleBinding(clientset *kubernetes.Clientset, serviceAccount, role string) (brokerRoleBinding *rbac.RoleBinding, err error) { return clientset.RbacV1().RoleBindings(SubmarinerBrokerNamespace).Create( @@ -196,6 +200,8 @@ func CreateNewBrokerRoleBinding(clientset *kubernetes.Clientset, serviceAccount, ) } +// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=create + func CreateNewBrokerSA(clientset *kubernetes.Clientset, submarinerBrokerSA string) (brokerSA *v1.ServiceAccount, err error) { return clientset.CoreV1().ServiceAccounts(SubmarinerBrokerNamespace).Create(NewBrokerSA(submarinerBrokerSA)) } diff --git a/pkg/broker/globalcidr_cm.go b/pkg/broker/globalcidr_cm.go index 834c4b9d9..ec8ad40e3 100644 --- a/pkg/broker/globalcidr_cm.go +++ b/pkg/broker/globalcidr_cm.go @@ -39,6 +39,8 @@ type ClusterInfo struct { GlobalCidr []string `json:"global_cidr"` } +// +kubebuilder:rbac:groups="",resources=configmaps,verbs=create + func CreateGlobalnetConfigMap(config *rest.Config, globalnetEnabled bool, defaultGlobalCidrRange string, defaultGlobalClusterSize uint, namespace string) error { clientset, err := kubernetes.NewForConfig(config) @@ -95,6 +97,8 @@ func NewGlobalnetConfigMap(globalnetEnabled bool, defaultGlobalCidrRange string, return cm, nil } +// +kubebuilder:rbac:groups="",resources=configmaps,verbs=update + func UpdateGlobalnetConfigMap(k8sClientset *kubernetes.Clientset, namespace string, configMap *v1.ConfigMap, newCluster ClusterInfo) error { var clusterInfo []ClusterInfo @@ -128,6 +132,8 @@ func UpdateGlobalnetConfigMap(k8sClientset *kubernetes.Clientset, namespace stri return err } +// +kubebuilder:rbac:groups="",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 { diff --git a/pkg/broker/rbac.go b/pkg/broker/rbac.go index cc1b9c090..68a707aeb 100644 --- a/pkg/broker/rbac.go +++ b/pkg/broker/rbac.go @@ -129,6 +129,9 @@ func NewBrokerRoleBinding(serviceAccount, role string) *rbacv1.RoleBinding { return binding } +// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get +// +kubebuilder:rbac:groups="",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 { diff --git a/pkg/discovery/network/canal.go b/pkg/discovery/network/canal.go index ed253519d..f4a1638fc 100644 --- a/pkg/discovery/network/canal.go +++ b/pkg/discovery/network/canal.go @@ -26,6 +26,8 @@ import ( "k8s.io/client-go/kubernetes" ) +// +kubebuilder:rbac:groups="",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: diff --git a/pkg/discovery/network/generic.go b/pkg/discovery/network/generic.go index 8d9753cb7..1cdadcc50 100644 --- a/pkg/discovery/network/generic.go +++ b/pkg/discovery/network/generic.go @@ -76,6 +76,8 @@ func findClusterIPRangeFromApiserver(clientSet kubernetes.Interface) (string, er return findPodCommandParameter(clientSet, "component=kube-apiserver", "--service-cluster-ip-range") } +// +kubebuilder:rbac:groups="",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{ @@ -160,6 +162,8 @@ func findPodIPRangeKubeProxy(clientSet kubernetes.Interface) (string, error) { return findPodCommandParameter(clientSet, "component=kube-proxy", "--cluster-cidr") } +// +kubebuilder:rbac:groups="",resources=nodes,verbs=list + func findPodIPRangeFromNodeSpec(clientSet kubernetes.Interface) (string, error) { nodes, err := clientSet.CoreV1().Nodes().List(v1meta.ListOptions{}) diff --git a/pkg/discovery/network/ovnkubernetes.go b/pkg/discovery/network/ovnkubernetes.go index f3091b41d..65cb63900 100644 --- a/pkg/discovery/network/ovnkubernetes.go +++ b/pkg/discovery/network/ovnkubernetes.go @@ -33,6 +33,9 @@ const ( OvnKubernetes = "OVNKubernetes" ) +// +kubebuilder:rbac:groups="",resources=services,verbs=get +// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get + func discoverOvnKubernetesNetwork(clientSet kubernetes.Interface) (*ClusterNetwork, error) { ovnDBPod, err := findPod(clientSet, "name=ovnkube-db") diff --git a/pkg/discovery/network/pods.go b/pkg/discovery/network/pods.go index dafc881b4..bb73f73f5 100644 --- a/pkg/discovery/network/pods.go +++ b/pkg/discovery/network/pods.go @@ -49,6 +49,8 @@ func findPodCommandParameter(clientSet kubernetes.Interface, labelSelector, para return "", nil } +// +kubebuilder:rbac:groups="",resources=pods,verbs=list + func findPod(clientSet kubernetes.Interface, labelSelector string) (*v1.Pod, error) { pods, err := clientSet.CoreV1().Pods("").List(v1meta.ListOptions{ LabelSelector: labelSelector, diff --git a/pkg/subctl/cmd/root.go b/pkg/subctl/cmd/root.go index 0cfd706f2..5a3b157d5 100644 --- a/pkg/subctl/cmd/root.go +++ b/pkg/subctl/cmd/root.go @@ -129,6 +129,8 @@ func getClientConfig(kubeConfigPath, kubeContext string) clientcmd.ClientConfig return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(rules, overrides) } +// +kubebuilder:rbac:groups="",resources=nodes,verbs=list + func handleNodeLabels(config *rest.Config) error { _, clientset, err := getClients(config) exitOnError("Unable to set the Kubernetes cluster connection up", err) @@ -160,6 +162,8 @@ func handleNodeLabels(config *rest.Config) error { return nil } +// +kubebuilder:rbac:groups="",resources=nodes,verbs=list + func askForGatewayNode(clientset kubernetes.Interface) (struct{ Node string }, error) { // List all nodes and select one allNodes, err := clientset.CoreV1().Nodes().List(metav1.ListOptions{LabelSelector: "!node-role.kubernetes.io/master"}) @@ -194,6 +198,8 @@ func askForGatewayNode(clientset kubernetes.Interface) (struct{ Node string }, e return answers, nil } +// +kubebuilder:rbac:groups="",resources=nodes,verbs=patch + // this function was sourced from: // https://github.com/kubernetes/kubernetes/blob/a3ccea9d8743f2ff82e41b6c2af6dc2c41dc7b10/test/utils/density_utils.go#L36 func addLabelsToNode(c kubernetes.Interface, nodeName string, labelsToAdd map[string]string) error { diff --git a/pkg/subctl/operator/common/embeddedyamls/generators/yamls2go.go b/pkg/subctl/operator/common/embeddedyamls/generators/yamls2go.go index 24d648cd8..661432339 100644 --- a/pkg/subctl/operator/common/embeddedyamls/generators/yamls2go.go +++ b/pkg/subctl/operator/common/embeddedyamls/generators/yamls2go.go @@ -37,8 +37,6 @@ var files = []string{ "config/rbac/submariner-operator/service_account.yaml", "config/rbac/submariner-operator/role.yaml", "config/rbac/submariner-operator/role_binding.yaml", - "config/rbac/submariner-operator/cluster_role.yaml", - "config/rbac/submariner-operator/cluster_role_binding.yaml", "config/rbac/submariner-gateway/service_account.yaml", "config/rbac/submariner-gateway/role.yaml", "config/rbac/submariner-gateway/role_binding.yaml", diff --git a/pkg/subctl/operator/common/namespace/ensure.go b/pkg/subctl/operator/common/namespace/ensure.go index b3e8ed0b9..98147aa20 100644 --- a/pkg/subctl/operator/common/namespace/ensure.go +++ b/pkg/subctl/operator/common/namespace/ensure.go @@ -24,6 +24,8 @@ import ( "k8s.io/client-go/rest" ) +// +kubebuilder:rbac:groups="",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) diff --git a/pkg/subctl/operator/submarinerop/serviceaccount/ensure.go b/pkg/subctl/operator/submarinerop/serviceaccount/ensure.go index c05f0af79..c1952d831 100644 --- a/pkg/subctl/operator/submarinerop/serviceaccount/ensure.go +++ b/pkg/subctl/operator/submarinerop/serviceaccount/ensure.go @@ -91,7 +91,7 @@ func ensureServiceAccounts(clientSet *clientset.Clientset, namespace string) (bo func ensureClusterRoles(clientSet *clientset.Clientset) (bool, error) { createdOperatorCR, err := serviceaccount.EnsureClusterRole(clientSet, - embeddedyamls.Config_rbac_submariner_operator_cluster_role_yaml) + embeddedyamls.Config_rbac_submariner_operator_role_yaml) if err != nil { return false, err } @@ -121,7 +121,7 @@ func ensureClusterRoles(clientSet *clientset.Clientset) (bool, error) { func ensureClusterRoleBindings(clientSet *clientset.Clientset, namespace string) (bool, error) { createdOperatorCRB, err := serviceaccount.EnsureClusterRoleBinding(clientSet, namespace, - embeddedyamls.Config_rbac_submariner_operator_cluster_role_binding_yaml) + embeddedyamls.Config_rbac_submariner_operator_role_binding_yaml) if err != nil { return false, err } @@ -150,12 +150,6 @@ func ensureClusterRoleBindings(clientSet *clientset.Clientset, namespace string) } func ensureRoles(clientSet *clientset.Clientset, namespace string) (bool, error) { - createdOperatorRole, err := serviceaccount.EnsureRole(clientSet, namespace, - embeddedyamls.Config_rbac_submariner_operator_role_yaml) - if err != nil { - return false, err - } - createdSubmarinerRole, err := serviceaccount.EnsureRole(clientSet, namespace, embeddedyamls.Config_rbac_submariner_gateway_role_yaml) if err != nil { @@ -174,16 +168,10 @@ func ensureRoles(clientSet *clientset.Clientset, namespace string) (bool, error) return false, err } - return createdOperatorRole || createdSubmarinerRole || createdRouteAgentRole || createdGlobalnetRole, err + return createdSubmarinerRole || createdRouteAgentRole || createdGlobalnetRole, err } func ensureRoleBindings(clientSet *clientset.Clientset, namespace string) (bool, error) { - createdOperatorRB, err := serviceaccount.EnsureRoleBinding(clientSet, namespace, - embeddedyamls.Config_rbac_submariner_operator_role_binding_yaml) - if err != nil { - return false, err - } - createdSubmarinerRB, err := serviceaccount.EnsureRoleBinding(clientSet, namespace, embeddedyamls.Config_rbac_submariner_gateway_role_binding_yaml) if err != nil { @@ -202,5 +190,5 @@ func ensureRoleBindings(clientSet *clientset.Clientset, namespace string) (bool, return false, err } - return createdOperatorRB || createdSubmarinerRB || createdRouteAgentRB || createdGlobalnetRB, err + return createdSubmarinerRB || createdRouteAgentRB || createdGlobalnetRB, err } diff --git a/pkg/utils/createorupdate.go b/pkg/utils/createorupdate.go index 8c464da12..813763d54 100644 --- a/pkg/utils/createorupdate.go +++ b/pkg/utils/createorupdate.go @@ -32,6 +32,8 @@ import ( crdutils "github.com/submariner-io/submariner-operator/pkg/utils/crds" ) +// +kubebuilder:rbac:groups=rbac,resources=clusterroles,verbs=create;get;update + func CreateOrUpdateClusterRole(clientSet clientset.Interface, clusterRole *rbacv1.ClusterRole) (bool, error) { _, err := clientSet.RbacV1().ClusterRoles().Create(clusterRole) if err == nil { @@ -52,6 +54,8 @@ func CreateOrUpdateClusterRole(clientSet clientset.Interface, clusterRole *rbacv return false, err } +// +kubebuilder:rbac:groups=rbac,resources=clusterrolebindings,verbs=create;get;update + func CreateOrUpdateClusterRoleBinding(clientSet clientset.Interface, clusterRoleBinding *rbacv1.ClusterRoleBinding) (bool, error) { _, err := clientSet.RbacV1().ClusterRoleBindings().Create(clusterRoleBinding) if err == nil { @@ -72,6 +76,8 @@ func CreateOrUpdateClusterRoleBinding(clientSet clientset.Interface, clusterRole return false, err } +// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=create;get;update + func CreateOrUpdateCRD(updater crdutils.CRDUpdater, crd *apiextensions.CustomResourceDefinition) (bool, error) { _, err := updater.Create(crd) if err == nil { @@ -102,6 +108,8 @@ func CreateOrUpdateEmbeddedCRD(updater crdutils.CRDUpdater, crdYaml string) (boo return CreateOrUpdateCRD(updater, crd) } +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=create;get;update + func CreateOrUpdateDeployment(clientSet clientset.Interface, namespace string, deployment *appsv1.Deployment) (bool, error) { _, err := clientSet.AppsV1().Deployments(namespace).Create(deployment) if err != nil && errors.IsAlreadyExists(err) { @@ -120,6 +128,8 @@ func CreateOrUpdateDeployment(clientSet clientset.Interface, namespace string, d return true, err } +// +kubebuilder:rbac:groups=rbac,resources=roles,verbs=create;get;update + func CreateOrUpdateRole(clientSet clientset.Interface, namespace string, role *rbacv1.Role) (bool, error) { _, err := clientSet.RbacV1().Roles(namespace).Create(role) if err != nil && errors.IsAlreadyExists(err) { @@ -138,6 +148,8 @@ func CreateOrUpdateRole(clientSet clientset.Interface, namespace string, role *r return true, err } +// +kubebuilder:rbac:groups=rbac,resources=rolebindings,verbs=create;get;update + func CreateOrUpdateRoleBinding(clientSet clientset.Interface, namespace string, roleBinding *rbacv1.RoleBinding) (bool, error) { _, err := clientSet.RbacV1().RoleBindings(namespace).Create(roleBinding) if err != nil && errors.IsAlreadyExists(err) { @@ -156,6 +168,8 @@ func CreateOrUpdateRoleBinding(clientSet clientset.Interface, namespace string, return true, err } +// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=create;get;update + func CreateOrUpdateServiceAccount(clientSet clientset.Interface, namespace string, sa *corev1.ServiceAccount) (bool, error) { _, err := clientSet.CoreV1().ServiceAccounts(namespace).Create(sa) if err != nil && errors.IsAlreadyExists(err) {