Search in sources :

Example 96 with Reconciliation

use of io.strimzi.operator.common.Reconciliation in project strimzi by strimzi.

the class ConnectBuildOperator method kubernetesBuildWaitForFinish.

/**
 * Waits for the Kafka Connect build to finish and collects the results from it
 *
 * @param reconciliation        The reconciliation
 * @param namespace             Namespace of the Connect cluster
 * @param connectBuild          KafkaConnectBuild object
 *
 * @return                      Future which completes with the built image when the build is finished (or fails if it fails)
 */
private Future<String> kubernetesBuildWaitForFinish(Reconciliation reconciliation, String namespace, KafkaConnectBuild connectBuild) {
    return podOperator.waitFor(reconciliation, namespace, KafkaConnectResources.buildPodName(connectBuild.getCluster()), "complete", 1_000, connectBuildTimeoutMs, (ignore1, ignore2) -> kubernetesBuildPodFinished(namespace, KafkaConnectResources.buildPodName(connectBuild.getCluster()))).compose(ignore -> podOperator.getAsync(namespace, KafkaConnectResources.buildPodName(connectBuild.getCluster()))).compose(pod -> {
        if (KafkaConnectBuildUtils.buildPodSucceeded(pod)) {
            ContainerStateTerminated state = pod.getStatus().getContainerStatuses().get(0).getState().getTerminated();
            String image = state.getMessage().trim();
            LOGGER.infoCr(reconciliation, "Build completed successfully. New image is {}.", image);
            return Future.succeededFuture(image);
        } else {
            ContainerStateTerminated state = pod.getStatus().getContainerStatuses().get(0).getState().getTerminated();
            LOGGER.warnCr(reconciliation, "Build failed with code {}: {}", state.getExitCode(), state.getMessage());
            return Future.failedFuture("The Kafka Connect build failed");
        }
    });
}
Also used : Annotations(io.strimzi.operator.common.Annotations) LocalObjectReference(io.fabric8.kubernetes.api.model.LocalObjectReference) AtomicReference(java.util.concurrent.atomic.AtomicReference) ServiceAccountOperator(io.strimzi.operator.common.operator.resource.ServiceAccountOperator) BuildOperator(io.strimzi.operator.common.operator.resource.BuildOperator) ConfigMapOperator(io.strimzi.operator.common.operator.resource.ConfigMapOperator) BuildConfigOperator(io.strimzi.operator.common.operator.resource.BuildConfigOperator) PodOperator(io.strimzi.operator.common.operator.resource.PodOperator) Build(io.fabric8.openshift.api.model.Build) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) KafkaConnectBuild(io.strimzi.operator.cluster.model.KafkaConnectBuild) DeploymentOperator(io.strimzi.operator.common.operator.resource.DeploymentOperator) Pod(io.fabric8.kubernetes.api.model.Pod) KafkaConnectDockerfile(io.strimzi.operator.cluster.model.KafkaConnectDockerfile) Future(io.vertx.core.Future) ConfigMap(io.fabric8.kubernetes.api.model.ConfigMap) Reconciliation(io.strimzi.operator.common.Reconciliation) ImagePullPolicy(io.strimzi.operator.cluster.model.ImagePullPolicy) KafkaConnectBuildUtils(io.strimzi.operator.cluster.model.KafkaConnectBuildUtils) List(java.util.List) Util(io.strimzi.operator.common.Util) ContainerStateTerminated(io.fabric8.kubernetes.api.model.ContainerStateTerminated) Deployment(io.fabric8.kubernetes.api.model.apps.Deployment) PlatformFeaturesAvailability(io.strimzi.operator.PlatformFeaturesAvailability) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) KafkaConnectResources(io.strimzi.api.kafka.model.KafkaConnectResources) ContainerStateTerminated(io.fabric8.kubernetes.api.model.ContainerStateTerminated)

Example 97 with Reconciliation

use of io.strimzi.operator.common.Reconciliation in project strimzi by strimzi.

the class KafkaBridgeAssemblyOperator method createOrUpdate.

