Search in sources :

Example 36 with StrimziPodSet

use of io.strimzi.api.kafka.model.StrimziPodSet in project strimzi by strimzi.

the class StrimziPodSetCrdOperatorIT method testUpdateStatusAfterResourceUpdated.

/**
 * Tests what happens when the resource is modified while updating the status
 *
 * @param context
 */
@Test
public void testUpdateStatusAfterResourceUpdated(VertxTestContext context) {
    String resourceName = getResourceName(RESOURCE_NAME);
    Checkpoint async = context.checkpoint();
    String namespace = getNamespace();
    StrimziPodSetOperator op = operator();
    Promise updateStatus = Promise.promise();
    // Required to be able to create the resource
    readinessHelper(op, namespace, resourceName);
    LOGGER.info("Creating resource");
    op.reconcile(Reconciliation.DUMMY_RECONCILIATION, namespace, resourceName, getResource(resourceName)).onComplete(context.succeedingThenComplete()).compose(rrCreated -> {
        StrimziPodSet updated = getResourceWithModifications(rrCreated.resource());
        StrimziPodSet newStatus = getResourceWithNewReadyStatus(rrCreated.resource());
        LOGGER.info("Updating resource (mocking an update due to some other reason)");
        op.operation().inNamespace(namespace).withName(resourceName).patch(updated);
        LOGGER.info("Updating resource status after underlying resource has changed");
        return op.updateStatusAsync(Reconciliation.DUMMY_RECONCILIATION, newStatus);
    }).onComplete(context.succeeding(res -> context.verify(() -> {
        assertThat(res.getMetadata().getName(), Matchers.is(resourceName));
        assertThat(res.getMetadata().getNamespace(), Matchers.is(namespace));
        updateStatus.complete();
    })));
    updateStatus.future().compose(v -> {
        LOGGER.info("Deleting resource");
        return op.reconcile(Reconciliation.DUMMY_RECONCILIATION, namespace, resourceName, null);
    }).onComplete(context.succeeding(v -> async.flag()));
}
Also used : VertxTestContext(io.vertx.junit5.VertxTestContext) CoreMatchers.is(org.hamcrest.CoreMatchers.is) AtomicReference(java.util.concurrent.atomic.AtomicReference) CoreMatchers.instanceOf(org.hamcrest.CoreMatchers.instanceOf) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) Map(java.util.Map) TestUtils(io.strimzi.test.TestUtils) ContainerBuilder(io.fabric8.kubernetes.api.model.ContainerBuilder) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) TypeReference(com.fasterxml.jackson.core.type.TypeReference) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) LabelSelectorBuilder(io.fabric8.kubernetes.api.model.LabelSelectorBuilder) StrimziPodSetList(io.strimzi.api.kafka.StrimziPodSetList) Promise(io.vertx.core.Promise) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Pod(io.fabric8.kubernetes.api.model.Pod) Matchers(org.hamcrest.Matchers) VertxExtension(io.vertx.junit5.VertxExtension) Test(org.junit.jupiter.api.Test) Reconciliation(io.strimzi.operator.common.Reconciliation) Logger(org.apache.logging.log4j.Logger) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Checkpoint(io.vertx.junit5.Checkpoint) LogManager(org.apache.logging.log4j.LogManager) Promise(io.vertx.core.Promise) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) Checkpoint(io.vertx.junit5.Checkpoint) Test(org.junit.jupiter.api.Test)

Example 37 with StrimziPodSet

use of io.strimzi.api.kafka.model.StrimziPodSet in project strimzi by strimzi.

the class StrimziPodSetCrdOperatorIT method testUpdateStatus.

