github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/lib/scoped/querier.go (about) 1 package scoped 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/sirupsen/logrus" 8 corev1 "k8s.io/api/core/v1" 9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 11 v1 "github.com/operator-framework/api/pkg/operators/v1" 12 "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned" 13 ) 14 15 // NewUserDefinedServiceAccountQuerier returns a new instance of UserDefinedServiceAccountQuerier. 16 func NewUserDefinedServiceAccountQuerier(logger *logrus.Logger, crclient versioned.Interface) *UserDefinedServiceAccountQuerier { 17 return &UserDefinedServiceAccountQuerier{ 18 logger: logger, 19 crclient: crclient, 20 } 21 } 22 23 // UserDefinedServiceAccountQuerier retrieves reference to user defined service account(s). 24 type UserDefinedServiceAccountQuerier struct { 25 crclient versioned.Interface 26 logger *logrus.Logger 27 } 28 29 // NamespaceQuerier returns an instance of ServiceAccountQuerierFunc that can be used by the 30 // caller to get the reference to the service account associated with the namespace. 31 func (f *UserDefinedServiceAccountQuerier) NamespaceQuerier(namespace string) ServiceAccountQuerierFunc { 32 querierFunc := func() (reference *corev1.ObjectReference, err error) { 33 logger := f.logger.WithFields(logrus.Fields{ 34 "namespace": namespace, 35 logFieldName: logFieldValue, 36 }) 37 38 return queryServiceAccountFromNamespace(logger, f.crclient, namespace) 39 } 40 41 return querierFunc 42 } 43 44 // QueryServiceAccountFromNamespace will return the reference to a service account 45 // associated with the operator group for the given namespace. 46 // - If no operator group is found in the namespace, an error is returned. 47 // - If an operator group found is not managing the namespace then it is ignored. 48 // - If no operator group is managing this namespace then both reference and err are set to nil. 49 // - If more than one operator group are managing this namespace then an error is thrown. 50 func queryServiceAccountFromNamespace(logger *logrus.Entry, crclient versioned.Interface, namespace string) (reference *corev1.ObjectReference, err error) { 51 // TODO: use a lister instead of a noncached client here. 52 list, err := crclient.OperatorsV1().OperatorGroups(namespace).List(context.TODO(), metav1.ListOptions{}) 53 if err != nil { 54 return 55 } 56 57 if len(list.Items) == 0 { 58 err = NewOperatorGroupError("no operator group found that is managing this namespace") 59 return 60 } 61 62 groups := make([]*v1.OperatorGroup, 0) 63 for _, og := range list.Items { 64 if len(og.Status.Namespaces) == 0 { 65 logger.Warnf("skipping operator group since it is not managing any namespace og=%s", og.GetName()) 66 continue 67 } 68 69 groups = append(groups, &og) 70 } 71 72 if len(groups) == 0 { 73 err = NewOperatorGroupError("no operator group found that is managing this namespace") 74 return 75 } 76 77 if len(groups) > 1 { 78 err = NewOperatorGroupError(fmt.Sprintf("more than one operator group(s) are managing this namespace count=%d", len(groups))) 79 return 80 } 81 82 group := groups[0] 83 if !group.IsServiceAccountSpecified() { 84 // No user defined service account is specified. 85 return 86 } 87 88 if !group.HasServiceAccountSynced() { 89 err = NewOperatorGroupError(fmt.Sprintf("please make sure the service account exists. sa=%s operatorgroup=%s/%s", group.Spec.ServiceAccountName, group.GetNamespace(), group.GetName())) 90 return 91 } 92 93 reference = group.Status.ServiceAccountRef 94 return 95 }