@Override
protected Future<KafkaBridgeStatus> createOrUpdate(Reconciliation reconciliation, KafkaBridge assemblyResource) {
    KafkaBridgeStatus kafkaBridgeStatus = new KafkaBridgeStatus();
    String namespace = reconciliation.namespace();
    KafkaBridgeCluster bridge;
    try {
        bridge = KafkaBridgeCluster.fromCrd(reconciliation, assemblyResource, versions);
    } catch (Exception e) {
        LOGGER.warnCr(reconciliation, e);
        StatusUtils.setStatusConditionAndObservedGeneration(assemblyResource, kafkaBridgeStatus, Future.failedFuture(e));
        return Future.failedFuture(new ReconciliationException(kafkaBridgeStatus, e));
    }
    KafkaClientAuthentication auth = assemblyResource.getSpec().getAuthentication();
    List<CertSecretSource> trustedCertificates = assemblyResource.getSpec().getTls() == null ? Collections.emptyList() : assemblyResource.getSpec().getTls().getTrustedCertificates();
    Promise<KafkaBridgeStatus> createOrUpdatePromise = Promise.promise();
    boolean bridgeHasZeroReplicas = bridge.getReplicas() == 0;
    LOGGER.debugCr(reconciliation, "Updating Kafka Bridge cluster");
    kafkaBridgeServiceAccount(reconciliation, namespace, bridge).compose(i -> deploymentOperations.scaleDown(reconciliation, namespace, bridge.getName(), bridge.getReplicas())).compose(scale -> serviceOperations.reconcile(reconciliation, namespace, bridge.getServiceName(), bridge.generateService())).compose(i -> Util.metricsAndLogging(reconciliation, configMapOperations, namespace, bridge.getLogging(), null)).compose(metricsAndLogging -> configMapOperations.reconcile(reconciliation, namespace, bridge.getAncillaryConfigMapName(), bridge.generateMetricsAndLogConfigMap(metricsAndLogging))).compose(i -> pfa.hasPodDisruptionBudgetV1() ? podDisruptionBudgetOperator.reconcile(reconciliation, namespace, bridge.getName(), bridge.generatePodDisruptionBudget()) : Future.succeededFuture()).compose(i -> !pfa.hasPodDisruptionBudgetV1() ? podDisruptionBudgetV1Beta1Operator.reconcile(reconciliation, namespace, bridge.getName(), bridge.generatePodDisruptionBudgetV1Beta1()) : Future.succeededFuture()).compose(i -> Util.authTlsHash(secretOperations, namespace, auth, trustedCertificates)).compose(hash -> deploymentOperations.reconcile(reconciliation, namespace, bridge.getName(), bridge.generateDeployment(Collections.singletonMap(Annotations.ANNO_STRIMZI_AUTH_HASH, Integer.toString(hash)), pfa.isOpenshift(), imagePullPolicy, imagePullSecrets))).compose(i -> deploymentOperations.scaleUp(reconciliation, namespace, bridge.getName(), bridge.getReplicas())).compose(i -> deploymentOperations.waitForObserved(reconciliation, namespace, bridge.getName(), 1_000, operationTimeoutMs)).compose(i -> bridgeHasZeroReplicas ? Future.succeededFuture() : deploymentOperations.readiness(reconciliation, namespace, bridge.getName(), 1_000, operationTimeoutMs)).onComplete(reconciliationResult -> {
        StatusUtils.setStatusConditionAndObservedGeneration(assemblyResource, kafkaBridgeStatus, reconciliationResult.mapEmpty());
        if (!bridgeHasZeroReplicas) {
            int port = KafkaBridgeCluster.DEFAULT_REST_API_PORT;
            if (bridge.getHttp() != null) {
                port = bridge.getHttp().getPort();
            }
            kafkaBridgeStatus.setUrl(KafkaBridgeResources.url(bridge.getCluster(), namespace, port));
        }
        kafkaBridgeStatus.setReplicas(bridge.getReplicas());
        kafkaBridgeStatus.setLabelSelector(bridge.getSelectorLabels().toSelectorString());
        if (reconciliationResult.succeeded()) {
            createOrUpdatePromise.complete(kafkaBridgeStatus);
        } else {
            createOrUpdatePromise.fail(new ReconciliationException(kafkaBridgeStatus, reconciliationResult.cause()));
        }
    });
    return createOrUpdatePromise.future();
}
Also used : KafkaBridgeCluster(io.strimzi.operator.cluster.model.KafkaBridgeCluster) ReconciliationException(io.strimzi.operator.common.ReconciliationException) KafkaClientAuthentication(io.strimzi.api.kafka.model.authentication.KafkaClientAuthentication) CertManager(io.strimzi.certs.CertManager) Annotations(io.strimzi.operator.common.Annotations) Resource(io.fabric8.kubernetes.client.dsl.Resource) KafkaBridge(io.strimzi.api.kafka.model.KafkaBridge) ConfigMapOperator(io.strimzi.operator.common.operator.resource.ConfigMapOperator) ResourceOperatorSupplier(io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier) ReconciliationException(io.strimzi.operator.common.ReconciliationException) ReconcileResult(io.strimzi.operator.common.operator.resource.ReconcileResult) KafkaBridgeResources(io.strimzi.api.kafka.model.KafkaBridgeResources) StatusUtils(io.strimzi.operator.common.operator.resource.StatusUtils) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) ExternalLogging(io.strimzi.api.kafka.model.ExternalLogging) CertSecretSource(io.strimzi.api.kafka.model.CertSecretSource) DeploymentOperator(io.strimzi.operator.common.operator.resource.DeploymentOperator) Promise(io.vertx.core.Promise) KafkaVersion(io.strimzi.operator.cluster.model.KafkaVersion) Vertx(io.vertx.core.Vertx) KafkaBridgeSpec(io.strimzi.api.kafka.model.KafkaBridgeSpec) KafkaBridgeList(io.strimzi.api.kafka.KafkaBridgeList) Future(io.vertx.core.Future) ConfigMap(io.fabric8.kubernetes.api.model.ConfigMap) KafkaBridgeCluster(io.strimzi.operator.cluster.model.KafkaBridgeCluster) KafkaBridgeStatus(io.strimzi.api.kafka.model.status.KafkaBridgeStatus) Reconciliation(io.strimzi.operator.common.Reconciliation) List(java.util.List) Util(io.strimzi.operator.common.Util) PasswordGenerator(io.strimzi.operator.common.PasswordGenerator) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) ServiceAccount(io.fabric8.kubernetes.api.model.ServiceAccount) KafkaClientAuthentication(io.strimzi.api.kafka.model.authentication.KafkaClientAuthentication) PlatformFeaturesAvailability(io.strimzi.operator.PlatformFeaturesAvailability) Collections(java.util.Collections) ClusterOperatorConfig(io.strimzi.operator.cluster.ClusterOperatorConfig) CertSecretSource(io.strimzi.api.kafka.model.CertSecretSource) ReconciliationException(io.strimzi.operator.common.ReconciliationException) KafkaBridgeStatus(io.strimzi.api.kafka.model.status.KafkaBridgeStatus)

