From 310ee915041566a204e803a2b9ab7b185fe6565f Mon Sep 17 00:00:00 2001
From: James Hewitt
Date: Fri, 14 Jul 2023 09:57:18 +0100
Subject: [PATCH] fix: Treat empty runtime namespaces as All Namespaces mode
If the runtime configuration specifies an empty string as the namespaces to watch, we should treat that as all namespaces mode, mainly because that's how OLM signifies that an operator should watch all namespaces.
An empty string is treated the same as unset by the configuration parser, so we need to set a default on the field so we can explicitly check for it being unset, to determine if the empty string was used.
Fixes #656
Signed-off-by: James Hewitt
---
.../runtime/ConfigurationServiceRecorder.java | 20 +++++++++++++++++--
.../operatorsdk/runtime/Constants.java | 14 +++++++++++++
.../runtime/RunTimeOperatorConfiguration.java | 7 ++++++-
.../pages/includes/quarkus-operator-sdk.adoc | 2 +-
4 files changed, 39 insertions(+), 4 deletions(-)
create mode 100644 core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/Constants.java
diff --git a/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/ConfigurationServiceRecorder.java b/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/ConfigurationServiceRecorder.java
index b616cc8b..498a984a 100644
--- a/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/ConfigurationServiceRecorder.java
+++ b/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/ConfigurationServiceRecorder.java
@@ -1,5 +1,8 @@
package io.quarkiverse.operatorsdk.runtime;
+import static io.javaoperatorsdk.operator.api.reconciler.Constants.DEFAULT_NAMESPACES_SET;
+import static io.quarkiverse.operatorsdk.runtime.Constants.QOSDK_USE_BUILDTIME_NAMESPACES_SET;
+
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
@@ -55,9 +58,22 @@ public Supplier configurationServiceSupplier(Versio
c.setRetryConfiguration(null);
}
- // if despite all of this, we still haven't set the namespaces, use the operator-level default if it exists
+ // if the namespaces weren't set as an annotation, use the operator-level configuration if it exists
if (!c.isWereNamespacesSet()) {
- runTimeConfiguration.namespaces.ifPresent(ns -> c.setNamespaces(new HashSet<>(ns)));
+ // The namespaces field has a default value so that we are able to detect if the configuration value is set to "".
+ // Setting the value to "" will reset the configuration and result in an empty Optional.
+ // Not setting the value at all will result in the default being applied, which we can test for.
+ if (runTimeConfiguration.namespaces.isPresent()) {
+ final var runtimeNamespaces = new HashSet<>(runTimeConfiguration.namespaces.get());
+ // If it's not the default value, use it because it was set.
+ // If it is the default value, ignore it and let any build time config be used.
+ if (!QOSDK_USE_BUILDTIME_NAMESPACES_SET.equals(runtimeNamespaces)) {
+ c.setNamespaces(runtimeNamespaces);
+ }
+ } else {
+ // Value has been explicitly reset (value was empty string), use all namespaces mode
+ c.setNamespaces(DEFAULT_NAMESPACES_SET);
+ }
}
});
diff --git a/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/Constants.java b/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/Constants.java
new file mode 100644
index 00000000..902dffa5
--- /dev/null
+++ b/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/Constants.java
@@ -0,0 +1,14 @@
+package io.quarkiverse.operatorsdk.runtime;
+
+import java.util.Collections;
+import java.util.Set;
+
+public final class Constants {
+ private Constants() {
+ }
+
+ public static final Set QOSDK_USE_BUILDTIME_NAMESPACES_SET = Collections
+ .singleton(Constants.QOSDK_USE_BUILDTIME_NAMESPACES);
+
+ public static final String QOSDK_USE_BUILDTIME_NAMESPACES = "QOSDK_USE_BUILDTIME_NAMESPACES";
+}
diff --git a/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/RunTimeOperatorConfiguration.java b/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/RunTimeOperatorConfiguration.java
index 490a258f..41c9d816 100644
--- a/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/RunTimeOperatorConfiguration.java
+++ b/core/runtime/src/main/java/io/quarkiverse/operatorsdk/runtime/RunTimeOperatorConfiguration.java
@@ -14,6 +14,8 @@
*/
package io.quarkiverse.operatorsdk.runtime;
+import static io.quarkiverse.operatorsdk.runtime.Constants.QOSDK_USE_BUILDTIME_NAMESPACES;
+
import java.time.Duration;
import java.util.List;
import java.util.Map;
@@ -59,7 +61,10 @@ public class RunTimeOperatorConfiguration {
* specified by the kube config file the operator uses.
*
*/
- @ConfigItem
+ // We use a default here so that we are able to detect if the configuration value is set to "". Setting the value to "" will
+ // reset the configuration and result in an empty Optional, but not setting the value at all will result in the default being
+ // applied.
+ @ConfigItem(defaultValue = QOSDK_USE_BUILDTIME_NAMESPACES)
public Optional> namespaces;
/**
diff --git a/docs/modules/ROOT/pages/includes/quarkus-operator-sdk.adoc b/docs/modules/ROOT/pages/includes/quarkus-operator-sdk.adoc
index 04c642be..252fff91 100644
--- a/docs/modules/ROOT/pages/includes/quarkus-operator-sdk.adoc
+++ b/docs/modules/ROOT/pages/includes/quarkus-operator-sdk.adoc
@@ -303,7 +303,7 @@ ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_OPERATOR_SDK_NAMESPACES+++`
endif::add-copy-button-to-env-var[]
--|list of string
-|
+|`QOSDK_USE_BUILDTIME_NAMESPACES`
a| [[quarkus-operator-sdk_quarkus.operator-sdk.concurrent-workflow-threads]]`link:#quarkus-operator-sdk_quarkus.operator-sdk.concurrent-workflow-threads[quarkus.operator-sdk.concurrent-workflow-threads]`