@Test
public void testUpdateStatus(VertxTestContext context) {
    String resourceName = getResourceName(RESOURCE_NAME);
    Checkpoint async = context.checkpoint();
    String namespace = getNamespace();
    StrimziPodSetOperator op = operator();
    // Required to be able to create the resource
    readinessHelper(op, namespace, resourceName);
    LOGGER.info("Creating resource");
    op.reconcile(Reconciliation.DUMMY_RECONCILIATION, namespace, resourceName, getResource(resourceName)).onComplete(context.succeedingThenComplete()).compose(rrCreated -> {
        StrimziPodSet newStatus = getResourceWithNewReadyStatus(rrCreated.resource());
        LOGGER.info("Updating resource status");
        return op.updateStatusAsync(Reconciliation.DUMMY_RECONCILIATION, newStatus);
    }).onComplete(context.succeedingThenComplete()).compose(rrModified -> op.getAsync(namespace, resourceName)).onComplete(context.succeeding(modifiedCustomResource -> context.verify(() -> {
        assertReady(context, modifiedCustomResource);
    }))).compose(rrModified -> {
        LOGGER.info("Deleting resource");
        return op.reconcile(Reconciliation.DUMMY_RECONCILIATION, namespace, resourceName, null);
    }).onComplete(context.succeeding(rrDeleted -> async.flag()));
}
Also used : VertxTestContext(io.vertx.junit5.VertxTestContext) CoreMatchers.is(org.hamcrest.CoreMatchers.is) AtomicReference(java.util.concurrent.atomic.AtomicReference) CoreMatchers.instanceOf(org.hamcrest.CoreMatchers.instanceOf) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) PodBuilder(io.fabric8.kubernetes.api.model.PodBuilder) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) Map(java.util.Map) TestUtils(io.strimzi.test.TestUtils) ContainerBuilder(io.fabric8.kubernetes.api.model.ContainerBuilder) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) TypeReference(com.fasterxml.jackson.core.type.TypeReference) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException) LabelSelectorBuilder(io.fabric8.kubernetes.api.model.LabelSelectorBuilder) StrimziPodSetList(io.strimzi.api.kafka.StrimziPodSetList) Promise(io.vertx.core.Promise) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Pod(io.fabric8.kubernetes.api.model.Pod) Matchers(org.hamcrest.Matchers) VertxExtension(io.vertx.junit5.VertxExtension) Test(org.junit.jupiter.api.Test) Reconciliation(io.strimzi.operator.common.Reconciliation) Logger(org.apache.logging.log4j.Logger) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) Checkpoint(io.vertx.junit5.Checkpoint) LogManager(org.apache.logging.log4j.LogManager) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) Checkpoint(io.vertx.junit5.Checkpoint) Test(org.junit.jupiter.api.Test)

Example 38 with StrimziPodSet

use of io.strimzi.api.kafka.model.StrimziPodSet in project strimzi-kafka-operator by strimzi.

the class KafkaReconciler method scaleDown.

/**
 * Scales down the Kafka cluster if needed. Kafka scale-down is done in one go.
 *
 * @return  Future which completes when the scale-down is finished
 */