Example 98 with Reconciliation

use of io.strimzi.operator.common.Reconciliation in project strimzi by strimzi.

the class KafkaConnectApiImpl method createOrUpdatePutRequest.

@Override
@SuppressWarnings("unchecked")
public Future<Map<String, Object>> createOrUpdatePutRequest(Reconciliation reconciliation, String host, int port, String connectorName, JsonObject configJson) {
    Buffer data = configJson.toBuffer();
    String path = "/connectors/" + connectorName + "/config";
    LOGGER.debugCr(reconciliation, "Making PUT request to {} with body {}", path, configJson);
    return HttpClientUtils.withHttpClient(vertx, new HttpClientOptions().setLogActivity(true), (httpClient, result) -> httpClient.request(HttpMethod.PUT, port, host, path, request -> {
        if (request.succeeded()) {
            request.result().setFollowRedirects(true).putHeader("Accept", "application/json").putHeader("Content-Type", "application/json").putHeader("Content-Length", String.valueOf(data.length())).write(data);
            request.result().send(response -> {
                if (response.succeeded()) {
                    if (response.result().statusCode() == 200 || response.result().statusCode() == 201) {
                        response.result().bodyHandler(buffer -> {
                            try {
                                Map t = mapper.readValue(buffer.getBytes(), Map.class);
                                LOGGER.debugCr(reconciliation, "Got {} response to PUT request to {}: {}", response.result().statusCode(), path, t);
                                result.complete(t);
                            } catch (IOException e) {
                                result.fail(new ConnectRestException(response.result(), "Could not deserialize response: " + e));
                            }
                        });
                    } else {
                        // TODO Handle 409 (Conflict) indicating a rebalance in progress
                        LOGGER.debugCr(reconciliation, "Got {} response to PUT request to {}", response.result().statusCode(), path);
                        response.result().bodyHandler(buffer -> {
                            JsonObject x = buffer.toJsonObject();
                            result.fail(new ConnectRestException(response.result(), x.getString("message")));
                        });
                    }
                } else {
                    result.tryFail(response.cause());
                }
            });
        } else {
            result.fail(request.cause());
        }
    }));
}
Also used : Buffer(io.vertx.core.buffer.Buffer) OrderedProperties(io.strimzi.operator.common.model.OrderedProperties) BackOff(io.strimzi.operator.common.BackOff) HashMap(java.util.HashMap) Function(java.util.function.Function) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Arrays.asList(java.util.Arrays.asList) Map(java.util.Map) JsonObject(io.vertx.core.json.JsonObject) HttpClientOptions(io.vertx.core.http.HttpClientOptions) TypeReference(com.fasterxml.jackson.core.type.TypeReference) ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) Promise(io.vertx.core.Promise) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Vertx(io.vertx.core.Vertx) Set(java.util.Set) IOException(java.io.IOException) ConnectorPlugin(io.strimzi.api.kafka.model.connect.ConnectorPlugin) Collectors(java.util.stream.Collectors) Future(io.vertx.core.Future) Reconciliation(io.strimzi.operator.common.Reconciliation) JsonArray(io.vertx.core.json.JsonArray) List(java.util.List) Util(io.strimzi.operator.common.Util) TreeMap(java.util.TreeMap) Buffer(io.vertx.core.buffer.Buffer) HttpMethod(io.vertx.core.http.HttpMethod) Optional(java.util.Optional) HttpClientUtils(io.strimzi.operator.cluster.operator.resource.HttpClientUtils) Comparator(java.util.Comparator) Handler(io.vertx.core.Handler) Collections(java.util.Collections) JsonObject(io.vertx.core.json.JsonObject) IOException(java.io.IOException) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) HttpClientOptions(io.vertx.core.http.HttpClientOptions)

