Skip to content

Commit

Permalink
fix: remove build time namespaces property
Browse files Browse the repository at this point in the history
When / if quarkusio/quarkus#34094 is
addressed, we should revisit this aspect of QOSDK. An alternative
solution would also be to extract the generation aspects of the
extension into its own module so that people could activate it on demand
via a maven profile, for example.
  • Loading branch information
metacosm committed Jun 16, 2023
1 parent 0a2561b commit 66a4b4c
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BooleanSupplier;
import java.util.function.Function;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -57,8 +58,18 @@ public class BundleProcessor {
public static final String CRD_DISPLAY_NAME = "CRD_DISPLAY_NAME";
public static final String CRD_DESCRIPTION = "CRD_DESCRIPTION";

private static class IsGenerationEnabled implements BooleanSupplier {

private BundleGenerationConfiguration config;

@Override
public boolean getAsBoolean() {
return config.enabled;
}
}

@SuppressWarnings({ "unused" })
@BuildStep
@BuildStep(onlyIf = IsGenerationEnabled.class)
CSVMetadataBuildItem gatherCSVMetadata(ApplicationInfoBuildItem configuration,
BundleGenerationConfiguration bundleConfiguration,
CombinedIndexBuildItem combinedIndexBuildItem) {
Expand Down Expand Up @@ -156,7 +167,7 @@ private String getMetadataOriginInformation(AnnotationInstance csvMetadataAnnota
}

@SuppressWarnings("unused")
@BuildStep
@BuildStep(onlyIf = IsGenerationEnabled.class)
void generateBundle(ApplicationInfoBuildItem configuration,
BundleGenerationConfiguration bundleConfiguration,
OutputTargetBuildItem outputTarget,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class BundleGenerationConfiguration {
/**
* Whether the extension should generate the Operator bundle.
*/
@ConfigItem(defaultValue = "true")
@ConfigItem(defaultValue = "false")
public Boolean enabled;

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
package io.quarkiverse.operatorsdk.deployment;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;

Expand Down Expand Up @@ -35,22 +29,4 @@ boolean generationAware() {
AnnotationValue::asBoolean,
() -> operatorConfiguration.generationAware.orElse(true));
}

Set<String> namespaces() {
HashSet<String> namespaces = null;
if (controllerAnnotation != null) {
namespaces = Optional.ofNullable(controllerAnnotation.value("namespaces"))
.map(v -> new HashSet<>(Arrays.asList(v.asStringArray())))
.orElse(null);
}

if (externalConfiguration != null) {
Optional<List<String>> overrideNamespaces = externalConfiguration.namespaces;
if (overrideNamespaces.isPresent()) {
namespaces = new HashSet<>(overrideNamespaces.get());
}
}

return namespaces;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ QuarkusControllerConfiguration build(ReconcilerAugmentedClassInfo reconcilerInfo
}

// extract the namespaces
var namespaces = configExtractor.namespaces();
Set<String> namespaces = ConfigurationUtils.annotationValueOrDefault(controllerAnnotation, "namespaces",
v -> new HashSet<>(Arrays.asList(v.asStringArray())), () -> null);
final boolean wereNamespacesSet;
if (namespaces == null) {
namespaces = io.javaoperatorsdk.operator.api.reconciler.Constants.DEFAULT_NAMESPACES_SET;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.quarkiverse.operatorsdk.deployment;

import java.util.function.BooleanSupplier;

import io.quarkiverse.operatorsdk.runtime.BuildTimeOperatorConfiguration;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.kubernetes.spi.DecoratorBuildItem;

public class RBACAugmentationStep {

private static class IsRBACEnabled implements BooleanSupplier {

private BuildTimeOperatorConfiguration config;

@Override
public boolean getAsBoolean() {
return !config.disableRbacGeneration;
}
}

@BuildStep(onlyIf = IsRBACEnabled.class)
void augmentRBACForResources(BuildTimeOperatorConfiguration buildTimeConfiguration,
BuildProducer<DecoratorBuildItem> decorators,
ControllerConfigurationsBuildItem configurations) {

final var configs = configurations.getControllerConfigs().values();
decorators.produce(new DecoratorBuildItem(
new AddClusterRolesDecorator(configs, buildTimeConfiguration.crd.validate)));
decorators.produce(new DecoratorBuildItem(
new AddRoleBindingsDecorator(configs, buildTimeConfiguration)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,29 @@ public class BuildTimeControllerConfiguration {
public Optional<Boolean> generationAware;

/**
* An optional list of comma-separated namespace names the controller should watch. If this
* property is left empty then the controller will watch all namespaces.
* An optional list of comma-separated watched namespace names that will be used to generate manifests at build time.
*
* <p>
* Note that this is provided as a means to quickly deploy a specific controller to test it by applying the generated
* manifests to the target cluster. If empty, no manifests will be generated. The namespace in which the controller will be
* deployed will
* be the currently configured namespace as specified by your {@code .kube/config} file, unless you specify the target
* deployment namespace using the {@code quarkus.kubernetes.namespace} property.
* </p>
*
* <p>
* As this functionality cannot handle namespaces that are not know until runtime (because the generation happens during
* build time), we recommend that you use a different mechanism such as OLM or Helm charts to deploy your operator in
* production.
* </p>
*
* <p>
* This replaces the previous {@code namespaces} property which was confusing and against Quarkus best practices since it
* existed both at build time and runtime. That property wasn't also adequately capturing the fact that namespaces that
* wouldn't be known until runtime would render whatever got generated at build time invalid as far as generated manifests
* were concerned.
* </p>
*/
@ConfigItem
public Optional<List<String>> namespaces;
public Optional<List<String>> generateWithWatchedNamespaces;
}
14 changes: 9 additions & 5 deletions docs/modules/ROOT/pages/includes/quarkus-operator-sdk.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -335,19 +335,23 @@ endif::add-copy-button-to-env-var[]
|`true`


a|icon:lock[title=Fixed at build time] [[quarkus-operator-sdk_quarkus.operator-sdk.controllers.-controllers-.namespaces]]`link:#quarkus-operator-sdk_quarkus.operator-sdk.controllers.-controllers-.namespaces[quarkus.operator-sdk.controllers."controllers".namespaces]`
a|icon:lock[title=Fixed at build time] [[quarkus-operator-sdk_quarkus.operator-sdk.controllers.-controllers-.generate-with-watched-namespaces]]`link:#quarkus-operator-sdk_quarkus.operator-sdk.controllers.-controllers-.generate-with-watched-namespaces[quarkus.operator-sdk.controllers."controllers".generate-with-watched-namespaces]`

[.description]
--
An optional list of comma-separated namespace names the controller should watch. If this property is left empty then the controller will watch all namespaces.
An optional list of comma-separated watched namespace names that will be used to generate manifests at build time.
Note that this is provided as a means to quickly deploy a specific controller to test it by applying the generated manifests to the target cluster. If empty, no manifests will be generated. The namespace in which the controller will be deployed will be the currently configured namespace as specified by your `.kube/config` file, unless you specify the target deployment namespace using the `quarkus.kubernetes.namespace` property.

As this functionality cannot handle namespaces that are not know until runtime (because the generation happens during build time), we recommend that you use a different mechanism such as OLM or Helm charts to deploy your operator in production.
This replaces the previous `namespaces` property which was confusing and against Quarkus best practices since it existed both at build time and runtime. That property wasn't also adequately capturing the fact that namespaces that wouldn't be known until runtime would render whatever got generated at build time invalid as far as generated manifests were concerned.

ifdef::add-copy-button-to-env-var[]
Environment variable: env_var_with_copy_button:+++QUARKUS_OPERATOR_SDK_CONTROLLERS__CONTROLLERS__NAMESPACES+++[]
Environment variable: env_var_with_copy_button:+++QUARKUS_OPERATOR_SDK_CONTROLLERS__CONTROLLERS__GENERATE_WITH_WATCHED_NAMESPACES+++[]
endif::add-copy-button-to-env-var[]
ifndef::add-copy-button-to-env-var[]
Environment variable: `+++QUARKUS_OPERATOR_SDK_CONTROLLERS__CONTROLLERS__NAMESPACES+++`
Environment variable: `+++QUARKUS_OPERATOR_SDK_CONTROLLERS__CONTROLLERS__GENERATE_WITH_WATCHED_NAMESPACES+++`
endif::add-copy-button-to-env-var[]
--|list of string
--|list of string
|


Expand Down

0 comments on commit 66a4b4c

Please sign in to comment.