protected Future<Void> scaleDown() {
    if (currentReplicas != 0 && currentReplicas > kafka.getReplicas()) {
        // The previous (current) number of replicas is bigger than desired => we should scale-down
        LOGGER.infoCr(reconciliation, "Scaling Kafka down from {} to {} replicas", currentReplicas, kafka.getReplicas());
        if (featureGates.useStrimziPodSetsEnabled()) {
            Set<String> desiredPodNames = new HashSet<>(kafka.getReplicas());
            for (int i = 0; i < kafka.getReplicas(); i++) {
                desiredPodNames.add(kafka.getPodName(i));
            }
            return strimziPodSetOperator.getAsync(reconciliation.namespace(), kafka.getName()).compose(podSet -> {
                if (podSet == null) {
                    return Future.succeededFuture();
                } else {
                    List<Map<String, Object>> desiredPods = podSet.getSpec().getPods().stream().filter(pod -> desiredPodNames.contains(PodSetUtils.mapToPod(pod).getMetadata().getName())).collect(Collectors.toList());
                    StrimziPodSet scaledDownPodSet = new StrimziPodSetBuilder(podSet).editSpec().withPods(desiredPods).endSpec().build();
                    return strimziPodSetOperator.reconcile(reconciliation, reconciliation.namespace(), kafka.getName(), scaledDownPodSet).map((Void) null);
                }
            });
        } else {
            return stsOperator.scaleDown(reconciliation, reconciliation.namespace(), kafka.getName(), kafka.getReplicas()).map((Void) null);
        }
    } else {
        // desired replicas => no need to scale-down
        return Future.succeededFuture();
    }
}
Also used : IngressV1Beta1Operator(io.strimzi.operator.common.operator.resource.IngressV1Beta1Operator) Storage(io.strimzi.api.kafka.model.storage.Storage) StrimziPodSetOperator(io.strimzi.operator.common.operator.resource.StrimziPodSetOperator) Date(java.util.Date) Annotations(io.strimzi.operator.common.Annotations) KafkaException(org.apache.kafka.common.KafkaException) PodDisruptionBudget(io.fabric8.kubernetes.api.model.policy.v1.PodDisruptionBudget) ClusterRoleBindingOperator(io.strimzi.operator.common.operator.resource.ClusterRoleBindingOperator) KafkaResources(io.strimzi.api.kafka.model.KafkaResources) Ca(io.strimzi.operator.cluster.model.Ca) PodDisruptionBudgetV1Beta1Operator(io.strimzi.operator.common.operator.resource.PodDisruptionBudgetV1Beta1Operator) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) Map(java.util.Map) PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) AbstractModel(io.strimzi.operator.cluster.model.AbstractModel) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) KafkaVersionChange(io.strimzi.operator.cluster.model.KafkaVersionChange) ModelUtils(io.strimzi.operator.cluster.model.ModelUtils) ListenersUtils(io.strimzi.operator.cluster.model.ListenersUtils) ListenerAddress(io.strimzi.api.kafka.model.status.ListenerAddress) SecretOperator(io.strimzi.operator.common.operator.resource.SecretOperator) Set(java.util.Set) ClientsCa(io.strimzi.operator.cluster.model.ClientsCa) HasMetadata(io.fabric8.kubernetes.api.model.HasMetadata) NodeUtils(io.strimzi.operator.cluster.model.NodeUtils) Future(io.vertx.core.Future) Collectors(java.util.stream.Collectors) ListenerStatus(io.strimzi.api.kafka.model.status.ListenerStatus) List(java.util.List) KafkaConfiguration(io.strimzi.operator.cluster.model.KafkaConfiguration) Labels(io.strimzi.operator.common.model.Labels) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) PersistentVolumeClaim(io.fabric8.kubernetes.api.model.PersistentVolumeClaim) Secret(io.fabric8.kubernetes.api.model.Secret) RouteOperator(io.strimzi.operator.common.operator.resource.RouteOperator) AdminClientProvider(io.strimzi.operator.common.AdminClientProvider) ClusterCa(io.strimzi.operator.cluster.model.ClusterCa) PodDisruptionBudgetOperator(io.strimzi.operator.common.operator.resource.PodDisruptionBudgetOperator) PlatformFeaturesAvailability(io.strimzi.operator.PlatformFeaturesAvailability) SuppressFBWarnings(edu.umd.cs.findbugs.annotations.SuppressFBWarnings) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) IntStream(java.util.stream.IntStream) ClusterRoleBinding(io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding) KafkaStatus(io.strimzi.api.kafka.model.status.KafkaStatus) GenericKafkaListener(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListener) BackOff(io.strimzi.operator.common.BackOff) IngressOperator(io.strimzi.operator.common.operator.resource.IngressOperator) NetworkPolicyOperator(io.strimzi.operator.common.operator.resource.NetworkPolicyOperator) HashMap(java.util.HashMap) ListenerAddressBuilder(io.strimzi.api.kafka.model.status.ListenerAddressBuilder) LocalObjectReference(io.fabric8.kubernetes.api.model.LocalObjectReference) Function(java.util.function.Function) Supplier(java.util.function.Supplier) FeatureGates(io.strimzi.operator.cluster.FeatureGates) StorageDiff(io.strimzi.operator.cluster.model.StorageDiff) MetricsAndLogging(io.strimzi.operator.common.MetricsAndLogging) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) ServiceOperator(io.strimzi.operator.common.operator.resource.ServiceOperator) CompositeFuture(io.vertx.core.CompositeFuture) KafkaCluster(io.strimzi.operator.cluster.model.KafkaCluster) ServiceAccountOperator(io.strimzi.operator.common.operator.resource.ServiceAccountOperator) ConfigMapOperator(io.strimzi.operator.common.operator.resource.ConfigMapOperator) ANNO_STRIMZI_IO_KAFKA_VERSION(io.strimzi.operator.cluster.model.KafkaCluster.ANNO_STRIMZI_IO_KAFKA_VERSION) KafkaRoller(io.strimzi.operator.cluster.operator.resource.KafkaRoller) Admin(org.apache.kafka.clients.admin.Admin) ReconcileResult(io.strimzi.operator.common.operator.resource.ReconcileResult) ConcurrentDeletionException(io.strimzi.operator.cluster.operator.resource.ConcurrentDeletionException) Node(io.fabric8.kubernetes.api.model.Node) JbodStorage(io.strimzi.api.kafka.model.storage.JbodStorage) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) NodeOperator(io.strimzi.operator.common.operator.resource.NodeOperator) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) Pod(io.fabric8.kubernetes.api.model.Pod) PodSetUtils(io.strimzi.operator.cluster.model.PodSetUtils) StorageClassOperator(io.strimzi.operator.common.operator.resource.StorageClassOperator) StatefulSet(io.fabric8.kubernetes.api.model.apps.StatefulSet) PvcOperator(io.strimzi.operator.common.operator.resource.PvcOperator) ConfigMap(io.fabric8.kubernetes.api.model.ConfigMap) ExecutionException(java.util.concurrent.ExecutionException) Reconciliation(io.strimzi.operator.common.Reconciliation) ImagePullPolicy(io.strimzi.operator.cluster.model.ImagePullPolicy) ANNO_STRIMZI_IO_STORAGE(io.strimzi.operator.cluster.model.AbstractModel.ANNO_STRIMZI_IO_STORAGE) Util(io.strimzi.operator.common.Util) Kafka(io.strimzi.api.kafka.model.Kafka) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ConfigMap(io.fabric8.kubernetes.api.model.ConfigMap) HashSet(java.util.HashSet)

