From 941914bbc8f1a5b50e944bb0a72640165a1638aa 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/submariner-operator/role.yaml | 249 ++++++++++++++---- 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 + .../operator/common/namespace/ensure.go | 2 + pkg/utils/createorupdate.go | 14 + 18 files changed, 274 insertions(+), 60 deletions(-) diff --git a/.yamllint.yml b/.yamllint.yml index b6821603c9..303ddf459f 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 600f607f0a..bba7922446 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/submariner-operator/role.yaml b/config/rbac/submariner-operator/role.yaml index 2e44cd617a..7c85379a51 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/controllers/helpers/helpers.go b/controllers/helpers/helpers.go index 1007de8263..eaa7a25290 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 20c2814b30..da4cabab5b 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 aeb4c6b82a..be84e6c00e 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 302834f5ae..b0c305271d 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 68e88a354a..f14c34ad55 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 a41627c62d..d0cc0ff8a6 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 834c4b9d96..ec8ad40e31 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 cc1b9c090b..68a707aeb0 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 ed253519da..f4a1638fc1 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 8d9753cb78..1cdadcc504 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 f3091b41d2..65cb639007 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 dafc881b43..bb73f73f59 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 0cfd706f21..5a3b157d53 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/namespace/ensure.go b/pkg/subctl/operator/common/namespace/ensure.go index b3e8ed0b9d..98147aa20b 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/utils/createorupdate.go b/pkg/utils/createorupdate.go index 8c464da122..813763d548 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) {