Skip to content

Commit 4131977

Browse files
committed
feat: bulk dependent resource
Signed-off-by: Attila Mészáros <[email protected]>
1 parent ae6209d commit 4131977

File tree

8 files changed

+119
-18
lines changed

8 files changed

+119
-18
lines changed

Diff for: src/main/java/io/javaoperatorsdk/operator/glue/Utils.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,7 @@ public static String getKindFromTemplate(String resourceTemplate) {
138138
public static Set<String> leafResourceNames(Glue glue) {
139139
Set<String> result = new HashSet<>();
140140
glue.getSpec().getChildResources().forEach(r -> result.add(r.getName()));
141-
glue.getSpec().getChildResources().forEach(r -> {
142-
r.getDependsOn().forEach(result::remove);
143-
});
141+
glue.getSpec().getChildResources().forEach(r -> r.getDependsOn().forEach(result::remove));
144142
return result;
145143
}
146144

@@ -157,4 +155,10 @@ private static String getPropertyValueFromTemplate(String resourceTemplate, Stri
157155
"Template does not contain property. " + resourceTemplate));
158156
}
159157

158+
public static GroupVersionKind getGVKFromTemplate(String resourceTemplate) {
159+
String apiVersion = getApiVersionFromTemplate(resourceTemplate);
160+
String kind = getKindFromTemplate(resourceTemplate);
161+
return new GroupVersionKind(apiVersion, kind);
162+
}
163+
160164
}

