Search in sources :

Example 6 with KafkaVersion

use of io.strimzi.operator.cluster.model.KafkaVersion in project strimzi-kafka-operator by strimzi.

the class KafkaUpgradeDowngradeMockTest method testUpgradeWithoutAnyVersionInPodsOrStsFails.

// Tests upgrade when Kafka StatefulSet and/or Pods existing but without any of the version annotations. This
// indicates that the Statefulset / Pods were not using the current or recent Strimzi version and since we do not
// know the version, we should wail.
@Test
public void testUpgradeWithoutAnyVersionInPodsOrStsFails(VertxTestContext context) {
    KafkaVersion unsupported = VERSIONS.version("2.1.0");
    Kafka initialKafka = kafkaWithVersions(KafkaVersionTestUtils.LATEST_KAFKA_VERSION, unsupported.messageVersion(), unsupported.protocolVersion());
    Kafka updatedKafka = kafkaWithVersions(KafkaVersionTestUtils.LATEST_KAFKA_VERSION);
    Checkpoint reconciliation = context.checkpoint();
    initialize(context, initialKafka).onComplete(context.succeeding(v -> {
        context.verify(() -> {
            assertVersionsInStatefulSet(KafkaVersionTestUtils.LATEST_KAFKA_VERSION, unsupported.messageVersion(), unsupported.protocolVersion(), KafkaVersionTestUtils.LATEST_KAFKA_IMAGE);
        });
    })).compose(v -> {
        StatefulSet sts = client.apps().statefulSets().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka").get();
        StatefulSet modifiedSts = new StatefulSetBuilder(sts).editMetadata().removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION).endMetadata().editSpec().editTemplate().editMetadata().removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_LOG_MESSAGE_FORMAT_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_INTER_BROKER_PROTOCOL_VERSION).endMetadata().endTemplate().endSpec().build();
        client.apps().statefulSets().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka").createOrReplace(modifiedSts);
        for (int i = 0; i < 3; i++) {
            Pod pod = client.pods().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka-" + i).get();
            Pod modifiedPod = new PodBuilder(pod).editMetadata().removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_LOG_MESSAGE_FORMAT_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_INTER_BROKER_PROTOCOL_VERSION).endMetadata().build();
            client.pods().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka-" + i).createOrReplace(modifiedPod);
        }
        return Future.succeededFuture();
    }).compose(v -> operator.createOrUpdate(new Reconciliation("test-trigger", Kafka.RESOURCE_KIND, NAMESPACE, CLUSTER_NAME), updatedKafka)).onComplete(context.failing(v -> context.verify(() -> {
        assertThat(v.getMessage(), stringContainsInOrder("Kafka Pods or StatefulSet exist, but do not contain the strimzi.io/kafka-version annotation to detect their version. Kafka upgrade cannot be detected."));
        reconciliation.flag();
    })));
}
Also used : StatefulSetBuilder(io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder) VertxTestContext(io.vertx.junit5.VertxTestContext) CoreMatchers.is(org.hamcrest.CoreMatchers.is) KafkaBuilder(io.strimzi.api.kafka.model.KafkaBuilder) AfterAll(org.junit.jupiter.api.AfterAll) KafkaCluster(io.strimzi.operator.cluster.model.KafkaCluster) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) EnableKubernetesMockClient(io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient) KafkaVersionTestUtils(io.strimzi.operator.cluster.KafkaVersionTestUtils) BeforeAll(org.junit.jupiter.api.BeforeAll) Map(java.util.Map) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) ResourceUtils(io.strimzi.operator.cluster.ResourceUtils) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) MockKube2(io.strimzi.test.mockkube2.MockKube2) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) KubernetesVersion(io.strimzi.operator.KubernetesVersion) KafkaVersion(io.strimzi.operator.cluster.model.KafkaVersion) Vertx(io.vertx.core.Vertx) Pod(io.fabric8.kubernetes.api.model.Pod) GenericKafkaListenerBuilder(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerBuilder) VertxExtension(io.vertx.junit5.VertxExtension) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) Reconciliation(io.strimzi.operator.common.Reconciliation) AfterEach(org.junit.jupiter.api.AfterEach) KafkaConfiguration(io.strimzi.operator.cluster.model.KafkaConfiguration) Logger(org.apache.logging.log4j.Logger) KafkaListenerType(io.strimzi.api.kafka.model.listener.arraylistener.KafkaListenerType) PasswordGenerator(io.strimzi.operator.common.PasswordGenerator) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Checkpoint(io.vertx.junit5.Checkpoint) Matchers.stringContainsInOrder(org.hamcrest.Matchers.stringContainsInOrder) Kafka(io.strimzi.api.kafka.model.Kafka) PlatformFeaturesAvailability(io.strimzi.operator.PlatformFeaturesAvailability) LogManager(org.apache.logging.log4j.LogManager) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) MockCertManager(io.strimzi.operator.common.operator.MockCertManager) KafkaVersion(io.strimzi.operator.cluster.model.KafkaVersion) Checkpoint(io.vertx.junit5.Checkpoint) Pod(io.fabric8.kubernetes.api.model.Pod) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) Reconciliation(io.strimzi.operator.common.Reconciliation) Kafka(io.strimzi.api.kafka.model.Kafka) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) StatefulSetBuilder(io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder) Checkpoint(io.vertx.junit5.Checkpoint) Test(org.junit.jupiter.api.Test)

