Skip to content

Commit bff3b20

Browse files
committed
feat(operatorgroups): move annotation projection to csv loop
1 parent d9576a1 commit bff3b20

File tree

17 files changed

+275
-591
lines changed

17 files changed

+275
-591
lines changed

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 []string `json:"namespaces,omitempty"`
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/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)