Example 39 with StrimziPodSet

use of io.strimzi.api.kafka.model.StrimziPodSet in project strimzi-kafka-operator by strimzi.

the class ManualPodCleaner method cleanPodPvcAndPodSet.

/**
 * Handles the modification of the StrimziPodSet controlling the pod which should be cleaned. In order
 * to clean the pod and its PVCs, we first need to remove the pod from the StrimziPodSet. Otherwise, the
 * StrimziPodSet will break the process by recreating the pods or PVCs. This method first modifies the StrimziPodSet
 * and then calls other method to delete the Pod, PVCs and create the new PVCs. Once this method completes, it
 * will update the StrimziPodSet again. The Pod will be then recreated by the StrimziPodSet and this method just
 * waits for it to become ready.
 *
 * The complete flow looks like this
 *     1. Remove the deleted pod from the PodSet
 *     2. Trigger the Pod and PVC deletion and recreation
 *     3. Recreate the original PodSet
 *     4. Wait for the Pod to be created and become ready
 *
 * @param podSetName    Name of the StrimziPodSet to which this pod belongs
 * @param podName       Name of the Pod which should be cleaned / deleted
 * @param desiredPvcs   The list of desired PVCs which should be created after the old Pod and PVCs are deleted
 * @param currentPvcs   The list of current PVCs which should be deleted
 *
 * @return              Future indicating the result of the cleanup
 */
private Future<Void> cleanPodPvcAndPodSet(String podSetName, String podName, List<PersistentVolumeClaim> desiredPvcs, List<PersistentVolumeClaim> currentPvcs) {
    return strimziPodSetOperator.getAsync(reconciliation.namespace(), podSetName).compose(podSet -> {
        List<Map<String, Object>> desiredPods = podSet.getSpec().getPods().stream().filter(pod -> !podName.equals(PodSetUtils.mapToPod(pod).getMetadata().getName())).collect(Collectors.toList());
        StrimziPodSet reducedPodSet = new StrimziPodSetBuilder(podSet).editSpec().withPods(desiredPods).endSpec().build();
        return strimziPodSetOperator.reconcile(reconciliation, reconciliation.namespace(), podSetName, reducedPodSet).compose(ignore -> cleanPodAndPvc(podName, desiredPvcs, currentPvcs)).compose(ignore -> {
            // We recreate the StrimziPodSet in its old configuration => any further changes have to be done by rolling update
            // These fields need to be cleared before recreating the StatefulSet
            podSet.getMetadata().setResourceVersion(null);
            podSet.getMetadata().setSelfLink(null);
            podSet.getMetadata().setUid(null);
            podSet.setStatus(null);
            return strimziPodSetOperator.reconcile(reconciliation, reconciliation.namespace(), podSetName, podSet);
        }).compose(ignore -> podOperator.readiness(reconciliation, reconciliation.namespace(), podName, 1_000L, operationTimeoutMs)).map((Void) null);
    });
}
Also used : AbstractScalableResourceOperator(io.strimzi.operator.common.operator.resource.AbstractScalableResourceOperator) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) StrimziPodSetOperator(io.strimzi.operator.common.operator.resource.StrimziPodSetOperator) Pod(io.fabric8.kubernetes.api.model.Pod) PodSetUtils(io.strimzi.operator.cluster.model.PodSetUtils) Annotations(io.strimzi.operator.common.Annotations) PvcOperator(io.strimzi.operator.common.operator.resource.PvcOperator) Future(io.vertx.core.Future) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) Reconciliation(io.strimzi.operator.common.Reconciliation) CompositeFuture(io.vertx.core.CompositeFuture) List(java.util.List) Labels(io.strimzi.operator.common.model.Labels) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) Map(java.util.Map) PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) PersistentVolumeClaim(io.fabric8.kubernetes.api.model.PersistentVolumeClaim) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) StatefulSetOperator(io.strimzi.operator.cluster.operator.resource.StatefulSetOperator) StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) Map(java.util.Map)

