Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
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
3 changes: 2 additions & 1 deletion .github/workflows/e2e-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ on:
paths-ignore:
- 'docs/**'
- 'adr/**'
branches: [ main, next ]
branches: [ main, next, v5.3 ]
push:
paths-ignore:
- 'docs/**'
- 'adr/**'
branches:
- main
- next
- v5.3

jobs:
sample_operators_tests:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
paths-ignore:
- 'docs/**'
- 'adr/**'
branches: [ main, v1, v2, v3, next ]
branches: [ main, v1, v2, v3, next, v5.3 ]
workflow_dispatch:
jobs:
check_format_and_unit_tests:
Expand Down
2 changes: 1 addition & 1 deletion bootstrapper-maven-plugin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<parent>
<groupId>io.javaoperatorsdk</groupId>
<artifactId>java-operator-sdk</artifactId>
<version>5.2.1-SNAPSHOT</version>
<version>5.3.0-SNAPSHOT</version>
</parent>

<artifactId>bootstrapper</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion caffeine-bounded-cache-support/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>io.javaoperatorsdk</groupId>
<artifactId>java-operator-sdk</artifactId>
<version>5.2.1-SNAPSHOT</version>
<version>5.3.0-SNAPSHOT</version>
</parent>

<artifactId>caffeine-bounded-cache-support</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion micrometer-support/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>io.javaoperatorsdk</groupId>
<artifactId>java-operator-sdk</artifactId>
<version>5.2.1-SNAPSHOT</version>
<version>5.3.0-SNAPSHOT</version>
</parent>

<artifactId>micrometer-support</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion operator-framework-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

<groupId>io.javaoperatorsdk</groupId>
<artifactId>operator-framework-bom</artifactId>
<version>5.2.1-SNAPSHOT</version>
<version>5.3.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Operator SDK - Bill of Materials</name>
<description>Java SDK for implementing Kubernetes operators</description>
Expand Down
2 changes: 1 addition & 1 deletion operator-framework-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<parent>
<groupId>io.javaoperatorsdk</groupId>
<artifactId>java-operator-sdk</artifactId>
<version>5.2.1-SNAPSHOT</version>
<version>5.3.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ public <P extends HasMetadata> RegisteredController<P> register(
"Cannot register reconciler with name "
+ reconciler.getClass().getCanonicalName()
+ " reconciler named "
+ ReconcilerUtils.getNameFor(reconciler)
+ ReconcilerUtilsInternal.getNameFor(reconciler)
+ " because its configuration cannot be found.\n"
+ " Known reconcilers are: "
+ configurationService.getKnownReconcilerNames());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;

