Skip to content

Commit bb46d55

Browse files
Merge pull request #571 from ecordell/serviceaccount-rbac
Create role bindings for operator service accounts
2 parents 38adfbb + bff3b20 commit bb46d55

File tree

149 files changed

+9802
-9886
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

149 files changed

+9802
-9886
lines changed

deploy/chart/templates/0000_30_14-operatorgroup.crd.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ spec:
6767
type: string
6868
namespaces:
6969
items:
70-
type: object
70+
type: string
7171
type: array
7272
required:
7373
- namespaces
@@ -76,4 +76,3 @@ spec:
7676
required:
7777
- metadata
7878
- spec
79-
version: v1alpha2

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ require (
6666
google.golang.org/grpc v1.16.0 // indirect
6767
gopkg.in/inf.v0 v0.9.1 // indirect
6868
gopkg.in/natefinch/lumberjack.v2 v2.0.0-20170531160350-a96e63847dc3 // indirect
69-
k8s.io/api v0.0.0-20181108095152-eee84a6322ca
69+
k8s.io/api v0.0.0-20180904230853-4e7be11eab3f
7070
k8s.io/apiextensions-apiserver v0.0.0-20180905004947-16750353bf97
7171
k8s.io/apimachinery v0.0.0-20181026144827-8ee1a638bafa
7272
k8s.io/apiserver v0.0.0-20181026151315-13cfe3978170

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -210,16 +210,16 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD
210210
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
211211
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
212212
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
213-
k8s.io/api v0.0.0-20181108095152-eee84a6322ca h1:0gIeW03B5m7yni69Y95oPgDXv7ow7puUMt2WqhJIKY8=
214-
k8s.io/api v0.0.0-20181108095152-eee84a6322ca/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
213+
k8s.io/api v0.0.0-20180904230853-4e7be11eab3f h1:DLRkv8Ps4Sdx8Srj+UtGisj4whV7v/HezlHx6QqiZqE=
214+
k8s.io/api v0.0.0-20180904230853-4e7be11eab3f/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
215215
k8s.io/apiextensions-apiserver v0.0.0-20180905004947-16750353bf97 h1:s4lWWs6JN5kWVzk5bztddkr5kgO/cGIbqTDP+QttUeQ=
216216
k8s.io/apiextensions-apiserver v0.0.0-20180905004947-16750353bf97/go.mod h1:IxkesAMoaCRoLrPJdZNZUQp9NfZnzqaVzLhb2VEQzXE=
217217
k8s.io/apiextensions-apiserver v0.0.0-20181110192823-2c43ee60e25b h1:O3KqnOdhludLAAHs7bvV7UpPYow3gqLqF5Junc5hbw8=
218218
k8s.io/apimachinery v0.0.0-20181026144827-8ee1a638bafa h1:i0EOpPFWExNx7efINILpw8LJeah7gakRl1zjvwVfjiI=
219219
k8s.io/apimachinery v0.0.0-20181026144827-8ee1a638bafa/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
220220
k8s.io/apiserver v0.0.0-20181026151315-13cfe3978170 h1:CqI85nZvPaV+7JFono0nAOGOx2brocqefcOhDPVhHKI=
221221
k8s.io/apiserver v0.0.0-20181026151315-13cfe3978170/go.mod h1:6bqaTSOSJavUIXUtfaR9Os9JtTCm8ZqH2SUl2S60C4w=
222-
k8s.io/client-go v8.0.0+incompatible h1:tTI4hRmb1DRMl4fG6Vclfdi6nTM82oIrTT7HfitmxC4=
222+
k8s.io/client-go v8.0.0+incompatible h1:2pUaSg2x6iEHr8cia6zmWhoCXG1EDG9TCx9s//Aq7HY=
223223
k8s.io/client-go v8.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
224224
k8s.io/client-go v9.0.0+incompatible h1:2kqW3X2xQ9SbFvWZjGEHBLlWc1LG9JIJNXWkuqwdZ3A=
225225
k8s.io/code-generator v0.0.0-20180904193909-8c97d6ab64da h1:L6YB6ObZIbZlYikTQcCjzZGilwS3OVyQBA2esULs8VM=
@@ -233,5 +233,5 @@ k8s.io/kube-aggregator v0.0.0-20180905000155-efa32eb095fe/go.mod h1:8sbzT4QQKDEm
233233
k8s.io/kube-aggregator v0.0.0-20181110192014-6f96af33cb59 h1:8VFjmCurXo3sMW0ASrUvoE4aT8FCzsIz55uic1EyUIc=
234234
k8s.io/kube-openapi v0.0.0-20181031203759-72693cb1fadd h1:ggv/Vfza0i5xuhUZyYyxcc25AmQvHY8Zi1C2m8WgBvA=
235235
k8s.io/kube-openapi v0.0.0-20181031203759-72693cb1fadd/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc=
236-
k8s.io/kubernetes v1.11.5-beta.0.0.20181108064615-3290824d1c7b h1:i9PV0cnNZrleFj2YjDYDAUku1qg/SlKfdm4LdTJzAFo=
236+
k8s.io/kubernetes v1.11.5-beta.0.0.20181108064615-3290824d1c7b h1:Ej2VgtycDFPfQunFFfAsWvdjT+dhte1CcwnPNId+V1k=
237237
k8s.io/kubernetes v1.11.5-beta.0.0.20181108064615-3290824d1c7b/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=

pkg/api/apis/operators/v1alpha1/clusterserviceversion.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,23 @@ var obsoleteReasons = map[ConditionReason]struct{}{
1212
CSVReasonBeingReplaced: {},
1313
}
1414

15-
func (c *ClusterServiceVersion) SetPhaseWithEvent(phase ClusterServiceVersionPhase, reason ConditionReason, message string, recorder record.EventRecorder) {
15+
func (c *ClusterServiceVersion) SetPhaseWithEvent(phase ClusterServiceVersionPhase, reason ConditionReason, message string, now metav1.Time, recorder record.EventRecorder) {
1616
var eventtype string
1717
if phase == CSVPhaseFailed {
1818
eventtype = v1.EventTypeWarning
1919
} else {
2020
eventtype = v1.EventTypeNormal
2121
}
2222
go recorder.Event(c, eventtype, string(reason), message)
23-
c.SetPhase(phase, reason, message)
23+
c.SetPhase(phase, reason, message, now)
2424
}
2525

2626
// SetPhase sets the current phase and adds a condition if necessary
27-
func (c *ClusterServiceVersion) SetPhase(phase ClusterServiceVersionPhase, reason ConditionReason, message string) {
28-
c.Status.LastUpdateTime = metav1.Now()
27+
func (c *ClusterServiceVersion) SetPhase(phase ClusterServiceVersionPhase, reason ConditionReason, message string, now metav1.Time) {
28+
c.Status.LastUpdateTime = now
2929
if c.Status.Phase != phase {
3030
c.Status.Phase = phase
31-
c.Status.LastTransitionTime = metav1.Now()
31+
c.Status.LastTransitionTime = now
3232
}
3333
c.Status.Message = message
3434
c.Status.Reason = reason

pkg/api/apis/operators/v1alpha1/clusterserviceversion_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"testing"
55

66
"github.com/stretchr/testify/require"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
78
)
89

910
func TestSetRequirementStatus(t *testing.T) {
@@ -51,7 +52,7 @@ func TestSetPhase(t *testing.T) {
5152
Conditions: tt.currentConditions,
5253
},
5354
}
54-
csv.SetPhase(tt.inPhase, "test", "test")
55+
csv.SetPhase(tt.inPhase, "test", "test", metav1.Now())
5556
require.EqualValues(t, tt.outPhase, csv.Status.Phase)
5657
})
5758
}

