Skip to content
Draft
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
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.0-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.0-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.0-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.0-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.0-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 @@ -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 @@ -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;
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ public class InformerConfiguration<R extends HasMetadata> {
private ItemStore<R> itemStore;
private Long informerListLimit;
private FieldSelector fieldSelector;
private boolean comparableResourceVersions;

protected InformerConfiguration(
Class<R> resourceClass,
Expand All @@ -66,7 +67,8 @@ protected InformerConfiguration(
GenericFilter<? super R> genericFilter,
ItemStore<R> itemStore,
Long informerListLimit,
FieldSelector fieldSelector) {
FieldSelector fieldSelector,
boolean comparableResourceVersions) {
this(resourceClass);
this.name = name;
this.namespaces = namespaces;
Expand All @@ -79,6 +81,7 @@ protected InformerConfiguration(
this.itemStore = itemStore;
this.informerListLimit = informerListLimit;
this.fieldSelector = fieldSelector;
this.comparableResourceVersions = comparableResourceVersions;
}

private InformerConfiguration(Class<R> resourceClass) {
Expand Down Expand Up @@ -113,7 +116,8 @@ public static <R extends HasMetadata> InformerConfiguration<R>.Builder builder(
original.genericFilter,
original.itemStore,
original.informerListLimit,
original.fieldSelector)
original.fieldSelector,
original.comparableResourceVersions)
.builder;
}

Expand Down Expand Up @@ -288,6 +292,10 @@ public FieldSelector getFieldSelector() {
return fieldSelector;
}

public boolean isComparableResourceVersions() {
return comparableResourceVersions;
}

@SuppressWarnings("UnusedReturnValue")
public class Builder {

Expand Down Expand Up @@ -359,6 +367,7 @@ public InformerConfiguration<R>.Builder initFromAnnotation(
Arrays.stream(informerConfig.fieldSelector())
.map(f -> new FieldSelector.Field(f.path(), f.value(), f.negated()))
.toList()));
withComparableResourceVersions(informerConfig.comparableResourceVersions());
}
return this;
}
Expand Down Expand Up @@ -459,5 +468,10 @@ public Builder withFieldSelector(FieldSelector fieldSelector) {
InformerConfiguration.this.fieldSelector = fieldSelector;
return this;
}

public Builder withComparableResourceVersions(boolean comparableResourceVersions) {
InformerConfiguration.this.comparableResourceVersions = comparableResourceVersions;
return this;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import io.javaoperatorsdk.operator.processing.event.source.filter.OnUpdateFilter;
import io.javaoperatorsdk.operator.processing.event.source.informer.Mappers;

import static io.javaoperatorsdk.operator.api.reconciler.Constants.DEFAULT_COMPARABLE_RESOURCE_VERSION;
import static io.javaoperatorsdk.operator.api.reconciler.Constants.SAME_AS_CONTROLLER_NAMESPACES_SET;
import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_ALL_NAMESPACE_SET;
import static io.javaoperatorsdk.operator.api.reconciler.Constants.WATCH_CURRENT_NAMESPACE_SET;
Expand Down Expand Up @@ -96,18 +97,21 @@ class DefaultInformerEventSourceConfiguration<R extends HasMetadata>
private final GroupVersionKind groupVersionKind;
private final InformerConfiguration<R> informerConfig;
private final KubernetesClient kubernetesClient;
private final boolean comparableResourceVersion;

protected DefaultInformerEventSourceConfiguration(
GroupVersionKind groupVersionKind,
PrimaryToSecondaryMapper<?> primaryToSecondaryMapper,
SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper,
InformerConfiguration<R> informerConfig,
KubernetesClient kubernetesClient) {
KubernetesClient kubernetesClient,
boolean comparableResourceVersion) {
this.informerConfig = Objects.requireNonNull(informerConfig);
this.groupVersionKind = groupVersionKind;
this.primaryToSecondaryMapper = primaryToSecondaryMapper;
this.secondaryToPrimaryMapper = secondaryToPrimaryMapper;
this.kubernetesClient = kubernetesClient;
this.comparableResourceVersion = comparableResourceVersion;
}

@Override
Expand Down Expand Up @@ -135,6 +139,11 @@ public Optional<GroupVersionKind> getGroupVersionKind() {
public Optional<KubernetesClient> getKubernetesClient() {
return Optional.ofNullable(kubernetesClient);
}

@Override
public boolean comparableResourceVersion() {
return this.comparableResourceVersion;
}
}

@SuppressWarnings({"unused", "UnusedReturnValue"})
Expand All @@ -148,6 +157,7 @@ class Builder<R extends HasMetadata> {
private PrimaryToSecondaryMapper<?> primaryToSecondaryMapper;
private SecondaryToPrimaryMapper<R> secondaryToPrimaryMapper;
private KubernetesClient kubernetesClient;
private boolean comparableResourceVersion = DEFAULT_COMPARABLE_RESOURCE_VERSION;

private Builder(Class<R> resourceClass, Class<? extends HasMetadata> primaryResourceClass) {
this(resourceClass, primaryResourceClass, null);
Expand Down Expand Up @@ -285,6 +295,11 @@ public Builder<R> withFieldSelector(FieldSelector fieldSelector) {
return this;
}

public Builder<R> withComparableResourceVersion(boolean comparableResourceVersion) {
this.comparableResourceVersion = comparableResourceVersion;
return this;
}

public void updateFrom(InformerConfiguration<R> informerConfig) {
if (informerConfig != null) {
final var informerConfigName = informerConfig.getName();
Expand Down Expand Up @@ -324,7 +339,10 @@ public InformerEventSourceConfiguration<R> build() {
HasMetadata.getKind(primaryResourceClass),
false)),
config.build(),
kubernetesClient);
kubernetesClient,
comparableResourceVersion);
}
}

boolean comparableResourceVersion();
}
Loading
Loading