From 0cb5cbe5d7775c6c523ef7bd7826f5fa097774aa Mon Sep 17 00:00:00 2001 From: Jakub Scholz Date: Mon, 19 Aug 2024 20:47:25 +0200 Subject: [PATCH] Update of unit tests to use KRaft - part 9 Signed-off-by: Jakub Scholz --- .../cluster/model/cruisecontrol/Capacity.java | 2 + .../cluster/model/CruiseControlTest.java | 1015 ++++++++--------- .../cluster/model/EntityOperatorTest.java | 545 ++++----- .../model/EntityTopicOperatorTest.java | 406 +++---- .../cluster/model/EntityUserOperatorTest.java | 451 ++++---- .../CruiseControlMetricsReporterTest.java | 33 +- .../HashLoginServiceApiCredentialsTest.java | 69 +- 7 files changed, 1120 insertions(+), 1401 deletions(-) diff --git a/cluster-operator/src/main/java/io/strimzi/operator/cluster/model/cruisecontrol/Capacity.java b/cluster-operator/src/main/java/io/strimzi/operator/cluster/model/cruisecontrol/Capacity.java index 15c830402d5..604cbeb4056 100644 --- a/cluster-operator/src/main/java/io/strimzi/operator/cluster/model/cruisecontrol/Capacity.java +++ b/cluster-operator/src/main/java/io/strimzi/operator/cluster/model/cruisecontrol/Capacity.java @@ -326,6 +326,8 @@ private static DiskCapacity generateDiskCapacity(Storage storage) { } else { return DiskCapacity.of(BrokerCapacity.DEFAULT_DISK_CAPACITY_IN_MIB); } + } else if (storage == null) { + throw new IllegalStateException("The storage declaration is missing"); } else { throw new IllegalStateException("The declared storage '" + storage.getType() + "' is not supported"); } diff --git a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/CruiseControlTest.java b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/CruiseControlTest.java index 62213094b10..b4ca620959b 100644 --- a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/CruiseControlTest.java +++ b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/CruiseControlTest.java @@ -36,17 +36,13 @@ import io.fabric8.kubernetes.api.model.networking.v1.NetworkPolicyPeer; import io.fabric8.kubernetes.api.model.networking.v1.NetworkPolicyPeerBuilder; import io.strimzi.api.kafka.model.common.ContainerEnvVar; -import io.strimzi.api.kafka.model.common.InlineLogging; import io.strimzi.api.kafka.model.common.JvmOptions; import io.strimzi.api.kafka.model.common.SystemPropertyBuilder; import io.strimzi.api.kafka.model.common.metrics.JmxPrometheusExporterMetricsBuilder; -import io.strimzi.api.kafka.model.common.metrics.MetricsConfig; import io.strimzi.api.kafka.model.common.template.AdditionalVolume; import io.strimzi.api.kafka.model.common.template.AdditionalVolumeBuilder; import io.strimzi.api.kafka.model.common.template.IpFamily; import io.strimzi.api.kafka.model.common.template.IpFamilyPolicy; -import io.strimzi.api.kafka.model.kafka.EphemeralStorage; -import io.strimzi.api.kafka.model.kafka.JbodStorage; import io.strimzi.api.kafka.model.kafka.JbodStorageBuilder; import io.strimzi.api.kafka.model.kafka.Kafka; import io.strimzi.api.kafka.model.kafka.KafkaBuilder; @@ -55,14 +51,15 @@ import io.strimzi.api.kafka.model.kafka.Storage; import io.strimzi.api.kafka.model.kafka.cruisecontrol.BrokerCapacityBuilder; import io.strimzi.api.kafka.model.kafka.cruisecontrol.CruiseControlResources; -import io.strimzi.api.kafka.model.kafka.cruisecontrol.CruiseControlSpec; -import io.strimzi.api.kafka.model.kafka.cruisecontrol.CruiseControlSpecBuilder; +import io.strimzi.api.kafka.model.kafka.listener.GenericKafkaListenerBuilder; +import io.strimzi.api.kafka.model.kafka.listener.KafkaListenerType; import io.strimzi.operator.cluster.KafkaVersionTestUtils; import io.strimzi.operator.cluster.PlatformFeaturesAvailability; import io.strimzi.operator.cluster.ResourceUtils; import io.strimzi.operator.cluster.model.cruisecontrol.BrokerCapacity; import io.strimzi.operator.cluster.model.cruisecontrol.Capacity; import io.strimzi.operator.cluster.model.cruisecontrol.CpuCapacity; +import io.strimzi.operator.common.Annotations; import io.strimzi.operator.common.Reconciliation; import io.strimzi.operator.common.model.Labels; import io.strimzi.operator.common.model.cruisecontrol.CruiseControlApiProperties; @@ -92,7 +89,6 @@ import static io.strimzi.operator.common.model.cruisecontrol.CruiseControlConfigurationParameters.DEFAULT_GOALS_CONFIG_KEY; import static java.lang.String.format; import static java.util.Collections.singletonList; -import static java.util.Collections.singletonMap; import static org.hamcrest.CoreMatchers.containsString; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.hasItem; @@ -112,133 +108,49 @@ }) @ParallelSuite public class CruiseControlTest { - private final static Set NODES = Set.of( - new NodeRef("foo-kafka-0", 0, "kafka", false, true), - new NodeRef("foo-kafka-1", 1, "kafka", false, true), - new NodeRef("foo-kafka-2", 2, "kafka", false, true)); - - private static final SharedEnvironmentProvider SHARED_ENV_PROVIDER = new MockSharedEnvironmentProvider(); - - private static final String NAMESPACE = "test"; - private static final String CLUSTER = "foo"; - private static final int REPLICAS = 1; - private static final String IMAGE = "my-image:latest"; - private static final int HEALTH_DELAY = 120; - private static final int HEALTH_TIMEOUT = 30; + private static final String NAMESPACE = "my-namespace"; + private static final String CLUSTER_NAME = "my-cluster"; private static final String REPLICATION_FACTOR = "3"; private static final String MIN_INSYNC_REPLICAS = "2"; - private static final String BROKER_CAPACITY_CPU = "6.0"; - private static final String BROKER_CAPACITY_OVERRIDE_CPU = "2.0"; - private static final String RESOURCE_LIMIT_CPU = "3.0"; - private static final String RESOURCE_REQUESTS_CPU = "4.0"; - - private final Map kafkaConfig = new HashMap<>() {{ - put(CruiseControl.MIN_INSYNC_REPLICAS, MIN_INSYNC_REPLICAS); - put(KafkaConfiguration.DEFAULT_REPLICATION_FACTOR, REPLICATION_FACTOR); - }}; - - private final Storage kafkaStorage = new EphemeralStorage(); - private final InlineLogging kafkaLogJson = new InlineLogging(); - private final InlineLogging zooLogJson = new InlineLogging(); + private static final SharedEnvironmentProvider SHARED_ENV_PROVIDER = new MockSharedEnvironmentProvider(); private static final KafkaVersion.Lookup VERSIONS = KafkaVersionTestUtils.getKafkaVersionLookup(); - private final String ccImage = "my-cruise-control-image"; - - { - kafkaLogJson.setLoggers(singletonMap("kafka.root.logger.level", "OFF")); - zooLogJson.setLoggers(singletonMap("zookeeper.root.logger", "OFF")); - } - private final CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withNewTemplate() - .withNewPod() - .withTmpDirSizeLimit("100Mi") - .endPod() - .endTemplate() + private static final Kafka KAFKA = new KafkaBuilder() + .withNewMetadata() + .withNamespace(NAMESPACE) + .withName(CLUSTER_NAME) + .withLabels(Map.of("my-user-label", "cromulent")) + .withAnnotations(Map.of(Annotations.ANNO_STRIMZI_IO_NODE_POOLS, "enabled", Annotations.ANNO_STRIMZI_IO_KRAFT, "enabled")) + .endMetadata() + .withNewSpec() + .withNewKafka() + .withListeners(new GenericKafkaListenerBuilder() + .withName("tls") + .withPort(9092) + .withType(KafkaListenerType.INTERNAL) + .withTls(true) + .build()) + .withConfig(Map.of(CruiseControl.MIN_INSYNC_REPLICAS, MIN_INSYNC_REPLICAS, KafkaConfiguration.DEFAULT_REPLICATION_FACTOR, REPLICATION_FACTOR)) + .endKafka() + .withNewCruiseControl() + .endCruiseControl() + .endSpec() .build(); + private static final Set NODES = Set.of( + new NodeRef("my-cluster-brokers-0", 0, "brokers", false, true), + new NodeRef("my-cluster-brokers-1", 1, "brokers", false, true), + new NodeRef("my-cluster-brokers-2", 2, "brokers", false, true) + ); + private static final Map STORAGE = Map.of("brokers", new JbodStorageBuilder().withVolumes(new PersistentClaimStorageBuilder().withId(0).withSize("100Gi").build()).build()); - private final Kafka kafka = createKafka(cruiseControlSpec); - private final CruiseControl cc = createCruiseControl(kafka); - - private Map createStorageMap(Kafka kafkaAssembly) { - Map storage = new HashMap<>(); - storage.put("kafka", kafkaAssembly.getSpec().getKafka().getStorage()); - - return storage; - } - - private Map createResourceRequirementsMap(Kafka kafkaAssembly) { - Map resources = new HashMap<>(); - resources.put("kafka", kafkaAssembly.getSpec().getKafka().getResources()); - - return resources; - } - private CruiseControl createCruiseControl(Kafka kafkaAssembly) { - return CruiseControl - .fromCrd( - Reconciliation.DUMMY_RECONCILIATION, - kafkaAssembly, - VERSIONS, - NODES, - createStorageMap(kafkaAssembly), - createResourceRequirementsMap(kafkaAssembly), - SHARED_ENV_PROVIDER - ); - } - - private Kafka createKafka(CruiseControlSpec cruiseControlSpec) { - return new KafkaBuilder(ResourceUtils.createKafka(NAMESPACE, CLUSTER, REPLICAS, IMAGE, HEALTH_DELAY, HEALTH_TIMEOUT)) - .editSpec() - .editKafka() - .withConfig(kafkaConfig) - .withStorage(kafkaStorage) - .endKafka() - .withCruiseControl(cruiseControlSpec) - .endSpec() - .build(); - } - - private Map expectedLabels(String name) { - return TestUtils.map(Labels.STRIMZI_CLUSTER_LABEL, CLUSTER, - "my-user-label", "cromulent", - Labels.STRIMZI_KIND_LABEL, Kafka.RESOURCE_KIND, - Labels.STRIMZI_NAME_LABEL, name, - Labels.STRIMZI_COMPONENT_TYPE_LABEL, CruiseControl.COMPONENT_TYPE, - Labels.KUBERNETES_NAME_LABEL, CruiseControl.COMPONENT_TYPE, - Labels.KUBERNETES_INSTANCE_LABEL, CLUSTER, - Labels.KUBERNETES_PART_OF_LABEL, Labels.APPLICATION_NAME + "-" + CLUSTER, - Labels.KUBERNETES_MANAGED_BY_LABEL, AbstractModel.STRIMZI_CLUSTER_OPERATOR_NAME); - } - - private Map expectedSelectorLabels() { - return Labels.fromMap(expectedLabels()).strimziSelectorLabels().toMap(); - } - - private Map expectedLabels() { - return expectedLabels(CruiseControlResources.componentName(CLUSTER)); - } - - private List getExpectedEnvVars() { - List expected = new ArrayList<>(); - expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_CRUISE_CONTROL_METRICS_ENABLED).withValue(Boolean.toString(CruiseControl.DEFAULT_CRUISE_CONTROL_METRICS_ENABLED)).build()); - expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_STRIMZI_KAFKA_BOOTSTRAP_SERVERS).withValue(KafkaResources.bootstrapServiceName(CLUSTER) + ":" + KafkaCluster.REPLICATION_PORT).build()); - expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_STRIMZI_KAFKA_GC_LOG_ENABLED).withValue(Boolean.toString(JvmOptions.DEFAULT_GC_LOGGING_ENABLED)).build()); - expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_API_SSL_ENABLED).withValue(Boolean.toString(CruiseControlConfigurationParameters.DEFAULT_WEBSERVER_SSL_ENABLED)).build()); - expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_API_AUTH_ENABLED).withValue(Boolean.toString(CruiseControlConfigurationParameters.DEFAULT_WEBSERVER_SECURITY_ENABLED)).build()); - expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_API_HEALTHCHECK_USERNAME).withValue(CruiseControlApiProperties.HEALTHCHECK_USERNAME).build()); - expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_API_PORT).withValue(Integer.toString(CruiseControl.REST_API_PORT)).build()); - expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_API_HEALTHCHECK_PATH).withValue(API_HEALTHCHECK_PATH).build()); - expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_KAFKA_HEAP_OPTS).withValue("-Xms" + JvmOptionUtils.DEFAULT_JVM_XMS).build()); - return expected; - } - - private static boolean isJBOD(Object diskCapacity) { - return diskCapacity instanceof JsonObject; + @AfterAll + public static void cleanUp() { + ResourceUtils.cleanUpTemporaryTLSFiles(); } @ParallelTest - public void testBrokerCapacities() { + public void testBrokerCapacity() { // Test user defined capacities String userDefinedCpuCapacity = "2575m"; JsonObject expectedCpuCapacity = new CpuCapacity(userDefinedCpuCapacity).getJson(); @@ -248,40 +160,21 @@ public void testBrokerCapacities() { userDefinedBrokerCapacity.setInboundNetwork("50000KB/s"); userDefinedBrokerCapacity.setOutboundNetwork("50000KB/s"); - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withBrokerCapacity(userDefinedBrokerCapacity) + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withBrokerCapacity(userDefinedBrokerCapacity) + .endCruiseControl() + .endSpec() .build(); + Map storage = Map.of("brokers", new JbodStorageBuilder().withVolumes(new PersistentClaimStorageBuilder().withId(0).withSize("50Gi").build(), new PersistentClaimStorageBuilder().withId(1).withSize("60Gi").build()).build()); + Map resources = Map.of("brokers", new ResourceRequirementsBuilder().withRequests(Map.of(Capacity.RESOURCE_TYPE, new Quantity("400m"))).withLimits(Map.of(Capacity.RESOURCE_TYPE, new Quantity("0.5"))).build()); + CruiseControl cc = createCruiseControl(kafka, NODES, storage, resources); - Kafka resource = createKafka(cruiseControlSpec); - - // Test generated disk capacity - JbodStorage jbodStorage = new JbodStorageBuilder() - .withVolumes( - new PersistentClaimStorageBuilder().withDeleteClaim(true).withId(0).withSize("50Gi").build(), - new PersistentClaimStorageBuilder().withDeleteClaim(true).withId(1).build() - ).build(); - - Map requests = Map.of(Capacity.RESOURCE_TYPE, new Quantity("400m")); - Map limits = Map.of(Capacity.RESOURCE_TYPE, new Quantity("0.5")); - - resource = new KafkaBuilder(ResourceUtils.createKafka(NAMESPACE, CLUSTER, REPLICAS, IMAGE, HEALTH_DELAY, HEALTH_TIMEOUT)) - .editSpec() - .editKafka() - .withVersion(KafkaVersionTestUtils.DEFAULT_KAFKA_VERSION) - .withConfig(kafkaConfig) - .withStorage(jbodStorage) - .withResources(new ResourceRequirementsBuilder().withRequests(requests).withLimits(limits).build()) - .endKafka() - .withCruiseControl(cruiseControlSpec) - .endSpec() - .build(); - - CruiseControl cc = createCruiseControl(resource); ConfigMap configMap = cc.generateConfigMap(new MetricsAndLogging(null, null)); - JsonObject capacity = new JsonObject(configMap.getData().get(CruiseControl.CAPACITY_CONFIG_FILENAME)); JsonArray brokerEntries = capacity.getJsonArray(Capacity.CAPACITIES_KEY); + for (Object brokerEntry : brokerEntries) { JsonObject brokerCapacity = ((JsonObject) brokerEntry).getJsonObject(Capacity.CAPACITY_KEY); Object diskCapacity = brokerCapacity.getValue(Capacity.DISK_KEY); @@ -290,8 +183,12 @@ public void testBrokerCapacities() { assertThat(isJBOD(diskCapacity), is(true)); assertThat(cpuCapacity, is(expectedCpuCapacity)); } + } + @ParallelTest + public void testBrokerCapacityOverrides() { // Test capacity overrides + String userDefinedCpuCapacity = "2575m"; String userDefinedCpuCapacityOverride0 = "1.222"; String inboundNetwork = "50000KB/s"; String inboundNetworkOverride0 = "25000KB/s"; @@ -305,30 +202,33 @@ public void testBrokerCapacities() { List overrideList0 = List.of(broker0, broker1, broker2, broker0); List overrideList1 = List.of(broker1); - cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withNewBrokerCapacity() - .withCpu(userDefinedCpuCapacity) - .withInboundNetwork(inboundNetwork) - .addNewOverride() - .withBrokers(overrideList0) - .withCpu(userDefinedCpuCapacityOverride0) - .withInboundNetwork(inboundNetworkOverride0) - .endOverride() - .addNewOverride() - .withBrokers(overrideList1) - .withInboundNetwork(inboundNetworkOverride1) - .withOutboundNetwork(outboundNetworkOverride1) - .endOverride() - .endBrokerCapacity() - .build(); - - resource = createKafka(cruiseControlSpec); - cc = createCruiseControl(resource); - configMap = cc.generateConfigMap(new MetricsAndLogging(null, null)); + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withNewBrokerCapacity() + .withCpu(userDefinedCpuCapacity) + .withInboundNetwork(inboundNetwork) + .addNewOverride() + .withBrokers(overrideList0) + .withCpu(userDefinedCpuCapacityOverride0) + .withInboundNetwork(inboundNetworkOverride0) + .endOverride() + .addNewOverride() + .withBrokers(overrideList1) + .withInboundNetwork(inboundNetworkOverride1) + .withOutboundNetwork(outboundNetworkOverride1) + .endOverride() + .endBrokerCapacity() + .endCruiseControl() + .endSpec() + .build(); + Map storage = Map.of("brokers", new PersistentClaimStorageBuilder().withId(0).withSize("50Gi").build()); + Map resources = Map.of("brokers", new ResourceRequirementsBuilder().withRequests(Map.of(Capacity.RESOURCE_TYPE, new Quantity("400m"))).withLimits(Map.of(Capacity.RESOURCE_TYPE, new Quantity("0.5"))).build()); + CruiseControl cc = createCruiseControl(kafka, NODES, storage, resources); - capacity = new JsonObject(configMap.getData().get(CruiseControl.CAPACITY_CONFIG_FILENAME)); - brokerEntries = capacity.getJsonArray(Capacity.CAPACITIES_KEY); + ConfigMap configMap = cc.generateConfigMap(new MetricsAndLogging(null, null)); + JsonObject capacity = new JsonObject(configMap.getData().get(CruiseControl.CAPACITY_CONFIG_FILENAME)); + JsonArray brokerEntries = capacity.getJsonArray(Capacity.CAPACITIES_KEY); for (Object brokerEntry : brokerEntries) { JsonObject brokerCapacity = ((JsonObject) brokerEntry).getJsonObject(Capacity.CAPACITY_KEY); @@ -349,34 +249,54 @@ public void testBrokerCapacities() { assertThat(brokerEntry1.getString(Capacity.OUTBOUND_NETWORK_KEY), is(BrokerCapacity.DEFAULT_OUTBOUND_NETWORK_CAPACITY_IN_KIB_PER_SECOND)); JsonObject brokerEntry2 = brokerEntries.getJsonObject(broker2).getJsonObject(Capacity.CAPACITY_KEY); - assertThat(brokerEntry1.getJsonObject(Capacity.CPU_KEY), is(new CpuCapacity(userDefinedCpuCapacityOverride0).getJson())); - assertThat(brokerEntry1.getString(Capacity.INBOUND_NETWORK_KEY), is(Capacity.getThroughputInKiB(inboundNetworkOverride0))); + assertThat(brokerEntry2.getJsonObject(Capacity.CPU_KEY), is(new CpuCapacity(userDefinedCpuCapacityOverride0).getJson())); + assertThat(brokerEntry2.getString(Capacity.INBOUND_NETWORK_KEY), is(Capacity.getThroughputInKiB(inboundNetworkOverride0))); + } - // Test generated CPU capacity - userDefinedCpuCapacity = "500m"; - - requests = Map.of(Capacity.RESOURCE_TYPE, new Quantity(userDefinedCpuCapacity)); - limits = Map.of(Capacity.RESOURCE_TYPE, new Quantity("0.5")); - - resource = new KafkaBuilder(ResourceUtils.createKafka(NAMESPACE, CLUSTER, REPLICAS, IMAGE, HEALTH_DELAY, HEALTH_TIMEOUT)) - .editSpec() - .editKafka() - .withVersion(KafkaVersionTestUtils.DEFAULT_KAFKA_VERSION) - .withStorage(jbodStorage) - .withResources(new ResourceRequirementsBuilder().withRequests(requests).withLimits(limits).build()) - .withConfig(kafkaConfig) - .endKafka() - .withCruiseControl(cruiseControlSpec) - .endSpec() - .build(); + @ParallelTest + public void testBrokerCapacityGeneratedCpu() { + String userDefinedCpuCapacity = "2575m"; + String userDefinedCpuCapacityOverride0 = "1.222"; + String inboundNetwork = "50000KB/s"; + String inboundNetworkOverride0 = "25000KB/s"; + String inboundNetworkOverride1 = "10000KiB/s"; + String outboundNetworkOverride1 = "15000KB/s"; - cc = createCruiseControl(resource); - configMap = cc.generateConfigMap(new MetricsAndLogging(null, null)); - capacity = new JsonObject(configMap.getData().get(CruiseControl.CAPACITY_CONFIG_FILENAME)); + int broker0 = 0; + int broker1 = 1; + int broker2 = 2; - expectedCpuCapacity = new CpuCapacity(userDefinedCpuCapacityOverride0).getJson(); + List overrideList0 = List.of(broker0, broker1, broker2, broker0); + List overrideList1 = List.of(broker1); + + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withNewBrokerCapacity() + .withCpu(userDefinedCpuCapacity) + .withInboundNetwork(inboundNetwork) + .addNewOverride() + .withBrokers(overrideList0) + .withCpu(userDefinedCpuCapacityOverride0) + .withInboundNetwork(inboundNetworkOverride0) + .endOverride() + .addNewOverride() + .withBrokers(overrideList1) + .withInboundNetwork(inboundNetworkOverride1) + .withOutboundNetwork(outboundNetworkOverride1) + .endOverride() + .endBrokerCapacity() + .endCruiseControl() + .endSpec() + .build(); + Map storage = Map.of("brokers", new JbodStorageBuilder().withVolumes(new PersistentClaimStorageBuilder().withId(0).withSize("50Gi").build(), new PersistentClaimStorageBuilder().withId(1).withSize("60Gi").build()).build()); + Map resources = Map.of("brokers", new ResourceRequirementsBuilder().withRequests(Map.of(Capacity.RESOURCE_TYPE, new Quantity("500m"))).withLimits(Map.of(Capacity.RESOURCE_TYPE, new Quantity("0.5"))).build()); + CruiseControl cc = createCruiseControl(kafka, NODES, storage, resources); - brokerEntries = capacity.getJsonArray(Capacity.CAPACITIES_KEY); + ConfigMap configMap = cc.generateConfigMap(new MetricsAndLogging(null, null)); + JsonObject capacity = new JsonObject(configMap.getData().get(CruiseControl.CAPACITY_CONFIG_FILENAME)); + JsonObject expectedCpuCapacity = new CpuCapacity(userDefinedCpuCapacityOverride0).getJson(); + JsonArray brokerEntries = capacity.getJsonArray(Capacity.CAPACITIES_KEY); for (Object brokerEntry : brokerEntries) { JsonObject brokerCapacity = ((JsonObject) brokerEntry).getJsonObject(Capacity.CAPACITY_KEY); JsonObject cpuCapacity = brokerCapacity.getJsonObject(Capacity.CPU_KEY); @@ -387,12 +307,12 @@ public void testBrokerCapacities() { @ParallelTest public void testBrokerCapacitiesWithPools() { Set nodes = Set.of( - new NodeRef("foo-pool1-0", 0, "pool1", false, true), - new NodeRef("foo-pool1-1", 1, "pool1", false, true), - new NodeRef("foo-pool1-2", 2, "pool1", false, true), - new NodeRef("foo-pool2-10", 10, "pool2", false, true), - new NodeRef("foo-pool2-11", 11, "pool2", false, true), - new NodeRef("foo-pool2-12", 12, "pool2", false, true) + new NodeRef("my-cluster-pool1-0", 0, "pool1", false, true), + new NodeRef("my-cluster-pool1-1", 1, "pool1", false, true), + new NodeRef("my-cluster-pool1-2", 2, "pool1", false, true), + new NodeRef("my-cluster-pool2-10", 10, "pool2", false, true), + new NodeRef("my-cluster-pool2-11", 11, "pool2", false, true), + new NodeRef("my-cluster-pool2-12", 12, "pool2", false, true) ); Map storage = new HashMap<>(); @@ -404,7 +324,7 @@ public void testBrokerCapacitiesWithPools() { resources.put("pool2", new ResourceRequirementsBuilder().withLimits(Map.of("cpu", new Quantity("5"), "memory", new Quantity("20Gi"))).build()); // Test the capacity - CruiseControl cc = CruiseControl.fromCrd(Reconciliation.DUMMY_RECONCILIATION, kafka, VERSIONS, nodes, storage, resources, SHARED_ENV_PROVIDER); + CruiseControl cc = createCruiseControl(KAFKA, nodes, storage, resources); ConfigMap configMap = cc.generateConfigMap(new MetricsAndLogging(null, null)); JsonObject capacity = new JsonObject(configMap.getData().get(CruiseControl.CAPACITY_CONFIG_FILENAME)); JsonArray brokerEntries = capacity.getJsonArray(Capacity.CAPACITIES_KEY); @@ -462,25 +382,46 @@ public void testBrokerCapacitiesWithPools() { @ParallelTest public void testFromConfigMap() { + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withImage("my-image:latest") + .endCruiseControl() + .endSpec() + .build(); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); + assertThat(cc.namespace, is(NAMESPACE)); - assertThat(cc.cluster, is(CLUSTER)); - assertThat(cc.getImage(), is(ccImage)); + assertThat(cc.cluster, is(CLUSTER_NAME)); + assertThat(cc.getImage(), is("my-image:latest")); } @ParallelTest public void testGenerateDeployment() { + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withNewTemplate() + .withNewPod() + .withTmpDirSizeLimit("100Mi") + .endPod() + .endTemplate() + .endCruiseControl() + .endSpec() + .build(); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); + Deployment dep = cc.generateDeployment(Map.of(), true, null, null); + assertThat(dep.getMetadata().getName(), is(CruiseControlResources.componentName(CLUSTER_NAME))); + assertThat(dep.getMetadata().getNamespace(), is(NAMESPACE)); + assertThat(dep.getSpec().getTemplate().getSpec().getSecurityContext(), is(nullValue())); + TestUtils.checkOwnerReference(dep, kafka); List containers = dep.getSpec().getTemplate().getSpec().getContainers(); - assertThat(containers.size(), is(1)); - assertThat(dep.getMetadata().getName(), is(CruiseControlResources.componentName(CLUSTER))); - assertThat(dep.getMetadata().getNamespace(), is(NAMESPACE)); - TestUtils.checkOwnerReference(dep, kafka); - // checks on the main Cruise Control container - Container ccContainer = containers.stream().filter(container -> ccImage.equals(container.getImage())).findFirst().orElseThrow(); + Container ccContainer = containers.get(0); assertThat(ccContainer.getImage(), is(cc.image)); assertThat(ccContainer.getLivenessProbe().getInitialDelaySeconds(), is(15)); assertThat(ccContainer.getLivenessProbe().getTimeoutSeconds(), is(5)); @@ -499,15 +440,15 @@ public void testGenerateDeployment() { Volume volume = volumes.stream().filter(vol -> CruiseControl.TLS_CC_CERTS_VOLUME_NAME.equals(vol.getName())).findFirst().orElseThrow(); assertThat(volume, is(notNullValue())); - assertThat(volume.getSecret().getSecretName(), is(CruiseControlResources.secretName(CLUSTER))); + assertThat(volume.getSecret().getSecretName(), is(CruiseControlResources.secretName(CLUSTER_NAME))); volume = volumes.stream().filter(vol -> CruiseControl.TLS_CA_CERTS_VOLUME_NAME.equals(vol.getName())).findFirst().orElseThrow(); assertThat(volume, is(notNullValue())); - assertThat(volume.getSecret().getSecretName(), is(AbstractModel.clusterCaCertSecretName(CLUSTER))); + assertThat(volume.getSecret().getSecretName(), is(AbstractModel.clusterCaCertSecretName(CLUSTER_NAME))); volume = volumes.stream().filter(vol -> CruiseControl.API_AUTH_CONFIG_VOLUME_NAME.equals(vol.getName())).findFirst().orElseThrow(); assertThat(volume, is(notNullValue())); - assertThat(volume.getSecret().getSecretName(), is(CruiseControlResources.apiSecretName(CLUSTER))); + assertThat(volume.getSecret().getSecretName(), is(CruiseControlResources.apiSecretName(CLUSTER_NAME))); volume = volumes.stream().filter(vol -> VolumeUtils.STRIMZI_TMP_DIRECTORY_DEFAULT_VOLUME_NAME.equals(vol.getName())).findFirst().orElseThrow(); assertThat(volume, is(notNullValue())); @@ -516,7 +457,7 @@ public void testGenerateDeployment() { volume = volumes.stream().filter(vol -> CruiseControl.CONFIG_VOLUME_NAME.equals(vol.getName())).findFirst().orElseThrow(); assertThat(volume, is(notNullValue())); - assertThat(volume.getConfigMap().getName(), is(CruiseControlResources.configMapName(CLUSTER))); + assertThat(volume.getConfigMap().getName(), is(CruiseControlResources.configMapName(CLUSTER_NAME))); // Test volume mounts List volumesMounts = dep.getSpec().getTemplate().getSpec().getContainers().get(0).getVolumeMounts(); @@ -545,51 +486,19 @@ public void testGenerateDeployment() { @ParallelTest public void testEnvVars() { + CruiseControl cc = createCruiseControl(KAFKA, NODES, STORAGE, Map.of()); assertThat(cc.getEnvVars(), is(getExpectedEnvVars())); } @ParallelTest public void testImagePullPolicy() { + CruiseControl cc = createCruiseControl(KAFKA, NODES, STORAGE, Map.of()); + Deployment dep = cc.generateDeployment(Map.of(), true, ImagePullPolicy.ALWAYS, null); - List containers = dep.getSpec().getTemplate().getSpec().getContainers(); - Container ccContainer = containers.stream().filter(container -> ccImage.equals(container.getImage())).findFirst().orElseThrow(); - assertThat(ccContainer.getImagePullPolicy(), is(ImagePullPolicy.ALWAYS.toString())); + assertThat(dep.getSpec().getTemplate().getSpec().getContainers().get(0).getImagePullPolicy(), is(ImagePullPolicy.ALWAYS.toString())); dep = cc.generateDeployment(Map.of(), true, ImagePullPolicy.IFNOTPRESENT, null); - containers = dep.getSpec().getTemplate().getSpec().getContainers(); - ccContainer = containers.stream().filter(container -> ccImage.equals(container.getImage())).findFirst().orElseThrow(); - assertThat(ccContainer.getImagePullPolicy(), is(ImagePullPolicy.IFNOTPRESENT.toString())); - } - - @ParallelTest - public void testContainerTemplateEnvVars() { - ContainerEnvVar envVar1 = new ContainerEnvVar(); - String testEnvOneKey = "TEST_ENV_1"; - String testEnvOneValue = "test.env.one"; - envVar1.setName(testEnvOneKey); - envVar1.setValue(testEnvOneValue); - - ContainerEnvVar envVar2 = new ContainerEnvVar(); - String testEnvTwoKey = "TEST_ENV_2"; - String testEnvTwoValue = "test.env.two"; - envVar2.setName(testEnvTwoKey); - envVar2.setValue(testEnvTwoValue); - - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withNewTemplate() - .withNewCruiseControlContainer() - .withEnv(envVar1, envVar2) - .endCruiseControlContainer() - .endTemplate() - .build(); - - Kafka resource = createKafka(cruiseControlSpec); - CruiseControl cc = createCruiseControl(resource); - List envVarList = cc.getEnvVars(); - - assertThat(envVarList, hasItems(new EnvVar(testEnvOneKey, testEnvOneValue, null))); - assertThat(envVarList, hasItems(new EnvVar(testEnvTwoKey, testEnvTwoValue, null))); + assertThat(dep.getSpec().getTemplate().getSpec().getContainers().get(0).getImagePullPolicy(), is(ImagePullPolicy.IFNOTPRESENT.toString())); } @ParallelTest @@ -601,40 +510,46 @@ public void testContainerTemplateEnvVarsWithKeyConflict() { envVar1.setValue(testEnvOneValue); ContainerEnvVar envVar2 = new ContainerEnvVar(); - String testEnvTwoKey = "TEST_ENV_2"; + String testEnvTwoKey = "STRIMZI_KAFKA_BOOTSTRAP_SERVERS"; String testEnvTwoValue = "my-special-value"; envVar2.setName(testEnvTwoKey); envVar2.setValue(testEnvTwoValue); - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withNewTemplate() - .withNewCruiseControlContainer() - .withEnv(envVar1, envVar2) - .endCruiseControlContainer() - .endTemplate() + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withNewTemplate() + .withNewCruiseControlContainer() + .withEnv(envVar1, envVar2) + .endCruiseControlContainer() + .endTemplate() + .endCruiseControl() + .endSpec() .build(); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); - Kafka resource = createKafka(cruiseControlSpec); - CruiseControl cc = createCruiseControl(resource); List envVarList = cc.getEnvVars(); - assertThat(envVarList, hasItems(new EnvVar(testEnvOneKey, testEnvOneValue, null))); - assertThat(envVarList, hasItems(new EnvVar(testEnvTwoKey, testEnvTwoValue, null))); + assertThat(envVarList, hasItems(new EnvVar(testEnvTwoKey, "my-cluster-kafka-bootstrap:9091", null))); } @ParallelTest public void testCruiseControlNotDeployed() { - Kafka kafka = createKafka(null); - assertThat(createCruiseControl(kafka), is(nullValue())); + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withCruiseControl(null) + .endSpec() + .build(); + assertThat(createCruiseControl(kafka, NODES, STORAGE, Map.of()), is(nullValue())); } @ParallelTest public void testGenerateService() { + CruiseControl cc = createCruiseControl(KAFKA, NODES, STORAGE, Map.of()); Service svc = cc.generateService(); assertThat(svc.getSpec().getType(), is("ClusterIP")); - assertThat(svc.getMetadata().getLabels(), is(expectedLabels(CruiseControlResources.serviceName(CLUSTER)))); + assertThat(svc.getMetadata().getLabels(), is(expectedLabels(CruiseControlResources.serviceName(CLUSTER_NAME)))); assertThat(svc.getSpec().getSelector(), is(expectedSelectorLabels())); assertThat(svc.getSpec().getPorts().size(), is(1)); assertThat(svc.getSpec().getPorts().get(0).getName(), is(CruiseControl.REST_API_PORT_NAME)); @@ -643,22 +558,23 @@ public void testGenerateService() { assertThat(svc.getSpec().getIpFamilyPolicy(), is(nullValue())); assertThat(svc.getSpec().getIpFamilies(), is(nullValue())); - TestUtils.checkOwnerReference(svc, kafka); + TestUtils.checkOwnerReference(svc, KAFKA); } + @SuppressWarnings("MethodLength") @ParallelTest public void testTemplate() { Map depLabels = TestUtils.map("l1", "v1", "l2", "v2"); - Map depAnots = TestUtils.map("a1", "v1", "a2", "v2"); + Map depAnnotations = TestUtils.map("a1", "v1", "a2", "v2"); Map podLabels = TestUtils.map("l3", "v3", "l4", "v4"); - Map podAnots = TestUtils.map("a3", "v3", "a4", "v4"); + Map podAnnotations = TestUtils.map("a3", "v3", "a4", "v4"); Map svcLabels = TestUtils.map("l5", "v5", "l6", "v6"); - Map svcAnots = TestUtils.map("a5", "v5", "a6", "v6"); + Map svcAnnotations = TestUtils.map("a5", "v5", "a6", "v6"); Map saLabels = TestUtils.map("l7", "v7", "l8", "v8"); - Map saAnots = TestUtils.map("a7", "v7", "a8", "v8"); + Map saAnnotations = TestUtils.map("a7", "v7", "a8", "v8"); Affinity affinity = new AffinityBuilder() .withNewNodeAffinity() @@ -705,60 +621,74 @@ public void testTemplate() { .withSubPath("def") .build()); - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withNewTemplate() - .withNewDeployment() - .withNewMetadata() - .withLabels(depLabels) - .withAnnotations(depAnots) - .endMetadata() - .endDeployment() - .withNewPod() - .withNewMetadata() - .withLabels(podLabels) - .withAnnotations(podAnots) - .endMetadata() - .withPriorityClassName("top-priority") - .withSchedulerName("my-scheduler") - .withHostAliases(hostAlias1, hostAlias2) - .withAffinity(affinity) - .withTolerations(tolerations) - .withVolumes(additionalVolumes) - .endPod() - .withNewCruiseControlContainer() - .withVolumeMounts(additionalVolumeMounts) - .endCruiseControlContainer() - .withNewApiService() - .withNewMetadata() - .withLabels(svcLabels) - .withAnnotations(svcAnots) - .endMetadata() - .withIpFamilyPolicy(IpFamilyPolicy.PREFER_DUAL_STACK) - .withIpFamilies(IpFamily.IPV6, IpFamily.IPV4) - .endApiService() - .withNewServiceAccount() - .withNewMetadata() - .withLabels(saLabels) - .withAnnotations(saAnots) - .endMetadata() - .endServiceAccount() - .endTemplate() - .build(); + ContainerEnvVar envVar1 = new ContainerEnvVar(); + String testEnvOneKey = "TEST_ENV_1"; + String testEnvOneValue = "test.env.one"; + envVar1.setName(testEnvOneKey); + envVar1.setValue(testEnvOneValue); + + ContainerEnvVar envVar2 = new ContainerEnvVar(); + String testEnvTwoKey = "TEST_ENV_2"; + String testEnvTwoValue = "my-special-value"; + envVar2.setName(testEnvTwoKey); + envVar2.setValue(testEnvTwoValue); - Kafka resource = createKafka(cruiseControlSpec); - CruiseControl cc = createCruiseControl(resource); + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withNewTemplate() + .withNewDeployment() + .withNewMetadata() + .withLabels(depLabels) + .withAnnotations(depAnnotations) + .endMetadata() + .endDeployment() + .withNewPod() + .withNewMetadata() + .withLabels(podLabels) + .withAnnotations(podAnnotations) + .endMetadata() + .withPriorityClassName("top-priority") + .withSchedulerName("my-scheduler") + .withHostAliases(hostAlias1, hostAlias2) + .withAffinity(affinity) + .withTolerations(tolerations) + .withVolumes(additionalVolumes) + .endPod() + .withNewCruiseControlContainer() + .withVolumeMounts(additionalVolumeMounts) + .withEnv(envVar1, envVar2) + .endCruiseControlContainer() + .withNewApiService() + .withNewMetadata() + .withLabels(svcLabels) + .withAnnotations(svcAnnotations) + .endMetadata() + .withIpFamilyPolicy(IpFamilyPolicy.PREFER_DUAL_STACK) + .withIpFamilies(IpFamily.IPV6, IpFamily.IPV4) + .endApiService() + .withNewServiceAccount() + .withNewMetadata() + .withLabels(saLabels) + .withAnnotations(saAnnotations) + .endMetadata() + .endServiceAccount() + .endTemplate() + .endCruiseControl() + .endSpec() + .build(); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); // Check Deployment Deployment dep = cc.generateDeployment(Map.of(), true, null, null); depLabels.putAll(expectedLabels()); assertThat(dep.getMetadata().getLabels(), is(depLabels)); - assertThat(dep.getMetadata().getAnnotations(), is(depAnots)); + assertThat(dep.getMetadata().getAnnotations(), is(depAnnotations)); // Check Pods podLabels.putAll(expectedLabels()); assertThat(dep.getSpec().getTemplate().getMetadata().getLabels(), is(podLabels)); - assertThat(dep.getSpec().getTemplate().getMetadata().getAnnotations(), is(podAnots)); + assertThat(dep.getSpec().getTemplate().getMetadata().getAnnotations(), is(podAnnotations)); assertThat(dep.getSpec().getTemplate().getSpec().getPriorityClassName(), is("top-priority")); assertThat(dep.getSpec().getTemplate().getSpec().getSchedulerName(), is("my-scheduler")); assertThat(dep.getSpec().getTemplate().getSpec().getAffinity(), is(affinity)); @@ -766,19 +696,24 @@ public void testTemplate() { assertThat(dep.getSpec().getTemplate().getSpec().getHostAliases(), containsInAnyOrder(hostAlias1, hostAlias2)); assertThat(dep.getSpec().getTemplate().getSpec().getVolumes().stream().filter(volume -> "secret-volume-name".equals(volume.getName())).iterator().next().getSecret(), is(secret)); assertThat(dep.getSpec().getTemplate().getSpec().getContainers().get(0).getVolumeMounts().stream().filter(volumeMount -> "secret-volume-name".equals(volumeMount.getName())).iterator().next(), is(additionalVolumeMounts.get(0))); - + + // Check Env Vars + List envVarList = cc.getEnvVars(); + assertThat(envVarList, hasItems(new EnvVar(testEnvOneKey, testEnvOneValue, null))); + assertThat(envVarList, hasItems(new EnvVar(testEnvTwoKey, testEnvTwoValue, null))); + // Check Service svcLabels.putAll(expectedLabels()); Service svc = cc.generateService(); assertThat(svc.getMetadata().getLabels(), is(svcLabels)); - assertThat(svc.getMetadata().getAnnotations(), is(svcAnots)); + assertThat(svc.getMetadata().getAnnotations(), is(svcAnnotations)); assertThat(svc.getSpec().getIpFamilyPolicy(), is("PreferDualStack")); assertThat(svc.getSpec().getIpFamilies(), contains("IPv6", "IPv4")); // Check Service Account ServiceAccount sa = cc.generateServiceAccount(); assertThat(sa.getMetadata().getLabels().entrySet().containsAll(saLabels.entrySet()), is(true)); - assertThat(sa.getMetadata().getAnnotations().entrySet().containsAll(saAnots.entrySet()), is(true)); + assertThat(sa.getMetadata().getAnnotations().entrySet().containsAll(saAnnotations.entrySet()), is(true)); } @ParallelTest @@ -791,110 +726,91 @@ public void testResources() { limits.put("cpu", new Quantity("500m")); limits.put("memory", new Quantity("1024Mi")); - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withResources(new ResourceRequirementsBuilder().withLimits(limits).withRequests(requests).build()) + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withResources(new ResourceRequirementsBuilder().withLimits(limits).withRequests(requests).build()) + .endCruiseControl() + .endSpec() .build(); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); - Kafka resource = createKafka(cruiseControlSpec); - - CruiseControl cc = createCruiseControl(resource); Deployment dep = cc.generateDeployment(Map.of(), true, null, null); - List containers = dep.getSpec().getTemplate().getSpec().getContainers(); - Container ccContainer = containers.stream().filter(container -> ccImage.equals(container.getImage())).findFirst().orElseThrow(); - + Container ccContainer = dep.getSpec().getTemplate().getSpec().getContainers().get(0); assertThat(ccContainer.getResources().getLimits(), is(limits)); assertThat(ccContainer.getResources().getRequests(), is(requests)); } @ParallelTest public void testCpuCapacityGeneration() { - Set nodes = Set.of( - new NodeRef("foo-pool1-0", 0, "pool1", false, true), - new NodeRef("foo-pool1-1", 1, "pool1", false, true), - new NodeRef("foo-pool1-2", 2, "pool1", false, true) - ); + String brokerCpuCapacity = "6.0"; + String brokerCpuCapacityOverride = "2.0"; + String resourceLimitCpu = "3.0"; + String resourceRequestCpu = "4.0"; - Map storage = new HashMap<>(); - storage.put("pool1", new JbodStorageBuilder().withVolumes(new PersistentClaimStorageBuilder().withId(0).withSize("100Gi").build()).build()); + Map storage = Map.of("brokers", new JbodStorageBuilder().withVolumes(new PersistentClaimStorageBuilder().withId(0).withSize("100Gi").build()).build()); /* In this test case, when override is set for a broker, it takes precedence over the general broker capacity setting for that specific broker, but the general broker capacity takes precedence over the Kafka resource request */ - ResourceRequirements resourceRequirements = new ResourceRequirementsBuilder() - .addToLimits("cpu", new Quantity(RESOURCE_LIMIT_CPU)) - .addToRequests("cpu", new Quantity(RESOURCE_REQUESTS_CPU)) - .build(); + Map resources = Map.of("brokers", new ResourceRequirementsBuilder().addToLimits("cpu", new Quantity(resourceLimitCpu)).addToRequests("cpu", new Quantity(resourceRequestCpu)).build()); io.strimzi.api.kafka.model.kafka.cruisecontrol.BrokerCapacity brokerCapacityOne = new BrokerCapacityBuilder() - .withCpu(BROKER_CAPACITY_CPU) + .withCpu(brokerCpuCapacity) .withOverrides() .addNewOverride() .addToBrokers(0) - .withCpu(BROKER_CAPACITY_OVERRIDE_CPU) + .withCpu(brokerCpuCapacityOverride) .endOverride() .build(); - verifyBrokerCapacity(nodes, storage, resourceRequirements, brokerCapacityOne, BROKER_CAPACITY_OVERRIDE_CPU, BROKER_CAPACITY_CPU, BROKER_CAPACITY_CPU); + verifyBrokerCapacity(storage, resources, brokerCapacityOne, brokerCpuCapacityOverride, brokerCpuCapacity, brokerCpuCapacity); // In this test case, when override is set for a broker, it takes precedence over the Kafka resource request io.strimzi.api.kafka.model.kafka.cruisecontrol.BrokerCapacity brokerCapacityTwo = new BrokerCapacityBuilder() .withOverrides() .addNewOverride() .addToBrokers(0) - .withCpu(BROKER_CAPACITY_OVERRIDE_CPU) + .withCpu(brokerCpuCapacityOverride) .endOverride() .build(); - verifyBrokerCapacity(nodes, storage, resourceRequirements, brokerCapacityTwo, BROKER_CAPACITY_OVERRIDE_CPU, RESOURCE_REQUESTS_CPU, RESOURCE_REQUESTS_CPU); + verifyBrokerCapacity(storage, resources, brokerCapacityTwo, brokerCpuCapacityOverride, resourceRequestCpu, resourceRequestCpu); /* In this test case, when neither the override nor the CPU resource request are configured but the CPU resource limit for CPU is set for the Kafka brokers; therefore, resource limit will be used as the CPU capacity */ - ResourceRequirements resourceRequirements3 = new ResourceRequirementsBuilder() - .addToLimits("cpu", new Quantity(RESOURCE_LIMIT_CPU)) - .build(); + resources = Map.of("brokers", new ResourceRequirementsBuilder().addToLimits("cpu", new Quantity(resourceLimitCpu)).build()); - io.strimzi.api.kafka.model.kafka.cruisecontrol.BrokerCapacity brokerCapacityThree = new BrokerCapacityBuilder() - .build(); + io.strimzi.api.kafka.model.kafka.cruisecontrol.BrokerCapacity brokerCapacityThree = new BrokerCapacityBuilder().build(); - verifyBrokerCapacity(nodes, storage, resourceRequirements3, brokerCapacityThree, RESOURCE_LIMIT_CPU, RESOURCE_LIMIT_CPU, RESOURCE_LIMIT_CPU); + verifyBrokerCapacity(storage, resources, brokerCapacityThree, resourceLimitCpu, resourceLimitCpu, resourceLimitCpu); /* In this test case, when neither the override nor the Kafka resource requests or limits for CPU are configured, the CPU capacity will be set to DEFAULT_CPU_CORE_CAPACITY */ - ResourceRequirements resourceRequirements2 = new ResourceRequirementsBuilder() - .build(); + resources = Map.of("brokers", new ResourceRequirementsBuilder().build()); - verifyBrokerCapacity(nodes, storage, resourceRequirements2, brokerCapacityThree, BrokerCapacity.DEFAULT_CPU_CORE_CAPACITY, BrokerCapacity.DEFAULT_CPU_CORE_CAPACITY, BrokerCapacity.DEFAULT_CPU_CORE_CAPACITY); + verifyBrokerCapacity(storage, resources, brokerCapacityThree, BrokerCapacity.DEFAULT_CPU_CORE_CAPACITY, BrokerCapacity.DEFAULT_CPU_CORE_CAPACITY, BrokerCapacity.DEFAULT_CPU_CORE_CAPACITY); } - private void verifyBrokerCapacity(Set nodes, - Map storage, - ResourceRequirements resourceRequirements, - io.strimzi.api.kafka.model.kafka.cruisecontrol.BrokerCapacity brokerCapacity, - String brokerOneCpuValue, - String brokerTwoCpuValue, - String brokerThreeCpuValue) { - - HashMap resources = new HashMap<>(); - resources.put("pool1", resourceRequirements); - - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withBrokerCapacity(brokerCapacity) - .build(); - - Kafka kafka = new KafkaBuilder() - .withNewSpec() - .withNewKafka() - .withResources(resourceRequirements) - .withConfig(kafkaConfig) - .endKafka() - .withCruiseControl(cruiseControlSpec) + private void verifyBrokerCapacity(Map storage, + Map resources, + io.strimzi.api.kafka.model.kafka.cruisecontrol.BrokerCapacity brokerCapacity, + String brokerOneCpuValue, + String brokerTwoCpuValue, + String brokerThreeCpuValue) { + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withBrokerCapacity(brokerCapacity) + .endCruiseControl() .endSpec() .build(); - CruiseControl cc = CruiseControl.fromCrd(Reconciliation.DUMMY_RECONCILIATION, kafka, VERSIONS, nodes, storage, resources, SHARED_ENV_PROVIDER); + CruiseControl cc = createCruiseControl(kafka, NODES, storage, resources); + ConfigMap configMap = cc.generateConfigMap(new MetricsAndLogging(null, null)); JsonObject capacity = new JsonObject(configMap.getData().get(CruiseControl.CAPACITY_CONFIG_FILENAME)); JsonArray brokerEntries = capacity.getJsonArray(Capacity.CAPACITIES_KEY); + assertThat(brokerEntries.getJsonObject(0).getJsonObject(Capacity.CAPACITY_KEY).getJsonObject(Capacity.CPU_KEY).getString("num.cores"), is(Matchers.equalTo(brokerOneCpuValue))); assertThat(brokerEntries.getJsonObject(1).getJsonObject(Capacity.CAPACITY_KEY).getJsonObject(Capacity.CPU_KEY).getString("num.cores"), is(Matchers.equalTo(brokerTwoCpuValue))); assertThat(brokerEntries.getJsonObject(2).getJsonObject(Capacity.CAPACITY_KEY).getJsonObject(Capacity.CPU_KEY).getString("num.cores"), is(Matchers.equalTo(brokerThreeCpuValue))); @@ -918,72 +834,64 @@ public void testApiSecurity(Boolean apiAuthEnabled, Boolean apiSslEnabled) { String e2Value = apiSslEnabled.toString(); EnvVar e2 = new EnvVar(e2Key, e2Value, null); - Map config = new HashMap<>(); - config.put(CruiseControlConfigurationParameters.WEBSERVER_SECURITY_ENABLE.getValue(), apiAuthEnabled); - config.put(CruiseControlConfigurationParameters.WEBSERVER_SSL_ENABLE.getValue(), apiSslEnabled); - - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withConfig(config) + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withConfig(Map.of(CruiseControlConfigurationParameters.WEBSERVER_SECURITY_ENABLE.getValue(), apiAuthEnabled, + CruiseControlConfigurationParameters.WEBSERVER_SSL_ENABLE.getValue(), apiSslEnabled)) + .endCruiseControl() + .endSpec() .build(); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); - Kafka resource = createKafka(cruiseControlSpec); - - CruiseControl cc = createCruiseControl(resource); Deployment dep = cc.generateDeployment(Map.of(), true, null, null); - List containers = dep.getSpec().getTemplate().getSpec().getContainers(); - - // checks on the main Cruise Control container - Container ccContainer = containers.stream().filter(container -> ccImage.equals(container.getImage())).findFirst().orElseThrow(); - List envVarList = ccContainer.getEnv(); - + List envVarList = dep.getSpec().getTemplate().getSpec().getContainers().get(0).getEnv(); assertThat(envVarList.contains(e1), is(true)); assertThat(envVarList.contains(e2), is(true)); } @ParallelTest public void testProbeConfiguration() { - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withNewLivenessProbe() - .withInitialDelaySeconds(HEALTH_DELAY) - .withTimeoutSeconds(HEALTH_TIMEOUT) - .endLivenessProbe() - .withNewReadinessProbe() - .withInitialDelaySeconds(HEALTH_DELAY) - .withTimeoutSeconds(HEALTH_TIMEOUT) - .endReadinessProbe() + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withNewLivenessProbe() + .withInitialDelaySeconds(123) + .withTimeoutSeconds(456) + .endLivenessProbe() + .withNewReadinessProbe() + .withInitialDelaySeconds(789) + .withTimeoutSeconds(987) + .endReadinessProbe() + .endCruiseControl() + .endSpec() .build(); - - Kafka resource = createKafka(cruiseControlSpec); - - CruiseControl cc = createCruiseControl(resource); - Deployment dep = cc.generateDeployment(Map.of(), true, null, null); - List containers = dep.getSpec().getTemplate().getSpec().getContainers(); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); // checks on the main Cruise Control container - Container ccContainer = containers.stream().filter(container -> ccImage.equals(container.getImage())).findFirst().orElseThrow(); + Deployment dep = cc.generateDeployment(Map.of(), true, null, null); + Container ccContainer = dep.getSpec().getTemplate().getSpec().getContainers().get(0); assertThat(ccContainer.getImage(), is(cc.image)); - assertThat(ccContainer.getLivenessProbe().getInitialDelaySeconds(), is(HEALTH_DELAY)); - assertThat(ccContainer.getLivenessProbe().getTimeoutSeconds(), is(HEALTH_TIMEOUT)); - assertThat(ccContainer.getReadinessProbe().getInitialDelaySeconds(), is(HEALTH_DELAY)); - assertThat(ccContainer.getReadinessProbe().getTimeoutSeconds(), is(HEALTH_TIMEOUT)); + assertThat(ccContainer.getLivenessProbe().getInitialDelaySeconds(), is(123)); + assertThat(ccContainer.getLivenessProbe().getTimeoutSeconds(), is(456)); + assertThat(ccContainer.getReadinessProbe().getInitialDelaySeconds(), is(789)); + assertThat(ccContainer.getReadinessProbe().getTimeoutSeconds(), is(987)); } @ParallelTest public void testSecurityContext() { - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withNewTemplate() - .withNewPod() - .withSecurityContext(new PodSecurityContextBuilder().withFsGroup(123L).withRunAsGroup(456L).withRunAsUser(789L).build()) - .endPod() - .endTemplate() + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withNewTemplate() + .withNewPod() + .withSecurityContext(new PodSecurityContextBuilder().withFsGroup(123L).withRunAsGroup(456L).withRunAsUser(789L).build()) + .endPod() + .endTemplate() + .endCruiseControl() + .endSpec() .build(); - - Kafka resource = createKafka(cruiseControlSpec); - - CruiseControl cc = createCruiseControl(resource); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); Deployment dep = cc.generateDeployment(Map.of(), true, null, null); assertThat(dep.getSpec().getTemplate().getSpec().getSecurityContext(), is(notNullValue())); @@ -994,7 +902,7 @@ public void testSecurityContext() { @ParallelTest public void testRestrictedSecurityContext() { - CruiseControl cc = createCruiseControl(createKafka(cruiseControlSpec)); + CruiseControl cc = createCruiseControl(KAFKA, NODES, STORAGE, Map.of()); cc.securityProvider = new RestrictedPodSecurityProvider(); cc.securityProvider.configure(new PlatformFeaturesAvailability(false, KubernetesVersion.MINIMAL_SUPPORTED_VERSION)); @@ -1008,19 +916,20 @@ public void testRestrictedSecurityContext() { @ParallelTest public void testJvmOptions() { - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withNewJvmOptions() - .withXms("128m") - .withXmx("256m") - .withXx(Map.of("InitiatingHeapOccupancyPercent", "36")) - .withJavaSystemProperties(new SystemPropertyBuilder().withName("myProperty").withValue("myValue").build(), - new SystemPropertyBuilder().withName("myProperty2").withValue("myValue2").build()) - .endJvmOptions() + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withNewJvmOptions() + .withXms("128m") + .withXmx("256m") + .withXx(Map.of("InitiatingHeapOccupancyPercent", "36")) + .withJavaSystemProperties(new SystemPropertyBuilder().withName("myProperty").withValue("myValue").build(), + new SystemPropertyBuilder().withName("myProperty2").withValue("myValue2").build()) + .endJvmOptions() + .endCruiseControl() + .endSpec() .build(); - - Kafka resource = createKafka(cruiseControlSpec); - - CruiseControl cc = createCruiseControl(resource); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); EnvVar systemProps = cc.getEnvVars().stream().filter(var -> AbstractModel.ENV_VAR_STRIMZI_JAVA_SYSTEM_PROPERTIES.equals(var.getName())).findFirst().orElse(null); assertThat(systemProps, is(notNullValue())); @@ -1037,12 +946,6 @@ public void testJvmOptions() { assertThat(perfOptions.getValue(), containsString("-XX:InitiatingHeapOccupancyPercent=36")); } - @ParallelTest - public void testDefaultSecurityContext() { - Deployment dep = cc.generateDeployment(Map.of(), true, null, null); - assertThat(dep.getSpec().getTemplate().getSpec().getSecurityContext(), is(nullValue())); - } - @ParallelTest public void testCruiseControlContainerSecurityContext() { SecurityContext securityContext = new SecurityContextBuilder() @@ -1055,21 +958,20 @@ public void testCruiseControlContainerSecurityContext() { .endCapabilities() .build(); - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withNewTemplate() - .withNewCruiseControlContainer() - .withSecurityContext(securityContext) - .endCruiseControlContainer() - .endTemplate() + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withNewTemplate() + .withNewCruiseControlContainer() + .withSecurityContext(securityContext) + .endCruiseControlContainer() + .endTemplate() + .endCruiseControl() + .endSpec() .build(); - - Kafka resource = createKafka(cruiseControlSpec); - - CruiseControl cc = createCruiseControl(resource); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); Deployment dep = cc.generateDeployment(Map.of(), true, null, null); - assertThat(dep.getSpec().getTemplate().getSpec().getContainers(), hasItem(allOf( hasProperty("name", equalTo(CruiseControl.CRUISE_CONTROL_CONTAINER_NAME)), @@ -1086,12 +988,12 @@ public void testRestApiPortNetworkPolicy() { .withNewNamespaceSelector().endNamespaceSelector() .build(); - NetworkPolicy np = cc.generateNetworkPolicy("operator-namespace", null, false); + CruiseControl cc = createCruiseControl(KAFKA, NODES, STORAGE, Map.of()); + NetworkPolicy np = cc.generateNetworkPolicy("operator-namespace", null, false); assertThat(np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(CruiseControl.REST_API_PORT))).findFirst().orElse(null), is(notNullValue())); List rules = np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(CruiseControl.REST_API_PORT))).map(NetworkPolicyIngressRule::getFrom).findFirst().orElse(null); - assertThat(rules.size(), is(1)); assertThat(rules.contains(clusterOperatorPeer), is(true)); } @@ -1105,16 +1007,16 @@ public void testRestApiPortNetworkPolicyInTheSameNamespace() { .build(); NetworkPolicyPeer entityOperatorPeer = new NetworkPolicyPeerBuilder() .withNewPodSelector() - .withMatchLabels(Collections.singletonMap(Labels.STRIMZI_NAME_LABEL, format("%s-entity-operator", CLUSTER))) + .withMatchLabels(Collections.singletonMap(Labels.STRIMZI_NAME_LABEL, format("%s-entity-operator", CLUSTER_NAME))) .endPodSelector() .build(); - NetworkPolicy np = cc.generateNetworkPolicy(NAMESPACE, null, true); + CruiseControl cc = createCruiseControl(KAFKA, NODES, STORAGE, Map.of()); + NetworkPolicy np = cc.generateNetworkPolicy(NAMESPACE, null, true); assertThat(np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(CruiseControl.REST_API_PORT))).findFirst().orElse(null), is(notNullValue())); List rules = np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(CruiseControl.REST_API_PORT))).map(NetworkPolicyIngressRule::getFrom).findFirst().orElse(null); - assertThat(rules.size(), is(2)); assertThat(rules.contains(clusterOperatorPeer), is(true)); assertThat(rules.contains(entityOperatorPeer), is(true)); @@ -1132,19 +1034,19 @@ public void testRestApiPortNetworkPolicyWithNamespaceLabels() { .build(); NetworkPolicyPeer entityOperatorPeer = new NetworkPolicyPeerBuilder() .withNewPodSelector() - .withMatchLabels(Collections.singletonMap(Labels.STRIMZI_NAME_LABEL, format("%s-entity-operator", CLUSTER))) + .withMatchLabels(Collections.singletonMap(Labels.STRIMZI_NAME_LABEL, format("%s-entity-operator", CLUSTER_NAME))) .endPodSelector() .withNewNamespaceSelector() .withMatchLabels(Collections.singletonMap("nsLabelKey", "nsLabelValue")) .endNamespaceSelector() .build(); - NetworkPolicy np = cc.generateNetworkPolicy(null, Labels.fromMap(Collections.singletonMap("nsLabelKey", "nsLabelValue")), true); + CruiseControl cc = createCruiseControl(KAFKA, NODES, STORAGE, Map.of()); + NetworkPolicy np = cc.generateNetworkPolicy(null, Labels.fromMap(Collections.singletonMap("nsLabelKey", "nsLabelValue")), true); assertThat(np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(CruiseControl.REST_API_PORT))).findFirst().orElse(null), is(notNullValue())); List rules = np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(CruiseControl.REST_API_PORT))).map(NetworkPolicyIngressRule::getFrom).findFirst().orElseThrow(); - assertThat(rules.size(), is(2)); assertThat(rules.contains(clusterOperatorPeer), is(true)); assertThat(rules.contains(entityOperatorPeer), is(true)); @@ -1152,43 +1054,36 @@ public void testRestApiPortNetworkPolicyWithNamespaceLabels() { @ParallelTest public void testGoalsCheck() { - String customGoals = "com.linkedin.kafka.cruisecontrol.analyzer.goals.RackAwareGoal," + "com.linkedin.kafka.cruisecontrol.analyzer.goals.ReplicaCapacityGoal"; - Map customGoalConfig = new HashMap<>(); - customGoalConfig.put(DEFAULT_GOALS_CONFIG_KEY.getValue(), customGoals); - - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withConfig(customGoalConfig) + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withConfig(Map.of(DEFAULT_GOALS_CONFIG_KEY.getValue(), customGoals)) + .endCruiseControl() + .endSpec() .build(); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); - Kafka resourceWithCustomGoals = createKafka(cruiseControlSpec); - - CruiseControl cruiseControlWithCustomGoals = createCruiseControl(resourceWithCustomGoals); - - String anomalyDetectionGoals = cruiseControlWithCustomGoals - .configuration.asOrderedProperties().asMap() - .get(ANOMALY_DETECTION_CONFIG_KEY.getValue()); - + String anomalyDetectionGoals = cc.configuration.asOrderedProperties().asMap().get(ANOMALY_DETECTION_CONFIG_KEY.getValue()); assertThat(anomalyDetectionGoals, is(customGoals)); } @ParallelTest public void testMetricsParsingFromConfigMap() { - MetricsConfig metrics = new JmxPrometheusExporterMetricsBuilder() - .withNewValueFrom() - .withConfigMapKeyRef(new ConfigMapKeySelectorBuilder().withName("my-metrics-configuration").withKey("config.yaml").build()) - .endValueFrom() - .build(); - - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withMetricsConfig(metrics) + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withMetricsConfig(new JmxPrometheusExporterMetricsBuilder() + .withNewValueFrom() + .withConfigMapKeyRef(new ConfigMapKeySelectorBuilder().withName("my-metrics-configuration").withKey("config.yaml").build()) + .endValueFrom() + .build()) + .endCruiseControl() + .endSpec() .build(); - - Kafka kafkaAssembly = createKafka(cruiseControlSpec); - CruiseControl cc = createCruiseControl(kafkaAssembly); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); assertThat(cc.metrics().isEnabled(), is(true)); assertThat(cc.metrics().getConfigMapName(), is("my-metrics-configuration")); @@ -1197,10 +1092,7 @@ public void testMetricsParsingFromConfigMap() { @ParallelTest public void testMetricsParsingNoMetrics() { - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder().build(); - Kafka kafkaAssembly = createKafka(cruiseControlSpec); - - CruiseControl cc = createCruiseControl(kafkaAssembly); + CruiseControl cc = createCruiseControl(KAFKA, NODES, STORAGE, Map.of()); assertThat(cc.metrics().isEnabled(), is(false)); assertThat(cc.metrics().getConfigMapName(), is(nullValue())); @@ -1209,45 +1101,64 @@ public void testMetricsParsingNoMetrics() { @ParallelTest public void testDefaultTopicNames() { - Map topicConfigs = new HashMap<>(); - topicConfigs.put(CruiseControlConfigurationParameters.PARTITION_METRIC_TOPIC_NAME.getValue(), CruiseControlConfigurationParameters.DEFAULT_PARTITION_METRIC_TOPIC_NAME); - topicConfigs.put(CruiseControlConfigurationParameters.BROKER_METRIC_TOPIC_NAME.getValue(), CruiseControlConfigurationParameters.DEFAULT_BROKER_METRIC_TOPIC_NAME); - topicConfigs.put(CruiseControlConfigurationParameters.METRIC_REPORTER_TOPIC_NAME.getValue(), CruiseControlConfigurationParameters.DEFAULT_METRIC_REPORTER_TOPIC_NAME); + CruiseControl cc = createCruiseControl(KAFKA, NODES, STORAGE, Map.of()); - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .build(); + Map expectedTopicConfigs = new HashMap<>(); + expectedTopicConfigs.put(CruiseControlConfigurationParameters.PARTITION_METRIC_TOPIC_NAME.getValue(), CruiseControlConfigurationParameters.DEFAULT_PARTITION_METRIC_TOPIC_NAME); + expectedTopicConfigs.put(CruiseControlConfigurationParameters.BROKER_METRIC_TOPIC_NAME.getValue(), CruiseControlConfigurationParameters.DEFAULT_BROKER_METRIC_TOPIC_NAME); + expectedTopicConfigs.put(CruiseControlConfigurationParameters.METRIC_REPORTER_TOPIC_NAME.getValue(), CruiseControlConfigurationParameters.DEFAULT_METRIC_REPORTER_TOPIC_NAME); - Kafka resource = createKafka(cruiseControlSpec); - CruiseControl cc = createCruiseControl(resource); - topicConfigs.forEach((configParam, name) -> assertThat(cc.configuration.getConfiguration(), containsString(String.format("%s=%s", configParam, name)))); + expectedTopicConfigs.forEach((configParam, name) -> assertThat(cc.configuration.getConfiguration(), containsString(String.format("%s=%s", configParam, name)))); } @ParallelTest public void testCustomTopicNames() { - Map topicConfigs = new HashMap<>(); - topicConfigs.put(CruiseControlConfigurationParameters.PARTITION_METRIC_TOPIC_NAME.getValue(), "partition-topic"); - topicConfigs.put(CruiseControlConfigurationParameters.BROKER_METRIC_TOPIC_NAME.getValue(), "broker-topic"); - topicConfigs.put(CruiseControlConfigurationParameters.METRIC_REPORTER_TOPIC_NAME.getValue(), "metric-reporter-topic"); Map customConfig = new HashMap<>(); - customConfig.putAll(topicConfigs); + customConfig.put(CruiseControlConfigurationParameters.PARTITION_METRIC_TOPIC_NAME.getValue(), "partition-topic"); + customConfig.put(CruiseControlConfigurationParameters.BROKER_METRIC_TOPIC_NAME.getValue(), "broker-topic"); + customConfig.put(CruiseControlConfigurationParameters.METRIC_REPORTER_TOPIC_NAME.getValue(), "metric-reporter-topic"); - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withConfig(customConfig) + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withConfig(customConfig) + .endCruiseControl() + .endSpec() .build(); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); + customConfig.forEach((configParam, name) -> assertThat(cc.configuration.getConfiguration(), containsString(String.format("%s=%s", configParam, name)))); + } + + @ParallelTest + public void testDefaultSampleStoreTopicReplicationFactorConfig() { + // Test that the replication factor of Cruise Control's sample store topic is set to Kafka cluster's `default.replication.factor` + // when not explicitly set in Cruise Control config + CruiseControl cc = createCruiseControl(KAFKA, NODES, STORAGE, Map.of()); - Kafka resource = createKafka(cruiseControlSpec); - CruiseControl cc = createCruiseControl(resource); - topicConfigs.forEach((configParam, name) -> assertThat(cc.configuration.getConfiguration(), containsString(String.format("%s=%s", configParam, name)))); + ConfigMap configMap = cc.generateConfigMap(new MetricsAndLogging(null, null)); + assertThat(parsePropertiesString(configMap.getData().get(CruiseControl.SERVER_CONFIG_FILENAME)).getProperty(CruiseControlConfigurationParameters.SAMPLE_STORE_TOPIC_REPLICATION_FACTOR.getValue()), is("3")); } - private Properties getCcProperties(Kafka resource) { - CruiseControl cc = createCruiseControl(resource); + @ParallelTest + public void testCustomSampleStoreTopicReplicationFactorConfig() { + // Test that the replication factor of Cruise Control's sample store topic is set to value set in Cruise Control config + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewCruiseControl() + .withConfig(Map.of(CruiseControlConfigurationParameters.SAMPLE_STORE_TOPIC_REPLICATION_FACTOR.getValue(), 7)) + .endCruiseControl() + .endSpec() + .build(); + CruiseControl cc = createCruiseControl(kafka, NODES, STORAGE, Map.of()); + ConfigMap configMap = cc.generateConfigMap(new MetricsAndLogging(null, null)); - return parsePropertiesString(configMap.getData().get(CruiseControl.SERVER_CONFIG_FILENAME)); + assertThat(parsePropertiesString(configMap.getData().get(CruiseControl.SERVER_CONFIG_FILENAME)).getProperty(CruiseControlConfigurationParameters.SAMPLE_STORE_TOPIC_REPLICATION_FACTOR.getValue()), is("7")); } + //////////////////// + // Utility methods + //////////////////// + private static Properties parsePropertiesString(String kafkaPropertiesString) { Properties properties = new Properties(); try (StringReader reader = new StringReader(kafkaPropertiesString)) { @@ -1258,26 +1169,54 @@ private static Properties parsePropertiesString(String kafkaPropertiesString) { return properties; } - @ParallelTest - public void testSampleStoreTopicReplicationFactorConfig() { - // Test that the replication factor of Cruise Control's sample store topic is set to Kafka cluster's `default.replication.factor` - // when not explicitly set in Cruise Control config - Properties properties = getCcProperties(kafka); - assertThat(properties.getProperty(CruiseControlConfigurationParameters.SAMPLE_STORE_TOPIC_REPLICATION_FACTOR.getValue()), is(REPLICATION_FACTOR)); + private CruiseControl createCruiseControl(Kafka kafka, Set nodes, Map storageMap, Map resourceRequirementsMap) { + return CruiseControl + .fromCrd( + Reconciliation.DUMMY_RECONCILIATION, + kafka, + VERSIONS, + nodes, + storageMap, + resourceRequirementsMap, + SHARED_ENV_PROVIDER + ); + } - // Test that the replication factor of Cruise Control's sample store topic is set to value set in Cruise Control config - String replicationFactor = "1"; - CruiseControlSpec cruiseControlSpec = new CruiseControlSpecBuilder() - .withImage(ccImage) - .withConfig(Map.of(CruiseControlConfigurationParameters.SAMPLE_STORE_TOPIC_REPLICATION_FACTOR.getValue(), replicationFactor)) - .build(); + private Map expectedLabels(String name) { + return TestUtils.map(Labels.STRIMZI_CLUSTER_LABEL, CLUSTER_NAME, + "my-user-label", "cromulent", + Labels.STRIMZI_KIND_LABEL, Kafka.RESOURCE_KIND, + Labels.STRIMZI_NAME_LABEL, name, + Labels.STRIMZI_COMPONENT_TYPE_LABEL, CruiseControl.COMPONENT_TYPE, + Labels.KUBERNETES_NAME_LABEL, CruiseControl.COMPONENT_TYPE, + Labels.KUBERNETES_INSTANCE_LABEL, CLUSTER_NAME, + Labels.KUBERNETES_PART_OF_LABEL, Labels.APPLICATION_NAME + "-" + CLUSTER_NAME, + Labels.KUBERNETES_MANAGED_BY_LABEL, AbstractModel.STRIMZI_CLUSTER_OPERATOR_NAME); + } - properties = getCcProperties(createKafka(cruiseControlSpec)); - assertThat(properties.getProperty(CruiseControlConfigurationParameters.SAMPLE_STORE_TOPIC_REPLICATION_FACTOR.getValue()), is(replicationFactor)); + private Map expectedSelectorLabels() { + return Labels.fromMap(expectedLabels()).strimziSelectorLabels().toMap(); } - @AfterAll - public static void cleanUp() { - ResourceUtils.cleanUpTemporaryTLSFiles(); + private Map expectedLabels() { + return expectedLabels(CruiseControlResources.componentName(CLUSTER_NAME)); + } + + private List getExpectedEnvVars() { + List expected = new ArrayList<>(); + expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_CRUISE_CONTROL_METRICS_ENABLED).withValue(Boolean.toString(CruiseControl.DEFAULT_CRUISE_CONTROL_METRICS_ENABLED)).build()); + expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_STRIMZI_KAFKA_BOOTSTRAP_SERVERS).withValue(KafkaResources.bootstrapServiceName(CLUSTER_NAME) + ":" + KafkaCluster.REPLICATION_PORT).build()); + expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_STRIMZI_KAFKA_GC_LOG_ENABLED).withValue(Boolean.toString(JvmOptions.DEFAULT_GC_LOGGING_ENABLED)).build()); + expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_API_SSL_ENABLED).withValue(Boolean.toString(CruiseControlConfigurationParameters.DEFAULT_WEBSERVER_SSL_ENABLED)).build()); + expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_API_AUTH_ENABLED).withValue(Boolean.toString(CruiseControlConfigurationParameters.DEFAULT_WEBSERVER_SECURITY_ENABLED)).build()); + expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_API_HEALTHCHECK_USERNAME).withValue(CruiseControlApiProperties.HEALTHCHECK_USERNAME).build()); + expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_API_PORT).withValue(Integer.toString(CruiseControl.REST_API_PORT)).build()); + expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_API_HEALTHCHECK_PATH).withValue(API_HEALTHCHECK_PATH).build()); + expected.add(new EnvVarBuilder().withName(CruiseControl.ENV_VAR_KAFKA_HEAP_OPTS).withValue("-Xms" + JvmOptionUtils.DEFAULT_JVM_XMS).build()); + return expected; + } + + private static boolean isJBOD(Object diskCapacity) { + return diskCapacity instanceof JsonObject; } } diff --git a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityOperatorTest.java b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityOperatorTest.java index 75b574f3b35..0e1a11c505e 100644 --- a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityOperatorTest.java +++ b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityOperatorTest.java @@ -38,15 +38,12 @@ import io.strimzi.api.kafka.model.kafka.Kafka; import io.strimzi.api.kafka.model.kafka.KafkaBuilder; import io.strimzi.api.kafka.model.kafka.KafkaResources; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityOperatorSpec; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityOperatorSpecBuilder; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityTopicOperatorSpec; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityTopicOperatorSpecBuilder; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityUserOperatorSpec; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityUserOperatorSpecBuilder; +import io.strimzi.api.kafka.model.kafka.listener.GenericKafkaListenerBuilder; +import io.strimzi.api.kafka.model.kafka.listener.KafkaListenerType; import io.strimzi.operator.cluster.ClusterOperatorConfig; import io.strimzi.operator.cluster.KafkaVersionTestUtils; import io.strimzi.operator.cluster.ResourceUtils; +import io.strimzi.operator.common.Annotations; import io.strimzi.operator.common.Reconciliation; import io.strimzi.operator.common.model.Labels; import io.strimzi.test.TestUtils; @@ -80,54 +77,56 @@ public class EntityOperatorTest { private static final KafkaVersion.Lookup VERSIONS = KafkaVersionTestUtils.getKafkaVersionLookup(); private static final SharedEnvironmentProvider SHARED_ENV_PROVIDER = new MockSharedEnvironmentProvider(); - - static Map volumeMounts(List mounts) { - return mounts.stream().collect(Collectors.toMap(VolumeMount::getName, VolumeMount::getMountPath)); - } - - private final String namespace = "test"; - private final String cluster = "foo"; - private final int replicas = 3; - private final String image = "my-image:latest"; - private final int healthDelay = 120; - private final int healthTimeout = 30; - - private final EntityUserOperatorSpec entityUserOperatorSpec = new EntityUserOperatorSpecBuilder() - .build(); - private final EntityTopicOperatorSpec entityTopicOperatorSpec = new EntityTopicOperatorSpecBuilder() - .build(); - - private final EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .withNewTemplate() - .withNewPod() - .withTmpDirSizeLimit("100Mi") - .endPod() - .endTemplate() + private static final String NAMESPACE = "my-namespace"; + private static final String CLUSTER_NAME = "my-cluster"; + private static final Kafka KAFKA = new KafkaBuilder() + .withNewMetadata() + .withNamespace(NAMESPACE) + .withName(CLUSTER_NAME) + .withLabels(Map.of("my-user-label", "cromulent")) + .withAnnotations(Map.of(Annotations.ANNO_STRIMZI_IO_NODE_POOLS, "enabled", Annotations.ANNO_STRIMZI_IO_KRAFT, "enabled")) + .endMetadata() + .withNewSpec() + .withNewKafka() + .withListeners(new GenericKafkaListenerBuilder() + .withName("tls") + .withPort(9092) + .withType(KafkaListenerType.INTERNAL) + .withTls(true) + .build()) + .endKafka() + .withNewEntityOperator() + .withNewUserOperator() + .endUserOperator() + .withNewTopicOperator() + .endTopicOperator() + .withNewTemplate() + .withNewPod() + .withTmpDirSizeLimit("100Mi") + .endPod() + .endTemplate() + .endEntityOperator() + .endSpec() .build(); + private static final EntityOperator ENTITY_OPERATOR = EntityOperator.fromCrd(new Reconciliation("test", KAFKA.getKind(), KAFKA.getMetadata().getNamespace(), KAFKA.getMetadata().getName()), KAFKA, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - private final Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withEntityOperator(entityOperatorSpec) - .endSpec() - .build(); + @AfterAll + public static void cleanUp() { + ResourceUtils.cleanUpTemporaryTLSFiles(); + } - private final EntityOperator entityOperator = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - @ParameterizedTest @ValueSource(booleans = { true, false }) public void testGenerateDeployment(boolean cruiseControlEnabled) { - entityOperator.cruiseControlEnabled = cruiseControlEnabled; - Deployment dep = entityOperator.generateDeployment(Map.of(), true, null, null); + ENTITY_OPERATOR.cruiseControlEnabled = cruiseControlEnabled; + Deployment dep = ENTITY_OPERATOR.generateDeployment(Map.of(), true, null, null); List containers = dep.getSpec().getTemplate().getSpec().getContainers(); - assertThat(dep.getMetadata().getName(), is(KafkaResources.entityOperatorDeploymentName(cluster))); - assertThat(dep.getMetadata().getNamespace(), is(namespace)); + assertThat(dep.getMetadata().getName(), is(KafkaResources.entityOperatorDeploymentName(CLUSTER_NAME))); + assertThat(dep.getMetadata().getNamespace(), is(NAMESPACE)); assertThat(dep.getSpec().getReplicas(), is(1)); - TestUtils.checkOwnerReference(dep, resource); + TestUtils.checkOwnerReference(dep, KAFKA); assertThat(containers.size(), is(2)); // just check names of topic and user operators (their containers are tested in the related unit test classes) @@ -146,16 +145,16 @@ public void testGenerateDeployment(boolean cruiseControlEnabled) { @ParallelTest public void testFromCrd() { - assertThat(entityOperator.namespace, is(namespace)); - assertThat(entityOperator.cluster, is(cluster)); + assertThat(ENTITY_OPERATOR.namespace, is(NAMESPACE)); + assertThat(ENTITY_OPERATOR.cluster, is(CLUSTER_NAME)); } @ParallelTest public void testFromCrdNoTopicAndUserOperatorInEntityOperator() { - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder().build(); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withEntityOperator(entityOperatorSpec) + .withNewEntityOperator() + .endEntityOperator() .endSpec() .build(); @@ -166,13 +165,12 @@ public void testFromCrdNoTopicAndUserOperatorInEntityOperator() { @ParallelTest public void testFromCrdNoTopicInEntityOperator() { - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withNewUserOperator() - .endUserOperator() - .build(); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withEntityOperator(entityOperatorSpec) + .withNewEntityOperator() + .withNewUserOperator() + .endUserOperator() + .endEntityOperator() .endSpec() .build(); @@ -184,13 +182,12 @@ public void testFromCrdNoTopicInEntityOperator() { @ParallelTest public void testFromCrdNoUserOperatorInEntityOperator() { - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withNewTopicOperator() - .endTopicOperator() - .build(); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withEntityOperator(entityOperatorSpec) + .withNewEntityOperator() + .withNewTopicOperator() + .endTopicOperator() + .endEntityOperator() .endSpec() .build(); @@ -202,7 +199,7 @@ public void testFromCrdNoUserOperatorInEntityOperator() { @ParallelTest public void withAffinityAndTolerations() throws IOException { - ResourceTester helper = new ResourceTester<>(Kafka.class, VERSIONS, (kAssembly, versions) -> EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), kAssembly, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()), this.getClass().getSimpleName() + ".withAffinityAndTolerations"); + ResourceTester helper = new ResourceTester<>(Kafka.class, VERSIONS, (kAssembly, versions) -> EntityOperator.fromCrd(new Reconciliation("test", KAFKA.getKind(), KAFKA.getMetadata().getNamespace(), KAFKA.getMetadata().getName()), kAssembly, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()), this.getClass().getSimpleName() + ".withAffinityAndTolerations"); helper.assertDesiredModel("-DeploymentAffinity.yaml", zc -> zc.generateDeployment(Map.of(), true, null, null).getSpec().getTemplate().getSpec().getAffinity()); helper.assertDesiredModel("-DeploymentTolerations.yaml", zc -> zc.generateDeployment(Map.of(), true, null, null).getSpec().getTemplate().getSpec().getTolerations()); } @@ -223,7 +220,7 @@ public void testTemplate() { Map saAnnotations = TestUtils.map("a5", "v5", "a6", "v6"); Map rLabels = TestUtils.map("l7", "v7", "l8", "v8"); - Map rAnots = TestUtils.map("a7", "v7", "a8", "v8"); + Map rAnnotations = TestUtils.map("a7", "v7", "a8", "v8"); Toleration toleration = new TolerationBuilder() .withEffect("NoSchedule") @@ -259,53 +256,50 @@ public void testTemplate() { .withSubPath("def") .build()); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .withNewTemplate() - .withNewDeployment() - .withNewMetadata() - .withLabels(depLabels) - .withAnnotations(depAnnotations) - .endMetadata() - .endDeployment() - .withNewPod() - .withNewMetadata() - .withLabels(podLabels) - .withAnnotations(podAnnotations) - .endMetadata() - .withPriorityClassName("top-priority") - .withSchedulerName("my-scheduler") - .withTolerations(singletonList(toleration)) - .withTopologySpreadConstraints(tsc1, tsc2) - .withEnableServiceLinks(false) - .withVolumes(additionalVolumes) - .endPod() - .withNewTopicOperatorContainer() - .withVolumeMounts(additionalVolumeMounts) - .endTopicOperatorContainer() - .withNewUserOperatorContainer() - .withVolumeMounts(additionalVolumeMounts) - .endUserOperatorContainer() - .withNewEntityOperatorRole() - .withNewMetadata() - .withLabels(rLabels) - .withAnnotations(rAnots) - .endMetadata() - .endEntityOperatorRole() - .withNewServiceAccount() - .withNewMetadata() - .withLabels(saLabels) - .withAnnotations(saAnnotations) - .endMetadata() - .endServiceAccount() - .endTemplate() - .endEntityOperator() - .endSpec() - .build(); + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .editEntityOperator() + .withNewTemplate() + .withNewDeployment() + .withNewMetadata() + .withLabels(depLabels) + .withAnnotations(depAnnotations) + .endMetadata() + .endDeployment() + .withNewPod() + .withNewMetadata() + .withLabels(podLabels) + .withAnnotations(podAnnotations) + .endMetadata() + .withPriorityClassName("top-priority") + .withSchedulerName("my-scheduler") + .withTolerations(singletonList(toleration)) + .withTopologySpreadConstraints(tsc1, tsc2) + .withEnableServiceLinks(false) + .withVolumes(additionalVolumes) + .endPod() + .withNewTopicOperatorContainer() + .withVolumeMounts(additionalVolumeMounts) + .endTopicOperatorContainer() + .withNewUserOperatorContainer() + .withVolumeMounts(additionalVolumeMounts) + .endUserOperatorContainer() + .withNewEntityOperatorRole() + .withNewMetadata() + .withLabels(rLabels) + .withAnnotations(rAnnotations) + .endMetadata() + .endEntityOperatorRole() + .withNewServiceAccount() + .withNewMetadata() + .withLabels(saLabels) + .withAnnotations(saAnnotations) + .endMetadata() + .endServiceAccount() + .endTemplate() + .endEntityOperator() + .endSpec() + .build(); EntityOperator entityOperator = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); @@ -327,9 +321,9 @@ public void testTemplate() { assertThat(dep.getSpec().getTemplate().getSpec().getContainers().get(1).getVolumeMounts().stream().filter(volumeMount -> "secret-volume-name".equals(volumeMount.getName())).iterator().next(), is(additionalVolumeMounts.get(0))); // Generate Role metadata - Role crb = entityOperator.generateRole(null, namespace); + Role crb = entityOperator.generateRole(null, NAMESPACE); assertThat(crb.getMetadata().getLabels().entrySet().containsAll(rLabels.entrySet()), is(true)); - assertThat(crb.getMetadata().getAnnotations().entrySet().containsAll(rAnots.entrySet()), is(true)); + assertThat(crb.getMetadata().getAnnotations().entrySet().containsAll(rAnnotations.entrySet()), is(true)); // Check Service Account ServiceAccount sa = entityOperator.generateServiceAccount(); @@ -339,16 +333,14 @@ public void testTemplate() { @ParallelTest public void testGracePeriod() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .withNewTemplate() - .withNewPod() - .withTerminationGracePeriodSeconds(123) - .endPod() - .endTemplate() + .editEntityOperator() + .withNewTemplate() + .withNewPod() + .withTerminationGracePeriodSeconds(123) + .endPod() + .endTemplate() .endEntityOperator() .endSpec() .build(); @@ -361,18 +353,7 @@ public void testGracePeriod() { @ParallelTest public void testDefaultGracePeriod() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .endEntityOperator() - .endSpec() - .build(); - - EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - - Deployment dep = eo.generateDeployment(Map.of(), true, null, null); + Deployment dep = ENTITY_OPERATOR.generateDeployment(Map.of(), true, null, null); assertThat(dep.getSpec().getTemplate().getSpec().getTerminationGracePeriodSeconds(), is(30L)); } @@ -381,16 +362,14 @@ public void testImagePullSecrets() { LocalObjectReference secret1 = new LocalObjectReference("some-pull-secret"); LocalObjectReference secret2 = new LocalObjectReference("some-other-pull-secret"); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .withNewTemplate() - .withNewPod() - .withImagePullSecrets(secret1, secret2) - .endPod() - .endTemplate() + .editEntityOperator() + .withNewTemplate() + .withNewPod() + .withImagePullSecrets(secret1, secret2) + .endPod() + .endTemplate() .endEntityOperator() .endSpec() .build(); @@ -412,18 +391,7 @@ public void testImagePullSecretsFromCo() { secrets.add(secret1); secrets.add(secret2); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .endEntityOperator() - .endSpec() - .build(); - - EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - - Deployment dep = eo.generateDeployment(Map.of(), true, null, secrets); + Deployment dep = ENTITY_OPERATOR.generateDeployment(Map.of(), true, null, secrets); assertThat(dep.getSpec().getTemplate().getSpec().getImagePullSecrets().size(), is(2)); assertThat(dep.getSpec().getTemplate().getSpec().getImagePullSecrets().contains(secret1), is(true)); assertThat(dep.getSpec().getTemplate().getSpec().getImagePullSecrets().contains(secret2), is(true)); @@ -434,17 +402,15 @@ public void testImagePullSecretsFromBoth() { LocalObjectReference secret1 = new LocalObjectReference("some-pull-secret"); LocalObjectReference secret2 = new LocalObjectReference("some-other-pull-secret"); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .withNewTemplate() - .withNewPod() - .withImagePullSecrets(secret2) - .endPod() - .endTemplate() - .endEntityOperator() + .editEntityOperator() + .withNewTemplate() + .withNewPod() + .withImagePullSecrets(secret2) + .endPod() + .endTemplate() + .endEntityOperator() .endSpec() .build(); @@ -458,28 +424,15 @@ public void testImagePullSecretsFromBoth() { @ParallelTest public void testDefaultImagePullSecrets() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .endEntityOperator() - .endSpec() - .build(); - - EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - - Deployment dep = eo.generateDeployment(Map.of(), true, null, null); + Deployment dep = ENTITY_OPERATOR.generateDeployment(Map.of(), true, null, null); assertThat(dep.getSpec().getTemplate().getSpec().getImagePullSecrets(), is(nullValue())); } @ParallelTest public void testSecurityContext() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) + .editEntityOperator() .withNewTemplate() .withNewPod() .withSecurityContext(new PodSecurityContextBuilder().withFsGroup(123L).withRunAsGroup(456L).withRunAsUser(789L).build()) @@ -500,51 +453,23 @@ public void testSecurityContext() { @ParallelTest public void testDefaultSecurityContext() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .endEntityOperator() - .endSpec() - .build(); - - EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - - Deployment dep = eo.generateDeployment(Map.of(), true, null, null); + Deployment dep = ENTITY_OPERATOR.generateDeployment(Map.of(), true, null, null); assertThat(dep.getSpec().getTemplate().getSpec().getSecurityContext(), is(nullValue())); } @ParallelTest public void testImagePullPolicy() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .endEntityOperator() - .endSpec() - .build(); - - EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - - Deployment dep = eo.generateDeployment(Map.of(), true, ImagePullPolicy.ALWAYS, null); + Deployment dep = ENTITY_OPERATOR.generateDeployment(Map.of(), true, ImagePullPolicy.ALWAYS, null); assertThat(dep.getSpec().getTemplate().getSpec().getContainers().get(0).getImagePullPolicy(), is(ImagePullPolicy.ALWAYS.toString())); assertThat(dep.getSpec().getTemplate().getSpec().getContainers().get(1).getImagePullPolicy(), is(ImagePullPolicy.ALWAYS.toString())); - dep = eo.generateDeployment(Map.of(), true, ImagePullPolicy.IFNOTPRESENT, null); + dep = ENTITY_OPERATOR.generateDeployment(Map.of(), true, ImagePullPolicy.IFNOTPRESENT, null); assertThat(dep.getSpec().getTemplate().getSpec().getContainers().get(0).getImagePullPolicy(), is(ImagePullPolicy.IFNOTPRESENT.toString())); assertThat(dep.getSpec().getTemplate().getSpec().getContainers().get(1).getImagePullPolicy(), is(ImagePullPolicy.IFNOTPRESENT.toString())); } - @AfterAll - public static void cleanUp() { - ResourceUtils.cleanUpTemporaryTLSFiles(); - } - @ParallelTest public void testTopicOperatorContainerEnvVars() { - ContainerEnvVar envVar1 = new ContainerEnvVar(); String testEnvOneKey = "TEST_ENV_1"; String testEnvOneValue = "test.env.one"; @@ -564,18 +489,15 @@ public void testTopicOperatorContainerEnvVars() { ContainerTemplate topicOperatorContainer = new ContainerTemplate(); topicOperatorContainer.setEnv(testEnvs); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .editEntityOperator() .withNewTemplate() - .withTopicOperatorContainer(topicOperatorContainer) + .withTopicOperatorContainer(topicOperatorContainer) .endTemplate() - .endEntityOperator() - .endSpec() - .build(); + .endEntityOperator() + .endSpec() + .build(); List containerEnvVars = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()).topicOperator().getEnvVars(); @@ -585,8 +507,6 @@ public void testTopicOperatorContainerEnvVars() { assertThat("Failed to correctly set container environment variable: " + testEnvTwoKey, containerEnvVars.stream().filter(env -> testEnvTwoKey.equals(env.getName())) .map(EnvVar::getValue).findFirst().orElse("").equals(testEnvTwoValue), is(true)); - - } @ParallelTest @@ -609,18 +529,15 @@ public void testTopicOperatorContainerEnvVarsConflict() { ContainerTemplate topicOperatorContainer = new ContainerTemplate(); topicOperatorContainer.setEnv(testEnvs); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .editEntityOperator() .withNewTemplate() - .withTopicOperatorContainer(topicOperatorContainer) + .withTopicOperatorContainer(topicOperatorContainer) .endTemplate() - .endEntityOperator() - .endSpec() - .build(); + .endEntityOperator() + .endSpec() + .build(); List containerEnvVars = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()).topicOperator().getEnvVars(); @@ -630,12 +547,10 @@ public void testTopicOperatorContainerEnvVarsConflict() { assertThat("Failed to prevent over writing existing container environment variable: " + testEnvTwoKey, containerEnvVars.stream().filter(env -> testEnvTwoKey.equals(env.getName())) .map(EnvVar::getValue).findFirst().orElse("").equals(testEnvTwoValue), is(false)); - } @ParallelTest public void testUserOperatorContainerEnvVars() { - ContainerEnvVar envVar1 = new ContainerEnvVar(); String testEnvOneKey = "TEST_ENV_1"; String testEnvOneValue = "test.env.one"; @@ -655,18 +570,15 @@ public void testUserOperatorContainerEnvVars() { ContainerTemplate userOperatorContainer = new ContainerTemplate(); userOperatorContainer.setEnv(testEnvs); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .editEntityOperator() .withNewTemplate() - .withUserOperatorContainer(userOperatorContainer) + .withUserOperatorContainer(userOperatorContainer) .endTemplate() - .endEntityOperator() - .endSpec() - .build(); + .endEntityOperator() + .endSpec() + .build(); List containerEnvVars = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()).userOperator().getEnvVars(); @@ -676,7 +588,6 @@ public void testUserOperatorContainerEnvVars() { assertThat("Failed to correctly set container environment variable: " + testEnvTwoKey, containerEnvVars.stream().filter(env -> testEnvTwoKey.equals(env.getName())) .map(EnvVar::getValue).findFirst().orElse("").equals(testEnvTwoValue), is(true)); - } @ParallelTest @@ -692,18 +603,15 @@ public void testUserOperatorContainerEnvVarsConflict() { ContainerTemplate userOperatorContainer = new ContainerTemplate(); userOperatorContainer.setEnv(testEnvs); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .editEntityOperator() .withNewTemplate() - .withUserOperatorContainer(userOperatorContainer) + .withUserOperatorContainer(userOperatorContainer) .endTemplate() - .endEntityOperator() - .endSpec() - .build(); + .endEntityOperator() + .endSpec() + .build(); List containerEnvVars = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()).userOperator().getEnvVars(); @@ -715,7 +623,6 @@ public void testUserOperatorContainerEnvVarsConflict() { @ParallelTest public void testUserOperatorContainerSecurityContext() { - SecurityContext securityContext = new SecurityContextBuilder() .withPrivileged(false) .withReadOnlyRootFilesystem(false) @@ -726,13 +633,11 @@ public void testUserOperatorContainerSecurityContext() { .endCapabilities() .build(); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .editOrNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .editOrNewTemplate() - .editOrNewUserOperatorContainer() + .editEntityOperator() + .withNewTemplate() + .withNewUserOperatorContainer() .withSecurityContext(securityContext) .endUserOperatorContainer() .endTemplate() @@ -752,7 +657,6 @@ public void testUserOperatorContainerSecurityContext() { @ParallelTest public void testTopicOperatorContainerSecurityContext() { - SecurityContext securityContext = new SecurityContextBuilder() .withPrivileged(false) .withReadOnlyRootFilesystem(false) @@ -763,13 +667,11 @@ public void testTopicOperatorContainerSecurityContext() { .endCapabilities() .build(); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .editOrNewEntityOperator() - .withTopicOperator(entityTopicOperatorSpec) - .withUserOperator(entityUserOperatorSpec) - .editOrNewTemplate() - .editOrNewTopicOperatorContainer() + .editEntityOperator() + .withNewTemplate() + .withNewTopicOperatorContainer() .withSecurityContext(securityContext) .endTopicOperatorContainer() .endTemplate() @@ -789,20 +691,10 @@ public void testTopicOperatorContainerSecurityContext() { @ParallelTest public void testRole() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .editOrNewEntityOperator() - .withNewTopicOperator() - .endTopicOperator() - .endEntityOperator() - .endSpec() - .build(); + Role role = ENTITY_OPERATOR.generateRole(NAMESPACE, NAMESPACE); - EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - Role role = eo.generateRole(namespace, namespace); - - assertThat(role.getMetadata().getName(), is("foo-entity-operator")); - assertThat(role.getMetadata().getNamespace(), is(namespace)); + assertThat(role.getMetadata().getName(), is("my-cluster-entity-operator")); + assertThat(role.getMetadata().getNamespace(), is(NAMESPACE)); List rules = new ArrayList<>(); rules.add(new PolicyRuleBuilder() @@ -830,90 +722,61 @@ public void testRole() { @ParallelTest public void testRoleInDifferentNamespace() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .editOrNewEntityOperator() - .withNewTopicOperator() - .endTopicOperator() - .endEntityOperator() - .endSpec() - .build(); - - EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - Role role = eo.generateRole(namespace, namespace); + Role role = ENTITY_OPERATOR.generateRole(NAMESPACE, NAMESPACE); + TestUtils.checkOwnerReference(role, KAFKA); - TestUtils.checkOwnerReference(role, resource); - - role = eo.generateRole(namespace, "some-other-namespace"); + role = ENTITY_OPERATOR.generateRole(NAMESPACE, "some-other-namespace"); assertThat(role.getMetadata().getOwnerReferences().size(), is(0)); } @ParallelTest public void testTopicOperatorNetworkPolicy() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .editOrNewEntityOperator() - .withNewTopicOperator() - .endTopicOperator() - .endEntityOperator() + .withNewEntityOperator() + .withNewTopicOperator() + .endTopicOperator() + .endEntityOperator() .endSpec() .build(); EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); NetworkPolicy np = eo.generateNetworkPolicy(); - assertThat(np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(EntityTopicOperator.HEALTHCHECK_PORT))).findFirst().orElse(null), is(notNullValue())); assertThat(np.getSpec().getIngress().size(), is(1)); assertThat(np.getSpec().getIngress().get(0).getPorts().get(0).getPort(), is(new IntOrString(EntityTopicOperator.HEALTHCHECK_PORT))); - List rules = np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(EntityTopicOperator.HEALTHCHECK_PORT))).map(NetworkPolicyIngressRule::getFrom).findFirst().orElse(null); + List rules = np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(EntityTopicOperator.HEALTHCHECK_PORT))).map(NetworkPolicyIngressRule::getFrom).findFirst().orElse(null); assertThat(rules.size(), is(0)); } @ParallelTest public void testUserOperatorNetworkPolicy() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .editOrNewEntityOperator() - .withNewUserOperator() - .endUserOperator() - .endEntityOperator() + .withNewEntityOperator() + .withNewUserOperator() + .endUserOperator() + .endEntityOperator() .endSpec() .build(); EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); NetworkPolicy np = eo.generateNetworkPolicy(); - assertThat(np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(EntityUserOperator.HEALTHCHECK_PORT))).findFirst().orElse(null), is(notNullValue())); assertThat(np.getSpec().getIngress().size(), is(1)); assertThat(np.getSpec().getIngress().get(0).getPorts().get(0).getPort(), is(new IntOrString(EntityUserOperator.HEALTHCHECK_PORT))); List rules = np.getSpec().getIngress().stream().filter(ing -> ing.getPorts().get(0).getPort().equals(new IntOrString(EntityUserOperator.HEALTHCHECK_PORT))).map(NetworkPolicyIngressRule::getFrom).findFirst().orElse(null); - assertThat(rules.size(), is(0)); - } @ParallelTest public void testUserOperatorAndTopicOperatorNetworkPolicy() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .editOrNewEntityOperator() - .withNewUserOperator() - .endUserOperator() - .withNewTopicOperator() - .endTopicOperator() - .endEntityOperator() - .endSpec() - .build(); - - EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - - NetworkPolicy np = eo.generateNetworkPolicy(); - + NetworkPolicy np = ENTITY_OPERATOR.generateNetworkPolicy(); assertThat(np.getSpec().getIngress().size(), is(2)); assertThat(np.getSpec().getIngress().get(0).getPorts().get(0).getPort(), is(new IntOrString(EntityTopicOperator.HEALTHCHECK_PORT))); assertThat(np.getSpec().getIngress().get(1).getPorts().get(0).getPort(), is(new IntOrString(EntityUserOperator.HEALTHCHECK_PORT))); @@ -921,25 +784,29 @@ public void testUserOperatorAndTopicOperatorNetworkPolicy() { @ParallelTest public void testFeatureGateEnvVars() { - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withNewEntityOperator() - .withNewTopicOperator() - .endTopicOperator() - .withNewUserOperator() - .endUserOperator() - .endEntityOperator() - .endSpec() - .build(); - ClusterOperatorConfig config = new ClusterOperatorConfig.ClusterOperatorConfigBuilder(ResourceUtils.dummyClusterOperatorConfig(), VERSIONS) .with(ClusterOperatorConfig.FEATURE_GATES.key(), "+ContinueReconciliationOnManualRollingUpdateFailure") .build(); - EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, config); + EntityOperator eo = EntityOperator.fromCrd(new Reconciliation("test", KAFKA.getKind(), KAFKA.getMetadata().getNamespace(), KAFKA.getMetadata().getName()), KAFKA, SHARED_ENV_PROVIDER, config); Deployment dep = eo.generateDeployment(Map.of(), false, null, null); assertThat(dep.getSpec().getTemplate().getSpec().getContainers().get(0).getEnv().stream().filter(env -> "STRIMZI_FEATURE_GATES".equals(env.getName())).map(EnvVar::getValue).findFirst().orElseThrow(), is("+ContinueReconciliationOnManualRollingUpdateFailure")); assertThat(dep.getSpec().getTemplate().getSpec().getContainers().get(1).getEnv().stream().filter(env -> "STRIMZI_FEATURE_GATES".equals(env.getName())).map(EnvVar::getValue).findFirst().orElseThrow(), is("+ContinueReconciliationOnManualRollingUpdateFailure")); } + + //////////////////// + // Utility methods + //////////////////// + + /** + * Converts list of volume mounts to a map. This is used also from the EUO and ETO test classes. + * + * @param mounts List of volume mounts + * + * @return Map with volume mounts where the mount name is used as a key + */ + static Map volumeMounts(List mounts) { + return mounts.stream().collect(Collectors.toMap(VolumeMount::getName, VolumeMount::getMountPath)); + } } \ No newline at end of file diff --git a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityTopicOperatorTest.java b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityTopicOperatorTest.java index 5d8f52eced4..19b90370ed8 100644 --- a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityTopicOperatorTest.java +++ b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityTopicOperatorTest.java @@ -7,30 +7,28 @@ import io.fabric8.kubernetes.api.model.Container; import io.fabric8.kubernetes.api.model.EnvVar; import io.fabric8.kubernetes.api.model.EnvVarBuilder; +import io.fabric8.kubernetes.api.model.Secret; import io.fabric8.kubernetes.api.model.SecretBuilder; import io.fabric8.kubernetes.api.model.rbac.RoleBinding; import io.strimzi.api.kafka.model.common.InlineLogging; import io.strimzi.api.kafka.model.common.JvmOptions; -import io.strimzi.api.kafka.model.common.Probe; import io.strimzi.api.kafka.model.common.RackBuilder; -import io.strimzi.api.kafka.model.common.SystemProperty; import io.strimzi.api.kafka.model.common.SystemPropertyBuilder; import io.strimzi.api.kafka.model.kafka.Kafka; import io.strimzi.api.kafka.model.kafka.KafkaBuilder; import io.strimzi.api.kafka.model.kafka.KafkaResources; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityOperatorSpec; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityOperatorSpecBuilder; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityOperatorTemplateBuilder; import io.strimzi.api.kafka.model.kafka.entityoperator.EntityTopicOperatorSpec; import io.strimzi.api.kafka.model.kafka.entityoperator.EntityTopicOperatorSpecBuilder; +import io.strimzi.api.kafka.model.kafka.listener.GenericKafkaListenerBuilder; +import io.strimzi.api.kafka.model.kafka.listener.KafkaListenerType; import io.strimzi.operator.cluster.ResourceUtils; +import io.strimzi.operator.common.Annotations; import io.strimzi.operator.common.Reconciliation; import io.strimzi.operator.common.Util; import io.strimzi.test.annotations.ParallelSuite; import io.strimzi.test.annotations.ParallelTest; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -48,119 +46,91 @@ @ParallelSuite public class EntityTopicOperatorTest { private static final SharedEnvironmentProvider SHARED_ENV_PROVIDER = new MockSharedEnvironmentProvider(); - - private final String namespace = "test"; - private final String cluster = "foo"; - private final int replicas = 3; - private final String image = "my-image:latest"; - private final int healthDelay = 120; - private final int healthTimeout = 30; - private final InlineLogging topicOperatorLogging = new InlineLogging(); - { - topicOperatorLogging.setLoggers(Collections.singletonMap("topic-operator.root.logger", "OFF")); - } - private final Probe livenessProbe = new Probe(); - { - livenessProbe.setInitialDelaySeconds(15); - livenessProbe.setTimeoutSeconds(20); - livenessProbe.setFailureThreshold(12); - livenessProbe.setSuccessThreshold(5); - livenessProbe.setPeriodSeconds(180); - } - - private final Probe readinessProbe = new Probe(); - { - readinessProbe.setInitialDelaySeconds(15); - readinessProbe.setInitialDelaySeconds(20); - readinessProbe.setFailureThreshold(12); - readinessProbe.setSuccessThreshold(5); - readinessProbe.setPeriodSeconds(180); - } - - private final String toWatchedNamespace = "my-topic-namespace"; - private final String toImage = "my-topic-operator-image"; - private final long reconciliationIntervalMs = 60_000L; - - private final List javaSystemProperties = new ArrayList<>() {{ - add(new SystemPropertyBuilder().withName("javax.net.debug").withValue("verbose").build()); - add(new SystemPropertyBuilder().withName("something.else").withValue("42").build()); - }}; - - private final EntityTopicOperatorSpec entityTopicOperatorSpec = new EntityTopicOperatorSpecBuilder() - .withWatchedNamespace(toWatchedNamespace) - .withImage(toImage) - .withReconciliationIntervalMs(reconciliationIntervalMs) - .withLivenessProbe(livenessProbe) - .withReadinessProbe(readinessProbe) - .withLogging(topicOperatorLogging) - .withNewJvmOptions() - .withXms("128m") - .addAllToJavaSystemProperties(javaSystemProperties) - .endJvmOptions() + private static final String NAMESPACE = "my-namespace"; + private static final String CLUSTER_NAME = "my-cluster"; + private static final Kafka KAFKA = new KafkaBuilder() + .withNewMetadata() + .withNamespace(NAMESPACE) + .withName(CLUSTER_NAME) + .withLabels(Map.of("my-user-label", "cromulent")) + .withAnnotations(Map.of(Annotations.ANNO_STRIMZI_IO_NODE_POOLS, "enabled", Annotations.ANNO_STRIMZI_IO_KRAFT, "enabled")) + .endMetadata() + .withNewSpec() + .withNewKafka() + .withListeners(new GenericKafkaListenerBuilder() + .withName("tls") + .withPort(9092) + .withType(KafkaListenerType.INTERNAL) + .withTls(true) + .build()) + .endKafka() + .withNewEntityOperator() + .withNewTopicOperator() + .withWatchedNamespace("my-topic-namespace") + .withImage("my-image:latest") + .withReconciliationIntervalMs(60_000L) + .withNewLivenessProbe() + .withInitialDelaySeconds(15) + .withTimeoutSeconds(20) + .withFailureThreshold(12) + .withSuccessThreshold(5) + .withPeriodSeconds(180) + .endLivenessProbe() + .withNewReadinessProbe() + .withInitialDelaySeconds(15) + .withTimeoutSeconds(20) + .withFailureThreshold(12) + .withSuccessThreshold(5) + .withPeriodSeconds(180) + .endReadinessProbe() + .withNewInlineLogging() + .withLoggers(Map.of("topic-operator.root.logger", "OFF")) + .endInlineLogging() + .withNewJvmOptions() + .withXms("128m") + .addAllToJavaSystemProperties(List.of(new SystemPropertyBuilder().withName("javax.net.debug").withValue("verbose").build(), + new SystemPropertyBuilder().withName("something.else").withValue("42").build())) + .endJvmOptions() + .endTopicOperator() + .withNewTemplate() + .withNewTopicOperatorRoleBinding() + .withNewMetadata() + .withLabels(Map.of("label-1", "value-1")) + .withAnnotations(Map.of("anno-1", "value-1")) + .endMetadata() + .endTopicOperatorRoleBinding() + .endTemplate() + .endEntityOperator() + .endSpec() .build(); - - private final EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withTopicOperator(entityTopicOperatorSpec) - .withTemplate(new EntityOperatorTemplateBuilder() - .withNewTopicOperatorRoleBinding() - .withNewMetadata() - .withLabels(Map.of("label-1", "value-1")) - .withAnnotations(Map.of("anno-1", "value-1")) - .endMetadata() - .endTopicOperatorRoleBinding() - .build()) - .build(); - - private final Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withEntityOperator(entityOperatorSpec) - .endSpec() - .build(); - - private final EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd( - new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - - private List getExpectedEnvVars() { - List expected = new ArrayList<>(); - expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_RESOURCE_LABELS).withValue(ModelUtils.defaultResourceLabels(cluster)).build()); - expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_KAFKA_BOOTSTRAP_SERVERS).withValue(KafkaResources.bootstrapServiceName(cluster) + ":" + KafkaCluster.REPLICATION_PORT).build()); - expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_WATCHED_NAMESPACE).withValue(toWatchedNamespace).build()); - expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_FULL_RECONCILIATION_INTERVAL_MS).withValue(String.valueOf(reconciliationIntervalMs)).build()); - expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_SECURITY_PROTOCOL).withValue(EntityTopicOperatorSpec.DEFAULT_SECURITY_PROTOCOL).build()); - expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_TLS_ENABLED).withValue(Boolean.toString(true)).build()); - expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_STRIMZI_GC_LOG_ENABLED).withValue(Boolean.toString(JvmOptions.DEFAULT_GC_LOGGING_ENABLED)).build()); - expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_STRIMZI_JAVA_OPTS).withValue("-Xms128m").build()); - expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_STRIMZI_JAVA_SYSTEM_PROPERTIES).withValue("-Djavax.net.debug=verbose -Dsomething.else=42").build()); - return expected; - } + private static final EntityTopicOperator ETO = EntityTopicOperator.fromCrd(new Reconciliation("test", KAFKA.getKind(), KAFKA.getMetadata().getNamespace(), KAFKA.getMetadata().getName()), KAFKA, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); @ParallelTest public void testEnvVars() { - assertThat(entityTopicOperator.getEnvVars(), is(getExpectedEnvVars())); + assertThat(ETO.getEnvVars(), is(getExpectedEnvVars())); } @ParallelTest public void testFromCrd() { - assertThat(entityTopicOperator.namespace, is(namespace)); - assertThat(entityTopicOperator.cluster, is(cluster)); - assertThat(entityTopicOperator.image, is(toImage)); - assertThat(entityTopicOperator.readinessProbeOptions.getInitialDelaySeconds(), is(readinessProbe.getInitialDelaySeconds())); - assertThat(entityTopicOperator.readinessProbeOptions.getTimeoutSeconds(), is(readinessProbe.getTimeoutSeconds())); - assertThat(entityTopicOperator.readinessProbeOptions.getSuccessThreshold(), is(readinessProbe.getSuccessThreshold())); - assertThat(entityTopicOperator.readinessProbeOptions.getFailureThreshold(), is(readinessProbe.getFailureThreshold())); - assertThat(entityTopicOperator.readinessProbeOptions.getPeriodSeconds(), is(readinessProbe.getPeriodSeconds())); - assertThat(entityTopicOperator.livenessProbeOptions.getInitialDelaySeconds(), is(livenessProbe.getInitialDelaySeconds())); - assertThat(entityTopicOperator.livenessProbeOptions.getTimeoutSeconds(), is(livenessProbe.getTimeoutSeconds())); - assertThat(entityTopicOperator.livenessProbeOptions.getSuccessThreshold(), is(livenessProbe.getSuccessThreshold())); - assertThat(entityTopicOperator.livenessProbeOptions.getFailureThreshold(), is(livenessProbe.getFailureThreshold())); - assertThat(entityTopicOperator.livenessProbeOptions.getPeriodSeconds(), is(livenessProbe.getPeriodSeconds())); - assertThat(entityTopicOperator.watchedNamespace(), is(toWatchedNamespace)); - assertThat(entityTopicOperator.reconciliationIntervalMs, is(reconciliationIntervalMs)); - assertThat(entityTopicOperator.kafkaBootstrapServers, is(KafkaResources.bootstrapServiceName(cluster) + ":" + KafkaCluster.REPLICATION_PORT)); - assertThat(entityTopicOperator.resourceLabels, is(ModelUtils.defaultResourceLabels(cluster))); - assertThat(entityTopicOperator.logging().getLogging().getType(), is(topicOperatorLogging.getType())); - assertThat(((InlineLogging) entityTopicOperator.logging().getLogging()).getLoggers(), is(topicOperatorLogging.getLoggers())); + assertThat(ETO.namespace, is(NAMESPACE)); + assertThat(ETO.cluster, is(CLUSTER_NAME)); + assertThat(ETO.image, is("my-image:latest")); + assertThat(ETO.readinessProbeOptions.getInitialDelaySeconds(), is(15)); + assertThat(ETO.readinessProbeOptions.getTimeoutSeconds(), is(20)); + assertThat(ETO.readinessProbeOptions.getSuccessThreshold(), is(5)); + assertThat(ETO.readinessProbeOptions.getFailureThreshold(), is(12)); + assertThat(ETO.readinessProbeOptions.getPeriodSeconds(), is(180)); + assertThat(ETO.livenessProbeOptions.getInitialDelaySeconds(), is(15)); + assertThat(ETO.livenessProbeOptions.getTimeoutSeconds(), is(20)); + assertThat(ETO.livenessProbeOptions.getSuccessThreshold(), is(5)); + assertThat(ETO.livenessProbeOptions.getFailureThreshold(), is(12)); + assertThat(ETO.livenessProbeOptions.getPeriodSeconds(), is(180)); + assertThat(ETO.watchedNamespace(), is("my-topic-namespace")); + assertThat(ETO.reconciliationIntervalMs, is(60_000L)); + assertThat(ETO.kafkaBootstrapServers, is(KafkaResources.bootstrapServiceName(CLUSTER_NAME) + ":" + KafkaCluster.REPLICATION_PORT)); + assertThat(ETO.resourceLabels, is(ModelUtils.defaultResourceLabels(CLUSTER_NAME))); + assertThat(ETO.logging().getLogging().getType(), is(InlineLogging.TYPE_INLINE)); + assertThat(((InlineLogging) ETO.logging().getLogging()).getLoggers(), is(Map.of("topic-operator.root.logger", "OFF"))); } @ParallelTest @@ -188,34 +158,34 @@ public void testPeriodicReconciliationIntervalConfig() { } private EntityTopicOperator buildEntityTopicOperatorWithReconciliationInterval(EntityTopicOperatorSpec topicOperatorSpec) { - EntityOperatorSpec eoSpec = new EntityOperatorSpecBuilder().withTopicOperator(topicOperatorSpec).build(); - Kafka kafka = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec().withEntityOperator(eoSpec).endSpec().build(); - return EntityTopicOperator.fromCrd(new Reconciliation("test", kafka.getKind(), kafka.getMetadata().getNamespace(), - kafka.getMetadata().getName()), kafka, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewEntityOperator() + .withTopicOperator(topicOperatorSpec) + .endEntityOperator() + .endSpec() + .build(); + + return EntityTopicOperator.fromCrd(new Reconciliation("test", kafka.getKind(), kafka.getMetadata().getNamespace(), kafka.getMetadata().getName()), kafka, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); } @ParallelTest public void testFromCrdDefault() { - EntityTopicOperatorSpec entityTopicOperatorSpec = new EntityTopicOperatorSpecBuilder() - .build(); - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withTopicOperator(entityTopicOperatorSpec) + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .withNewEntityOperator() + .withNewTopicOperator() + .endTopicOperator() + .endEntityOperator() + .endSpec() .build(); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withEntityOperator(entityOperatorSpec) - .endSpec() - .build(); - EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd( - new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); + EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - assertThat(entityTopicOperator.watchedNamespace(), is(namespace)); + assertThat(entityTopicOperator.watchedNamespace(), is(NAMESPACE)); assertThat(entityTopicOperator.getImage(), is("quay.io/strimzi/operator:latest")); assertThat(entityTopicOperator.reconciliationIntervalMs, nullValue()); - assertThat(entityTopicOperator.kafkaBootstrapServers, is(KafkaResources.bootstrapServiceName(cluster) + ":" + KafkaCluster.REPLICATION_PORT)); - assertThat(entityTopicOperator.resourceLabels, is(ModelUtils.defaultResourceLabels(cluster))); + assertThat(entityTopicOperator.kafkaBootstrapServers, is(KafkaResources.bootstrapServiceName(CLUSTER_NAME) + ":" + KafkaCluster.REPLICATION_PORT)); + assertThat(entityTopicOperator.resourceLabels, is(ModelUtils.defaultResourceLabels(CLUSTER_NAME))); assertThat(entityTopicOperator.readinessProbeOptions.getInitialDelaySeconds(), is(10)); assertThat(entityTopicOperator.readinessProbeOptions.getTimeoutSeconds(), is(5)); assertThat(entityTopicOperator.livenessProbeOptions.getInitialDelaySeconds(), is(10)); @@ -225,55 +195,38 @@ public void testFromCrdDefault() { @ParallelTest public void testFromCrdNoEntityOperator() { - Kafka resource = ResourceUtils.createKafka(namespace, cluster, replicas, image, - healthDelay, healthTimeout); - EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd( - new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - assertThat(entityTopicOperator, is(nullValue())); - } + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .withEntityOperator(null) + .endSpec() + .build(); + EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - @ParallelTest - public void testFromCrdNoTopicOperatorInEntityOperator() { - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder().build(); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withEntityOperator(entityOperatorSpec) - .endSpec() - .build(); - EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd( - new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); assertThat(entityTopicOperator, is(nullValue())); } @ParallelTest - public void testNoWatchedNamespace() { - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withNewTopicOperator() - .endTopicOperator() + public void testFromCrdNoTopicOperatorInEntityOperator() { + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .withNewEntityOperator() + .endEntityOperator() + .endSpec() .build(); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withEntityOperator(entityOperatorSpec) - .endSpec() - .build(); - - EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd( - new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); + EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - assertThat(entityTopicOperator.watchedNamespace(), is(namespace)); + assertThat(entityTopicOperator, is(nullValue())); } @ParallelTest public void testWatchedNamespace() { - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withNewTopicOperator() - .withWatchedNamespace("some-other-namespace") - .endTopicOperator() - .build(); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withEntityOperator(entityOperatorSpec) + .editEntityOperator() + .editTopicOperator() + .withWatchedNamespace("some-other-namespace") + .endTopicOperator() + .endEntityOperator() .endSpec() .build(); @@ -285,14 +238,14 @@ public void testWatchedNamespace() { @ParallelTest public void testGetContainers() { - Container container = entityTopicOperator.createContainer(null); + Container container = ETO.createContainer(null); assertThat(container.getName(), is(EntityTopicOperator.TOPIC_OPERATOR_CONTAINER_NAME)); - assertThat(container.getImage(), is(entityTopicOperator.getImage())); + assertThat(container.getImage(), is(ETO.getImage())); assertThat(container.getEnv(), is(getExpectedEnvVars())); - assertThat(container.getLivenessProbe().getInitialDelaySeconds(), is(livenessProbe.getInitialDelaySeconds())); - assertThat(container.getLivenessProbe().getTimeoutSeconds(), is(livenessProbe.getTimeoutSeconds())); - assertThat(container.getReadinessProbe().getInitialDelaySeconds(), is(readinessProbe.getInitialDelaySeconds())); - assertThat(container.getReadinessProbe().getTimeoutSeconds(), is(readinessProbe.getTimeoutSeconds())); + assertThat(container.getLivenessProbe().getInitialDelaySeconds(), is(15)); + assertThat(container.getLivenessProbe().getTimeoutSeconds(), is(20)); + assertThat(container.getReadinessProbe().getInitialDelaySeconds(), is(15)); + assertThat(container.getReadinessProbe().getTimeoutSeconds(), is(20)); assertThat(container.getPorts().size(), is(1)); assertThat(container.getPorts().get(0).getContainerPort(), is(EntityTopicOperator.HEALTHCHECK_PORT)); assertThat(container.getPorts().get(0).getName(), is(EntityTopicOperator.HEALTHCHECK_PORT_NAME)); @@ -306,65 +259,59 @@ public void testGetContainers() { @ParallelTest public void testRoleBindingInOtherNamespace() { - RoleBinding binding = entityTopicOperator.generateRoleBindingForRole(namespace, toWatchedNamespace); + RoleBinding binding = ETO.generateRoleBindingForRole(NAMESPACE, "my-topic-namespace"); - assertThat(binding.getSubjects().get(0).getNamespace(), is(namespace)); - assertThat(binding.getMetadata().getNamespace(), is(toWatchedNamespace)); + assertThat(binding.getSubjects().get(0).getNamespace(), is(NAMESPACE)); + assertThat(binding.getMetadata().getNamespace(), is("my-topic-namespace")); assertThat(binding.getMetadata().getOwnerReferences().size(), is(0)); assertThat(binding.getMetadata().getLabels().get("label-1"), is("value-1")); assertThat(binding.getMetadata().getAnnotations().get("anno-1"), is("value-1")); assertThat(binding.getRoleRef().getKind(), is("Role")); - assertThat(binding.getRoleRef().getName(), is("foo-entity-operator")); + assertThat(binding.getRoleRef().getName(), is("my-cluster-entity-operator")); } @ParallelTest public void testRoleBindingInTheSameNamespace() { - RoleBinding binding = entityTopicOperator.generateRoleBindingForRole(namespace, namespace); + RoleBinding binding = ETO.generateRoleBindingForRole(NAMESPACE, NAMESPACE); - assertThat(binding.getSubjects().get(0).getNamespace(), is(namespace)); - assertThat(binding.getMetadata().getNamespace(), is(namespace)); + assertThat(binding.getSubjects().get(0).getNamespace(), is(NAMESPACE)); + assertThat(binding.getMetadata().getNamespace(), is(NAMESPACE)); assertThat(binding.getMetadata().getOwnerReferences().size(), is(1)); assertThat(binding.getMetadata().getLabels().get("label-1"), is("value-1")); assertThat(binding.getMetadata().getAnnotations().get("anno-1"), is("value-1")); assertThat(binding.getRoleRef().getKind(), is("Role")); - assertThat(binding.getRoleRef().getName(), is("foo-entity-operator")); + assertThat(binding.getRoleRef().getName(), is("my-cluster-entity-operator")); } @ParallelTest public void testSetupWithCruiseControlEnabled() { - EntityTopicOperatorSpec entityTopicOperatorSpec = new EntityTopicOperatorSpecBuilder() - .build(); - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withTopicOperator(entityTopicOperatorSpec) - .build(); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .editKafka().withRack(new RackBuilder() - .withTopologyKey("foo") - .build()) + .editKafka() + .withRack(new RackBuilder().withTopologyKey("foo").build()) .endKafka() - .withEntityOperator(entityOperatorSpec) + .withNewEntityOperator() + .withNewTopicOperator() + .endTopicOperator() + .endEntityOperator() .withNewCruiseControl() .endCruiseControl() .endSpec() .build(); - EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd( - new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), - resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); + EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); List expectedEnvVars = new ArrayList<>(); - expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_RESOURCE_LABELS).withValue(ModelUtils.defaultResourceLabels(cluster)).build()); - expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_KAFKA_BOOTSTRAP_SERVERS).withValue(KafkaResources.bootstrapServiceName(cluster) + ":" + KafkaCluster.REPLICATION_PORT).build()); - expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_WATCHED_NAMESPACE).withValue(namespace).build()); + expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_RESOURCE_LABELS).withValue(ModelUtils.defaultResourceLabels(CLUSTER_NAME)).build()); + expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_KAFKA_BOOTSTRAP_SERVERS).withValue(KafkaResources.bootstrapServiceName(CLUSTER_NAME) + ":" + KafkaCluster.REPLICATION_PORT).build()); + expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_WATCHED_NAMESPACE).withValue(NAMESPACE).build()); expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_SECURITY_PROTOCOL).withValue(EntityTopicOperatorSpec.DEFAULT_SECURITY_PROTOCOL).build()); expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_TLS_ENABLED).withValue(Boolean.toString(true)).build()); expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_STRIMZI_GC_LOG_ENABLED).withValue(Boolean.toString(JvmOptions.DEFAULT_GC_LOGGING_ENABLED)).build()); expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_CRUISE_CONTROL_ENABLED).withValue(Boolean.toString(true)).build()); expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_CRUISE_CONTROL_RACK_ENABLED).withValue(Boolean.toString(true)).build()); - expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_CRUISE_CONTROL_HOSTNAME).withValue(String.format("%s-cruise-control.%s.svc", cluster, namespace)).build()); + expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_CRUISE_CONTROL_HOSTNAME).withValue(String.format("%s-cruise-control.%s.svc", CLUSTER_NAME, NAMESPACE)).build()); expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_CRUISE_CONTROL_PORT).withValue(String.valueOf(CRUISE_CONTROL_API_PORT)).build()); expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_CRUISE_CONTROL_SSL_ENABLED).withValue(Boolean.toString(true)).build()); expectedEnvVars.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_CRUISE_CONTROL_AUTH_ENABLED).withValue(Boolean.toString(true)).build()); @@ -382,53 +329,56 @@ public void testSetupWithCruiseControlEnabled() { @ParallelTest public void testGenerateCruiseControlApiSecret() { - EntityTopicOperatorSpec entityTopicOperatorSpec = new EntityTopicOperatorSpecBuilder() - .build(); - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withTopicOperator(entityTopicOperatorSpec) - .build(); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withEntityOperator(entityOperatorSpec) + .withNewEntityOperator() + .withNewTopicOperator() + .endTopicOperator() + .endEntityOperator() .withNewCruiseControl() .endCruiseControl() .endSpec() .build(); - EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd( - new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), - resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); + EntityTopicOperator entityTopicOperator = EntityTopicOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - var newSecret = entityTopicOperator.generateCruiseControlApiSecret(null); + Secret newSecret = entityTopicOperator.generateCruiseControlApiSecret(null); assertThat(newSecret, is(notNullValue())); assertThat(newSecret.getData(), is(notNullValue())); assertThat(newSecret.getData().size(), is(2)); assertThat(newSecret.getData().get(TOPIC_OPERATOR_USERNAME_KEY), is(Util.encodeToBase64(TOPIC_OPERATOR_USERNAME))); assertThat(newSecret.getData().get(TOPIC_OPERATOR_USERNAME_KEY), is(notNullValue())); - var name = Util.encodeToBase64(TOPIC_OPERATOR_USERNAME); - var password = Util.encodeToBase64("changeit"); - var oldSecret = entityTopicOperator.generateCruiseControlApiSecret( - new SecretBuilder().withData(Map.of(TOPIC_OPERATOR_USERNAME_KEY, name, TOPIC_OPERATOR_PASSWORD_KEY, password)).build()); + String name = Util.encodeToBase64(TOPIC_OPERATOR_USERNAME); + String password = Util.encodeToBase64("change-it"); + Secret oldSecret = entityTopicOperator.generateCruiseControlApiSecret(new SecretBuilder().withData(Map.of(TOPIC_OPERATOR_USERNAME_KEY, name, TOPIC_OPERATOR_PASSWORD_KEY, password)).build()); assertThat(oldSecret, is(notNullValue())); assertThat(oldSecret.getData(), is(notNullValue())); assertThat(oldSecret.getData().size(), is(2)); assertThat(oldSecret.getData().get(TOPIC_OPERATOR_USERNAME_KEY), is(name)); assertThat(oldSecret.getData().get(TOPIC_OPERATOR_PASSWORD_KEY), is(password)); - assertThrows(RuntimeException.class, () -> entityTopicOperator.generateCruiseControlApiSecret( - new SecretBuilder().withData(Map.of(TOPIC_OPERATOR_USERNAME_KEY, name)).build())); - - assertThrows(RuntimeException.class, () -> entityTopicOperator.generateCruiseControlApiSecret( - new SecretBuilder().withData(Map.of(TOPIC_OPERATOR_PASSWORD_KEY, password)).build())); - - assertThrows(RuntimeException.class, () -> entityTopicOperator.generateCruiseControlApiSecret( - new SecretBuilder().withData(Map.of()).build())); + assertThrows(RuntimeException.class, () -> entityTopicOperator.generateCruiseControlApiSecret(new SecretBuilder().withData(Map.of(TOPIC_OPERATOR_USERNAME_KEY, name)).build())); + assertThrows(RuntimeException.class, () -> entityTopicOperator.generateCruiseControlApiSecret(new SecretBuilder().withData(Map.of(TOPIC_OPERATOR_PASSWORD_KEY, password)).build())); + assertThrows(RuntimeException.class, () -> entityTopicOperator.generateCruiseControlApiSecret(new SecretBuilder().withData(Map.of()).build())); + assertThrows(RuntimeException.class, () -> entityTopicOperator.generateCruiseControlApiSecret(new SecretBuilder().withData(Map.of(TOPIC_OPERATOR_USERNAME_KEY, " ", TOPIC_OPERATOR_PASSWORD_KEY, password)).build())); + assertThrows(RuntimeException.class, () -> entityTopicOperator.generateCruiseControlApiSecret(new SecretBuilder().withData(Map.of(TOPIC_OPERATOR_USERNAME_KEY, name, TOPIC_OPERATOR_PASSWORD_KEY, " ")).build())); + } - assertThrows(RuntimeException.class, () -> entityTopicOperator.generateCruiseControlApiSecret( - new SecretBuilder().withData(Map.of(TOPIC_OPERATOR_USERNAME_KEY, " ", TOPIC_OPERATOR_PASSWORD_KEY, password)).build())); + //////////////////// + // Utility methods + //////////////////// - assertThrows(RuntimeException.class, () -> entityTopicOperator.generateCruiseControlApiSecret( - new SecretBuilder().withData(Map.of(TOPIC_OPERATOR_USERNAME_KEY, name, TOPIC_OPERATOR_PASSWORD_KEY, " ")).build())); + private List getExpectedEnvVars() { + List expected = new ArrayList<>(); + expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_RESOURCE_LABELS).withValue(ModelUtils.defaultResourceLabels(CLUSTER_NAME)).build()); + expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_KAFKA_BOOTSTRAP_SERVERS).withValue(KafkaResources.bootstrapServiceName(CLUSTER_NAME) + ":" + KafkaCluster.REPLICATION_PORT).build()); + expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_WATCHED_NAMESPACE).withValue("my-topic-namespace").build()); + expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_FULL_RECONCILIATION_INTERVAL_MS).withValue(String.valueOf(60000)).build()); + expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_SECURITY_PROTOCOL).withValue(EntityTopicOperatorSpec.DEFAULT_SECURITY_PROTOCOL).build()); + expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_TLS_ENABLED).withValue(Boolean.toString(true)).build()); + expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_STRIMZI_GC_LOG_ENABLED).withValue(Boolean.toString(JvmOptions.DEFAULT_GC_LOGGING_ENABLED)).build()); + expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_STRIMZI_JAVA_OPTS).withValue("-Xms128m").build()); + expected.add(new EnvVarBuilder().withName(EntityTopicOperator.ENV_VAR_STRIMZI_JAVA_SYSTEM_PROPERTIES).withValue("-Djavax.net.debug=verbose -Dsomething.else=42").build()); + return expected; } } diff --git a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityUserOperatorTest.java b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityUserOperatorTest.java index 2ed37b8971c..268645f7fc4 100644 --- a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityUserOperatorTest.java +++ b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/EntityUserOperatorTest.java @@ -11,10 +11,7 @@ import io.strimzi.api.kafka.model.common.CertificateAuthority; import io.strimzi.api.kafka.model.common.InlineLogging; import io.strimzi.api.kafka.model.common.JvmOptions; -import io.strimzi.api.kafka.model.common.Probe; -import io.strimzi.api.kafka.model.common.SystemProperty; import io.strimzi.api.kafka.model.common.SystemPropertyBuilder; -import io.strimzi.api.kafka.model.common.metrics.JmxPrometheusExporterMetrics; import io.strimzi.api.kafka.model.kafka.Kafka; import io.strimzi.api.kafka.model.kafka.KafkaAuthorization; import io.strimzi.api.kafka.model.kafka.KafkaAuthorizationCustomBuilder; @@ -23,25 +20,21 @@ import io.strimzi.api.kafka.model.kafka.KafkaAuthorizationSimple; import io.strimzi.api.kafka.model.kafka.KafkaBuilder; import io.strimzi.api.kafka.model.kafka.KafkaResources; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityOperatorSpec; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityOperatorSpecBuilder; -import io.strimzi.api.kafka.model.kafka.entityoperator.EntityOperatorTemplateBuilder; import io.strimzi.api.kafka.model.kafka.entityoperator.EntityUserOperatorSpec; import io.strimzi.api.kafka.model.kafka.entityoperator.EntityUserOperatorSpecBuilder; +import io.strimzi.api.kafka.model.kafka.listener.GenericKafkaListenerBuilder; +import io.strimzi.api.kafka.model.kafka.listener.KafkaListenerType; import io.strimzi.operator.cluster.ResourceUtils; -import io.strimzi.operator.cluster.model.metrics.MetricsModel; +import io.strimzi.operator.common.Annotations; import io.strimzi.operator.common.Reconciliation; import io.strimzi.test.annotations.ParallelSuite; import io.strimzi.test.annotations.ParallelTest; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; import static io.strimzi.test.TestUtils.map; -import static java.util.Collections.emptyMap; -import static java.util.Collections.singletonMap; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; @@ -49,138 +42,92 @@ @ParallelSuite public class EntityUserOperatorTest { private static final SharedEnvironmentProvider SHARED_ENV_PROVIDER = new MockSharedEnvironmentProvider(); - - private final String namespace = "test"; - private final String cluster = "foo"; - private final int replicas = 3; - private final String image = "my-image:latest"; - private final int healthDelay = 120; - private final int healthTimeout = 30; - private final InlineLogging userOperatorLogging = new InlineLogging(); - { - userOperatorLogging.setLoggers(Collections.singletonMap("user-operator.root.logger", "OFF")); - } - private final Probe livenessProbe = new Probe(); - { - livenessProbe.setInitialDelaySeconds(15); - livenessProbe.setTimeoutSeconds(20); - livenessProbe.setFailureThreshold(12); - livenessProbe.setSuccessThreshold(5); - livenessProbe.setPeriodSeconds(180); - } - - private final Probe readinessProbe = new Probe(); - { - readinessProbe.setInitialDelaySeconds(15); - livenessProbe.setInitialDelaySeconds(20); - readinessProbe.setFailureThreshold(12); - readinessProbe.setSuccessThreshold(5); - readinessProbe.setPeriodSeconds(180); - } - - private final String uoWatchedNamespace = "my-user-namespace"; - private final String uoImage = "my-user-operator-image"; - private final String secretPrefix = "strimzi-"; - private final long reconciliationIntervalMs = 60_000L; - - private final String metricsCMName = "metrics-cm"; - private final JmxPrometheusExporterMetrics jmxMetricsConfig = io.strimzi.operator.cluster.TestUtils.getJmxPrometheusExporterMetrics(MetricsModel.CONFIG_MAP_KEY, metricsCMName); - private final List javaSystemProperties = new ArrayList<>() {{ - add(new SystemPropertyBuilder().withName("javax.net.debug").withValue("verbose").build()); - add(new SystemPropertyBuilder().withName("something.else").withValue("42").build()); - }}; - - private final EntityUserOperatorSpec entityUserOperatorSpec = new EntityUserOperatorSpecBuilder() - .withWatchedNamespace(uoWatchedNamespace) - .withImage(uoImage) - .withReconciliationIntervalMs(reconciliationIntervalMs) - .withSecretPrefix(secretPrefix) - .withLivenessProbe(livenessProbe) - .withReadinessProbe(readinessProbe) - .withLogging(userOperatorLogging) - .withNewJvmOptions() - .addAllToJavaSystemProperties(javaSystemProperties) - .withXmx("256m") - .endJvmOptions() - .build(); - - private final EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withUserOperator(entityUserOperatorSpec) - .withTemplate(new EntityOperatorTemplateBuilder() - .withNewUserOperatorRoleBinding() - .withNewMetadata() - .withLabels(Map.of("label-1", "value-1")) - .withAnnotations(Map.of("anno-1", "value-1")) - .endMetadata() - .endUserOperatorRoleBinding() - .build()) + private static final String NAMESPACE = "my-namespace"; + private static final String CLUSTER_NAME = "my-cluster"; + private static final Kafka KAFKA = new KafkaBuilder() + .withNewMetadata() + .withNamespace(NAMESPACE) + .withName(CLUSTER_NAME) + .withLabels(Map.of("my-user-label", "cromulent")) + .withAnnotations(Map.of(Annotations.ANNO_STRIMZI_IO_NODE_POOLS, "enabled", Annotations.ANNO_STRIMZI_IO_KRAFT, "enabled")) + .endMetadata() + .withNewSpec() + .withNewKafka() + .withListeners(new GenericKafkaListenerBuilder() + .withName("tls") + .withPort(9092) + .withType(KafkaListenerType.INTERNAL) + .withTls(true) + .build()) + .endKafka() + .withNewEntityOperator() + .withNewUserOperator() + .withWatchedNamespace("my-user-namespace") + .withImage("my-image:latest") + .withReconciliationIntervalMs(60_000L) + .withSecretPrefix("strimzi-") + .withNewLivenessProbe() + .withInitialDelaySeconds(15) + .withTimeoutSeconds(20) + .withFailureThreshold(12) + .withSuccessThreshold(5) + .withPeriodSeconds(180) + .endLivenessProbe() + .withNewReadinessProbe() + .withInitialDelaySeconds(15) + .withTimeoutSeconds(20) + .withFailureThreshold(12) + .withSuccessThreshold(5) + .withPeriodSeconds(180) + .endReadinessProbe() + .withNewInlineLogging() + .withLoggers(Map.of("user-operator.root.logger", "OFF")) + .endInlineLogging() + .withNewJvmOptions() + .withXmx("256m") + .addAllToJavaSystemProperties(List.of(new SystemPropertyBuilder().withName("javax.net.debug").withValue("verbose").build(), + new SystemPropertyBuilder().withName("something.else").withValue("42").build())) + .endJvmOptions() + .endUserOperator() + .withNewTemplate() + .withNewUserOperatorRoleBinding() + .withNewMetadata() + .withLabels(Map.of("label-1", "value-1")) + .withAnnotations(Map.of("anno-1", "value-1")) + .endMetadata() + .endUserOperatorRoleBinding() + .endTemplate() + .endEntityOperator() + .endSpec() .build(); - - private final Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withEntityOperator(entityOperatorSpec) - .endSpec() - .build(); - - private final EntityUserOperator entityUserOperator = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - - private List getExpectedEnvVars() { - List expected = new ArrayList<>(); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_KAFKA_BOOTSTRAP_SERVERS).withValue(String.format("%s:%d", "foo-kafka-bootstrap", EntityUserOperatorSpec.DEFAULT_BOOTSTRAP_SERVERS_PORT)).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_WATCHED_NAMESPACE).withValue(uoWatchedNamespace).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_RESOURCE_LABELS).withValue(ModelUtils.defaultResourceLabels(cluster)).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_FULL_RECONCILIATION_INTERVAL_MS).withValue(String.valueOf(reconciliationIntervalMs)).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLIENTS_CA_KEY_SECRET_NAME).withValue(KafkaResources.clientsCaKeySecretName(cluster)).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLIENTS_CA_CERT_SECRET_NAME).withValue(KafkaResources.clientsCaCertificateSecretName(cluster)).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLIENTS_CA_NAMESPACE).withValue(namespace).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLUSTER_CA_CERT_SECRET_NAME).withValue(KafkaCluster.clusterCaCertSecretName(cluster)).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_EO_KEY_SECRET_NAME).withValue(KafkaResources.entityUserOperatorSecretName(cluster)).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_STRIMZI_GC_LOG_ENABLED).withValue(Boolean.toString(JvmOptions.DEFAULT_GC_LOGGING_ENABLED)).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLIENTS_CA_VALIDITY).withValue(Integer.toString(CertificateAuthority.DEFAULT_CERTS_VALIDITY_DAYS)).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLIENTS_CA_RENEWAL).withValue(Integer.toString(CertificateAuthority.DEFAULT_CERTS_RENEWAL_DAYS)).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_STRIMZI_JAVA_OPTS).withValue("-Xmx256m").build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_STRIMZI_JAVA_SYSTEM_PROPERTIES).withValue("-Djavax.net.debug=verbose -Dsomething.else=42").build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_SECRET_PREFIX).withValue(secretPrefix).build()); - expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_ACLS_ADMIN_API_SUPPORTED).withValue(String.valueOf(false)).build()); - - return expected; - } - - private void checkEnvVars(List expected, List actual) { - assertThat(actual.size(), is(expected.size())); - - for (EnvVar var : expected) { - assertThat(actual.contains(var), is(true)); - } - } + private static final EntityUserOperator EUO = EntityUserOperator.fromCrd(new Reconciliation("test", KAFKA.getKind(), KAFKA.getMetadata().getNamespace(), KAFKA.getMetadata().getName()), KAFKA, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); @ParallelTest public void testEnvVars() { - checkEnvVars(getExpectedEnvVars(), entityUserOperator.getEnvVars()); + checkEnvVars(getExpectedEnvVars(), EUO.getEnvVars()); } @ParallelTest public void testFromCrd() { - assertThat(entityUserOperator.namespace, is(namespace)); - assertThat(entityUserOperator.cluster, is(cluster)); - assertThat(entityUserOperator.image, is(uoImage)); - assertThat(entityUserOperator.readinessProbeOptions.getInitialDelaySeconds(), is(readinessProbe.getInitialDelaySeconds())); - assertThat(entityUserOperator.readinessProbeOptions.getTimeoutSeconds(), is(readinessProbe.getTimeoutSeconds())); - assertThat(entityUserOperator.readinessProbeOptions.getSuccessThreshold(), is(readinessProbe.getSuccessThreshold())); - assertThat(entityUserOperator.readinessProbeOptions.getFailureThreshold(), is(readinessProbe.getFailureThreshold())); - assertThat(entityUserOperator.readinessProbeOptions.getPeriodSeconds(), is(readinessProbe.getPeriodSeconds())); - assertThat(entityUserOperator.livenessProbeOptions.getInitialDelaySeconds(), is(livenessProbe.getInitialDelaySeconds())); - assertThat(entityUserOperator.livenessProbeOptions.getTimeoutSeconds(), is(livenessProbe.getTimeoutSeconds())); - assertThat(entityUserOperator.livenessProbeOptions.getSuccessThreshold(), is(livenessProbe.getSuccessThreshold())); - assertThat(entityUserOperator.livenessProbeOptions.getFailureThreshold(), is(livenessProbe.getFailureThreshold())); - assertThat(entityUserOperator.livenessProbeOptions.getPeriodSeconds(), is(livenessProbe.getPeriodSeconds())); - assertThat(entityUserOperator.watchedNamespace(), is(uoWatchedNamespace)); - assertThat(entityUserOperator.reconciliationIntervalMs, is(reconciliationIntervalMs)); - assertThat(entityUserOperator.kafkaBootstrapServers, is(String.format("%s:%d", KafkaResources.bootstrapServiceName(cluster), EntityUserOperatorSpec.DEFAULT_BOOTSTRAP_SERVERS_PORT))); - assertThat(entityUserOperator.logging().getLogging().getType(), is(userOperatorLogging.getType())); - assertThat(((InlineLogging) entityUserOperator.logging().getLogging()).getLoggers(), is(userOperatorLogging.getLoggers())); - assertThat(entityUserOperator.secretPrefix, is(secretPrefix)); + assertThat(EUO.namespace, is(NAMESPACE)); + assertThat(EUO.cluster, is(CLUSTER_NAME)); + assertThat(EUO.image, is("my-image:latest")); + assertThat(EUO.readinessProbeOptions.getInitialDelaySeconds(), is(15)); + assertThat(EUO.readinessProbeOptions.getTimeoutSeconds(), is(20)); + assertThat(EUO.readinessProbeOptions.getSuccessThreshold(), is(5)); + assertThat(EUO.readinessProbeOptions.getFailureThreshold(), is(12)); + assertThat(EUO.readinessProbeOptions.getPeriodSeconds(), is(180)); + assertThat(EUO.livenessProbeOptions.getInitialDelaySeconds(), is(15)); + assertThat(EUO.livenessProbeOptions.getTimeoutSeconds(), is(20)); + assertThat(EUO.livenessProbeOptions.getSuccessThreshold(), is(5)); + assertThat(EUO.livenessProbeOptions.getFailureThreshold(), is(12)); + assertThat(EUO.livenessProbeOptions.getPeriodSeconds(), is(180)); + assertThat(EUO.watchedNamespace(), is("my-user-namespace")); + assertThat(EUO.reconciliationIntervalMs, is(60_000L)); + assertThat(EUO.kafkaBootstrapServers, is(String.format("%s:%d", KafkaResources.bootstrapServiceName(CLUSTER_NAME), EntityUserOperatorSpec.DEFAULT_BOOTSTRAP_SERVERS_PORT))); + assertThat(EUO.logging().getLogging().getType(), is(InlineLogging.TYPE_INLINE)); + assertThat(((InlineLogging) EUO.logging().getLogging()).getLoggers(), is(Map.of("user-operator.root.logger", "OFF"))); + assertThat(EUO.secretPrefix, is("strimzi-")); } @ParallelTest @@ -208,46 +155,49 @@ public void testPeriodicReconciliationIntervalConfig() { } private EntityUserOperator buildEntityUserOperatorWithReconciliationInterval(EntityUserOperatorSpec userOperatorSpec) { - EntityOperatorSpec eoSpec = new EntityOperatorSpecBuilder().withUserOperator(userOperatorSpec).build(); - Kafka kafka = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec().withEntityOperator(eoSpec).endSpec().build(); - return EntityUserOperator.fromCrd(new Reconciliation("test", kafka.getKind(), kafka.getMetadata().getNamespace(), - kafka.getMetadata().getName()), kafka, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); + Kafka kafka = new KafkaBuilder(KAFKA) + .editSpec() + .withNewEntityOperator() + .withUserOperator(userOperatorSpec) + .endEntityOperator() + .endSpec() + .build(); + + return EntityUserOperator.fromCrd(new Reconciliation("test", kafka.getKind(), kafka.getMetadata().getNamespace(), kafka.getMetadata().getName()), kafka, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); } @ParallelTest public void testFromCrdDefault() { - EntityUserOperatorSpec entityUserOperatorSpec = new EntityUserOperatorSpecBuilder() - .build(); - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withUserOperator(entityUserOperatorSpec) + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .withNewEntityOperator() + .withNewUserOperator() + .endUserOperator() + .endEntityOperator() + .endSpec() .build(); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withEntityOperator(entityOperatorSpec) - .endSpec() - .build(); EntityUserOperator entityUserOperator = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - assertThat(entityUserOperator.watchedNamespace(), is(namespace)); + assertThat(entityUserOperator.watchedNamespace(), is(NAMESPACE)); assertThat(entityUserOperator.getImage(), is("quay.io/strimzi/operator:latest")); assertThat(entityUserOperator.reconciliationIntervalMs, nullValue()); assertThat(entityUserOperator.readinessProbeOptions.getInitialDelaySeconds(), is(10)); assertThat(entityUserOperator.readinessProbeOptions.getTimeoutSeconds(), is(5)); assertThat(entityUserOperator.livenessProbeOptions.getInitialDelaySeconds(), is(10)); assertThat(entityUserOperator.livenessProbeOptions.getTimeoutSeconds(), is(5)); - assertThat(entityUserOperator.kafkaBootstrapServers, is(KafkaResources.bootstrapServiceName(cluster) + ":" + EntityUserOperatorSpec.DEFAULT_BOOTSTRAP_SERVERS_PORT)); + assertThat(entityUserOperator.kafkaBootstrapServers, is(KafkaResources.bootstrapServiceName(CLUSTER_NAME) + ":" + EntityUserOperatorSpec.DEFAULT_BOOTSTRAP_SERVERS_PORT)); assertThat(entityUserOperator.logging().getLogging(), is(nullValue())); assertThat(entityUserOperator.secretPrefix, is(EntityUserOperatorSpec.DEFAULT_SECRET_PREFIX)); } @ParallelTest public void testFromCrdNoEntityOperator() { - Kafka resource = ResourceUtils.createKafka(namespace, cluster, replicas, image, - healthDelay, healthTimeout); - + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .withEntityOperator(null) + .endSpec() + .build(); EntityUserOperator entityUserOperator = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); assertThat(entityUserOperator, is(nullValue())); @@ -255,14 +205,12 @@ public void testFromCrdNoEntityOperator() { @ParallelTest public void testFromCrdNoUserOperatorInEntityOperator() { - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder().build(); - Kafka resource = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withEntityOperator(entityOperatorSpec) - .endSpec() - .build(); - + Kafka resource = new KafkaBuilder(KAFKA) + .editSpec() + .withNewEntityOperator() + .endEntityOperator() + .endSpec() + .build(); EntityUserOperator entityUserOperator = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); assertThat(entityUserOperator, is(nullValue())); @@ -270,14 +218,14 @@ public void testFromCrdNoUserOperatorInEntityOperator() { @ParallelTest public void testGetContainers() { - Container container = entityUserOperator.createContainer(null); + Container container = EUO.createContainer(null); assertThat(container.getName(), is(EntityUserOperator.USER_OPERATOR_CONTAINER_NAME)); - assertThat(container.getImage(), is(entityUserOperator.getImage())); + assertThat(container.getImage(), is(EUO.getImage())); checkEnvVars(getExpectedEnvVars(), container.getEnv()); - assertThat(container.getLivenessProbe().getInitialDelaySeconds(), is(livenessProbe.getInitialDelaySeconds())); - assertThat(container.getLivenessProbe().getTimeoutSeconds(), is(livenessProbe.getTimeoutSeconds())); - assertThat(container.getReadinessProbe().getInitialDelaySeconds(), is(readinessProbe.getInitialDelaySeconds())); - assertThat(container.getReadinessProbe().getTimeoutSeconds(), is(readinessProbe.getTimeoutSeconds())); + assertThat(container.getLivenessProbe().getInitialDelaySeconds(), is(15)); + assertThat(container.getLivenessProbe().getTimeoutSeconds(), is(20)); + assertThat(container.getReadinessProbe().getInitialDelaySeconds(), is(15)); + assertThat(container.getReadinessProbe().getTimeoutSeconds(), is(20)); assertThat(container.getPorts().size(), is(1)); assertThat(container.getPorts().get(0).getContainerPort(), is(EntityUserOperator.HEALTHCHECK_PORT)); assertThat(container.getPorts().get(0).getName(), is(EntityUserOperator.HEALTHCHECK_PORT_NAME)); @@ -291,91 +239,69 @@ public void testGetContainers() { @ParallelTest public void testFromCrdCaValidityAndRenewal() { - EntityUserOperatorSpec entityUserOperatorSpec = new EntityUserOperatorSpecBuilder() + Kafka customValues = new KafkaBuilder(KAFKA) + .editSpec() + .withNewEntityOperator() + .withNewUserOperator() + .endUserOperator() + .endEntityOperator() + .withNewClientsCa() + .withValidityDays(42) + .withRenewalDays(69) + .endClientsCa() + .endSpec() .build(); - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withUserOperator(entityUserOperatorSpec) + EntityUserOperator entityUserOperator = EntityUserOperator.fromCrd(new Reconciliation("test", KAFKA.getKind(), KAFKA.getMetadata().getNamespace(), KAFKA.getMetadata().getName()), customValues, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); + + Kafka defaultValues = new KafkaBuilder(KAFKA) + .editSpec() + .withNewEntityOperator() + .withNewUserOperator() + .endUserOperator() + .endEntityOperator() + .endSpec() .build(); - CertificateAuthority ca = new CertificateAuthority(); - ca.setValidityDays(42); - ca.setRenewalDays(69); - Kafka customValues = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withEntityOperator(entityOperatorSpec) - .withClientsCa(ca) - .endSpec() - .build(); - - EntityUserOperator entityUserOperator = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), customValues, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - - Kafka defaultValues = - new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) - .editSpec() - .withEntityOperator(entityOperatorSpec) - .endSpec() - .build(); - - EntityUserOperator entityUserOperator2 = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), defaultValues, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); + EntityUserOperator entityUserOperator2 = EntityUserOperator.fromCrd(new Reconciliation("test", KAFKA.getKind(), KAFKA.getMetadata().getNamespace(), KAFKA.getMetadata().getName()), defaultValues, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); assertThat(entityUserOperator.clientsCaValidityDays, is(42)); assertThat(entityUserOperator.clientsCaRenewalDays, is(69)); assertThat(entityUserOperator2.clientsCaValidityDays, is(CertificateAuthority.DEFAULT_CERTS_VALIDITY_DAYS)); assertThat(entityUserOperator2.clientsCaRenewalDays, is(CertificateAuthority.DEFAULT_CERTS_RENEWAL_DAYS)); - } - - @ParallelTest - public void testEntityUserOperatorEnvVarValidityAndRenewal() { - int validity = 100; - int renewal = 42; - - Kafka kafkaAssembly = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, - image, healthDelay, healthTimeout, jmxMetricsConfig, singletonMap("foo", "bar"), emptyMap())) - .editSpec() - .withNewClientsCa() - .withRenewalDays(renewal) - .withValidityDays(validity) - .endClientsCa() - .withNewEntityOperator() - .withNewUserOperator() - .endUserOperator() - .endEntityOperator() - .endSpec() - .build(); - EntityUserOperator f = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), kafkaAssembly, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - - List envvar = f.getEnvVars(); - assertThat(Integer.parseInt(envvar.stream().filter(a -> a.getName().equals(EntityUserOperator.ENV_VAR_CLIENTS_CA_VALIDITY)).findFirst().orElseThrow().getValue()), is(validity)); - assertThat(Integer.parseInt(envvar.stream().filter(a -> a.getName().equals(EntityUserOperator.ENV_VAR_CLIENTS_CA_RENEWAL)).findFirst().orElseThrow().getValue()), is(renewal)); + List envVars = entityUserOperator.getEnvVars(); + List envVars2 = entityUserOperator2.getEnvVars(); + assertThat(Integer.parseInt(envVars.stream().filter(a -> a.getName().equals(EntityUserOperator.ENV_VAR_CLIENTS_CA_VALIDITY)).findFirst().orElseThrow().getValue()), is(42)); + assertThat(Integer.parseInt(envVars.stream().filter(a -> a.getName().equals(EntityUserOperator.ENV_VAR_CLIENTS_CA_RENEWAL)).findFirst().orElseThrow().getValue()), is(69)); + assertThat(Integer.parseInt(envVars2.stream().filter(a -> a.getName().equals(EntityUserOperator.ENV_VAR_CLIENTS_CA_VALIDITY)).findFirst().orElseThrow().getValue()), is(CertificateAuthority.DEFAULT_CERTS_VALIDITY_DAYS)); + assertThat(Integer.parseInt(envVars2.stream().filter(a -> a.getName().equals(EntityUserOperator.ENV_VAR_CLIENTS_CA_RENEWAL)).findFirst().orElseThrow().getValue()), is(CertificateAuthority.DEFAULT_CERTS_RENEWAL_DAYS)); } @ParallelTest public void testRoleBindingInOtherNamespace() { - RoleBinding binding = entityUserOperator.generateRoleBindingForRole(namespace, uoWatchedNamespace); + RoleBinding binding = EUO.generateRoleBindingForRole(NAMESPACE, "my-user-namespace"); - assertThat(binding.getSubjects().get(0).getNamespace(), is(namespace)); - assertThat(binding.getMetadata().getNamespace(), is(uoWatchedNamespace)); + assertThat(binding.getSubjects().get(0).getNamespace(), is(NAMESPACE)); + assertThat(binding.getMetadata().getNamespace(), is("my-user-namespace")); assertThat(binding.getMetadata().getOwnerReferences().size(), is(0)); assertThat(binding.getMetadata().getLabels().get("label-1"), is("value-1")); assertThat(binding.getMetadata().getAnnotations().get("anno-1"), is("value-1")); assertThat(binding.getRoleRef().getKind(), is("Role")); - assertThat(binding.getRoleRef().getName(), is("foo-entity-operator")); + assertThat(binding.getRoleRef().getName(), is("my-cluster-entity-operator")); } @ParallelTest public void testRoleBindingInTheSameNamespace() { - RoleBinding binding = entityUserOperator.generateRoleBindingForRole(namespace, namespace); + RoleBinding binding = EUO.generateRoleBindingForRole(NAMESPACE, NAMESPACE); - assertThat(binding.getSubjects().get(0).getNamespace(), is(namespace)); - assertThat(binding.getMetadata().getNamespace(), is(namespace)); + assertThat(binding.getSubjects().get(0).getNamespace(), is(NAMESPACE)); + assertThat(binding.getMetadata().getNamespace(), is(NAMESPACE)); assertThat(binding.getMetadata().getOwnerReferences().size(), is(1)); assertThat(binding.getMetadata().getLabels().get("label-1"), is("value-1")); assertThat(binding.getMetadata().getAnnotations().get("anno-1"), is("value-1")); assertThat(binding.getRoleRef().getKind(), is("Role")); - assertThat(binding.getRoleRef().getName(), is("foo-entity-operator")); + assertThat(binding.getRoleRef().getName(), is("my-cluster-entity-operator")); } @ParallelTest @@ -389,8 +315,7 @@ public void testAclsAdminApiSupported() { } private void testAclsAdminApiSupported(KafkaAuthorization authorizer) { - Kafka kafkaAssembly = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, - image, healthDelay, healthTimeout, jmxMetricsConfig, singletonMap("foo", "bar"), emptyMap())) + Kafka kafkaAssembly = new KafkaBuilder(KAFKA) .editSpec() .editKafka() .withAuthorization(authorizer) @@ -401,8 +326,7 @@ image, healthDelay, healthTimeout, jmxMetricsConfig, singletonMap("foo", "bar"), .endEntityOperator() .endSpec() .build(); - - EntityUserOperator f = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), kafkaAssembly, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); + EntityUserOperator f = EntityUserOperator.fromCrd(new Reconciliation("test", KAFKA.getKind(), KAFKA.getMetadata().getNamespace(), KAFKA.getMetadata().getName()), kafkaAssembly, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); assertThat(f.getEnvVars() .stream() @@ -415,8 +339,7 @@ image, healthDelay, healthTimeout, jmxMetricsConfig, singletonMap("foo", "bar"), @ParallelTest public void testMaintenanceTimeWindows() { - Kafka kafkaAssembly = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, - image, healthDelay, healthTimeout, jmxMetricsConfig, singletonMap("foo", "bar"), emptyMap())) + Kafka kafkaAssembly = new KafkaBuilder(KAFKA) .editSpec() .withNewEntityOperator() .withNewUserOperator() @@ -424,8 +347,8 @@ image, healthDelay, healthTimeout, jmxMetricsConfig, singletonMap("foo", "bar"), .endEntityOperator() .endSpec() .build(); + EntityUserOperator f = EntityUserOperator.fromCrd(new Reconciliation("test", KAFKA.getKind(), KAFKA.getMetadata().getNamespace(), KAFKA.getMetadata().getName()), kafkaAssembly, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - EntityUserOperator f = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), kafkaAssembly, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); assertThat(f.getEnvVars().stream().anyMatch(a -> EntityUserOperator.ENV_VAR_MAINTENANCE_TIME_WINDOWS.equals(a.getName())), is(false)); kafkaAssembly = new KafkaBuilder(kafkaAssembly) @@ -433,43 +356,73 @@ image, healthDelay, healthTimeout, jmxMetricsConfig, singletonMap("foo", "bar"), .withMaintenanceTimeWindows("* * 8-10 * * ?", "* * 14-15 * * ?") .endSpec() .build(); + f = EntityUserOperator.fromCrd(new Reconciliation("test", KAFKA.getKind(), KAFKA.getMetadata().getNamespace(), KAFKA.getMetadata().getName()), kafkaAssembly, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - f = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), kafkaAssembly, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); assertThat(f.getEnvVars().stream().filter(a -> EntityUserOperator.ENV_VAR_MAINTENANCE_TIME_WINDOWS.equals(a.getName())).findFirst().orElseThrow().getValue(), is("* * 8-10 * * ?;* * 14-15 * * ?")); } @ParallelTest public void testNoWatchedNamespace() { - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withNewUserOperator() - .endUserOperator() - .build(); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withEntityOperator(entityOperatorSpec) + .withNewEntityOperator() + .withNewUserOperator() + .endUserOperator() + .endEntityOperator() .endSpec() .build(); - EntityUserOperator entityUserOperator = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); - assertThat(entityUserOperator.watchedNamespace(), is(namespace)); + assertThat(entityUserOperator.watchedNamespace(), is(NAMESPACE)); } @ParallelTest public void testWatchedNamespace() { - EntityOperatorSpec entityOperatorSpec = new EntityOperatorSpecBuilder() - .withNewUserOperator() - .withWatchedNamespace("some-other-namespace") - .endUserOperator() - .build(); - Kafka resource = new KafkaBuilder(ResourceUtils.createKafka(namespace, cluster, replicas, image, healthDelay, healthTimeout)) + Kafka resource = new KafkaBuilder(KAFKA) .editSpec() - .withEntityOperator(entityOperatorSpec) + .withNewEntityOperator() + .withNewUserOperator() + .withWatchedNamespace("some-other-namespace") + .endUserOperator() + .endEntityOperator() .endSpec() .build(); - EntityUserOperator entityUserOperator = EntityUserOperator.fromCrd(new Reconciliation("test", resource.getKind(), resource.getMetadata().getNamespace(), resource.getMetadata().getName()), resource, SHARED_ENV_PROVIDER, ResourceUtils.dummyClusterOperatorConfig()); assertThat(entityUserOperator.watchedNamespace(), is("some-other-namespace")); } + + //////////////////// + // Utility methods + //////////////////// + + private List getExpectedEnvVars() { + List expected = new ArrayList<>(); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_KAFKA_BOOTSTRAP_SERVERS).withValue(String.format("%s:%d", "my-cluster-kafka-bootstrap", EntityUserOperatorSpec.DEFAULT_BOOTSTRAP_SERVERS_PORT)).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_WATCHED_NAMESPACE).withValue("my-user-namespace").build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_RESOURCE_LABELS).withValue(ModelUtils.defaultResourceLabels(CLUSTER_NAME)).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_FULL_RECONCILIATION_INTERVAL_MS).withValue(String.valueOf(60_000L)).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLIENTS_CA_KEY_SECRET_NAME).withValue(KafkaResources.clientsCaKeySecretName(CLUSTER_NAME)).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLIENTS_CA_CERT_SECRET_NAME).withValue(KafkaResources.clientsCaCertificateSecretName(CLUSTER_NAME)).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLIENTS_CA_NAMESPACE).withValue(NAMESPACE).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLUSTER_CA_CERT_SECRET_NAME).withValue(KafkaCluster.clusterCaCertSecretName(CLUSTER_NAME)).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_EO_KEY_SECRET_NAME).withValue(KafkaResources.entityUserOperatorSecretName(CLUSTER_NAME)).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_STRIMZI_GC_LOG_ENABLED).withValue(Boolean.toString(JvmOptions.DEFAULT_GC_LOGGING_ENABLED)).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLIENTS_CA_VALIDITY).withValue(Integer.toString(CertificateAuthority.DEFAULT_CERTS_VALIDITY_DAYS)).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_CLIENTS_CA_RENEWAL).withValue(Integer.toString(CertificateAuthority.DEFAULT_CERTS_RENEWAL_DAYS)).build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_STRIMZI_JAVA_OPTS).withValue("-Xmx256m").build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_STRIMZI_JAVA_SYSTEM_PROPERTIES).withValue("-Djavax.net.debug=verbose -Dsomething.else=42").build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_SECRET_PREFIX).withValue("strimzi-").build()); + expected.add(new EnvVarBuilder().withName(EntityUserOperator.ENV_VAR_ACLS_ADMIN_API_SUPPORTED).withValue(String.valueOf(false)).build()); + + return expected; + } + + private void checkEnvVars(List expected, List actual) { + assertThat(actual.size(), is(expected.size())); + + for (EnvVar var : expected) { + assertThat(actual.contains(var), is(true)); + } + } } diff --git a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/cruisecontrol/CruiseControlMetricsReporterTest.java b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/cruisecontrol/CruiseControlMetricsReporterTest.java index d220afe6ef2..499c4a954e6 100644 --- a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/cruisecontrol/CruiseControlMetricsReporterTest.java +++ b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/cruisecontrol/CruiseControlMetricsReporterTest.java @@ -6,7 +6,10 @@ import io.strimzi.api.kafka.model.kafka.Kafka; import io.strimzi.api.kafka.model.kafka.KafkaBuilder; +import io.strimzi.api.kafka.model.kafka.listener.GenericKafkaListenerBuilder; +import io.strimzi.api.kafka.model.kafka.listener.KafkaListenerType; import io.strimzi.operator.cluster.model.KafkaConfiguration; +import io.strimzi.operator.common.Annotations; import io.strimzi.operator.common.Reconciliation; import io.strimzi.operator.common.model.InvalidResourceException; import io.strimzi.operator.common.model.cruisecontrol.CruiseControlConfigurationParameters; @@ -27,22 +30,30 @@ public class CruiseControlMetricsReporterTest { private final static String NAMESPACE = "my-namespace"; private final static Kafka KAFKA = new KafkaBuilder() - .withNewMetadata() - .withName(NAME) - .withNamespace(NAMESPACE) - .endMetadata() - .withNewSpec() + .withNewMetadata() + .withName(NAME) + .withNamespace(NAMESPACE) + .withAnnotations(Map.of(Annotations.ANNO_STRIMZI_IO_NODE_POOLS, "enabled", Annotations.ANNO_STRIMZI_IO_KRAFT, "enabled")) + .endMetadata() + .withNewSpec() .withNewKafka() + .withListeners(new GenericKafkaListenerBuilder() + .withName("tls") + .withPort(9092) + .withType(KafkaListenerType.INTERNAL) + .withTls(true) + .build()) .endKafka() - .withNewCruiseControl() - .endCruiseControl() - .endSpec() - .build(); + .withNewCruiseControl() + .endCruiseControl() + .endSpec() + .build(); @Test public void testDisabledCruiseControl() { Kafka kafka = new KafkaBuilder(KAFKA) - .withNewSpec() + .editSpec() + .withCruiseControl(null) .endSpec() .build(); @@ -79,7 +90,7 @@ public void testEnabledCruiseControlWithSettingsFromKafka() { @Test public void testEnabledCruiseControlWithSettingsFromCC() { Kafka kafka = new KafkaBuilder(KAFKA) - .withNewSpec() + .editSpec() .withNewCruiseControl() .withConfig(Map.of("metric.reporter.topic", "my-custom-topic")) .endCruiseControl() diff --git a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/cruisecontrol/HashLoginServiceApiCredentialsTest.java b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/cruisecontrol/HashLoginServiceApiCredentialsTest.java index 850428e3bc5..e3d9662c928 100644 --- a/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/cruisecontrol/HashLoginServiceApiCredentialsTest.java +++ b/cluster-operator/src/test/java/io/strimzi/operator/cluster/model/cruisecontrol/HashLoginServiceApiCredentialsTest.java @@ -12,16 +12,17 @@ import io.strimzi.api.kafka.model.kafka.Kafka; import io.strimzi.api.kafka.model.kafka.KafkaBuilder; import io.strimzi.api.kafka.model.kafka.Storage; -import io.strimzi.api.kafka.model.kafka.cruisecontrol.CruiseControlApiUsers; import io.strimzi.api.kafka.model.kafka.cruisecontrol.CruiseControlSpec; import io.strimzi.api.kafka.model.kafka.cruisecontrol.CruiseControlSpecBuilder; -import io.strimzi.api.kafka.model.kafka.cruisecontrol.HashLoginServiceApiUsers; +import io.strimzi.api.kafka.model.kafka.listener.GenericKafkaListenerBuilder; +import io.strimzi.api.kafka.model.kafka.listener.KafkaListenerType; import io.strimzi.operator.cluster.KafkaVersionTestUtils; import io.strimzi.operator.cluster.model.CruiseControl; import io.strimzi.operator.cluster.model.KafkaVersion; import io.strimzi.operator.cluster.model.MockSharedEnvironmentProvider; import io.strimzi.operator.cluster.model.NodeRef; import io.strimzi.operator.cluster.model.SharedEnvironmentProvider; +import io.strimzi.operator.common.Annotations; import io.strimzi.operator.common.InvalidConfigurationException; import io.strimzi.operator.common.Reconciliation; import io.strimzi.operator.common.model.InvalidResourceException; @@ -51,7 +52,6 @@ public class HashLoginServiceApiCredentialsTest { private final static String CLUSTER = "my-cluster"; private final static String NAMESPACE = "my-namespace"; - private final static int REPLICAS = 3; private static final KafkaVersion.Lookup VERSIONS = KafkaVersionTestUtils.getKafkaVersionLookup(); private static final SharedEnvironmentProvider SHARED_ENV_PROVIDER = new MockSharedEnvironmentProvider(); private static final String SECRET_NAME = "secretName"; @@ -84,23 +84,23 @@ public class HashLoginServiceApiCredentialsTest { private static Kafka createKafka(CruiseControlSpec ccSpec) { return new KafkaBuilder() - .withNewMetadata() - .withName(CLUSTER) - .withNamespace(NAMESPACE) - .endMetadata() - .withNewSpec() - .withNewZookeeper() - .withReplicas(REPLICAS) - .endZookeeper() - .withNewKafka() - .withReplicas(REPLICAS) - .withNewEphemeralStorage() - .withSizeLimit("10Gi") - .endEphemeralStorage() - .endKafka() - .withCruiseControl(ccSpec) - .endSpec() - .build(); + .withNewMetadata() + .withName(CLUSTER) + .withNamespace(NAMESPACE) + .withAnnotations(Map.of(Annotations.ANNO_STRIMZI_IO_NODE_POOLS, "enabled", Annotations.ANNO_STRIMZI_IO_KRAFT, "enabled")) + .endMetadata() + .withNewSpec() + .withNewKafka() + .withListeners(new GenericKafkaListenerBuilder() + .withName("tls") + .withPort(9092) + .withType(KafkaListenerType.INTERNAL) + .withTls(true) + .build()) + .endKafka() + .withCruiseControl(ccSpec) + .endSpec() + .build(); } private static Secret createSecret(Map data) { @@ -152,7 +152,7 @@ public void testApiUsersObjectCreation() { assertThrows(Exception.class, () -> new HashLoginServiceApiCredentials(NAMESPACE, CLUSTER, LABELS, OWNER_REFERENCE, s4)); } - private void assertParseThrows(String illegalConfig, CruiseControlApiUsers apiUsers) { + private void assertParseThrows(String illegalConfig) { assertThrows(InvalidConfigurationException.class, () -> HashLoginServiceApiCredentials.parseEntriesFromString(illegalConfig)); } @@ -163,7 +163,6 @@ public void testParseEntriesFromString() { username1: password1,VIEWER username2: password2,USER """; - CruiseControlApiUsers apiUsers = new HashLoginServiceApiUsers(); Map entries = HashLoginServiceApiCredentials.parseEntriesFromString(config); assertThat(entries.get("username0").username(), is("username0")); assertThat(entries.get("username0").password(), is("password0")); @@ -171,19 +170,19 @@ public void testParseEntriesFromString() { assertParseThrows(""" username1: , USER - """, apiUsers); + """); assertParseThrows(""" : password1, USER - """, apiUsers); + """); assertParseThrows(""" username1 username2: password1 USER - """, apiUsers); + """); assertParseThrows(""" username1: password1,USER,VIEWER - """, apiUsers); + """); assertParseThrows(""" username1: password1 password2,USER - """, apiUsers); + """); } @ParallelTest @@ -201,7 +200,7 @@ public void testGenerateToManagedApiCredentials() { assertThat(entries.size(), is(0)); } - private void assertParseThrowsForUserManagedCreds(String illegalConfig, CruiseControlApiUsers apiUsers) { + private void assertParseThrowsForUserManagedCreds(String illegalConfig) { illegalConfig = encodeToBase64(illegalConfig); Secret secret = createSecret(Map.of(SECRET_KEY, illegalConfig)); Map entries = new HashMap<>(); @@ -215,7 +214,6 @@ public void testGenerateUserManagedApiCredentials() { username1: password1,VIEWER username2: password2,USER """); - CruiseControlApiUsers apiUsers = new HashLoginServiceApiUsers(); Secret secret = createSecret(Map.of(SECRET_KEY, config)); Map entries = new HashMap<>(); HashLoginServiceApiCredentials.generateUserManagedApiCredentials(entries, secret, SECRET_KEY); @@ -243,27 +241,27 @@ public void testGenerateUserManagedApiCredentials() { assertParseThrowsForUserManagedCreds(""" username1: password1,USER username2: password2,TEST - """, apiUsers); + """); assertParseThrowsForUserManagedCreds(""" rebalance-operator: password1,USER username2: password2,USER - """, apiUsers); + """); assertParseThrowsForUserManagedCreds(""" topic-operator: password1,USER username2: password2,USER - """, apiUsers); + """); assertParseThrowsForUserManagedCreds(""" healthcheck: password1,USER username2: password2,USER - """, apiUsers); + """); assertParseThrowsForUserManagedCreds(""" username1: password1,USER username2: password2,ADMIN - """, apiUsers); + """); assertParseThrowsForUserManagedCreds(""" username1: password1,USER username1: password2,ADMIN - """, apiUsers); + """); } @ParallelTest @@ -274,7 +272,6 @@ public void testGenerateCoManagedApiCredentials() { Map map1 = Map.of("cruise-control.authFile", encodeToBase64("rebalance-operator: password,ADMIN\n" + "healthcheck: password,USER")); - CruiseControlApiUsers apiUsers = new HashLoginServiceApiUsers(); Map entries = new HashMap<>(); HashLoginServiceApiCredentials.generateCoManagedApiCredentials(entries, mockPasswordGenerator, createSecret(map1)); assertThat(entries.get("rebalance-operator").username(), is("rebalance-operator"));