pkg/api/apis/operators/v1alpha2/operatorgroup_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ type OperatorGroupSpec struct {
1111
}
1212

1313
type OperatorGroupStatus struct {
14-
Namespaces []*corev1.Namespace `json:"namespaces"`
15-
LastUpdated metav1.Time `json:"lastUpdated"`
14+
Namespaces []string `json:"namespaces,omitempty"`
15+
LastUpdated metav1.Time `json:"lastUpdated"`
1616
}
1717

1818
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

pkg/api/apis/operators/v1alpha2/zz_generated.deepcopy.go

Lines changed: 2 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/api/wrappers/deployment_install_client.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ var _ InstallStrategyDeploymentInterface = &InstallStrategyDeploymentClientForNa
3838
func NewInstallStrategyDeploymentClient(opClient operatorclient.ClientInterface, opLister operatorlister.OperatorLister, namespace string) InstallStrategyDeploymentInterface {
3939
return &InstallStrategyDeploymentClientForNamespace{
4040
opClient: opClient,
41-
opLister: opLister,
41+
opLister: opLister,
4242
Namespace: namespace,
4343
}
4444
}

pkg/api/wrappers/deployment_install_client_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ import (
1313
apierrors "k8s.io/apimachinery/pkg/api/errors"
1414
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1515
"k8s.io/apimachinery/pkg/util/diff"
16-
17-
listerfakes "github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/client-go/listers"
16+
1817
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/apis/operators/v1alpha1"
18+
listerfakes "github.com/operator-framework/operator-lifecycle-manager/pkg/fakes/client-go/listers"
1919
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorclient"
2020
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/operatorlister/operatorlisterfakes"
2121
)
2222

