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
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ public ControllerConfigurationOverrider<R> withLabelSelector(String labelSelecto
return this;
}

public ControllerConfigurationOverrider<R> withShardSelector(String shardSelector) {
config.withShardSelector(shardSelector);
return this;
}

public ControllerConfigurationOverrider<R> withReconciliationMaxInterval(
Duration reconciliationMaxInterval) {
this.reconciliationMaxInterval = reconciliationMaxInterval;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,18 @@
*/
String labelSelector() default NO_VALUE_SET;

/**
* Optional shard selector used to restrict the set of resources the associated informer will act
* upon to a single shard, typically when the same workload is split across several operator
* instances. Just like {@link #labelSelector()} it is expressed as a label selector and can be
* made of multiple comma separated requirements that act as a logical AND operator. When both a
* label selector and a shard selector are set, the resulting informer only watches resources
* matching both (the two selectors are combined with a logical AND).
*
* @return the shard selector
*/
String shardSelector() default NO_VALUE_SET;

/**
* Optional {@link OnAddFilter} to filter add events sent to the associated informer
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ public class InformerConfiguration<R extends HasMetadata> {
private Set<String> namespaces;
private Boolean followControllerNamespaceChanges;
private String labelSelector;
private String shardSelector;
private OnAddFilter<? super R> onAddFilter;
private OnUpdateFilter<? super R> onUpdateFilter;
private OnDeleteFilter<? super R> onDeleteFilter;
Expand All @@ -62,6 +63,7 @@ protected InformerConfiguration(
Set<String> namespaces,
boolean followControllerNamespaceChanges,
String labelSelector,
String shardSelector,
OnAddFilter<? super R> onAddFilter,
OnUpdateFilter<? super R> onUpdateFilter,
OnDeleteFilter<? super R> onDeleteFilter,
Expand All @@ -77,6 +79,7 @@ protected InformerConfiguration(
this.namespaces = namespaces;
this.followControllerNamespaceChanges = followControllerNamespaceChanges;
this.labelSelector = labelSelector;
this.shardSelector = shardSelector;
this.onAddFilter = onAddFilter;
this.onUpdateFilter = onUpdateFilter;
this.onDeleteFilter = onDeleteFilter;
Expand Down Expand Up @@ -113,6 +116,7 @@ public static <R extends HasMetadata> InformerConfiguration<R>.Builder builder(
original.namespaces,
original.followControllerNamespaceChanges,
original.labelSelector,
original.shardSelector,
original.onAddFilter,
original.onUpdateFilter,
original.onDeleteFilter,
Expand All @@ -130,6 +134,11 @@ public static String ensureValidLabelSelector(String labelSelector) {
return labelSelector;
}

public static String ensureValidShardSelector(String shardSelector) {
// might want to implement validation here?
return shardSelector;
}

public static boolean allNamespacesWatched(Set<String> namespaces) {
failIfNotValid(namespaces);
return DEFAULT_NAMESPACES_SET.equals(namespaces);
Expand Down Expand Up @@ -251,6 +260,20 @@ public String getLabelSelector() {
return labelSelector;
}

/**
* Retrieves the shard selector that is used, in addition to the {@link #getLabelSelector() label
* selector}, to restrict which resources are actually watched by the associated informer.
* Typically used to assign a subset (shard) of the resources to a given operator instance. It is
* expressed using the same syntax as a label selector. See the official documentation on the <a
* href="https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/">topic</a> for
* more details on syntax.
*
* @return the shard selector filtering watched resources
*/
public String getShardSelector() {
return shardSelector;
}

public OnAddFilter<? super R> getOnAddFilter() {
return onAddFilter;
}
Expand Down Expand Up @@ -353,6 +376,11 @@ public InformerConfiguration<R>.Builder initFromAnnotation(
var labelSelector = Constants.NO_VALUE_SET.equals(fromAnnotation) ? null : fromAnnotation;
withLabelSelector(labelSelector);

final var shardFromAnnotation = informerConfig.shardSelector();
var shardSelector =
Constants.NO_VALUE_SET.equals(shardFromAnnotation) ? null : shardFromAnnotation;
withShardSelector(shardSelector);

withOnAddFilter(
Utils.instantiate(informerConfig.onAddFilter(), OnAddFilter.class, context));

Expand Down Expand Up @@ -446,6 +474,11 @@ public Builder withLabelSelector(String labelSelector) {
return this;
}

public Builder withShardSelector(String shardSelector) {
InformerConfiguration.this.shardSelector = ensureValidShardSelector(shardSelector);
return this;
}

public Builder withOnAddFilter(OnAddFilter<? super R> onAddFilter) {
InformerConfiguration.this.onAddFilter = onAddFilter;
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,11 @@ public Builder<R> withLabelSelector(String labelSelector) {
return this;
}

public Builder<R> withShardSelector(String shardSelector) {
config.withShardSelector(shardSelector);
return this;
}

public Builder<R> withOnAddFilter(OnAddFilter<? super R> onAddFilter) {
config.withOnAddFilter(onAddFilter);
return this;
Expand Down Expand Up @@ -308,6 +313,7 @@ public void updateFrom(InformerConfiguration<R> informerConfig) {
.withFollowControllerNamespacesChanges(
informerConfig.getFollowControllerNamespaceChanges())
.withLabelSelector(informerConfig.getLabelSelector())
.withShardSelector(informerConfig.getShardSelector())
.withItemStore(informerConfig.getItemStore())
.withOnAddFilter(informerConfig.getOnAddFilter())
.withOnUpdateFilter(informerConfig.getOnUpdateFilter())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,18 @@ public void changeNamespaces(Set<String> namespaces) {
private InformerWrapper<R> createEventSourceForNamespace(String namespace) {
final InformerWrapper<R> source;
final var labelSelector = configuration.getInformerConfig().getLabelSelector();
final var shardSelector = configuration.getInformerConfig().getShardSelector();
if (namespace.equals(WATCH_ALL_NAMESPACES)) {
final var filteredBySelectorClient = client.inAnyNamespace().withLabelSelector(labelSelector);
final var filteredBySelectorClient =
client.inAnyNamespace().withLabelSelector(labelSelector).withShardSelector(shardSelector);
source = createEventSource(filteredBySelectorClient, eventHandler, WATCH_ALL_NAMESPACES);
} else {
source =
createEventSource(
client.inNamespace(namespace).withLabelSelector(labelSelector),
client
.inNamespace(namespace)
.withLabelSelector(labelSelector)
.withShardSelector(shardSelector),
eventHandler,
namespace);
}
Expand Down Expand Up @@ -265,12 +270,14 @@ public List<R> byIndex(String indexName, String indexKey) {
@Override
public String toString() {
final var informerConfig = configuration.getInformerConfig();
final var selector = informerConfig.getLabelSelector();
final var labelSelector = informerConfig.getLabelSelector();
final var shardSelector = informerConfig.getShardSelector();
return "InformerManager ["
+ ReconcilerUtilsInternal.getResourceTypeNameWithVersion(configuration.getResourceClass())
+ "] watching: "
+ informerConfig.getEffectiveNamespaces(controllerConfiguration)
+ (selector != null ? " selector: " + selector : "");
+ (labelSelector != null ? " label selector: " + labelSelector : "")
+ (shardSelector != null ? " shard selector: " + shardSelector : "");
}

public Map<String, InformerHealthIndicator> informerHealthIndicators() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,19 @@ void nullLabelSelectorByDefault() {
assertNull(informerConfig.getLabelSelector());
}

@Test
void nullShardSelectorByDefault() {
final var informerConfig = InformerConfiguration.builder(ConfigMap.class).build();
assertNull(informerConfig.getShardSelector());
}

@Test
void shardSelectorIsSetOnBuilder() {
final var informerConfig =
InformerConfiguration.builder(ConfigMap.class).withShardSelector("shard=1").build();
assertEquals("shard=1", informerConfig.getShardSelector());
}

@Test
void shouldWatchAllNamespacesByDefaultForControllers() {
final var informerConfig = InformerConfiguration.builder(ConfigMap.class).buildForController();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ public static ConfigLoader getDefault() {
ControllerConfigurationOverrider::withGenerationAware),
new ConfigBinding<>(
"label-selector", String.class, ControllerConfigurationOverrider::withLabelSelector),
new ConfigBinding<>(
"shard-selector", String.class, ControllerConfigurationOverrider::withShardSelector),
new ConfigBinding<>(
"max-reconciliation-interval",
Duration.class,
Expand All @@ -157,6 +159,10 @@ public static ConfigLoader getDefault() {
"informer.label-selector",
String.class,
ControllerConfigurationOverrider::withLabelSelector),
new ConfigBinding<>(
"informer.shard-selector",
String.class,
ControllerConfigurationOverrider::withShardSelector),
new ConfigBinding<>(
"informer.list-limit",
Long.class,
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
<sonar.host.url>https://sonarcloud.io</sonar.host.url>
<fabric8-httpclient-impl.name>jdk</fabric8-httpclient-impl.name>
<junit.version>6.0.3</junit.version>
<fabric8-client.version>7.7.0</fabric8-client.version>
<fabric8-client.version>999-SNAPSHOT</fabric8-client.version>
<slf4j.version>2.0.18</slf4j.version>
<log4j.version>2.26.0</log4j.version>
<mokito.version>5.23.0</mokito.version>
Expand Down
Loading