Example 7 with KafkaVersion

use of io.strimzi.operator.cluster.model.KafkaVersion in project strimzi by strimzi.

the class KafkaBrokerConfigurationDiff method diff.

/**
 * Computes diff between two maps. Entries in IGNORABLE_PROPERTIES are skipped
 * @param brokerId id of compared broker
 * @param desired desired configuration, may be null if the related ConfigMap does not exist yet or no changes are required
 * @param brokerConfigs current configuration
 * @param configModel default configuration for {@code kafkaVersion} of broker
 * @return Collection of AlterConfigOp containing all entries which were changed from current in desired configuration
 */
private Collection<AlterConfigOp> diff(int brokerId, String desired, Config brokerConfigs, Map<String, ConfigModel> configModel) {
    if (brokerConfigs == null || desired == null) {
        return Collections.emptyList();
    }
    Map<String, String> currentMap;
    Collection<AlterConfigOp> updatedCE = new ArrayList<>();
    currentMap = brokerConfigs.entries().stream().collect(Collectors.toMap(ConfigEntry::name, configEntry -> configEntry.value() == null ? "null" : configEntry.value()));
    OrderedProperties orderedProperties = new OrderedProperties();
    orderedProperties.addStringPairs(desired);
    Map<String, String> desiredMap = orderedProperties.asMap();
    fillPlaceholderValue(desiredMap, Integer.toString(brokerId));
    JsonNode source = patchMapper().configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true).valueToTree(currentMap);
    JsonNode target = patchMapper().configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true).valueToTree(desiredMap);
    JsonNode jsonDiff = JsonDiff.asJson(source, target);
    for (JsonNode d : jsonDiff) {
        String pathValue = d.get("path").asText();
        String pathValueWithoutSlash = pathValue.substring(1);
        Optional<ConfigEntry> optEntry = brokerConfigs.entries().stream().filter(configEntry -> configEntry.name().equals(pathValueWithoutSlash)).findFirst();
        String op = d.get("op").asText();
        if (optEntry.isPresent()) {
            ConfigEntry entry = optEntry.get();
            if ("remove".equals(op)) {
                removeProperty(configModel, updatedCE, pathValueWithoutSlash, entry);
            } else if ("replace".equals(op)) {
                // entry is in the current, desired is updated value
                updateOrAdd(entry.name(), configModel, desiredMap, updatedCE);
            }
        } else {
            if ("add".equals(op)) {
                // entry is not in the current, it is added
                updateOrAdd(pathValueWithoutSlash, configModel, desiredMap, updatedCE);
            }
        }
        if ("remove".equals(op)) {
            // there is a lot of properties set by default - not having them in desired causes very noisy log output
            LOGGER.traceCr(reconciliation, "Kafka Broker {} Config Differs : {}", brokerId, d);
            LOGGER.traceCr(reconciliation, "Current Kafka Broker Config path {} has value {}", pathValueWithoutSlash, lookupPath(source, pathValue));
            LOGGER.traceCr(reconciliation, "Desired Kafka Broker Config path {} has value {}", pathValueWithoutSlash, lookupPath(target, pathValue));
        } else {
            LOGGER.debugCr(reconciliation, "Kafka Broker {} Config Differs : {}", brokerId, d);
            LOGGER.debugCr(reconciliation, "Current Kafka Broker Config path {} has value {}", pathValueWithoutSlash, lookupPath(source, pathValue));
            LOGGER.debugCr(reconciliation, "Desired Kafka Broker Config path {} has value {}", pathValueWithoutSlash, lookupPath(target, pathValue));
        }
    }
    return updatedCE;
}
Also used : Scope(io.strimzi.kafka.config.model.Scope) AbstractJsonDiff(io.strimzi.operator.common.operator.resource.AbstractJsonDiff) Config(org.apache.kafka.clients.admin.Config) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) OrderedProperties(io.strimzi.operator.common.model.OrderedProperties) Collection(java.util.Collection) KafkaVersion(io.strimzi.operator.cluster.model.KafkaVersion) ConfigEntry(org.apache.kafka.clients.admin.ConfigEntry) JsonDiff(io.fabric8.zjsonpatch.JsonDiff) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) ConfigModel(io.strimzi.kafka.config.model.ConfigModel) Reconciliation(io.strimzi.operator.common.Reconciliation) AlterConfigOp(org.apache.kafka.clients.admin.AlterConfigOp) PatchUtils.patchMapper(io.fabric8.kubernetes.client.internal.PatchUtils.patchMapper) KafkaConfiguration(io.strimzi.operator.cluster.model.KafkaConfiguration) Map(java.util.Map) Optional(java.util.Optional) JsonNode(com.fasterxml.jackson.databind.JsonNode) SerializationFeature(com.fasterxml.jackson.databind.SerializationFeature) Pattern(java.util.regex.Pattern) Collections(java.util.Collections) ConfigEntry(org.apache.kafka.clients.admin.ConfigEntry) ArrayList(java.util.ArrayList) AlterConfigOp(org.apache.kafka.clients.admin.AlterConfigOp) OrderedProperties(io.strimzi.operator.common.model.OrderedProperties) JsonNode(com.fasterxml.jackson.databind.JsonNode)

