Skip to content

Commit a8c9b95

Browse files
committed
wip
Signed-off-by: Chris Laprun <metacosm@gmail.com>
1 parent 0dee1bf commit a8c9b95

File tree

6 files changed

+130
-0
lines changed

6 files changed

+130
-0
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package io.javaoperatorsdk.operator.processing;
2+
3+
import io.fabric8.kubernetes.api.model.HasMetadata;
4+
import io.javaoperatorsdk.operator.MockKubernetesClient;
5+
import io.javaoperatorsdk.operator.api.config.BaseConfigurationService;
6+
import io.javaoperatorsdk.operator.api.config.MockControllerConfiguration;
7+
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
8+
9+
import static org.mockito.Mockito.mock;
10+
import static org.mockito.Mockito.when;
11+
12+
public class MockController {
13+
public static <P extends HasMetadata> Controller<P> mockController(Class<P> primaryClass) {
14+
Reconciler<P> reconciler = mock(Reconciler.class);
15+
final var conf = MockControllerConfiguration.forResource(primaryClass);
16+
final var configurationService = new BaseConfigurationService();
17+
when(conf.getConfigurationService()).thenReturn(configurationService);
18+
return new Controller<>(reconciler, conf, MockKubernetesClient.client(primaryClass));
19+
}
20+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.javaoperatorsdk.operator.dependent.desiredonce;
2+
3+
import io.fabric8.kubernetes.client.CustomResource;
4+
import io.fabric8.kubernetes.model.annotation.Group;
5+
import io.fabric8.kubernetes.model.annotation.Version;
6+
7+
@Group("io.josdk")
8+
@Version("v1")
9+
public class DesiredOnce extends CustomResource<DesiredOnceSpec, Void> {
10+
static final String KEY = "key";
11+
static final String VALUE = "value";
12+
13+
public DesiredOnce() {}
14+
15+
public DesiredOnce(String value) {
16+
this.spec = new DesiredOnceSpec(value);
17+
}
18+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package io.javaoperatorsdk.operator.dependent.desiredonce;
2+
3+
import java.util.Map;
4+
5+
import io.fabric8.kubernetes.api.model.ConfigMap;
6+
import io.fabric8.kubernetes.api.model.ConfigMapBuilder;
7+
import io.javaoperatorsdk.operator.api.config.informer.Informer;
8+
import io.javaoperatorsdk.operator.api.reconciler.Context;
9+
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
10+
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;
11+
12+
@KubernetesDependent(informer = @Informer(labelSelector = "desiredonce=true"))
13+
public class DesiredOnceDependent extends CRUDKubernetesDependentResource<ConfigMap, DesiredOnce> {
14+
private boolean desiredAlreadyCalled;
15+
16+
@Override
17+
protected ConfigMap desired(DesiredOnce primary, Context<DesiredOnce> context) {
18+
if (desiredAlreadyCalled) {
19+
throw new IllegalStateException("desired should have only been called once");
20+
}
21+
desiredAlreadyCalled = true;
22+
return new ConfigMapBuilder()
23+
.editOrNewMetadata()
24+
.withName(getName(primary))
25+
.withNamespace(primary.getMetadata().getNamespace())
26+
.withLabels(Map.of("desiredonce", "true"))
27+
.endMetadata()
28+
.addToData(DesiredOnce.KEY, primary.getSpec().value())
29+
.build();
30+
}
31+
32+
static String getName(DesiredOnce primary) {
33+
return primary.getMetadata().getName() + "cm";
34+
}
35+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package io.javaoperatorsdk.operator.dependent.desiredonce;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.junit.jupiter.api.extension.RegisterExtension;
5+
6+
import io.fabric8.kubernetes.api.model.ConfigMap;
7+
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
8+
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
import static org.awaitility.Awaitility.await;
12+
13+
class DesiredOnceIT {
14+
15+
@RegisterExtension
16+
LocallyRunOperatorExtension operator =
17+
LocallyRunOperatorExtension.builder().withReconciler(DesiredOnceReconciler.class).build();
18+
19+
@Test
20+
public void checkThatDesiredIsOnlyCalledOncePerReconciliation() {
21+
var resource = operator.create(testResource());
22+
23+
await()
24+
.untilAsserted(
25+
() -> {
26+
var cm = operator.get(ConfigMap.class, DesiredOnceDependent.getName(resource));
27+
assertThat(cm).isNotNull();
28+
assertThat(cm.getData().get(DesiredOnce.KEY)).isEqualTo(DesiredOnce.VALUE);
29+
});
30+
}
31+
32+
private DesiredOnce testResource() {
33+
var res = new DesiredOnce(DesiredOnce.VALUE);
34+
res.setMetadata(
35+
new ObjectMetaBuilder().withName("test").withNamespace(operator.getNamespace()).build());
36+
return res;
37+
}
38+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.javaoperatorsdk.operator.dependent.desiredonce;
2+
3+
import io.javaoperatorsdk.operator.api.reconciler.Context;
4+
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
5+
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
6+
import io.javaoperatorsdk.operator.api.reconciler.Workflow;
7+
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;
8+
9+
@Workflow(dependents = @Dependent(type = DesiredOnceDependent.class))
10+
public class DesiredOnceReconciler implements Reconciler<DesiredOnce> {
11+
@Override
12+
public UpdateControl<DesiredOnce> reconcile(DesiredOnce resource, Context<DesiredOnce> context)
13+
throws Exception {
14+
return UpdateControl.noUpdate();
15+
}
16+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package io.javaoperatorsdk.operator.dependent.desiredonce;
2+
3+
public record DesiredOnceSpec(String value) {}

0 commit comments

Comments
 (0)