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