Example 8 with KafkaVersion

use of io.strimzi.operator.cluster.model.KafkaVersion in project strimzi by strimzi.

the class KafkaRoller method checkReconfigurability.

/**
 * Determine whether the pod should be restarted, or the broker reconfigured.
 */
@SuppressWarnings("checkstyle:CyclomaticComplexity")
private void checkReconfigurability(PodRef podRef, Pod pod, RestartContext restartContext) throws ForceableProblem, InterruptedException, FatalProblem {
    List<String> reasonToRestartPod = Objects.requireNonNull(podNeedsRestart.apply(pod));
    boolean podStuck = pod != null && pod.getStatus() != null && "Pending".equals(pod.getStatus().getPhase()) && pod.getStatus().getConditions().stream().anyMatch(ps -> "PodScheduled".equals(ps.getType()) && "Unschedulable".equals(ps.getReason()) && "False".equals(ps.getStatus()));
    if (podStuck && // "Pod has old generation" is used with StatefulSets
    !reasonToRestartPod.contains("Pod has old generation") && !reasonToRestartPod.contains("Pod has old revision")) {
        // and deleting a different pod in the meantime will likely result in another unschedulable pod.
        throw new FatalProblem("Pod is unschedulable");
    }
    // Unless the annotation is present, check the pod is at least ready.
    boolean needsRestart = !reasonToRestartPod.isEmpty();
    KafkaBrokerConfigurationDiff diff = null;
    KafkaBrokerLoggingConfigurationDiff loggingDiff = null;
    boolean needsReconfig = false;
    // connect to the broker and that it's capable of responding.
    if (!initAdminClient()) {
        LOGGER.infoCr(reconciliation, "Pod {} needs to be restarted, because it does not seem to responding to connection attempts", podRef);
        restartContext.needsRestart = false;
        restartContext.needsReconfig = false;
        restartContext.forceRestart = true;
        restartContext.diff = null;
        restartContext.logDiff = null;
        return;
    }
    Config brokerConfig;
    try {
        brokerConfig = brokerConfig(podRef);
    } catch (ForceableProblem e) {
        if (restartContext.backOff.done()) {
            needsRestart = true;
            brokerConfig = null;
        } else {
            throw e;
        }
    }
    if (!needsRestart && allowReconfiguration) {
        LOGGER.traceCr(reconciliation, "Broker {}: description {}", podRef, brokerConfig);
        diff = new KafkaBrokerConfigurationDiff(reconciliation, brokerConfig, kafkaConfigProvider.apply(podRef.getPodId()), kafkaVersion, podRef.getPodId());
        loggingDiff = logging(podRef);
        if (diff.getDiffSize() > 0) {
            if (diff.canBeUpdatedDynamically()) {
                LOGGER.debugCr(reconciliation, "Pod {} needs to be reconfigured.", podRef);
                needsReconfig = true;
            } else {
                LOGGER.infoCr(reconciliation, "Pod {} needs to be restarted, because reconfiguration cannot be done dynamically", podRef);
                needsRestart = true;
            }
        }
        // needsRestart value might have changed from the check in the parent if. So we need to check it again.
        if (!needsRestart && loggingDiff.getDiffSize() > 0) {
            LOGGER.debugCr(reconciliation, "Pod {} logging needs to be reconfigured.", podRef);
            needsReconfig = true;
        }
    } else if (needsRestart) {
        LOGGER.infoCr(reconciliation, "Pod {} needs to be restarted. Reason: {}", podRef, reasonToRestartPod);
    }
    if (podStuck) {
        LOGGER.infoCr(reconciliation, "Pod {} needs to be restarted, because it seems to be stuck and restart might help", podRef);
    }
    restartContext.needsRestart = needsRestart;
    restartContext.needsReconfig = needsReconfig;
    restartContext.forceRestart = podStuck;
    restartContext.diff = diff;
    restartContext.logDiff = loggingDiff;
}
Also used : TimeoutException(java.util.concurrent.TimeoutException) KafkaException(org.apache.kafka.common.KafkaException) Collections.singletonList(java.util.Collections.singletonList) KafkaResources(io.strimzi.api.kafka.model.KafkaResources) Duration(java.time.Duration) Map(java.util.Map) PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) ContainerStatus(io.fabric8.kubernetes.api.model.ContainerStatus) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) DnsNameGenerator(io.strimzi.operator.cluster.model.DnsNameGenerator) KafkaVersion(io.strimzi.operator.cluster.model.KafkaVersion) Set(java.util.Set) KafkaFuture(org.apache.kafka.common.KafkaFuture) InetSocketAddress(java.net.InetSocketAddress) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) Executors(java.util.concurrent.Executors) Objects(java.util.Objects) AlterConfigOp(org.apache.kafka.clients.admin.AlterConfigOp) List(java.util.List) AlterConfigsResult(org.apache.kafka.clients.admin.AlterConfigsResult) Optional(java.util.Optional) Secret(io.fabric8.kubernetes.api.model.Secret) AdminClientProvider(io.strimzi.operator.common.AdminClientProvider) Node(org.apache.kafka.common.Node) DescribeClusterResult(org.apache.kafka.clients.admin.DescribeClusterResult) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) IntStream(java.util.stream.IntStream) Config(org.apache.kafka.clients.admin.Config) Socket(java.net.Socket) BackOff(io.strimzi.operator.common.BackOff) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) CompositeFuture(io.vertx.core.CompositeFuture) ConfigResource(org.apache.kafka.common.config.ConfigResource) KafkaCluster(io.strimzi.operator.cluster.model.KafkaCluster) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Admin(org.apache.kafka.clients.admin.Admin) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Pod(io.fabric8.kubernetes.api.model.Pod) IOException(java.io.IOException) ConfigException(org.apache.kafka.common.config.ConfigException) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Reconciliation(io.strimzi.operator.common.Reconciliation) Util(io.strimzi.operator.common.Util) SslAuthenticationException(org.apache.kafka.common.errors.SslAuthenticationException) ContainerStateWaiting(io.fabric8.kubernetes.api.model.ContainerStateWaiting) Config(org.apache.kafka.clients.admin.Config)