Example 99 with Reconciliation

use of io.strimzi.operator.common.Reconciliation in project strimzi by strimzi.

the class StrimziPodSetController method run.

/**
 * The run loop of the controller thread. It picks reconciliations from the work queue and executes them.
 */
@Override
public void run() {
    LOGGER.infoOp("Starting StrimziPodSet controller for namespace {}", watchedNamespace);
    LOGGER.infoOp("Waiting for informers to sync");
    while (!stop && (!podInformer.hasSynced() || !strimziPodSetInformer.hasSynced() || !kafkaInformer.hasSynced())) {
    // Nothing to do => just loop
    }
    LOGGER.infoOp("Informers are in-sync");
    while (!stop) {
        try {
            LOGGER.debugOp("Waiting for next event from work queue");
            Reconciliation reconciliation = workQueue.take().toReconciliation();
            reconcile(reconciliation);
        } catch (InterruptedException e) {
            LOGGER.debugOp("StrimziPodSet Controller was interrupted", e);
        } catch (Exception e) {
            LOGGER.warnOp("StrimziPodSet reconciliation failed", e);
        }
    }
    LOGGER.infoOp("Stopping StrimziPodSet controller");
    podInformer.stop();
    strimziPodSetInformer.stop();
    kafkaInformer.stop();
}
Also used : Reconciliation(io.strimzi.operator.common.Reconciliation) KubernetesClientException(io.fabric8.kubernetes.client.KubernetesClientException)

Example 100 with Reconciliation

use of io.strimzi.operator.common.Reconciliation in project strimzi by strimzi.

the class ZookeeperScaler method connect.