Example 40 with StrimziPodSet

use of io.strimzi.api.kafka.model.StrimziPodSet in project strimzi-kafka-operator by strimzi.

the class StrimziPodSetController method maybeUpdateStatus.

/**
 * Updates the status of the StrimziPodSet. The status will be updated only when it changed since last time.
 *
 * @param reconciliation    Reconciliation in which this is executed
 * @param podSet            Original pod set with the current status
 * @param desiredStatus     The desired status which should be set if it differs
 */
private void maybeUpdateStatus(Reconciliation reconciliation, StrimziPodSet podSet, StrimziPodSetStatus desiredStatus) {
    if (!new StatusDiff(podSet.getStatus(), desiredStatus).isEmpty()) {
        try {
            LOGGER.debugCr(reconciliation, "Updating status of StrimziPodSet {} in namespace {}", reconciliation.name(), reconciliation.namespace());
            StrimziPodSet latestPodSet = strimziPodSetLister.namespace(reconciliation.namespace()).get(reconciliation.name());
            if (latestPodSet != null) {
                StrimziPodSet updatedPodSet = new StrimziPodSetBuilder(latestPodSet).withStatus(desiredStatus).build();
                strimziPodSetOperator.client().inNamespace(reconciliation.namespace()).withName(reconciliation.name()).patchStatus(updatedPodSet);
            }
        } catch (KubernetesClientException e) {
            if (e.getCode() == 409) {
                LOGGER.debugCr(reconciliation, "StrimziPodSet {} in namespace {} changed while trying to update status", reconciliation.name(), reconciliation.namespace());
            } else if (e.getCode() == 404) {
                LOGGER.debugCr(reconciliation, "StrimziPodSet {} in namespace {} was deleted while trying to update status", reconciliation.name(), reconciliation.namespace());
            } else {
                LOGGER.errorCr(reconciliation, "Failed to update status of StrimziPodSet {} in namespace {}", reconciliation.name(), reconciliation.namespace(), e);
            }
        }
    }
}
Also used : StrimziPodSet(io.strimzi.api.kafka.model.StrimziPodSet) StatusDiff(io.strimzi.operator.cluster.model.StatusDiff) StrimziPodSetBuilder(io.strimzi.api.kafka.model.StrimziPodSetBuilder) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException)

Aggregations

StrimziPodSet (io.strimzi.api.kafka.model.StrimziPodSet)106 Pod (io.fabric8.kubernetes.api.model.Pod)84 Test (org.junit.jupiter.api.Test)62 Reconciliation (io.strimzi.operator.common.Reconciliation)58 Kafka (io.strimzi.api.kafka.model.Kafka)54 KafkaBuilder (io.strimzi.api.kafka.model.KafkaBuilder)50 ResourceOperatorSupplier (io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier)44 StatefulSetOperator (io.strimzi.operator.cluster.operator.resource.StatefulSetOperator)44 Labels (io.strimzi.operator.common.model.Labels)44 PodOperator (io.strimzi.operator.common.operator.resource.PodOperator)44 Checkpoint (io.vertx.junit5.Checkpoint)44 CoreMatchers.is (org.hamcrest.CoreMatchers.is)44 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)44 GenericKafkaListenerBuilder (io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerBuilder)42 Map (java.util.Map)42 KubernetesClient (io.fabric8.kubernetes.client.KubernetesClient)40 PlatformFeaturesAvailability (io.strimzi.operator.PlatformFeaturesAvailability)38 KafkaVersionTestUtils (io.strimzi.operator.cluster.KafkaVersionTestUtils)38 KafkaCluster (io.strimzi.operator.cluster.model.KafkaCluster)38 ArrayList (java.util.ArrayList)38