8
8
import io .fabric8 .kubernetes .api .model .ObjectMetaBuilder ;
9
9
import io .fabric8 .kubernetes .api .model .rbac .ClusterRole ;
10
10
import io .fabric8 .kubernetes .api .model .rbac .ClusterRoleBinding ;
11
+ import io .fabric8 .kubernetes .api .model .rbac .Role ;
12
+ import io .fabric8 .kubernetes .api .model .rbac .RoleBinding ;
11
13
import io .fabric8 .kubernetes .client .ConfigBuilder ;
12
14
import io .fabric8 .kubernetes .client .KubernetesClient ;
13
15
import io .fabric8 .kubernetes .client .KubernetesClientBuilder ;
14
16
import io .fabric8 .kubernetes .client .utils .KubernetesResourceUtil ;
15
17
import io .javaoperatorsdk .operator .api .config .ConfigurationServiceProvider ;
18
+ import io .javaoperatorsdk .operator .health .InformerHealthIndicator ;
16
19
import io .javaoperatorsdk .operator .junit .LocallyRunOperatorExtension ;
17
20
import io .javaoperatorsdk .operator .processing .event .source .controller .ControllerResourceEventSource ;
21
+ import io .javaoperatorsdk .operator .sample .informerrelatedbehavior .ConfigMapDependentResource ;
18
22
import io .javaoperatorsdk .operator .sample .informerrelatedbehavior .InformerRelatedBehaviorTestCustomResource ;
19
23
import io .javaoperatorsdk .operator .sample .informerrelatedbehavior .InformerRelatedBehaviorTestReconciler ;
20
24
40
44
class InformerRelatedBehaviorITS {
41
45
42
46
public static final String TEST_RESOURCE_NAME = "test1" ;
47
+ public static final String ADDITIONAL_NAMESPACE_NAME = "additionalns" ;
43
48
44
49
KubernetesClient adminClient = new KubernetesClientBuilder ().build ();
45
50
InformerRelatedBehaviorTestReconciler reconciler ;
@@ -54,6 +59,8 @@ void beforeEach(TestInfo testInfo) {
54
59
actualNamespace = KubernetesResourceUtil .sanitizeName (method .getName ());
55
60
adminClient .resource (namespace ()).createOrReplace ();
56
61
});
62
+ // cleans up binding before test, not all test cases use cluster role
63
+ removeClusterRoleBinding ();
57
64
}
58
65
59
66
@ AfterEach
@@ -101,6 +108,51 @@ void startsUpWhenNoPermissionToSecondaryResource() {
101
108
assertReconciled ();
102
109
}
103
110
111
+ @ Test
112
+ void startsUpIfNoPermissionToOneOfTwoNamespaces () {
113
+ var otherNamespace =
114
+ adminClient .resource (namespace (ADDITIONAL_NAMESPACE_NAME )).createOrReplace ();
115
+ try {
116
+ addRoleBindingsToTestNamespaces ();
117
+ var operator = startOperator (false , false , actualNamespace , ADDITIONAL_NAMESPACE_NAME );
118
+ assertInformerNotWatchingForAdditionalNamespace (operator );
119
+
120
+ adminClient .resource (testCustomResource ()).createOrReplace ();
121
+ waitForWatchReconnect ();
122
+ assertReconciled ();
123
+
124
+ } finally {
125
+ adminClient .resource (otherNamespace ).delete ();
126
+ await ().untilAsserted (() -> {
127
+ var ns = adminClient .namespaces ().resource (otherNamespace ).fromServer ().get ();
128
+ assertThat (ns ).isNull ();
129
+ });
130
+ }
131
+ }
132
+
133
+ private void assertInformerNotWatchingForAdditionalNamespace (Operator operator ) {
134
+ assertThat (operator .getRuntimeInfo ().allEventSourcesAreHealthy ()).isFalse ();
135
+ var unhealthyEventSources =
136
+ operator .getRuntimeInfo ().unhealthyInformerWrappingEventSourceHealthIndicator ()
137
+ .get (INFORMER_RELATED_BEHAVIOR_TEST_RECONCILER );
138
+
139
+ InformerHealthIndicator controllerHealthIndicator =
140
+ (InformerHealthIndicator ) unhealthyEventSources
141
+ .get (ControllerResourceEventSource .class .getSimpleName ())
142
+ .informerHealthIndicators ().get (ADDITIONAL_NAMESPACE_NAME );
143
+ assertThat (controllerHealthIndicator ).isNotNull ();
144
+ assertThat (controllerHealthIndicator .getTargetNamespace ()).isEqualTo (ADDITIONAL_NAMESPACE_NAME );
145
+ assertThat (controllerHealthIndicator .isWatching ()).isFalse ();
146
+
147
+ InformerHealthIndicator configMapHealthIndicator =
148
+ (InformerHealthIndicator ) unhealthyEventSources
149
+ .get (ConfigMapDependentResource .class .getSimpleName ())
150
+ .informerHealthIndicators ().get (ADDITIONAL_NAMESPACE_NAME );
151
+ assertThat (configMapHealthIndicator ).isNotNull ();
152
+ assertThat (configMapHealthIndicator .getTargetNamespace ()).isEqualTo (ADDITIONAL_NAMESPACE_NAME );
153
+ assertThat (configMapHealthIndicator .isWatching ()).isFalse ();
154
+ }
155
+
104
156
@ Test
105
157
void resilientForLoosingPermissionForCustomResource () throws InterruptedException {
106
158
setFullResourcesAccess ();
@@ -240,7 +292,8 @@ Operator startOperator(boolean stopOnInformerErrorDuringStartup) {
240
292
return startOperator (stopOnInformerErrorDuringStartup , true );
241
293
}
242
294
243
- Operator startOperator (boolean stopOnInformerErrorDuringStartup , boolean addStopHandler ) {
295
+ Operator startOperator (boolean stopOnInformerErrorDuringStartup , boolean addStopHandler ,
296
+ String ... namespaces ) {
244
297
ConfigurationServiceProvider .reset ();
245
298
reconciler = new InformerRelatedBehaviorTestReconciler ();
246
299
@@ -252,7 +305,11 @@ Operator startOperator(boolean stopOnInformerErrorDuringStartup, boolean addStop
252
305
co .withInformerStoppedHandler ((informer , ex ) -> replacementStopHandlerCalled = true );
253
306
}
254
307
});
255
- operator .register (reconciler );
308
+ operator .register (reconciler , o -> {
309
+ if (namespaces .length > 0 ) {
310
+ o .settingNamespaces (namespaces );
311
+ }
312
+ });
256
313
operator .start ();
257
314
return operator ;
258
315
}
@@ -272,6 +329,16 @@ private void setFullResourcesAccess() {
272
329
applyClusterRoleBinding ();
273
330
}
274
331
332
+ private void addRoleBindingsToTestNamespaces () {
333
+ var role = ReconcilerUtils
334
+ .loadYaml (Role .class , this .getClass (), "rback-test-only-main-ns-access.yaml" );
335
+ adminClient .resource (role ).inNamespace (actualNamespace ).createOrReplace ();
336
+ var roleBinding = ReconcilerUtils
337
+ .loadYaml (RoleBinding .class , this .getClass (),
338
+ "rback-test-only-main-ns-access-binding.yaml" );
339
+ adminClient .resource (roleBinding ).inNamespace (actualNamespace ).createOrReplace ();
340
+ }
341
+
275
342
private void applyClusterRoleBinding () {
276
343
var clusterRoleBinding = ReconcilerUtils
277
344
.loadYaml (ClusterRoleBinding .class , this .getClass (), "rback-test-role-binding.yaml" );
@@ -285,10 +352,20 @@ private void applyClusterRole(String filename) {
285
352
}
286
353
287
354
private Namespace namespace () {
355
+ return namespace (actualNamespace );
356
+ }
357
+
358
+ private Namespace namespace (String name ) {
288
359
Namespace n = new Namespace ();
289
360
n .setMetadata (new ObjectMetaBuilder ()
290
- .withName (actualNamespace )
361
+ .withName (name )
291
362
.build ());
292
363
return n ;
293
364
}
365
+
366
+ private void removeClusterRoleBinding () {
367
+ var clusterRoleBinding = ReconcilerUtils
368
+ .loadYaml (ClusterRoleBinding .class , this .getClass (), "rback-test-role-binding.yaml" );
369
+ adminClient .resource (clusterRoleBinding ).delete ();
370
+ }
294
371
}
0 commit comments