2323
var (
2424
Controller = false
2525
BlockOwnerDeletion = false
26-
WakeupInterval = 5 * time.Second
26+
WakeupInterval = 5 * time.Second
2727
)
2828

2929
func ownerReferenceFromCSV(csv *v1alpha1.ClusterServiceVersion) metav1.OwnerReference {
@@ -421,7 +421,6 @@ func TestEnsureServiceAccount(t *testing.T) {
421421

422422
client := NewInstallStrategyDeploymentClient(mockOpClient, fakeLister, tt.state.namespace)
423423

424-
425424
mockOpClient.EXPECT().
426425
CreateServiceAccount(tt.input.serviceAccount).
427426
Return(tt.state.createServiceAccountResult, tt.state.createServiceAccountError).

pkg/controller/install/deployment.go

Lines changed: 22 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ import (
55

66
log "github.com/sirupsen/logrus"
77
appsv1 "k8s.io/api/apps/v1"
8-
corev1 "k8s.io/api/core/v1"
98
rbac "k8s.io/api/rbac/v1"
10-
apierrors "k8s.io/apimachinery/pkg/api/errors"
119

1210
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/wrappers"
1311
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
@@ -38,9 +36,10 @@ type StrategyDetailsDeployment struct {
3836
}
3937

4038
type StrategyDeploymentInstaller struct {
41-
strategyClient wrappers.InstallStrategyDeploymentInterface
42-
owner ownerutil.Owner
43-
previousStrategy Strategy
39+
strategyClient wrappers.InstallStrategyDeploymentInterface
40+
owner ownerutil.Owner
41+
previousStrategy Strategy
42+
templateAnnotations map[string]string
4443
}
4544

4645
func (d *StrategyDetailsDeployment) GetStrategyName() string {
@@ -50,70 +49,27 @@ func (d *StrategyDetailsDeployment) GetStrategyName() string {
5049
var _ Strategy = &StrategyDetailsDeployment{}
5150
var _ StrategyInstaller = &StrategyDeploymentInstaller{}
5251

53-
func NewStrategyDeploymentInstaller(strategyClient wrappers.InstallStrategyDeploymentInterface, owner ownerutil.Owner, previousStrategy Strategy) StrategyInstaller {
52+
func NewStrategyDeploymentInstaller(strategyClient wrappers.InstallStrategyDeploymentInterface, templateAnnotations map[string]string, owner ownerutil.Owner, previousStrategy Strategy) StrategyInstaller {
5453
return &StrategyDeploymentInstaller{
55-
strategyClient: strategyClient,
56-
owner: owner,
57-
previousStrategy: previousStrategy,
54+
strategyClient: strategyClient,
55+
owner: owner,
56+
previousStrategy: previousStrategy,
57+
templateAnnotations: templateAnnotations,
5858
}
5959
}
6060

61-
func (i *StrategyDeploymentInstaller) installPermissions(perms []StrategyDeploymentPermissions) error {
62-
for _, permission := range perms {
63-
// create role
64-
role := &rbac.Role{
65-
Rules: permission.Rules,
66-
}
67-
ownerutil.AddNonBlockingOwner(role, i.owner)
68-
role.SetGenerateName(fmt.Sprintf("%s-role-", i.owner.GetName()))
69-
createdRole, err := i.strategyClient.CreateRole(role)
70-
if err != nil {
71-
return err
72-
}
73-
74-
// create serviceaccount if necessary
75-
serviceAccount := &corev1.ServiceAccount{}
76-
serviceAccount.SetName(permission.ServiceAccountName)
77-
// EnsureServiceAccount verifies/creates ownerreferences so we don't add them here
78-
serviceAccount, err = i.strategyClient.EnsureServiceAccount(serviceAccount, i.owner)
79-
if err != nil {
80-
return err
81-
}
82-
83-
// create rolebinding
84-
roleBinding := &rbac.RoleBinding{
85-
RoleRef: rbac.RoleRef{
86-
Kind: "Role",
87-
Name: createdRole.GetName(),
88-
APIGroup: rbac.GroupName},
89-
Subjects: []rbac.Subject{{
90-
Kind: "ServiceAccount",
91-
Name: permission.ServiceAccountName,
92-
Namespace: i.owner.GetNamespace(),
93-
}},
94-
}
95-
ownerutil.AddNonBlockingOwner(roleBinding, i.owner)
96-
roleBinding.SetGenerateName(fmt.Sprintf("%s-%s-rolebinding-", createdRole.Name, serviceAccount.Name))
97-
98-
if _, err := i.strategyClient.CreateRoleBinding(roleBinding); err != nil {
99-
return err
100-
}
101-
}
102-
return nil
103-
}
104-
10561
func (i *StrategyDeploymentInstaller) installDeployments(deps []StrategyDeploymentSpec) error {
10662
for _, d := range deps {
107-
// Create or Update Deployment
10863
dep := &appsv1.Deployment{Spec: d.Spec}
10964
dep.SetName(d.Name)
11065
dep.SetNamespace(i.owner.GetNamespace())
66+
dep.Spec.Template.SetAnnotations(i.templateAnnotations)
11167
ownerutil.AddNonBlockingOwner(dep, i.owner)
11268
if dep.Labels == nil {
11369
dep.SetLabels(map[string]string{})
11470
}
115-
dep.Labels["alm-owner-name"] = i.owner.GetName()
116-
dep.Labels["alm-owner-namespace"] = i.owner.GetNamespace()
71+
dep.Labels["olm.owner"] = i.owner.GetName()
72+
dep.Labels["olm.owner.namespace"] = i.owner.GetNamespace()
11773
if _, err := i.strategyClient.CreateOrUpdateDeployment(dep); err != nil {
11874
return err
11975
}
@@ -167,33 +123,13 @@ func (i *StrategyDeploymentInstaller) CheckInstalled(s Strategy) (installed bool
167123
return false, StrategyError{Reason: StrategyErrReasonInvalidStrategy, Message: fmt.Sprintf("attempted to check %s strategy with deployment installer", strategy.GetStrategyName())}
168124
}
169125

170-
// Check service accounts
171-
for _, perm := range strategy.Permissions {
172-
if err := i.checkForServiceAccount(perm.ServiceAccountName); err != nil {
173-
return false, err
174-
}
175-
}
176-
177126
// Check deployments
178127
if err := i.checkForDeployments(strategy.DeploymentSpecs); err != nil {
179128
return false, err
180129
}
181130
return true, nil
182131
}
183132

184-
func (i *StrategyDeploymentInstaller) checkForServiceAccount(serviceAccountName string) error {
185-
if _, err := i.strategyClient.GetServiceAccountByName(serviceAccountName); err != nil {
186-
if apierrors.IsNotFound(err) {
187-
log.Debugf("service account not found: %s", serviceAccountName)
188-
return StrategyError{Reason: StrategyErrReasonComponentMissing, Message: fmt.Sprintf("service account not found: %s", serviceAccountName)}
189-
}
190-
log.Debugf("error querying for %s: %s", serviceAccountName, err)
191-
return StrategyError{Reason: StrategyErrReasonComponentMissing, Message: fmt.Sprintf("error querying for %s: %s", serviceAccountName, err)}
192-
}
193-
// TODO: use a SelfSubjectRulesReview (or a sync version) to verify ServiceAccount has correct access
194-
return nil
195-
}
196-
197133
func (i *StrategyDeploymentInstaller) checkForDeployments(deploymentSpecs []StrategyDeploymentSpec) error {
198134
var depNames []string
199135
for _, dep := range deploymentSpecs {
@@ -224,6 +160,16 @@ func (i *StrategyDeploymentInstaller) checkForDeployments(deploymentSpecs []Stra
224160
if !ready {
225161
return StrategyError{Reason: StrategyErrReasonWaiting, Message: fmt.Sprintf("waiting for deployment %s to become ready: %s", dep.Name, reason)}
226162
}
163+
164+
// check annotations
165+
if len(i.templateAnnotations) > 0 && dep.Spec.Template.Annotations == nil {
166+
return StrategyError{Reason: StrategyErrReasonAnnotationsMissing, Message: fmt.Sprintf("no annotations found on deployment")}
167+
}
168+
for key, value := range i.templateAnnotations {
169+
if dep.Spec.Template.Annotations[key] != value {
170+
return StrategyError{Reason: StrategyErrReasonAnnotationsMissing, Message: fmt.Sprintf("annotations on deployment don't match. couldn't find %s: %s", key, value)}
171+
}
172+
}
227173
}
228174
return nil
229175
}

0 commit comments

Comments
 (0)