Skip to content

feat: showcase sample for matcher with ssa in DR #1964

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion docs/documentation/v4-4-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ the `KubernetesDependentResource`.

The SSA based create/update can be combined with the legacy matcher, simply override the `match` method
and use the [GenericKubernetesResourceMatcher](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework-core/src/main/java/io/javaoperatorsdk/operator/processing/dependent/kubernetes/GenericKubernetesResourceMatcher.java#L19-L19)
directly.
directly. See related [sample](https://github.com/java-operator-sdk/java-operator-sdk/blob/main/operator-framework/src/test/java/io/javaoperatorsdk/operator/sample/ssalegacymatcher/ServiceDependentResource.java#L39-L44).

### Migration from plain Update/Create to SSA Based Patch

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
public class GenericKubernetesResourceMatcher<R extends HasMetadata, P extends HasMetadata>
implements Matcher<R, P> {

private static String SPEC = "/spec";
private static final String SPEC = "/spec";
private static final String ADD = "add";
private static final String OP = "op";
public static final String METADATA_LABELS = "/metadata/labels";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.javaoperatorsdk.operator;

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

import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
import io.fabric8.kubernetes.api.model.Service;
import io.javaoperatorsdk.operator.junit.LocallyRunOperatorExtension;
import io.javaoperatorsdk.operator.sample.ssalegacymatcher.SSALegacyMatcherCustomResource;
import io.javaoperatorsdk.operator.sample.ssalegacymatcher.SSALegacyMatcherReconciler;
import io.javaoperatorsdk.operator.sample.ssalegacymatcher.SSALegacyMatcherSpec;
import io.javaoperatorsdk.operator.sample.ssalegacymatcher.ServiceDependentResource;

import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;

public class SSAWithLegacyMatcherIT {

public static final String TEST_RESOURCE_NAME = "test1";

@RegisterExtension
LocallyRunOperatorExtension extension =
LocallyRunOperatorExtension.builder().withReconciler(new SSALegacyMatcherReconciler())
.build();

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

await().untilAsserted(() -> {
var service = extension.get(Service.class, TEST_RESOURCE_NAME);
assertThat(service).isNotNull();
assertThat(ServiceDependentResource.createUpdateCount.get()).isEqualTo(1);
});

resource.getSpec().setValue("other_value");

await().untilAsserted(() -> {
assertThat(ServiceDependentResource.createUpdateCount.get()).isEqualTo(1);
});
}

SSALegacyMatcherCustomResource testResource() {
SSALegacyMatcherCustomResource res = new SSALegacyMatcherCustomResource();
res.setMetadata(new ObjectMetaBuilder()
.withName(TEST_RESOURCE_NAME)
.build());
res.setSpec(new SSALegacyMatcherSpec());
res.getSpec().setValue("initial-value");
return res;
}

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

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("slm")
public class SSALegacyMatcherCustomResource
extends CustomResource<SSALegacyMatcherSpec, Void>
implements Namespaced {

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

import java.util.concurrent.atomic.AtomicInteger;

import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent;

@ControllerConfiguration(dependents = {@Dependent(type = ServiceDependentResource.class)})
public class SSALegacyMatcherReconciler
implements Reconciler<SSALegacyMatcherCustomResource> {

private final AtomicInteger numberOfExecutions = new AtomicInteger(0);

@Override
public UpdateControl<SSALegacyMatcherCustomResource> reconcile(
SSALegacyMatcherCustomResource resource,
Context<SSALegacyMatcherCustomResource> 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.ssalegacymatcher;

public class SSALegacyMatcherSpec {

private String value;

public String getValue() {
return value;
}

public SSALegacyMatcherSpec setValue(String value) {
this.value = value;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package io.javaoperatorsdk.operator.sample.ssalegacymatcher;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import io.fabric8.kubernetes.api.model.Service;
import io.javaoperatorsdk.operator.SSAWithLegacyMatcherIT;
import io.javaoperatorsdk.operator.api.reconciler.Context;
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource;
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.GenericKubernetesResourceMatcher;
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent;

import static io.javaoperatorsdk.operator.ReconcilerUtils.loadYaml;

@KubernetesDependent
public class ServiceDependentResource
extends CRUDKubernetesDependentResource<Service, SSALegacyMatcherCustomResource> {

public static AtomicInteger createUpdateCount = new AtomicInteger(0);

public ServiceDependentResource() {
super(Service.class);
}

@Override
protected Service desired(SSALegacyMatcherCustomResource primary,
Context<SSALegacyMatcherCustomResource> context) {

Service service = loadYaml(Service.class, SSAWithLegacyMatcherIT.class, "service.yaml");
service.getMetadata().setName(primary.getMetadata().getName());
service.getMetadata().setNamespace(primary.getMetadata().getNamespace());
Map<String, String> labels = new HashMap<>();
labels.put("app", "deployment-name");
service.getSpec().setSelector(labels);
return service;
}

@Override
public Result<Service> match(Service actualResource, SSALegacyMatcherCustomResource primary,
Context<SSALegacyMatcherCustomResource> context) {
return GenericKubernetesResourceMatcher.match(this, actualResource, primary, context,
true, false, false);
}

// override just to check the exec count
@Override
public Service update(Service actual, Service target, SSALegacyMatcherCustomResource primary,
Context<SSALegacyMatcherCustomResource> context) {
createUpdateCount.addAndGet(1);
return super.update(actual, target, primary, context);
}

// override just to check the exec count
@Override
public Service create(Service target, SSALegacyMatcherCustomResource primary,
Context<SSALegacyMatcherCustomResource> context) {
createUpdateCount.addAndGet(1);
return super.create(target, primary, context);
}
}