Skip to content

Commit

Permalink
fix: allow configuration of field manager / item store (#783)
Browse files Browse the repository at this point in the history
Fixes #780

Signed-off-by: Chris Laprun <claprun@redhat.com>
  • Loading branch information
metacosm authored Dec 12, 2023
1 parent bebcb15 commit a8137e5
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.rbac.PolicyRule;
import io.fabric8.kubernetes.api.model.rbac.PolicyRuleBuilder;
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
import io.javaoperatorsdk.operator.ReconcilerUtils;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.config.dependent.DependentResourceConfigurationResolver;
Expand Down Expand Up @@ -169,6 +170,8 @@ static QuarkusControllerConfiguration createConfiguration(
Class<? extends RateLimiter> rateLimiterClass = DefaultRateLimiter.class;
Class<?> rateLimiterConfigurationClass = null;
Long nullableInformerListLimit = null;
String fieldManager = null;
ItemStore<?> itemStore = null;
if (controllerAnnotation != null) {
final var intervalFromAnnotation = ConfigurationUtils.annotationValueOrDefault(
controllerAnnotation, "maxReconciliationInterval", AnnotationValue::asNested,
Expand Down Expand Up @@ -207,6 +210,10 @@ static QuarkusControllerConfiguration createConfiguration(
nullableInformerListLimit = ConfigurationUtils.annotationValueOrDefault(
controllerAnnotation, "informerListLimit", AnnotationValue::asLong,
() -> null);
fieldManager = ConfigurationUtils.annotationValueOrDefault(controllerAnnotation, "fieldManager",
AnnotationValue::asString, () -> null);
itemStore = ConfigurationUtils.instantiateImplementationClass(controllerAnnotation, "itemStore", ItemStore.class,
ItemStore.class, true, index);
}

// check if we have additional RBAC rules to handle
Expand Down Expand Up @@ -266,7 +273,7 @@ static QuarkusControllerConfiguration createConfiguration(
finalFilter,
maxReconciliationInterval,
onAddFilter, onUpdateFilter, genericFilter, retryClass, retryConfigurationClass, rateLimiterClass,
rateLimiterConfigurationClass, dependentResources, null, additionalRBACRules);
rateLimiterConfigurationClass, dependentResources, null, additionalRBACRules, fieldManager, itemStore);

if (hasDependents) {
dependentResourceInfos.forEach(dependent -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.rbac.PolicyRule;
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
import io.javaoperatorsdk.operator.ReconcilerUtils;
import io.javaoperatorsdk.operator.api.config.AnnotationConfigurable;
import io.javaoperatorsdk.operator.api.config.ConfigurationService;
Expand Down Expand Up @@ -74,6 +75,8 @@ public DefaultRateLimiter(Duration refreshPeriod, int limitForPeriod) {
private final Optional<OnUpdateFilter<? super R>> onUpdateFilter;
private final Optional<GenericFilter<? super R>> genericFilter;
private final List<PolicyRule> additionalRBACRules;
private final String fieldManager;
private final Optional<ItemStore<R>> itemStore;
private Class<? extends Annotation> retryConfigurationClass;
private Class<? extends Retry> retryClass;
private Class<? extends Annotation> rateLimiterConfigurationClass;
Expand Down Expand Up @@ -107,7 +110,7 @@ public QuarkusControllerConfiguration(
Class<? extends Retry> retryClass, Class<? extends Annotation> retryConfigurationClass,
Class<? extends RateLimiter> rateLimiterClass, Class<? extends Annotation> rateLimiterConfigurationClass,
Map<String, DependentResourceSpecMetadata<?, ?, ?>> dependentsMetadata, ManagedWorkflow<R> workflow,
List<PolicyRule> additionalRBACRules) {
List<PolicyRule> additionalRBACRules, String fieldManager, ItemStore<R> nullableItemStore) {
this.associatedReconcilerClassName = associatedReconcilerClassName;
this.name = name;
this.resourceTypeName = resourceTypeName;
Expand Down Expand Up @@ -138,6 +141,9 @@ public QuarkusControllerConfiguration(
this.rateLimiterClass = rateLimiterClass;
this.rateLimiter = DefaultRateLimiter.class.equals(rateLimiterClass) ? new DefaultRateLimiter() : null;
this.rateLimiterConfigurationClass = rateLimiterConfigurationClass;

this.fieldManager = fieldManager != null ? fieldManager : ControllerConfiguration.super.fieldManager();
this.itemStore = Optional.ofNullable(nullableItemStore);
}

@Override
Expand Down Expand Up @@ -409,4 +415,26 @@ private void configure(Class<? extends Reconciler> reconcilerClass, Class<? exte
public List<PolicyRule> getAdditionalRBACRules() {
return additionalRBACRules;
}

@SuppressWarnings("unused")
// this is needed by Quarkus for the RecordableConstructor
public String getFieldManager() {
return fieldManager;
}

@Override
public String fieldManager() {
return fieldManager;
}

@Override
public Optional<ItemStore<R>> getItemStore() {
return itemStore;
}

@SuppressWarnings("unused")
// this is needed by Quarkus for the RecordableConstructor
public ItemStore<R> getNullableItemStore() {
return itemStore.orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import io.javaoperatorsdk.operator.api.reconciler.Reconciler;
import io.javaoperatorsdk.operator.api.reconciler.UpdateControl;

@ControllerConfiguration(name = CustomRateLimiterReconciler.NAME, rateLimiter = CustomRateLimiter.class)
@ControllerConfiguration(name = CustomRateLimiterReconciler.NAME, rateLimiter = CustomRateLimiter.class, itemStore = NullItemStore.class)
@CustomRateConfiguration(42)
public class CustomRateLimiterReconciler implements Reconciler<ResourceQuota> {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package io.quarkiverse.operatorsdk.it;

import java.util.stream.Stream;

import io.fabric8.kubernetes.api.model.ResourceQuota;
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection // for proper serialization in native mode
public class NullItemStore implements ItemStore<ResourceQuota> {

public static final String NAME = "NullItemStoreName";

// so that it appears in the JSON configuration and we can check against it
public String getName() {
return NAME;
}

@Override
public String getKey(ResourceQuota resourceQuota) {
return null;
}

@Override
public ResourceQuota put(String s, ResourceQuota resourceQuota) {
return null;
}

@Override
public ResourceQuota remove(String s) {
return null;
}

@Override
public Stream<String> keySet() {
return null;
}

@Override
public Stream<ResourceQuota> values() {
return null;
}

@Override
public int size() {
return 0;
}

@Override
public ResourceQuota get(String s) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;

import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.client.informers.cache.ItemStore;
import io.javaoperatorsdk.operator.api.config.ControllerConfiguration;
import io.javaoperatorsdk.operator.api.config.RetryConfiguration;
import io.javaoperatorsdk.operator.api.config.Version;
Expand Down Expand Up @@ -230,6 +231,10 @@ public long maxReconciliationIntervalSeconds() {
public RateLimiter getRateLimiter() {
return conf.getRateLimiter();
}

public ItemStore<?> getItemStore() {
return conf.getItemStore().orElse(null);
}
}

static class JSONDependentResourceSpec {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@

import static io.restassured.RestAssured.given;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.startsWith;
import static org.hamcrest.Matchers.*;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -289,6 +283,7 @@ void customRateLimiterConfiguredViaCustomAnnotationShouldWork() {
.then()
.statusCode(200)
.body(
"rateLimiter.value", equalTo(42));
"rateLimiter.value", equalTo(42),
"itemStore.name", equalTo(NullItemStore.NAME));
}
}

0 comments on commit a8137e5

Please sign in to comment.