Diff for: src/main/java/io/javaoperatorsdk/operator/glue/customresource/glue/DependentResourceSpec.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public class DependentResourceSpec {
2323

2424
private Matcher matcher = Matcher.SSA;
2525

26+
private Boolean bulk = false;
27+
2628
private List<String> dependsOn = new ArrayList<>();
2729

2830
@PreserveUnknownFields
@@ -102,6 +104,14 @@ public void setMatcher(Matcher matcher) {
102104
this.matcher = matcher;
103105
}
104106

107+
public Boolean getBulk() {
108+
return bulk;
109+
}
110+
111+
public void setBulk(Boolean bulk) {
112+
this.bulk = bulk;
113+
}
114+
105115
@Override
106116
public boolean equals(Object o) {
107117
if (this == o)
@@ -112,14 +122,14 @@ public boolean equals(Object o) {
112122
return clusterScoped == that.clusterScoped && Objects.equals(name, that.name)
113123
&& Objects.equals(resource, that.resource)
114124
&& Objects.equals(resourceTemplate, that.resourceTemplate) && matcher == that.matcher
115-
&& Objects.equals(dependsOn, that.dependsOn)
125+
&& Objects.equals(bulk, that.bulk) && Objects.equals(dependsOn, that.dependsOn)
116126
&& Objects.equals(readyPostCondition, that.readyPostCondition)
117127
&& Objects.equals(condition, that.condition);
118128
}
119129

120130
@Override
121131
public int hashCode() {
122-
return Objects.hash(name, clusterScoped, resource, resourceTemplate, matcher, dependsOn,
132+
return Objects.hash(name, clusterScoped, resource, resourceTemplate, matcher, bulk, dependsOn,
123133
readyPostCondition, condition);
124134
}
125135
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.javaoperatorsdk.operator.glue.dependent;
2+
3+
import io.javaoperatorsdk.operator.api.reconciler.dependent.GarbageCollected;
4+
import io.javaoperatorsdk.operator.glue.customresource.glue.Glue;
5+
import io.javaoperatorsdk.operator.glue.customresource.glue.Matcher;
6+
import io.javaoperatorsdk.operator.glue.templating.GenericTemplateHandler;
7+
8+
public class GCGenericBulkDependentResource extends GenericBulkDependentResource
9+
implements GarbageCollected<Glue> {
10+
11+
public GCGenericBulkDependentResource(GenericTemplateHandler genericTemplateHandler,
12+
String desiredTemplate, String name,
13+
boolean clusterScoped, Matcher matcher) {
14+
super(genericTemplateHandler, desiredTemplate, name, clusterScoped, matcher);
15+
}
16+
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package io.javaoperatorsdk.operator.glue.dependent;
2+
3+
import java.util.Map;
4+
import java.util.stream.Collectors;
5+
6+
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
7+
import io.fabric8.kubernetes.api.model.GenericKubernetesResourceList;
8+
import io.fabric8.kubernetes.client.utils.Serialization;
9+
import io.javaoperatorsdk.operator.api.reconciler.Context;
10+
import io.javaoperatorsdk.operator.glue.customresource.glue.Glue;
11+
import io.javaoperatorsdk.operator.glue.customresource.glue.Matcher;
12+
import io.javaoperatorsdk.operator.glue.templating.GenericTemplateHandler;
13+
import io.javaoperatorsdk.operator.processing.dependent.BulkDependentResource;
14+
15+
import static io.javaoperatorsdk.operator.glue.reconciler.glue.GlueReconciler.DEPENDENT_NAME_ANNOTATION_KEY;
16+
17+
public class GenericBulkDependentResource extends
18+
GenericDependentResource implements
19+
BulkDependentResource<GenericKubernetesResource, Glue> {
20+
21+
public GenericBulkDependentResource(GenericTemplateHandler genericTemplateHandler,
22+
String desiredTemplate, String name,
23+
boolean clusterScoped,
24+
Matcher matcher) {
25+
super(genericTemplateHandler, desiredTemplate, name, clusterScoped, matcher);
26+
}
27+
28+
@Override
29+
public Map<String, GenericKubernetesResource> desiredResources(Glue primary,
30+
Context<Glue> context) {
31+
32+
var res = genericTemplateHandler.processTemplate(desiredTemplate, primary, context);
33+
var desiredList = Serialization.unmarshal(res, GenericKubernetesResourceList.class).getItems();
34+
desiredList.forEach(r -> {
35+
r.getMetadata().getAnnotations()
36+
.put(DEPENDENT_NAME_ANNOTATION_KEY, name);
37+
if (r.getMetadata().getNamespace() == null && !clusterScoped) {
38+
r.getMetadata().setNamespace(primary.getMetadata().getNamespace());
39+
}
40+
});
41+
return desiredList.stream().collect(Collectors.toMap(r -> r.getMetadata().getName(), r -> r));
42+
}
43+
44+
@Override
45+
public Map<String, GenericKubernetesResource> getSecondaryResources(Glue glue,
46+
Context<Glue> context) {
47+
return context.getSecondaryResources(GenericKubernetesResource.class).stream()
48+
.filter(
49+
r -> name.equals(r.getMetadata().getAnnotations().get(DEPENDENT_NAME_ANNOTATION_KEY)))
50+
.collect(Collectors.toMap(r -> r.getMetadata().getName(), r -> r));
51+
}
52+
}

Diff for: src/main/java/io/javaoperatorsdk/operator/glue/dependent/GenericDependentResource.java

+6-7
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,13 @@ public class GenericDependentResource
2020
Updater<GenericKubernetesResource, Glue>,
2121
Creator<GenericKubernetesResource, Glue> {
2222

23-
private final GenericKubernetesResource desired;
24-
private final String desiredTemplate;
25-
private final String name;
26-
private final boolean clusterScoped;
27-
private final Matcher matcher;
23+
protected final GenericKubernetesResource desired;
24+
protected final String desiredTemplate;
25+
protected final String name;
26+
protected final boolean clusterScoped;
27+
protected final Matcher matcher;
2828

29-
// optimize share between instances
30-
private final GenericTemplateHandler genericTemplateHandler;
29+
protected final GenericTemplateHandler genericTemplateHandler;
3130

3231
public GenericDependentResource(GenericTemplateHandler genericTemplateHandler,
3332
GenericKubernetesResource desired, String name,

Diff for: src/main/java/io/javaoperatorsdk/operator/glue/reconciler/ValidationAndErrorHandler.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,20 @@ public class ValidationAndErrorHandler {
4242
}
4343
}
4444

45-
public void checkIfNamesAreUnique(GlueSpec glueSpec) {
45+
public void checkIfValidGlueSpec(GlueSpec glueSpec) {
46+
checkIfBulkProvidesResourceTemplate(glueSpec);
47+
checkIfNamesAreUnique(glueSpec);
48+
}
49+
50+
private void checkIfBulkProvidesResourceTemplate(GlueSpec glueSpec) {
51+
glueSpec.getChildResources().forEach(r -> {
52+
if (Boolean.TRUE.equals(r.getBulk()) && r.getResourceTemplate() == null) {
53+
throw new GlueException("Bulk resource requires a template to be set");
54+
}
55+
});
56+
}
57+
58+
void checkIfNamesAreUnique(GlueSpec glueSpec) {
4659
Set<String> seen = new HashSet<>();
4760
List<String> duplicates = new ArrayList<>();
4861

Diff for: src/main/java/io/javaoperatorsdk/operator/glue/reconciler/glue/GlueReconciler.java

+10-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io.javaoperatorsdk.operator.glue.customresource.glue.condition.ConditionSpec;
2222
import io.javaoperatorsdk.operator.glue.customresource.glue.condition.JavaScriptConditionSpec;
2323
import io.javaoperatorsdk.operator.glue.customresource.glue.condition.ReadyConditionSpec;
24+
import io.javaoperatorsdk.operator.glue.dependent.GCGenericBulkDependentResource;
2425
import io.javaoperatorsdk.operator.glue.dependent.GCGenericDependentResource;
2526
import io.javaoperatorsdk.operator.glue.dependent.GenericDependentResource;
2627
import io.javaoperatorsdk.operator.glue.dependent.GenericResourceDiscriminator;
@@ -78,7 +79,7 @@ public UpdateControl<Glue> reconcile(Glue primary,
7879
log.debug("Reconciling glue. name: {} namespace: {}",
7980
primary.getMetadata().getName(), primary.getMetadata().getNamespace());
8081

81-
validationAndErrorHandler.checkIfNamesAreUnique(primary.getSpec());
82+
validationAndErrorHandler.checkIfValidGlueSpec(primary.getSpec());
8283

8384
registerRelatedResourceInformers(context, primary);
8485
if (deletedGlueIfParentMarkedForDeletion(context, primary)) {
@@ -209,9 +210,14 @@ private GenericDependentResource createDependentResource(DependentResourceSpec s
209210

210211
if (leafDependent && resourceInSameNamespaceAsPrimary && !spec.isClusterScoped()) {
211212
return spec.getResourceTemplate() != null
212-
? new GCGenericDependentResource(genericTemplateHandler, spec.getResourceTemplate(),
213-
spec.getName(),
214-
spec.isClusterScoped(), spec.getMatcher())
213+
? spec.getBulk()
214+
? new GCGenericBulkDependentResource(genericTemplateHandler,
215+
spec.getResourceTemplate(),
216+
spec.getName(),
217+
spec.isClusterScoped(), spec.getMatcher())
218+
: new GCGenericDependentResource(genericTemplateHandler, spec.getResourceTemplate(),
219+
spec.getName(),
220+
spec.isClusterScoped(), spec.getMatcher())
215221
: new GCGenericDependentResource(genericTemplateHandler, spec.getResource(),
216222
spec.getName(),
217223
spec.isClusterScoped(), spec.getMatcher());

Diff for: src/main/java/io/javaoperatorsdk/operator/glue/reconciler/operator/GlueOperatorReconciler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public UpdateControl<GlueOperator> reconcile(GlueOperator glueOperator,
7575
log.info("Reconciling GlueOperator {} in namespace: {}", glueOperator.getMetadata().getName(),
7676
glueOperator.getMetadata().getNamespace());
7777

78-
validationAndErrorHandler.checkIfNamesAreUnique(glueOperator.getSpec());
78+
validationAndErrorHandler.checkIfValidGlueSpec(glueOperator.getSpec());
7979

8080
var targetCREventSource = getOrRegisterCustomResourceEventSource(glueOperator, context);
8181
targetCREventSource.list().forEach(cr -> {

0 commit comments

Comments
 (0)