Skip to content

Commit

Permalink
add rbac task when karmada operator init
Browse files Browse the repository at this point in the history
Signed-off-by: Vacant2333 <vacant2333@gmail.com>
  • Loading branch information
Vacant2333 authored and Vacant2333 committed Aug 18, 2023
1 parent 6dea121 commit eeb36a9
Show file tree
Hide file tree
Showing 7 changed files with 249 additions and 9 deletions.
2 changes: 1 addition & 1 deletion operator/pkg/controlplane/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ spec:
- --cluster-name=karmada
- --cluster-signing-cert-file=/etc/karmada/pki/ca.crt
- --cluster-signing-key-file=/etc/karmada/pki/ca.key
- --controllers=namespace,garbagecollector,serviceaccount-token,ttl-after-finished,bootstrapsigner,csrapproving,csrcleaner,csrsigning
- --controllers=namespace,garbagecollector,serviceaccount-token,ttl-after-finished,bootstrapsigner,csrapproving,csrcleaner,csrsigning,clusterrole-aggregation
- --leader-elect=true
- --node-cidr-mask-size=24
- --root-ca-file=/etc/karmada/pki/ca.crt
Expand Down
1 change: 1 addition & 0 deletions operator/pkg/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ func NewInitJob(opt *InitOptions) *workflow.Job {
initJob.AppendTask(tasks.NewKarmadaAggregatedApiserverTask())
initJob.AppendTask(tasks.NewCheckApiserverHealthTask())
initJob.AppendTask(tasks.NewKarmadaResourcesTask())
initJob.AppendTask(tasks.NewRBACTask())
initJob.AppendTask(tasks.NewComponentTask())
initJob.AppendTask(tasks.NewWaitControlPlaneTask())

Expand Down
10 changes: 2 additions & 8 deletions operator/pkg/karmadaresource/apiservice/apiservice.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ func aggregatedAPIService(client *aggregator.Clientset, name, namespace string)
return fmt.Errorf("err when decoding AggregatedApiserver APIService: %w", err)
}

if err := apiclient.CreateOrUpdateAPIService(client, apiService); err != nil {
return err
}
return nil
return apiclient.CreateOrUpdateAPIService(client, apiService)
}

func aggregatedApiserverService(client clientset.Interface, name, namespace string) error {
Expand All @@ -77,8 +74,5 @@ func aggregatedApiserverService(client clientset.Interface, name, namespace stri
return fmt.Errorf("err when decoding AggregatedApiserver Service: %w", err)
}

if err := apiclient.CreateOrUpdateService(client, aggregatedService); err != nil {
return err
}
return nil
return apiclient.CreateOrUpdateService(client, aggregatedService)
}
154 changes: 154 additions & 0 deletions operator/pkg/karmadaresource/rbac/manifest.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
package rbac

const (
// KarmadaResourceViewClusterRole clusterrole for view karmada resources
KarmadaResourceViewClusterRole = `
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
# refer to https://kubernetes.io/docs/reference/access-authn-authz/rbac/#auto-reconciliation
# and https://kubernetes.io/docs/reference/access-authn-authz/rbac/#kubectl-auth-reconcile
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
# refer to https://kubernetes.io/docs/reference/access-authn-authz/rbac/#default-roles-and-role-bindings
kubernetes.io/bootstrapping: rbac-defaults
# used to aggregate rules to view clusterrole
rbac.authorization.k8s.io/aggregate-to-view: "true"
name: karmada-view
rules:
- apiGroups:
- "autoscaling.karmada.io"
resources:
- cronfederatedhpas
- cronfederatedhpas/status
- federatedhpas
- federatedhpas/status
verbs:
- get
- list
- watch
- apiGroups:
- "multicluster.x-k8s.io"
resources:
- serviceexports
- serviceexports/status
- serviceimports
- serviceimports/status
verbs:
- get
- list
- watch
- apiGroups:
- "networking.karmada.io"
resources:
- multiclusteringresses
- multiclusteringresses/status
- multiclusterservices
- multiclusterservices/status
verbs:
- get
- list
- watch
- apiGroups:
- "policy.karmada.io"
resources:
- overridepolicies
- propagationpolicies
verbs:
- get
- list
- watch
- apiGroups:
- "work.karmada.io"
resources:
- resourcebindings
- resourcebindings/status
- works
- works/status
verbs:
- get
- list
- watch
`
// KarmadaResourceEditClusterRole clusterrole for edit karmada resources
KarmadaResourceEditClusterRole = `
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
# refer to https://kubernetes.io/docs/reference/access-authn-authz/rbac/#auto-reconciliation
# and https://kubernetes.io/docs/reference/access-authn-authz/rbac/#kubectl-auth-reconcile
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
# refer to https://kubernetes.io/docs/reference/access-authn-authz/rbac/#default-roles-and-role-bindings
kubernetes.io/bootstrapping: rbac-defaults
# used to aggregate rules to view clusterrole
rbac.authorization.k8s.io/aggregate-to-edit: "true"
name: karmada-edit
rules:
- apiGroups:
- "autoscaling.karmada.io"
resources:
- cronfederatedhpas
- cronfederatedhpas/status
- federatedhpas
- federatedhpas/status
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- "multicluster.x-k8s.io"
resources:
- serviceexports
- serviceexports/status
- serviceimports
- serviceimports/status
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- "networking.karmada.io"
resources:
- multiclusteringresses
- multiclusteringresses/status
- multiclusterservices
- multiclusterservices/status
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- "policy.karmada.io"
resources:
- overridepolicies
- propagationpolicies
verbs:
- create
- delete
- deletecollection
- patch
- update
- apiGroups:
- "work.karmada.io"
resources:
- resourcebindings
- resourcebindings/status
- works
- works/status
verbs:
- create
- delete
- deletecollection
- patch
- update
`
)
36 changes: 36 additions & 0 deletions operator/pkg/karmadaresource/rbac/rbac.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package rbac

