Skip to content

Commit

Permalink
improve: rename resources to childResources in CRDs (#82)
Browse files Browse the repository at this point in the history
Signed-off-by: Attila Mészáros <[email protected]>
  • Loading branch information
csviri authored Apr 17, 2024
1 parent 97bc450 commit 5d2fd46
Show file tree
Hide file tree
Showing 29 changed files with 58 additions and 57 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ spec:
parent:
apiVersion: glueoperator.sample/v1 # watches all the custom resource of type WebPage
kind: WebPage
resources:
childResources:
- name: htmlconfigmap
resource:
apiVersion: v1
Expand Down Expand Up @@ -109,7 +109,7 @@ spec:
```

There are multiple aspects to see here. The four related resources will be templated
and applied to the cluster if such a resource is created. The reconciliation will be triggered if anything changes in the custom or managed resources.
and applied to the cluster if such a resource is created. The reconciliation will be triggered if anything changes in the custom or child resources.

Note also the `condition` part for `Ingress` resource contains multiple types of conditions, `JSCondition` is
used in this example, which allows writing conditions in Javascript. The `Ingress` will be created if the `.spec.exposed` property
Expand Down Expand Up @@ -137,7 +137,7 @@ kind: Glue
metadata:
name: mutation-webhook-deployment
spec:
resources:
childResources:
- name: service
resource:
apiVersion: v1
Expand Down
23 changes: 12 additions & 11 deletions docs/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,23 @@ Although it is limited only to Kubernetes resources it makes it very easy to use
## [Glue resource](https://github.com/csviri/kubernetes-glue-operator/releases/latest/download/glues.glue-v1.yml)

`Glue` is the heart of the operator. Note that `GlueOperator` controller just creates a new `Glue` with a related resource,
for each parent custom resource. `Glue` defines `resources` (sometimes referred to as managed resources) and `related resources`:
for each parent custom resource. `Glue` defines `childResources` (sometimes referred to as managed resources) and `related resources`:

### Managed resources
### Child Resources

#### Attributes

The `resources` section is a list of resources to be reconciled. It has several attributes:
The `childResources` section is a list of resources to be reconciled (created, updated, deleted by controller).
It has several attributes:

- **`name`** - is a mandatory unique (unique also regarding related resources) attribute.
The resource is referenced by this name from other places, typically other resource templates and `JSCondition`.
If it is used in a `JSCondition` the `name` must be a valid JavaScript variable name.
- **`resource`** - is the desired state of the resource applied by default using Server Side Apply. The resource is templated using
[qute templating engine](https://quarkus.io/guides/qute-reference), other resources can be referenced from the templates, see below.
There is a restriction, that the managed resource is namespaced, and the namespace is always the same as the namespace of the `Glue`
There is a restriction, that the child resource is namespaced, and the namespace is always the same as the namespace of the `Glue`
(and/or parent for `GlueOperator`), so the `namespace` field in resource **metadata should not be specified**.
- **`dependsOn`** - is a list of names of other managed resources (not related resources). The resource is not reconciled until all the resources
- **`dependsOn`** - is a list of names of other child resources (not related resources). The resource is not reconciled until all the resources
which it depends on are not reconciled and ready (if there is a `readyPostCondition` present).
Note that during the cleanup phase (when a `Glue` is deleted) resources are cleaned up in reverse order.
- **`condition`** - a condition to specify if the resource should be there or not, thus even if the condition is evaluated to be `true`
Expand All @@ -39,17 +40,17 @@ At the moment there are two types of built-in conditions provided:

- **`ReadyCondition`** - check if a resource is up and running. Use it only as a `readyPostCondition`. See sample usage [here](https://github.com/csviri/kubernetes-glue-operator/blob/main/src/test/resources/sample/mutation/mutation.glue.yaml#L24-L25).
- **`JSCondition`** - a generic condition, that allows writing conditions in JavaScript. As input, all the resources are available which
are either managed or related. The script should return a boolean value.
are either child or related. The script should return a boolean value.
See accessing the related resource in [WebPage sample](https://github.com/csviri/kubernetes-glue-operator/blob/main/src/test/resources/sample/webpage/webpage.operator.yaml#L62-L64),
and cross-referencing resources [here](https://github.com/csviri/kubernetes-glue-operator/blob/main/src/test/resources/glue/TwoResourcesAndCondition.yaml#L23-L28).

### Related resources

Related resources are resources that are not managed (not created, updated, or deleted) during reconciliation, but serve as an input for it.
Related resources are resources that are not reconciled (not created, updated, or deleted) during reconciliation, but serve as an input for it.
See sample usage within `Glue` [here](https://github.com/csviri/kubernetes-glue-operator/blob/main/src/test/resources/glue/RelatedResourceSimpleWithCondition.yaml)
The following attributes can be defined for a related resource:

- **`name`** - same as for managed resource, unique identifier, used to reference the resource.
- **`name`** - same as for child resource, unique identifier, used to reference the resource.
- **`apiVersion`** - Kubernetes resource API Version of the resource
- **`kind`** - Kubernetes kind property of the resource
- **`resourceNames`** - list of string of the resource names within the same namespace as `Glue`.
Expand All @@ -71,9 +72,9 @@ In addition to that in `GlueOperator` the **`parent`** attribute can be used to

### Reconciliation notes

The reconciliation is triggered either on a change of the `Glue` or any managed or related resources.
The reconciliation is triggered either on a change of the `Glue` or any child or related resources.

On every reconciliation, each managed resource is reconciled, and if a resource is updated, it is added to a cache, so it is available for templating
On every reconciliation, each child resource is reconciled, and if a resource is updated, it is added to a cache, so it is available for templating
for a resource that depends on it.

The `DependentResource` implementation of JOSDK makes all kinds of optimizations on the reconciliation which are utilized (or will be also here).
Expand All @@ -98,7 +99,7 @@ While we will provide more options, users are encouraged to enhance/adjust this

Since the project is a meta-controller, it needs to have access rights to all the resources it manages.
When creating specialized roles for a deployment, roles should contain the union of required access rights
for all the managed resources, specifically: `["list", "watch", "create", "patch", "delete"]`
for all the child resources, specifically: `["list", "watch", "create", "patch", "delete"]`
and `["list", "watch"]` for related resources.

The project is mainly tested with cluster-scoped deployment, however, QOSDK namespace-scoped deployments are also supported.
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/io/csviri/operator/glue/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public static Map<String, GenericKubernetesResource> getActualResourcesByNameInW
var secondaryResources = context.getSecondaryResources(GenericKubernetesResource.class);
Map<String, GenericKubernetesResource> res = new HashMap<>();
secondaryResources.forEach(sr -> {
var dependentSpec = glue.getSpec().getResources().stream()
var dependentSpec = glue.getSpec().getChildResources().stream()
.filter(r -> Utils.getApiVersion(r).equals(sr.getApiVersion())
&& Utils.getKind(r).equals(sr.getKind())
// comparing the name from annotation since the resource name might be templated in spec
Expand Down Expand Up @@ -139,8 +139,8 @@ public static String getKindFromTemplate(String resourceTemplate) {

public static Set<String> leafResourceNames(Glue glue) {
Set<String> result = new HashSet<>();
glue.getSpec().getResources().forEach(r -> result.add(r.getName()));
glue.getSpec().getResources().forEach(r -> {
glue.getSpec().getChildResources().forEach(r -> result.add(r.getName()));
glue.getSpec().getChildResources().forEach(r -> {
r.getDependsOn().forEach(result::remove);
});
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@

public class GlueSpec {

private List<DependentResourceSpec> resources = new ArrayList<>();
private List<DependentResourceSpec> childResources = new ArrayList<>();

private List<RelatedResourceSpec> relatedResources = new ArrayList<>();

public List<DependentResourceSpec> getResources() {
return resources;
public List<DependentResourceSpec> getChildResources() {
return childResources;
}

public void setResources(List<DependentResourceSpec> resources) {
this.resources = resources;
public void setChildResources(List<DependentResourceSpec> childResources) {
this.childResources = childResources;
}

public List<RelatedResourceSpec> getRelatedResources() {
Expand All @@ -30,7 +30,7 @@ public GlueSpec setRelatedResources(List<RelatedResourceSpec> relatedResources)
@Override
public String toString() {
return "GlueSpec{" +
"resources=" + resources +
"resources=" + childResources +
'}';
}

Expand All @@ -41,11 +41,11 @@ public boolean equals(Object o) {
if (o == null || getClass() != o.getClass())
return false;
GlueSpec that = (GlueSpec) o;
return Objects.equals(resources, that.resources);
return Objects.equals(childResources, that.childResources);
}

@Override
public int hashCode() {
return Objects.hash(resources);
return Objects.hash(childResources);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void checkIfNamesAreUnique(GlueSpec glueSpec) {
seen.add(n);
}
};
glueSpec.getResources().stream().map(DependentResourceSpec::getName).forEach(deduplicate);
glueSpec.getChildResources().stream().map(DependentResourceSpec::getName).forEach(deduplicate);
glueSpec.getRelatedResources().stream().map(RelatedResourceSpec::getName).forEach(deduplicate);

if (!duplicates.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ private void cleanupRemovedResourcesFromWorkflow(Context<Glue> context,
context.getSecondaryResources(GenericKubernetesResource.class).forEach(r -> {
String dependentName = r.getMetadata().getAnnotations().get(DEPENDENT_NAME_ANNOTATION_KEY);
// dependent name is null for related resources
if (dependentName != null && primary.getSpec().getResources().stream()
if (dependentName != null && primary.getSpec().getChildResources().stream()
.filter(pr -> pr.getName().equals(dependentName)).findAny().isEmpty()) {
try {
log.debug("Deleting resource with name: {}", dependentName + "for resource flow: {} "
Expand All @@ -146,7 +146,7 @@ private io.javaoperatorsdk.operator.processing.dependent.workflow.Workflow<Glue>
Set<String> leafDependentNames = Utils.leafResourceNames(primary);

Map<String, GenericDependentResource> genericDependentResourceMap = new HashMap<>();
primary.getSpec().getResources().forEach(spec -> createAndAddDependentToWorkflow(primary,
primary.getSpec().getChildResources().forEach(spec -> createAndAddDependentToWorkflow(primary,
context, spec, genericDependentResourceMap, builder,
leafDependentNames.contains(spec.getName())));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public synchronized void deRegisterInformerOnResourceFlowChange(Context<Glue> co
var registeredGVKSet =
new HashSet<>(glueToInformerGVK.get(primary.getMetadata().getName()));

var currentGVKSet = primary.getSpec().getResources().stream()
var currentGVKSet = primary.getSpec().getChildResources().stream()
.map(Utils::getGVK)
.collect(Collectors.toSet());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ private Glue createResourceFlow(GenericKubernetesResource targetParentResource,

private GlueSpec toWorkflowSpec(GlueOperatorSpec spec) {
var res = new GlueSpec();
res.setResources(new ArrayList<>(spec.getResources()));
res.setChildResources(new ArrayList<>(spec.getChildResources()));
res.setRelatedResources(new ArrayList<>(spec.getRelatedResources()));
return res;
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/java/io/csviri/operator/glue/GlueOperatorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ GlueOperator testWorkflowOperator() {
wo.setSpec(spec);
spec.setParent(new Parent(CR_GROUP + "/v1", TestCustomResource.class.getSimpleName()));

spec.setResources(new ArrayList<>());
spec.setChildResources(new ArrayList<>());
DependentResourceSpec drs = new DependentResourceSpec();
spec.getResources().add(drs);
spec.getChildResources().add(drs);
drs.setResource(TestUtils.load("/ConfigMap.yaml"));
drs.setName("configMap1");
return wo;
Expand Down
10 changes: 5 additions & 5 deletions src/test/java/io/csviri/operator/glue/GlueTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void simpleTemplating() {
assertThat(cm2.getData().get("valueFromCM1")).isEqualTo("value1");
});

((Map<String, String>) glue.getSpec().getResources().get(0).getResource()
((Map<String, String>) glue.getSpec().getChildResources().get(0).getResource()
.getAdditionalProperties().get("data"))
.put("key", CHANGED_VALUE);

Expand Down Expand Up @@ -77,7 +77,7 @@ void crossReferenceResource() {
});

var resourceTemplate =
glue.getSpec().getResources().stream().filter(r -> r.getName().equals("configMap1"))
glue.getSpec().getChildResources().stream().filter(r -> r.getName().equals("configMap1"))
.findAny().orElseThrow().getResource();
// set new value
((Map<String, String>) resourceTemplate.getAdditionalProperties().get("data")).put("key",
Expand Down Expand Up @@ -113,7 +113,7 @@ void javaScriptCondition() {
assertThat(cm2).isNull();
});

Map<String, String> map = (Map<String, String>) glue.getSpec().getResources()
Map<String, String> map = (Map<String, String>) glue.getSpec().getChildResources()
.get(0).getResource().getAdditionalProperties().get("data");
map.put("createOther", "true");

Expand Down Expand Up @@ -197,8 +197,8 @@ void changingWorkflow() {
assertThat(cm2).isNotNull();
});

glue.getSpec().getResources().remove(1);
glue.getSpec().getResources().add(new DependentResourceSpec()
glue.getSpec().getChildResources().remove(1);
glue.getSpec().getChildResources().add(new DependentResourceSpec()
.setName("secret")
.setResource(TestUtils.load("/Secret.yaml")));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ void injectsSecondaryResourcesResource() {

Glue glue = new Glue();
glue.setSpec(new GlueSpec());
glue.getSpec().setResources(new ArrayList<>());
glue.getSpec().setChildResources(new ArrayList<>());
var drSpec = new DependentResourceSpec();
drSpec.setName(DR_NAME);
drSpec.setResource(configMap());
glue.getSpec().getResources().add(drSpec);
glue.getSpec().getChildResources().add(drSpec);

var condition = new JavaScripCondition("""
secondary.data.key1 == "val1";
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/ChanginResources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: rf-to-change
spec:
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/ClusterScopeResource.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: "glue1"
spec:
resources:
childResources:
- name: cluster-scoped-resource
resource:
apiVersion: io.csviri.operator.glue/v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/CrossReferenceResource.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: "crossreference"
spec:
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/MultiNameRelatedResource.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: related-resource-test1
spec:
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/NonUniqueName.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ kind: Glue
metadata:
name: templating-sample
spec:
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: related-resource-test1
spec:
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/RelatesResourceSameType.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: related-resource-test1
spec:
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/ResourceInDifferentNamespace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: "testglue"
spec:
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/ResourceTemplate.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: resource-templating-sample
spec:
resources:
childResources:
- name: configMap1
resourceTemplate: |
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/TemplateForConcurrency.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: "concurrencysample"
spec:
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/Templating.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: templating-sample
spec:
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glue/TwoResourcesAndCondition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ kind: Glue
metadata:
name: two-resource-cross-condition
spec:
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glueoperator/Concurrency.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ spec:
parent:
apiVersion: io.csviri.operator.glue/v1
kind: TestCustomResource
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
2 changes: 1 addition & 1 deletion src/test/resources/glueoperator/Concurrency2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ spec:
parent:
apiVersion: io.csviri.operator.glue/v1
kind: TestCustomResource2
resources:
childResources:
- name: configMap1
resource:
apiVersion: v1
Expand Down
Loading

0 comments on commit 5d2fd46

Please sign in to comment.