Skip to content

Commit fce3bc3

Browse files
committed
additional tests
Signed-off-by: Attila Mészáros <[email protected]>
1 parent d6f8c95 commit fce3bc3

File tree

8 files changed

+120
-44
lines changed

8 files changed

+120
-44
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ spec:
169169
protocol: TCP
170170
171171
- name: mutation_hook_config
172+
clusterScoped: true
172173
# dependsOn relation means, that the resource will be reconciled only if all
173174
# the listed resources are already reconciled and ready (if ready post-condition is present).
174175
# This resource will be applied after the service and deployment are applied,

docs/reference.md

+2-11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ It has several attributes:
2121
- **`name`** - is a mandatory unique (unique also regarding related resources) attribute.
2222
The resource is referenced by this name from other places, typically other resource templates and `JSCondition`.
2323
If it is used in a `JSCondition` the `name` must be a valid JavaScript variable name.
24+
- **`clusterScoped`** - a flag to indicate if the resource is cluster scoped. Default value is `false`.
25+
It is mandatory to set this for cluster scoped resources.
2426
- **`resource`** - is the desired state of the resource applied by default using Server Side Apply. The resource is templated using
2527
[qute templating engine](https://quarkus.io/guides/qute-reference), other resources can be referenced from the templates, see below.
2628
There is a restriction, that the child resource is namespaced, and the namespace is always the same as the namespace of the `Glue`
@@ -175,17 +177,6 @@ resources containing the same resource type.
175177
The templating and some of the Javascript condition is probably the most time-consuming and resource-intensive part which will
176178
be continuously improved in the follow-up releases.
177179

178-
## Current limitations
179-
180-
Note that none of the limitations are unsolvable, and will be continuously removed in the coming releases.
181-
182-
1. Child resources and related resources are always namespace scoped resources, and in the same namespace as the
183-
primary resource (`Glue` or the parent in the case of `GlueOperator`)
184-
185-
2. ~~Related resource changes are not triggering the reconciliation.
186-
Due to a bug in fabric8 client, after that is fixed, this is trivial to fix too:
187-
https://github.com/fabric8io/kubernetes-client/issues/5729~~
188-
189180
## Samples
190181

191182
1. [WebPage](https://github.com/csviri/kubernetes-glue-operator/tree/main/src/test/resources/sample/webpage) `GlueOperator`, serves a static website from the cluster.

src/main/java/io/csviri/operator/glue/customresource/glue/RelatedResourceSpec.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@ public class RelatedResourceSpec {
1010
// name for referencing the resource from templates and conditions (not name from object metadata)
1111
@Required
1212
private String name;
13+
private String namespace;
1314

1415
@Required
1516
private String apiVersion;
1617
@Required
1718
private String kind;
1819
private boolean clusterScoped = Boolean.FALSE;
19-
private String namespace;
2020
private List<String> resourceNames;
2121

2222

src/test/java/io/csviri/operator/glue/GlueTest.java

+74-28
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
import io.csviri.operator.glue.customresource.glue.Glue;
1313
import io.csviri.operator.glue.reconciler.ValidationAndErrorHandler;
1414
import io.fabric8.kubernetes.api.model.ConfigMap;
15+
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
16+
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
1517
import io.fabric8.kubernetes.api.model.Secret;
18+
import io.fabric8.kubernetes.client.dsl.NonDeletingOperation;
1619
import io.quarkus.test.junit.QuarkusTest;
1720

1821
import static org.assertj.core.api.Assertions.assertThat;
@@ -237,35 +240,76 @@ void nonUniqueNameResultsInErrorMessageOnStatus() {
237240
});
238241
}
239242

243+
@Test
244+
void childInDifferentNamespace() {
245+
Glue glue = create(TestUtils.loadGlue("/glue/ResourceInDifferentNamespace.yaml"));
246+
247+
await().untilAsserted(() -> {
248+
var cmDifferentNS = client.configMaps().inNamespace("default")
249+
.withName("configmap1");
250+
var cm2 = get(ConfigMap.class, "configmap2");
251+
252+
assertThat(cmDifferentNS).isNotNull();
253+
assertThat(cm2).isNotNull();
254+
});
240255

241-
//
242-
// @Disabled("Not supported in current version")
243-
// @Test
244-
// void childInDifferentNamespaceAsPrimary() {
245-
// Glue w = extension
246-
// .create(TestUtils.loadResoureFlow("/glue/ResourceInDifferentNamespace.yaml"));
247-
//
248-
// await().untilAsserted(() -> {
249-
// var cmDifferentNS = extension.getKubernetesClient().configMaps().inNamespace("default")
250-
// .withName("configmap1");
251-
// var cm2 = extension.get(ConfigMap.class, "configmap2");
252-
//
253-
// assertThat(cmDifferentNS).isNotNull();
254-
// assertThat(cm2).isNotNull();
255-
// });
256-
//
257-
// extension.delete(w);
258-
//
259-
// await().untilAsserted(() -> {
260-
// var cmDifferentNS = extension.getKubernetesClient().configMaps().inNamespace("default")
261-
// .withName("configmap1");
262-
// var cm2 = extension.get(ConfigMap.class, "configmap2");
263-
//
264-
// assertThat(cmDifferentNS).isNull();
265-
// assertThat(cm2).isNull();
266-
// });
267-
//
268-
// }
256+
delete(glue);
257+
await().timeout(TestUtils.GC_WAIT_TIMEOUT).untilAsserted(() -> {
258+
var cmDifferentNS = client.configMaps().inNamespace("default")
259+
.withName("configmap1").get();
260+
var cm2 = get(ConfigMap.class, "configmap2");
261+
262+
assertThat(cmDifferentNS).isNull();
263+
assertThat(cm2).isNull();
264+
});
265+
}
266+
267+
@Test
268+
void clusterScopedChild() {
269+
var glue = create(TestUtils.loadGlue("/glue/ClusterScopedChild.yaml"));
270+
await().untilAsserted(() -> {
271+
var ns = client.namespaces()
272+
.withName("testnamespace");
273+
assertThat(ns).isNotNull();
274+
});
275+
276+
delete(glue);
277+
await().timeout(TestUtils.GC_WAIT_TIMEOUT).untilAsserted(() -> {
278+
var ns = client.namespaces()
279+
.withName("testnamespace").get();
280+
assertThat(ns).isNull();
281+
});
282+
}
283+
284+
@Test
285+
void relatedResourceFromDifferentNamespace() {
286+
client.resource(new ConfigMapBuilder()
287+
.withMetadata(new ObjectMetaBuilder()
288+
.withName("related-configmap")
289+
.withNamespace("default")
290+
.build())
291+
.withData(Map.of("key1", "value1"))
292+
.build()).createOr(NonDeletingOperation::update);
293+
294+
var glue = create(TestUtils.loadGlue("/glue/RelatedResourceFromDifferentNamespace.yaml"));
295+
296+
await().untilAsserted(() -> {
297+
var cm = get(ConfigMap.class, "configmap1");
298+
assertThat(cm).isNotNull();
299+
assertThat(cm.getData()).containsEntry("copy-key", "value1");
300+
});
301+
302+
delete(glue);
303+
await().timeout(TestUtils.GC_WAIT_TIMEOUT).untilAsserted(() -> {
304+
var cm = get(ConfigMap.class, "configmap1");
305+
assertThat(cm).isNull();
306+
});
307+
}
308+
309+
@Test
310+
void clusterScopedRelatedResource() {
311+
312+
}
269313

270314
private List<Glue> testWorkflowList(int num) {
271315
List<Glue> res = new ArrayList<>();
@@ -278,4 +322,6 @@ private List<Glue> testWorkflowList(int num) {
278322
return res;
279323
}
280324

325+
326+
281327
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: io.csviri.operator.glue/v1beta1
2+
kind: Glue
3+
metadata:
4+
name: "testglue"
5+
spec:
6+
childResources:
7+
- name: namespace
8+
clusterScoped: true
9+
resource:
10+
apiVersion: v1
11+
kind: Namespace
12+
metadata:
13+
name: "testnamespace"
14+
15+
16+
17+
18+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
apiVersion: io.csviri.operator.glue/v1beta1
2+
kind: Glue
3+
metadata:
4+
name: "testglue"
5+
spec:
6+
childResources:
7+
- name: configMap
8+
resource:
9+
apiVersion: v1
10+
kind: ConfigMap
11+
metadata:
12+
name: "configmap1"
13+
data:
14+
copy-key: "{related.data.key1}"
15+
relatedResources:
16+
- name: related
17+
apiVersion: v1
18+
kind: ConfigMap
19+
namespace: default
20+
resourceNames: ["related-configmap"]
21+
22+

src/test/resources/glue/ResourceInDifferentNamespace.yaml

+1-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ spec:
1010
kind: ConfigMap
1111
metadata:
1212
name: "configmap1"
13+
namespace: default
1314
data:
1415
key: "v1"
1516
- name: configMap2
@@ -20,7 +21,3 @@ spec:
2021
name: "configmap2"
2122
data:
2223
key: "v2"
23-
24-
25-
26-

src/test/resources/sample/mutation/mutation.glue.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ spec:
7474
optional: false
7575
secretName: tls-secret
7676
- name: mutation_hook_config
77+
clusterScoped: true
7778
dependsOn:
7879
- deployment
7980
- service

0 commit comments

Comments
 (0)