Skip to content

Commit 815611f

Browse files
Merge pull request #424 from enxebre/owned-deployments
Only reconcile owned deployments
2 parents c5c0be5 + a402a05 commit 815611f

File tree

4 files changed

+146
-31
lines changed

4 files changed

+146
-31
lines changed

pkg/operator/baremetal_pod.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ func newMetal3Deployment(config *OperatorConfig) *appsv1.Deployment {
106106
ObjectMeta: metav1.ObjectMeta{
107107
Name: "metal3",
108108
Namespace: config.TargetNamespace,
109+
Annotations: map[string]string{
110+
maoOwnedAnnotation: "",
111+
},
109112
Labels: map[string]string{
110113
"api": "clusterapi",
111114
"k8s-app": "controller",

pkg/operator/operator.go

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ const (
2828
// a machineconfig pool is going to be requeued:
2929
//
3030
// 5ms, 10ms, 20ms, 40ms, 80ms, 160ms, 320ms, 640ms, 1.3s, 2.6s, 5.1s, 10.2s, 20.4s, 41s, 82s
31-
maxRetries = 15
31+
maxRetries = 15
32+
maoOwnedAnnotation = "machine.openshift.io/owned"
3233
)
3334

3435
// Operator defines machine api operator.
@@ -88,7 +89,7 @@ func New(
8889
operandVersions: operandVersions,
8990
}
9091

91-
deployInformer.Informer().AddEventHandler(optr.eventHandler())
92+
deployInformer.Informer().AddEventHandler(optr.eventHandlerDeployments())
9293
featureGateInformer.Informer().AddEventHandler(optr.eventHandler())
9394

9495
optr.config = config
@@ -125,13 +126,72 @@ func (optr *Operator) Run(workers int, stopCh <-chan struct{}) {
125126
<-stopCh
126127
}
127128

129+
func logResource(obj interface{}) {
130+
metaObj, okObject := obj.(metav1.Object)
131+
if !okObject {
132+
glog.Errorf("Error assigning type to interface when logging")
133+
}
134+
glog.V(4).Infof("Resource type: %T", obj)
135+
glog.V(4).Infof("Resource: %v", metaObj.GetSelfLink())
136+
}
137+
128138
func (optr *Operator) eventHandler() cache.ResourceEventHandler {
129139
workQueueKey := fmt.Sprintf("%s/%s", optr.namespace, optr.name)
130140
return cache.ResourceEventHandlerFuncs{
131-
AddFunc: func(obj interface{}) { optr.queue.Add(workQueueKey) },
132-
UpdateFunc: func(old, new interface{}) { optr.queue.Add(workQueueKey) },
133-
DeleteFunc: func(obj interface{}) { optr.queue.Add(workQueueKey) },
141+
AddFunc: func(obj interface{}) {
142+
glog.V(4).Infof("Event: Add")
143+
logResource(obj)
144+
optr.queue.Add(workQueueKey)
145+
},
146+
UpdateFunc: func(old, new interface{}) {
147+
glog.V(4).Infof("Event: Update")
148+
logResource(old)
149+
optr.queue.Add(workQueueKey)
150+
},
151+
DeleteFunc: func(obj interface{}) {
152+
glog.V(4).Infof("Event: Delete")
153+
logResource(obj)
154+
optr.queue.Add(workQueueKey)
155+
},
156+
}
157+
}
158+
159+
// on deployments we only reconcile on update/delete events if its owned by mao
160+
func (optr *Operator) eventHandlerDeployments() cache.ResourceEventHandler {
161+
workQueueKey := fmt.Sprintf("%s/%s", optr.namespace, optr.name)
162+
return cache.ResourceEventHandlerFuncs{
163+
AddFunc: func(obj interface{}) {
164+
glog.V(4).Infof("Event: Add")
165+
logResource(obj)
166+
optr.queue.Add(workQueueKey)
167+
},
168+
UpdateFunc: func(old, new interface{}) {
169+
glog.V(4).Infof("Event: Update")
170+
logResource(old)
171+
if owned, err := isOwned(old); !owned || err != nil {
172+
return
173+
}
174+
optr.queue.Add(workQueueKey)
175+
},
176+
DeleteFunc: func(obj interface{}) {
177+
glog.V(4).Infof("Event: Delete")
178+
logResource(obj)
179+
if owned, err := isOwned(obj); !owned || err != nil {
180+
return
181+
}
182+
optr.queue.Add(workQueueKey)
183+
},
184+
}
185+
}
186+
187+
func isOwned(obj interface{}) (bool, error) {
188+
metaObj, okObject := obj.(metav1.Object)
189+
if !okObject {
190+
glog.Errorf("Error assigning metav1.Object type to object: %T", obj)
191+
return false, fmt.Errorf("error assigning metav1.Object type to object: %T", obj)
134192
}
193+
_, ok := metaObj.GetAnnotations()[maoOwnedAnnotation]
194+
return ok, nil
135195
}
136196

137197
func (optr *Operator) worker() {

pkg/operator/operator_test.go

Lines changed: 75 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ import (
55
"testing"
66
"time"
77

8+
openshiftv1 "github.com/openshift/api/config/v1"
9+
fakeos "github.com/openshift/client-go/config/clientset/versioned/fake"
10+
configinformersv1 "github.com/openshift/client-go/config/informers/externalversions"
11+
"github.com/stretchr/testify/assert"
12+
appsv1 "k8s.io/api/apps/v1"
813
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
914
"k8s.io/apimachinery/pkg/runtime"
1015
"k8s.io/apimachinery/pkg/util/wait"
1116
"k8s.io/client-go/informers"
1217
fakekube "k8s.io/client-go/kubernetes/fake"
1318
"k8s.io/client-go/tools/record"
1419
"k8s.io/client-go/util/workqueue"
15-
16-
v1 "github.com/openshift/api/config/v1"
17-
fakeos "github.com/openshift/client-go/config/clientset/versioned/fake"
18-
configinformersv1 "github.com/openshift/client-go/config/informers/externalversions"
19-
"github.com/stretchr/testify/assert"
2020
)
2121

2222
const (
@@ -25,12 +25,12 @@ const (
2525
hcControllerName = "machine-healthcheck-controller"
2626
)
2727

28-
func newFeatureGate(featureSet v1.FeatureSet) *v1.FeatureGate {
29-
return &v1.FeatureGate{
28+
func newFeatureGate(featureSet openshiftv1.FeatureSet) *openshiftv1.FeatureGate {
29+
return &openshiftv1.FeatureGate{
3030
ObjectMeta: metav1.ObjectMeta{
3131
Name: MachineAPIFeatureGateName,
3232
},
33-
Spec: v1.FeatureGateSpec{
33+
Spec: openshiftv1.FeatureGateSpec{
3434
FeatureSet: featureSet,
3535
},
3636
}
@@ -75,7 +75,7 @@ func newFakeOperator(kubeObjects []runtime.Object, osObjects []runtime.Object, s
7575
kubeNamespacedSharedInformer.Start(stopCh)
7676

7777
optr.syncHandler = optr.sync
78-
deployInformer.Informer().AddEventHandler(optr.eventHandler())
78+
deployInformer.Informer().AddEventHandler(optr.eventHandlerDeployments())
7979
featureGateInformer.Informer().AddEventHandler(optr.eventHandler())
8080

8181
return optr
@@ -85,43 +85,43 @@ func newFakeOperator(kubeObjects []runtime.Object, osObjects []runtime.Object, s
8585
// for platforms that are no-ops.
8686
func TestOperatorSync_NoOp(t *testing.T) {
8787
cases := []struct {
88-
platform v1.PlatformType
88+
platform openshiftv1.PlatformType
8989
expectedNoop bool
9090
}{
9191
{
92-
platform: v1.AWSPlatformType,
92+
platform: openshiftv1.AWSPlatformType,
9393
expectedNoop: false,
9494
},
9595
{
96-
platform: v1.LibvirtPlatformType,
96+
platform: openshiftv1.LibvirtPlatformType,
9797
expectedNoop: false,
9898
},
9999
{
100-
platform: v1.OpenStackPlatformType,
100+
platform: openshiftv1.OpenStackPlatformType,
101101
expectedNoop: false,
102102
},
103103
{
104-
platform: v1.AzurePlatformType,
104+
platform: openshiftv1.AzurePlatformType,
105105
expectedNoop: false,
106106
},
107107
{
108-
platform: v1.BareMetalPlatformType,
108+
platform: openshiftv1.BareMetalPlatformType,
109109
expectedNoop: false,
110110
},
111111
{
112-
platform: v1.GCPPlatformType,
112+
platform: openshiftv1.GCPPlatformType,
113113
expectedNoop: false,
114114
},
115115
{
116116
platform: kubemarkPlatform,
117117
expectedNoop: false,
118118
},
119119
{
120-
platform: v1.VSpherePlatformType,
120+
platform: openshiftv1.VSpherePlatformType,
121121
expectedNoop: true,
122122
},
123123
{
124-
platform: v1.NonePlatformType,
124+
platform: openshiftv1.NonePlatformType,
125125
expectedNoop: true,
126126
},
127127
{
@@ -132,17 +132,17 @@ func TestOperatorSync_NoOp(t *testing.T) {
132132

133133
for _, tc := range cases {
134134
t.Run(string(tc.platform), func(t *testing.T) {
135-
infra := &v1.Infrastructure{
135+
infra := &openshiftv1.Infrastructure{
136136
ObjectMeta: metav1.ObjectMeta{
137137
Name: "cluster",
138138
},
139-
Status: v1.InfrastructureStatus{
139+
Status: openshiftv1.InfrastructureStatus{
140140
Platform: tc.platform,
141141
},
142142
}
143143

144144
stopCh := make(<-chan struct{})
145-
optr := newFakeOperator(nil, []runtime.Object{newFeatureGate(v1.TechPreviewNoUpgrade), infra}, stopCh)
145+
optr := newFakeOperator(nil, []runtime.Object{newFeatureGate(openshiftv1.TechPreviewNoUpgrade), infra}, stopCh)
146146
go optr.Run(2, stopCh)
147147

148148
err := wait.PollImmediate(1*time.Second, 5*time.Second, func() (bool, error) {
@@ -162,15 +162,64 @@ func TestOperatorSync_NoOp(t *testing.T) {
162162
if !assert.NoError(t, err, "failed to get clusteroperator") {
163163
t.Fatal()
164164
}
165-
expectedConditions := map[v1.ClusterStatusConditionType]v1.ConditionStatus{
166-
v1.OperatorAvailable: v1.ConditionTrue,
167-
v1.OperatorProgressing: v1.ConditionFalse,
168-
v1.OperatorDegraded: v1.ConditionFalse,
169-
v1.OperatorUpgradeable: v1.ConditionTrue,
165+
expectedConditions := map[openshiftv1.ClusterStatusConditionType]openshiftv1.ConditionStatus{
166+
openshiftv1.OperatorAvailable: openshiftv1.ConditionTrue,
167+
openshiftv1.OperatorProgressing: openshiftv1.ConditionFalse,
168+
openshiftv1.OperatorDegraded: openshiftv1.ConditionFalse,
169+
openshiftv1.OperatorUpgradeable: openshiftv1.ConditionTrue,
170170
}
171171
for _, c := range o.Status.Conditions {
172172
assert.Equal(t, expectedConditions[c.Type], c.Status, fmt.Sprintf("unexpected clusteroperator condition %s status", c.Type))
173173
}
174174
})
175175
}
176176
}
177+
178+
func TestIsOwned(t *testing.T) {
179+
testCases := []struct {
180+
testCase string
181+
obj interface{}
182+
expected bool
183+
expectedError bool
184+
}{
185+
{
186+
testCase: "with maoOwnedAnnotation returns true",
187+
obj: &appsv1.Deployment{
188+
ObjectMeta: metav1.ObjectMeta{
189+
Annotations: map[string]string{
190+
maoOwnedAnnotation: "",
191+
},
192+
},
193+
},
194+
expected: true,
195+
},
196+
{
197+
testCase: "with no maoOwnedAnnotation returns false",
198+
obj: &appsv1.Deployment{
199+
ObjectMeta: metav1.ObjectMeta{
200+
Annotations: map[string]string{
201+
"any": "",
202+
},
203+
},
204+
},
205+
expected: false,
206+
},
207+
{
208+
testCase: "bad type object returns error",
209+
obj: "bad object",
210+
expected: false,
211+
expectedError: true,
212+
},
213+
}
214+
for _, tc := range testCases {
215+
t.Run(string(tc.testCase), func(t *testing.T) {
216+
got, err := isOwned(tc.obj)
217+
if got != tc.expected {
218+
t.Errorf("Expected: %v, got: %v", tc.expected, got)
219+
}
220+
if tc.expectedError != (err != nil) {
221+
t.Errorf("ExpectedError: %v, got: %v", tc.expectedError, err)
222+
}
223+
})
224+
}
225+
}

pkg/operator/sync.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ func newDeployment(config *OperatorConfig, features map[string]bool) *appsv1.Dep
154154
ObjectMeta: metav1.ObjectMeta{
155155
Name: "machine-api-controllers",
156156
Namespace: config.TargetNamespace,
157+
Annotations: map[string]string{
158+
maoOwnedAnnotation: "",
159+
},
157160
Labels: map[string]string{
158161
"api": "clusterapi",
159162
"k8s-app": "controller",

0 commit comments

Comments
 (0)