Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.javaoperatorsdk.operator;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.ConfigMapDependentResource;
import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.DependentDifferentNamespaceCustomResource;
import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.DependentDifferentNamespaceReconciler;
import io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.DependentDifferentNamespaceSpec;

import static io.javaoperatorsdk.operator.sample.dependentdifferentnamespace.ConfigMapDependentResource.KEY;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;

class DependentDifferentNamespaceIT {

public static final String TEST_1 = "test1";
public static final String INITIAL_VALUE = "initial_value";
public static final String CHANGED_VALUE = "changed_value";

@RegisterExtension
LocallyRunOperatorExtension extension =
LocallyRunOperatorExtension.builder()
.withReconciler(DependentDifferentNamespaceReconciler.class)
.build();

@Test
void managesCRUDOperationsForDependentInDifferentNamespace() {
var resource = extension.create(testResource());

await().untilAsserted(() -> {
var cm = getDependentConfigMap();
assertThat(cm).isNotNull();
assertThat(cm.getData()).containsEntry(KEY, INITIAL_VALUE);
});

resource.getSpec().setValue(CHANGED_VALUE);
resource = extension.replace(resource);

await().untilAsserted(() -> {
var cm = getDependentConfigMap();
assertThat(cm.getData()).containsEntry(KEY, CHANGED_VALUE);
});

extension.delete(resource);
await().untilAsserted(() -> {
var cm = getDependentConfigMap();
assertThat(cm).isNull();
});
}

private ConfigMap getDependentConfigMap() {
return extension.getKubernetesClient().configMaps()
.inNamespace(ConfigMapDependentResource.NAMESPACE)
.withName(TEST_1).get();
}

DependentDifferentNamespaceCustomResource testResource() {
var res = new DependentDifferentNamespaceCustomResource();
res.setMetadata(new ObjectMetaBuilder()
.withName(TEST_1)
.build());
res.setSpec(new DependentDifferentNamespaceSpec());
res.getSpec().setValue(INITIAL_VALUE);
return res;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace;

import java.util.HashMap;

import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDNoGCKubernetesDependentResource;

public class ConfigMapDependentResource extends
CRUDNoGCKubernetesDependentResource<ConfigMap, DependentDifferentNamespaceCustomResource> {

public static final String KEY = "key";

public static final String NAMESPACE = "default";

public ConfigMapDependentResource() {
super(ConfigMap.class);
}

@Override
protected ConfigMap desired(DependentDifferentNamespaceCustomResource primary,
Context<DependentDifferentNamespaceCustomResource> context) {

ConfigMap configMap = new ConfigMap();
configMap.setMetadata(new ObjectMeta());
configMap.getMetadata().setName(primary.getMetadata().getName());
configMap.getMetadata().setNamespace(NAMESPACE);
HashMap<String, String> data = new HashMap<>();
data.put(KEY, primary.getSpec().getValue());
configMap.setData(data);
return configMap;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace;

import io.fabric8.kubernetes.api.model.Namespaced;
import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.ShortNames;
import io.fabric8.kubernetes.model.annotation.Version;

@Group("sample.javaoperatorsdk")
@Version("v1")
@ShortNames("ddn")
public class DependentDifferentNamespaceCustomResource
extends CustomResource<DependentDifferentNamespaceSpec, Void>
implements Namespaced {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace;

import java.util.concurrent.atomic.AtomicInteger;

import io.javaoperatorsdk.operator.api.reconciler.*;
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
import io.javaoperatorsdk.operator.support.TestExecutionInfoProvider;

@ControllerConfiguration(
dependents = {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this should be made more explicit by making the reconciler only watch 2 namespaces: the one where the primary resources are deployed and the one where the dependents are supposed to be? It feels like we're somehow "cheating" by having the reconciler watch all namespaces… 😅

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that would require a change to the extension, if you insist can do that, I don't see it that important, on the other hand would be little nicer I agree.

@Dependent(type = ConfigMapDependentResource.class),
})
public class DependentDifferentNamespaceReconciler
implements Reconciler<DependentDifferentNamespaceCustomResource>,
TestExecutionInfoProvider {

private final AtomicInteger numberOfExecutions = new AtomicInteger(0);

@Override
public UpdateControl<DependentDifferentNamespaceCustomResource> reconcile(
DependentDifferentNamespaceCustomResource resource,
Context<DependentDifferentNamespaceCustomResource> context) {
numberOfExecutions.addAndGet(1);
return UpdateControl.noUpdate();
}

public int getNumberOfExecutions() {
return numberOfExecutions.get();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.javaoperatorsdk.operator.sample.dependentdifferentnamespace;

public class DependentDifferentNamespaceSpec {

private String value;

public String getValue() {
return value;
}

public DependentDifferentNamespaceSpec setValue(String value) {
this.value = value;
return this;
}
}