import (
"fmt"

rbacv1 "k8s.io/api/rbac/v1"
kuberuntime "k8s.io/apimachinery/pkg/runtime"
clientset "k8s.io/client-go/kubernetes"
clientsetscheme "k8s.io/client-go/kubernetes/scheme"

"github.com/karmada-io/karmada/operator/pkg/util/apiclient"
)

// EnsureKarmadaRBAC create karmada resource view and edit clusterrole
func EnsureKarmadaRBAC(client clientset.Interface) error {
if err := grantKarmadaResourceViewClusterrole(client); err != nil {
return err
}
return grantKarmadaResourceEditClusterrole(client)
}

func grantKarmadaResourceViewClusterrole(client clientset.Interface) error {
viewClusterrole := &rbacv1.ClusterRole{}
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(KarmadaResourceViewClusterRole), viewClusterrole); err != nil {
return fmt.Errorf("err when decoding Karmada view Clusterrole: %w", err)
}
return apiclient.CreateOrUpdateClusterRole(client, viewClusterrole)
}

func grantKarmadaResourceEditClusterrole(client clientset.Interface) error {
editClusterrole := &rbacv1.ClusterRole{}
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), []byte(KarmadaResourceEditClusterRole), editClusterrole); err != nil {
return fmt.Errorf("err when decoding Karmada edit Clusterrole: %w", err)
}
return apiclient.CreateOrUpdateClusterRole(client, editClusterrole)
}
29 changes: 29 additions & 0 deletions operator/pkg/tasks/init/rbac.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package tasks

import (
"errors"

"k8s.io/klog/v2"

"github.com/karmada-io/karmada/operator/pkg/karmadaresource/rbac"
"github.com/karmada-io/karmada/operator/pkg/workflow"
)

// NewRBACTask init a RBAC task, it will create clusterrole for view/edit karmada resources
func NewRBACTask() workflow.Task {
return workflow.Task{
Name: "rbac",
Run: runRBAC,
}
}

func runRBAC(r workflow.RunData) error {
data, ok := r.(InitData)
if !ok {
return errors.New("RBAC task invoked with an invalid data struct")
}

klog.V(4).InfoS("[RBAC] Running rbac task", "karmada", klog.KObj(data))

return rbac.EnsureKarmadaRBAC(data.RemoteClient())
}
26 changes: 26 additions & 0 deletions operator/pkg/util/apiclient/idempotency.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
crdsclient "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -230,6 +231,31 @@ func CreateOrUpdateStatefulSet(client clientset.Interface, statefuleSet *appsv1.
return nil
}

// CreateOrUpdateClusterRole creates a Clusterrole if the target resource doesn't exist. If the resource exists already, this function will update the resource instead.
func CreateOrUpdateClusterRole(client clientset.Interface, clusterrole *rbacv1.ClusterRole) error {
_, err := client.RbacV1().ClusterRoles().Create(context.TODO(), clusterrole, metav1.CreateOptions{})

if err != nil {
if !apierrors.IsAlreadyExists(err) {
return err
}

older, err := client.RbacV1().ClusterRoles().Get(context.TODO(), clusterrole.GetName(), metav1.GetOptions{})
if err != nil {
return err
}

clusterrole.ResourceVersion = older.ResourceVersion
_, err = client.RbacV1().ClusterRoles().Update(context.TODO(), clusterrole, metav1.UpdateOptions{})
if err != nil {
return err
}
}

klog.V(4).InfoS("Successfully created or updated clusterrole", "clusterrole", clusterrole.GetName)
return nil
}

// DeleteDeploymentIfHasLabels deletes a Deployment that exists the given labels.
func DeleteDeploymentIfHasLabels(client clientset.Interface, name, namespace string, ls labels.Set) error {
deployment, err := client.AppsV1().Deployments(namespace).Get(context.TODO(), name, metav1.GetOptions{})
Expand Down

0 comments on commit eeb36a9

Please sign in to comment.