Example 9 with KafkaVersion

use of io.strimzi.operator.cluster.model.KafkaVersion in project strimzi by strimzi.

the class KafkaUpgradeDowngradeMockTest method testUpgradeFromUnsupportedKafkaVersionWithMessageAndProtocol.

// Tests upgrade from Kafka version not supported by the current version of the operator with message format and
// protocol versions specified.
@Test
public void testUpgradeFromUnsupportedKafkaVersionWithMessageAndProtocol(VertxTestContext context) {
    KafkaVersion unsupported = VERSIONS.version("2.1.0");
    Kafka initialKafka = kafkaWithVersions(KafkaVersionTestUtils.LATEST_KAFKA_VERSION, unsupported.messageVersion(), unsupported.protocolVersion());
    Kafka updatedKafka = kafkaWithVersions(KafkaVersionTestUtils.LATEST_KAFKA_VERSION, unsupported.messageVersion(), unsupported.protocolVersion());
    Checkpoint reconciliation = context.checkpoint();
    initialize(context, initialKafka).onComplete(context.succeeding(v -> {
        context.verify(() -> {
            assertVersionsInStatefulSet(KafkaVersionTestUtils.LATEST_KAFKA_VERSION, unsupported.messageVersion(), unsupported.protocolVersion(), KafkaVersionTestUtils.LATEST_KAFKA_IMAGE);
        });
    })).compose(v -> {
        StatefulSet sts = client.apps().statefulSets().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka").get();
        StatefulSet modifiedSts = new StatefulSetBuilder(sts).editMetadata().addToAnnotations(KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION, unsupported.version()).endMetadata().editSpec().editTemplate().editMetadata().removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_LOG_MESSAGE_FORMAT_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_INTER_BROKER_PROTOCOL_VERSION).endMetadata().editSpec().editContainer(0).withImage("strimzi/kafka:old-kafka-2.1.0").endContainer().endSpec().endTemplate().endSpec().build();
        client.apps().statefulSets().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka").createOrReplace(modifiedSts);
        for (int i = 0; i < 3; i++) {
            Pod pod = client.pods().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka-" + i).get();
            Pod modifiedPod = new PodBuilder(pod).editMetadata().removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_LOG_MESSAGE_FORMAT_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_INTER_BROKER_PROTOCOL_VERSION).endMetadata().editSpec().editContainer(0).withImage("strimzi/kafka:old-kafka-2.1.0").endContainer().endSpec().build();
            client.pods().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka-" + i).createOrReplace(modifiedPod);
        }
        return Future.succeededFuture();
    }).compose(v -> operator.createOrUpdate(new Reconciliation("test-trigger", Kafka.RESOURCE_KIND, NAMESPACE, CLUSTER_NAME), updatedKafka)).onComplete(context.succeeding(v -> context.verify(() -> {
        assertVersionsInStatefulSet(KafkaVersionTestUtils.LATEST_KAFKA_VERSION, unsupported.messageVersion(), unsupported.protocolVersion(), KafkaVersionTestUtils.LATEST_KAFKA_IMAGE);
        reconciliation.flag();
    })));
}
Also used : StatefulSetBuilder(io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder) VertxTestContext(io.vertx.junit5.VertxTestContext) CoreMatchers.is(org.hamcrest.CoreMatchers.is) KafkaBuilder(io.strimzi.api.kafka.model.KafkaBuilder) AfterAll(org.junit.jupiter.api.AfterAll) KafkaCluster(io.strimzi.operator.cluster.model.KafkaCluster) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) EnableKubernetesMockClient(io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient) KafkaVersionTestUtils(io.strimzi.operator.cluster.KafkaVersionTestUtils) BeforeAll(org.junit.jupiter.api.BeforeAll) Map(java.util.Map) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) ResourceUtils(io.strimzi.operator.cluster.ResourceUtils) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) MockKube2(io.strimzi.test.mockkube2.MockKube2) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) KubernetesVersion(io.strimzi.operator.KubernetesVersion) KafkaVersion(io.strimzi.operator.cluster.model.KafkaVersion) Vertx(io.vertx.core.Vertx) Pod(io.fabric8.kubernetes.api.model.Pod) GenericKafkaListenerBuilder(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerBuilder) VertxExtension(io.vertx.junit5.VertxExtension) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) Reconciliation(io.strimzi.operator.common.Reconciliation) AfterEach(org.junit.jupiter.api.AfterEach) KafkaConfiguration(io.strimzi.operator.cluster.model.KafkaConfiguration) Logger(org.apache.logging.log4j.Logger) KafkaListenerType(io.strimzi.api.kafka.model.listener.arraylistener.KafkaListenerType) PasswordGenerator(io.strimzi.operator.common.PasswordGenerator) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Checkpoint(io.vertx.junit5.Checkpoint) Matchers.stringContainsInOrder(org.hamcrest.Matchers.stringContainsInOrder) Kafka(io.strimzi.api.kafka.model.Kafka) PlatformFeaturesAvailability(io.strimzi.operator.PlatformFeaturesAvailability) LogManager(org.apache.logging.log4j.LogManager) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) MockCertManager(io.strimzi.operator.common.operator.MockCertManager) KafkaVersion(io.strimzi.operator.cluster.model.KafkaVersion) Checkpoint(io.vertx.junit5.Checkpoint) Pod(io.fabric8.kubernetes.api.model.Pod) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) Reconciliation(io.strimzi.operator.common.Reconciliation) Kafka(io.strimzi.api.kafka.model.Kafka) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) StatefulSetBuilder(io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder) Checkpoint(io.vertx.junit5.Checkpoint) Test(org.junit.jupiter.api.Test)

