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  }