@SuppressWarnings("rawtypes")
public class ReconcilerUtils {
public class ReconcilerUtilsInternal {

private static final String FINALIZER_NAME_SUFFIX = "/finalizer";
protected static final String MISSING_GROUP_SUFFIX = ".javaoperatorsdk.io";
Expand All @@ -46,7 +46,7 @@ public class ReconcilerUtils {
Pattern.compile(".*http(s?)://[^/]*/api(s?)/(\\S*).*"); // NOSONAR: input is controlled

// prevent instantiation of util class
private ReconcilerUtils() {}
private ReconcilerUtilsInternal() {}

public static boolean isFinalizerValid(String finalizer) {
return HasMetadata.validateFinalizer(finalizer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.javaoperatorsdk.operator.ReconcilerUtils;
import io.javaoperatorsdk.operator.ReconcilerUtilsInternal;
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;

/**
Expand Down Expand Up @@ -145,7 +145,7 @@ private String getReconcilersNameMessage() {
}

protected <R extends HasMetadata> String keyFor(Reconciler<R> reconciler) {
return ReconcilerUtils.getNameFor(reconciler);
return ReconcilerUtilsInternal.getNameFor(reconciler);
}

@SuppressWarnings("unused")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.javaoperatorsdk.operator.ReconcilerUtils;
import io.javaoperatorsdk.operator.ReconcilerUtilsInternal;
import io.javaoperatorsdk.operator.api.config.Utils.Configurator;
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceConfigurationResolver;
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
Expand Down Expand Up @@ -265,7 +265,7 @@ private <P extends HasMetadata> ResolvedControllerConfiguration<P> controllerCon
io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration annotation) {
final var resourceClass = getResourceClassResolver().getPrimaryResourceClass(reconcilerClass);

final var name = ReconcilerUtils.getNameFor(reconcilerClass);
final var name = ReconcilerUtilsInternal.getNameFor(reconcilerClass);
final var generationAware =
valueOrDefaultFromAnnotation(
annotation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@
import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.api.model.apps.Deployment;
import io.fabric8.kubernetes.api.model.apps.StatefulSet;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.CustomResource;
Expand Down Expand Up @@ -447,64 +445,6 @@ default Set<Class<? extends HasMetadata>> defaultNonSSAResource() {
return defaultNonSSAResources();
}

/**
* If a javaoperatorsdk.io/previous annotation should be used so that the operator sdk can detect
* events from its own updates of dependent resources and then filter them.
*
* <p>Disable this if you want to react to your own dependent resource updates
*
* @return if special annotation should be used for dependent resource to filter events
* @since 4.5.0
*/
default boolean previousAnnotationForDependentResourcesEventFiltering() {
return true;
}

/**
* For dependent resources, the framework can add an annotation to filter out events resulting
* directly from the framework's operation. There are, however, some resources that do not follow
* the Kubernetes API conventions that changes in metadata should not increase the generation of
* the resource (as recorded in the {@code generation} field of the resource's {@code metadata}).
* For these resources, this convention is not respected and results in a new event for the
* framework to process. If that particular case is not handled correctly in the resource matcher,
* the framework will consider that the resource doesn't match the desired state and therefore
* triggers an update, which in turn, will re-add the annotation, thus starting the loop again,
* infinitely.
*
* <p>As a workaround, we automatically skip adding previous annotation for those well-known
* resources. Note that if you are sure that the matcher works for your use case, and it should in
* most instances, you can remove the resource type from the blocklist.
*
* <p>The consequence of adding a resource type to the set is that the framework will not use
* event filtering to prevent events, initiated by changes made by the framework itself as a
* result of its processing of dependent resources, to trigger the associated reconciler again.
*
* <p>Note that this method only takes effect if annotating dependent resources to prevent
* dependent resources events from triggering the associated reconciler again is activated as
* controlled by {@link #previousAnnotationForDependentResourcesEventFiltering()}
*
* @return a Set of resource classes where the previous version annotation won't be used.
*/
default Set<Class<? extends HasMetadata>> withPreviousAnnotationForDependentResourcesBlocklist() {
return Set.of(Deployment.class, StatefulSet.class);
}

/**
* If the event logic should parse the resourceVersion to determine the ordering of dependent
* resource events. This is typically not needed.
*
* <p>Disabled by default as Kubernetes does not support, and discourages, this interpretation of
* resourceVersions. Enable only if your api server event processing seems to lag the operator
* logic, and you want to further minimize the amount of work done / updates issued by the
* operator.
*
* @return if resource version should be parsed (as integer)
* @since 4.5.0
*/
default boolean parseResourceVersionsForEventFilteringAndCaching() {
return false;
}

/**
* {@link io.javaoperatorsdk.operator.api.reconciler.UpdateControl} patch resource or status can
* either use simple patches or SSA. Setting this to {@code true}, controllers will use SSA for
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,8 @@ public class ConfigurationServiceOverrider {
private Duration reconciliationTerminationTimeout;
private Boolean ssaBasedCreateUpdateMatchForDependentResources;
private Set<Class<? extends HasMetadata>> defaultNonSSAResource;
private Boolean previousAnnotationForDependentResources;
private Boolean parseResourceVersions;
private Boolean useSSAToPatchPrimaryResource;
private Boolean cloneSecondaryResourcesWhenGettingFromCache;
private Set<Class<? extends HasMetadata>> previousAnnotationUsageBlocklist;

@SuppressWarnings("rawtypes")
private DependentResourceFactory dependentResourceFactory;
Expand Down Expand Up @@ -168,31 +165,6 @@ public ConfigurationServiceOverrider withDefaultNonSSAResource(
return this;
}

public ConfigurationServiceOverrider withPreviousAnnotationForDependentResources(boolean value) {
this.previousAnnotationForDependentResources = value;
return this;
}

/**
* @param value true if internal algorithms can use metadata.resourceVersion as a numeric value.
* @return this
*/
public ConfigurationServiceOverrider withParseResourceVersions(boolean value) {
this.parseResourceVersions = value;
return this;
}

/**
* @deprecated use withParseResourceVersions
* @param value true if internal algorithms can use metadata.resourceVersion as a numeric value.
* @return this
*/
@Deprecated(forRemoval = true)
public ConfigurationServiceOverrider wihtParseResourceVersions(boolean value) {
this.parseResourceVersions = value;
return this;
}

public ConfigurationServiceOverrider withUseSSAToPatchPrimaryResource(boolean value) {
this.useSSAToPatchPrimaryResource = value;
return this;
Expand All @@ -204,12 +176,6 @@ public ConfigurationServiceOverrider withCloneSecondaryResourcesWhenGettingFromC
return this;
}

public ConfigurationServiceOverrider withPreviousAnnotationForDependentResourcesBlocklist(
Set<Class<? extends HasMetadata>> blocklist) {
this.previousAnnotationUsageBlocklist = blocklist;
return this;
}

public ConfigurationService build() {
return new BaseConfigurationService(original.getVersion(), cloner, client) {
@Override
Expand Down Expand Up @@ -331,20 +297,6 @@ public Set<Class<? extends HasMetadata>> defaultNonSSAResources() {
defaultNonSSAResource, ConfigurationService::defaultNonSSAResources);
}

@Override
public boolean previousAnnotationForDependentResourcesEventFiltering() {
return overriddenValueOrDefault(
previousAnnotationForDependentResources,
ConfigurationService::previousAnnotationForDependentResourcesEventFiltering);
}

@Override
public boolean parseResourceVersionsForEventFilteringAndCaching() {
return overriddenValueOrDefault(
parseResourceVersions,
ConfigurationService::parseResourceVersionsForEventFilteringAndCaching);
}

@Override
public boolean useSSAToPatchPrimaryResource() {
return overriddenValueOrDefault(
Expand All @@ -357,14 +309,6 @@ public boolean cloneSecondaryResourcesWhenGettingFromCache() {
cloneSecondaryResourcesWhenGettingFromCache,
ConfigurationService::cloneSecondaryResourcesWhenGettingFromCache);
}

@Override
public Set<Class<? extends HasMetadata>>
withPreviousAnnotationForDependentResourcesBlocklist() {
return overriddenValueOrDefault(
previousAnnotationUsageBlocklist,
ConfigurationService::withPreviousAnnotationForDependentResourcesBlocklist);
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import java.util.Set;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.javaoperatorsdk.operator.ReconcilerUtils;
import io.javaoperatorsdk.operator.ReconcilerUtilsInternal;
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceSpec;
import io.javaoperatorsdk.operator.api.config.workflow.WorkflowSpec;
import io.javaoperatorsdk.operator.api.reconciler.MaxReconciliationInterval;
Expand All @@ -42,16 +42,18 @@ default String getName() {
}

default String getFinalizerName() {
return ReconcilerUtils.getDefaultFinalizerName(getResourceClass());
return ReconcilerUtilsInternal.getDefaultFinalizerName(getResourceClass());
}

static String ensureValidName(String name, String reconcilerClassName) {
return name != null ? name : ReconcilerUtils.getDefaultReconcilerName(reconcilerClassName);
return name != null
? name
: ReconcilerUtilsInternal.getDefaultReconcilerName(reconcilerClassName);
}

static String ensureValidFinalizerName(String finalizer, String resourceTypeName) {
if (finalizer != null && !finalizer.isBlank()) {
if (ReconcilerUtils.isFinalizerValid(finalizer)) {
if (ReconcilerUtilsInternal.isFinalizerValid(finalizer)) {
return finalizer;
} else {
throw new IllegalArgumentException(
Expand All @@ -61,7 +63,7 @@ static String ensureValidFinalizerName(String finalizer, String resourceTypeName
+ " for details");
}
} else {
return ReconcilerUtils.getDefaultFinalizerName(resourceTypeName);
return ReconcilerUtilsInternal.getDefaultFinalizerName(resourceTypeName);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.javaoperatorsdk.operator.processing.event.source.filter.OnDeleteFilter;
import io.javaoperatorsdk.operator.processing.event.source.filter.OnUpdateFilter;

import static io.javaoperatorsdk.operator.api.reconciler.Constants.DEFAULT_COMPARABLE_RESOURCE_VERSION;
import static io.javaoperatorsdk.operator.api.reconciler.Constants.DEFAULT_FOLLOW_CONTROLLER_NAMESPACE_CHANGES;
import static io.javaoperatorsdk.operator.api.reconciler.Constants.NO_LONG_VALUE_SET;
import static io.javaoperatorsdk.operator.api.reconciler.Constants.NO_VALUE_SET;
Expand Down Expand Up @@ -131,4 +132,11 @@

/** Kubernetes field selector for additional resource filtering */
Field[] fieldSelector() default {};

/**
* true if we can consider resource versions as integers, therefore it is valid to compare them
*
* @since 5.3.0
*/
boolean comparableResourceVersions() default DEFAULT_COMPARABLE_RESOURCE_VERSION;
}
Loading