Example 10 with KafkaVersion

use of io.strimzi.operator.cluster.model.KafkaVersion in project strimzi by strimzi.

the class KafkaUpgradeDowngradeMockTest method testUpgradeWithoutAnyVersionInPodsOrStsFails.

// Tests upgrade when Kafka StatefulSet and/or Pods existing but without any of the version annotations. This
// indicates that the Statefulset / Pods were not using the current or recent Strimzi version and since we do not
// know the version, we should wail.
@Test
public void testUpgradeWithoutAnyVersionInPodsOrStsFails(VertxTestContext context) {
    KafkaVersion unsupported = VERSIONS.version("2.1.0");
    Kafka initialKafka = kafkaWithVersions(KafkaVersionTestUtils.LATEST_KAFKA_VERSION, unsupported.messageVersion(), unsupported.protocolVersion());
    Kafka updatedKafka = kafkaWithVersions(KafkaVersionTestUtils.LATEST_KAFKA_VERSION);
    Checkpoint reconciliation = context.checkpoint();
    initialize(context, initialKafka).onComplete(context.succeeding(v -> {
        context.verify(() -> {
            assertVersionsInStatefulSet(KafkaVersionTestUtils.LATEST_KAFKA_VERSION, unsupported.messageVersion(), unsupported.protocolVersion(), KafkaVersionTestUtils.LATEST_KAFKA_IMAGE);
        });
    })).compose(v -> {
        StatefulSet sts = client.apps().statefulSets().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka").get();
        StatefulSet modifiedSts = new StatefulSetBuilder(sts).editMetadata().removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION).endMetadata().editSpec().editTemplate().editMetadata().removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_LOG_MESSAGE_FORMAT_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_INTER_BROKER_PROTOCOL_VERSION).endMetadata().endTemplate().endSpec().build();
        client.apps().statefulSets().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka").createOrReplace(modifiedSts);
        for (int i = 0; i < 3; i++) {
            Pod pod = client.pods().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka-" + i).get();
            Pod modifiedPod = new PodBuilder(pod).editMetadata().removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_LOG_MESSAGE_FORMAT_VERSION).removeFromAnnotations(KafkaCluster.ANNO_STRIMZI_IO_INTER_BROKER_PROTOCOL_VERSION).endMetadata().build();
            client.pods().inNamespace(NAMESPACE).withName(CLUSTER_NAME + "-kafka-" + i).createOrReplace(modifiedPod);
        }
        return Future.succeededFuture();
    }).compose(v -> operator.createOrUpdate(new Reconciliation("test-trigger", Kafka.RESOURCE_KIND, NAMESPACE, CLUSTER_NAME), updatedKafka)).onComplete(context.failing(v -> context.verify(() -> {
        assertThat(v.getMessage(), stringContainsInOrder("Kafka Pods or StatefulSet exist, but do not contain the strimzi.io/kafka-version annotation to detect their version. Kafka upgrade cannot be detected."));
        reconciliation.flag();
    })));
}
Also used : StatefulSetBuilder(io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder) VertxTestContext(io.vertx.junit5.VertxTestContext) CoreMatchers.is(org.hamcrest.CoreMatchers.is) KafkaBuilder(io.strimzi.api.kafka.model.KafkaBuilder) AfterAll(org.junit.jupiter.api.AfterAll) KafkaCluster(io.strimzi.operator.cluster.model.KafkaCluster) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) EnableKubernetesMockClient(io.fabric8.kubernetes.client.server.mock.EnableKubernetesMockClient) KafkaVersionTestUtils(io.strimzi.operator.cluster.KafkaVersionTestUtils) BeforeAll(org.junit.jupiter.api.BeforeAll) Map(java.util.Map) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) ResourceUtils(io.strimzi.operator.cluster.ResourceUtils) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) MockKube2(io.strimzi.test.mockkube2.MockKube2) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) KubernetesVersion(io.strimzi.operator.KubernetesVersion) KafkaVersion(io.strimzi.operator.cluster.model.KafkaVersion) Vertx(io.vertx.core.Vertx) Pod(io.fabric8.kubernetes.api.model.Pod) GenericKafkaListenerBuilder(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerBuilder) VertxExtension(io.vertx.junit5.VertxExtension) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) Future(io.vertx.core.Future) Test(org.junit.jupiter.api.Test) Reconciliation(io.strimzi.operator.common.Reconciliation) AfterEach(org.junit.jupiter.api.AfterEach) KafkaConfiguration(io.strimzi.operator.cluster.model.KafkaConfiguration) Logger(org.apache.logging.log4j.Logger) KafkaListenerType(io.strimzi.api.kafka.model.listener.arraylistener.KafkaListenerType) PasswordGenerator(io.strimzi.operator.common.PasswordGenerator) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Checkpoint(io.vertx.junit5.Checkpoint) Matchers.stringContainsInOrder(org.hamcrest.Matchers.stringContainsInOrder) Kafka(io.strimzi.api.kafka.model.Kafka) PlatformFeaturesAvailability(io.strimzi.operator.PlatformFeaturesAvailability) LogManager(org.apache.logging.log4j.LogManager) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) MockCertManager(io.strimzi.operator.common.operator.MockCertManager) KafkaVersion(io.strimzi.operator.cluster.model.KafkaVersion) Checkpoint(io.vertx.junit5.Checkpoint) Pod(io.fabric8.kubernetes.api.model.Pod) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) Reconciliation(io.strimzi.operator.common.Reconciliation) Kafka(io.strimzi.api.kafka.model.Kafka) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) StatefulSetBuilder(io.fabric8.kubernetes.api.model.apps.StatefulSetBuilder) Checkpoint(io.vertx.junit5.Checkpoint) Test(org.junit.jupiter.api.Test)

