github.com/argoproj-labs/argocd-operator@v0.10.0/controllers/argocd/service_account.go (about) 1 // Copyright 2019 ArgoCD Operator Developers 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package argocd 16 17 import ( 18 "context" 19 "fmt" 20 21 corev1 "k8s.io/api/core/v1" 22 v1 "k8s.io/api/rbac/v1" 23 "k8s.io/apimachinery/pkg/api/errors" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" 26 27 argoproj "github.com/argoproj-labs/argocd-operator/api/v1beta1" 28 "github.com/argoproj-labs/argocd-operator/common" 29 "github.com/argoproj-labs/argocd-operator/controllers/argoutil" 30 ) 31 32 // newServiceAccount returns a new ServiceAccount instance. 33 func newServiceAccount(cr *argoproj.ArgoCD) *corev1.ServiceAccount { 34 return &corev1.ServiceAccount{ 35 ObjectMeta: metav1.ObjectMeta{ 36 Name: cr.Name, 37 Namespace: cr.Namespace, 38 Labels: argoutil.LabelsForCluster(cr), 39 }, 40 } 41 } 42 43 // newServiceAccountWithName creates a new ServiceAccount with the given name for the given ArgCD. 44 func newServiceAccountWithName(name string, cr *argoproj.ArgoCD) *corev1.ServiceAccount { 45 sa := newServiceAccount(cr) 46 sa.ObjectMeta.Name = getServiceAccountName(cr.Name, name) 47 48 lbls := sa.ObjectMeta.Labels 49 lbls[common.ArgoCDKeyName] = name 50 sa.ObjectMeta.Labels = lbls 51 52 return sa 53 } 54 55 func getServiceAccountName(crName, name string) string { 56 return fmt.Sprintf("%s-%s", crName, name) 57 } 58 59 // reconcileServiceAccounts will ensure that all ArgoCD Service Accounts are configured. 60 func (r *ReconcileArgoCD) reconcileServiceAccounts(cr *argoproj.ArgoCD) error { 61 params := getPolicyRuleList(r.Client) 62 63 for _, param := range params { 64 if err := r.reconcileServiceAccountPermissions(param.name, param.policyRule, cr); err != nil { 65 return err 66 } 67 } 68 69 clusterParams := getPolicyRuleClusterRoleList() 70 71 for _, clusterParam := range clusterParams { 72 if err := r.reconcileServiceAccountClusterPermissions(clusterParam.name, clusterParam.policyRule, cr); err != nil { 73 return err 74 } 75 } 76 77 return nil 78 } 79 80 func (r *ReconcileArgoCD) reconcileServiceAccountClusterPermissions(name string, rules []v1.PolicyRule, cr *argoproj.ArgoCD) error { 81 var role *v1.ClusterRole 82 var err error 83 84 _, err = r.reconcileServiceAccount(name, cr) 85 if err != nil { 86 return err 87 } 88 89 if role, err = r.reconcileClusterRole(name, rules, cr); err != nil { 90 return err 91 } 92 93 return r.reconcileClusterRoleBinding(name, role, cr) 94 } 95 96 func (r *ReconcileArgoCD) reconcileServiceAccountPermissions(name string, rules []v1.PolicyRule, cr *argoproj.ArgoCD) error { 97 return r.reconcileRoleBinding(name, rules, cr) 98 } 99 100 func (r *ReconcileArgoCD) reconcileServiceAccount(name string, cr *argoproj.ArgoCD) (*corev1.ServiceAccount, error) { 101 sa := newServiceAccountWithName(name, cr) 102 103 exists := true 104 if err := argoutil.FetchObject(r.Client, cr.Namespace, sa.Name, sa); err != nil { 105 if !errors.IsNotFound(err) { 106 return nil, err 107 } 108 109 if name == common.ArgoCDDexServerComponent && !UseDex(cr) { 110 return sa, nil // Dex installation not requested, do nothing 111 } 112 exists = false 113 } 114 if exists { 115 if name == common.ArgoCDDexServerComponent && !UseDex(cr) { 116 // Delete any existing Service Account created for Dex since dex is disabled 117 log.Info("deleting the existing Dex service account because dex uninstallation requested") 118 return sa, r.Client.Delete(context.TODO(), sa) 119 } 120 return sa, nil 121 } 122 123 if err := controllerutil.SetControllerReference(cr, sa, r.Scheme); err != nil { 124 return nil, err 125 } 126 127 log.Info(fmt.Sprintf("creating serviceaccount %s for Argo CD instance %s in namespace %s", sa.Name, cr.Name, cr.Namespace)) 128 129 err := r.Client.Create(context.TODO(), sa) 130 if err != nil { 131 return nil, err 132 } 133 134 return sa, nil 135 }