/**
 * Internal method used to create the Zookeeper Admin client and connect it to Zookeeper
 *
 * @return      Future indicating success or failure
 */
private Future<ZooKeeperAdmin> connect(ZKClientConfig clientConfig) {
    Promise<ZooKeeperAdmin> connected = Promise.promise();
    try {
        ZooKeeperAdmin zkAdmin = zooAdminProvider.createZookeeperAdmin(this.zookeeperConnectionString, zkAdminSessionTimeoutMs, watchedEvent -> LOGGER.debugCr(reconciliation, "Received event {} from ZooKeeperAdmin client connected to {}", watchedEvent, zookeeperConnectionString), clientConfig);
        Util.waitFor(reconciliation, vertx, String.format("ZooKeeperAdmin connection to %s", zookeeperConnectionString), "connected", 1_000, operationTimeoutMs, () -> zkAdmin.getState().isAlive() && zkAdmin.getState().isConnected()).onSuccess(nothing -> connected.complete(zkAdmin)).onFailure(cause -> {
            String message = String.format("Failed to connect to Zookeeper %s. Connection was not ready in %d ms.", zookeeperConnectionString, operationTimeoutMs);
            LOGGER.warnCr(reconciliation, message);
            closeConnection(zkAdmin).onComplete(nothing -> connected.fail(new ZookeeperScalingException(message, cause)));
        });
    } catch (IOException e) {
        LOGGER.warnCr(reconciliation, "Failed to connect to {} to scale Zookeeper", zookeeperConnectionString, e);
        connected.fail(new ZookeeperScalingException("Failed to connect to Zookeeper " + zookeeperConnectionString, e));
    }
    return connected.future();
}
Also used : ReconciliationLogger(io.strimzi.operator.common.ReconciliationLogger) KeeperException(org.apache.zookeeper.KeeperException) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) IOException(java.io.IOException) HashMap(java.util.HashMap) ZookeeperCluster(io.strimzi.operator.cluster.model.ZookeeperCluster) Future(io.vertx.core.Future) Function(java.util.function.Function) File(java.io.File) StandardCharsets(java.nio.charset.StandardCharsets) ArrayList(java.util.ArrayList) Reconciliation(io.strimzi.operator.common.Reconciliation) List(java.util.List) Util(io.strimzi.operator.common.Util) Ca(io.strimzi.operator.cluster.model.Ca) PasswordGenerator(io.strimzi.operator.common.PasswordGenerator) Map(java.util.Map) Secret(io.fabric8.kubernetes.api.model.Secret) ZKClientConfig(org.apache.zookeeper.client.ZKClientConfig) ZooKeeperAdmin(org.apache.zookeeper.admin.ZooKeeperAdmin) IOException(java.io.IOException) ZooKeeperAdmin(org.apache.zookeeper.admin.ZooKeeperAdmin)

Aggregations

Reconciliation (io.strimzi.operator.common.Reconciliation)748 Checkpoint (io.vertx.junit5.Checkpoint)504 Test (org.junit.jupiter.api.Test)496 Future (io.vertx.core.Future)478 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)474 ResourceOperatorSupplier (io.strimzi.operator.cluster.operator.resource.ResourceOperatorSupplier)462 Vertx (io.vertx.core.Vertx)450 VertxTestContext (io.vertx.junit5.VertxTestContext)446 VertxExtension (io.vertx.junit5.VertxExtension)436 List (java.util.List)436 ExtendWith (org.junit.jupiter.api.extension.ExtendWith)436 Map (java.util.Map)426 AfterAll (org.junit.jupiter.api.AfterAll)406 BeforeAll (org.junit.jupiter.api.BeforeAll)394 Kafka (io.strimzi.api.kafka.model.Kafka)392 PlatformFeaturesAvailability (io.strimzi.operator.PlatformFeaturesAvailability)392 ResourceUtils (io.strimzi.operator.cluster.ResourceUtils)390 CoreMatchers.is (org.hamcrest.CoreMatchers.is)380 KafkaVersionTestUtils (io.strimzi.operator.cluster.KafkaVersionTestUtils)368 Mockito.when (org.mockito.Mockito.when)360