Aggregations

KafkaVersion (io.strimzi.operator.cluster.model.KafkaVersion)14 Reconciliation (io.strimzi.operator.common.Reconciliation)14 Map (java.util.Map)14 KafkaCluster (io.strimzi.operator.cluster.model.KafkaCluster)12 Future (io.vertx.core.Future)12 Vertx (io.vertx.core.Vertx)12 Pod (io.fabric8.kubernetes.api.model.Pod)10 KafkaConfiguration (io.strimzi.operator.cluster.model.KafkaConfiguration)10 StatefulSet (io.fabric8.kubernetes.api.model.apps.StatefulSet)8 KubernetesClient (io.fabric8.kubernetes.client.KubernetesClient)8 Kafka (io.strimzi.api.kafka.model.Kafka)8 KafkaBuilder (io.strimzi.api.kafka.model.KafkaBuilder)8 GenericKafkaListenerBuilder (io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerBuilder)8 KafkaListenerType (io.strimzi.api.kafka.model.listener.arraylistener.KafkaListenerType)8 KubernetesVersion (io.strimzi.operator.KubernetesVersion)8 PlatformFeaturesAvailability (io.strimzi.operator.PlatformFeaturesAvailability)8 ClusterOperatorConfig (io.strimzi.operator.cluster.ClusterOperatorConfig)8 KafkaVersionTestUtils (io.strimzi.operator.cluster.KafkaVersionTestUtils)8 ResourceUtils (io.strimzi.operator.cluster.ResourceUtils)8 ResourceOperatorSupplier (io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier)8