Search in sources :

Example 1 with ConditionBuilder

use of io.fabric8.kubernetes.api.model.ConditionBuilder in project strimzi by strimzi.

the class AbstractOperator method reconcile.

/**
 * Reconcile assembly resources in the given namespace having the given {@code name}.
 * Reconciliation works by getting the assembly resource (e.g. {@code KafkaUser})
 * in the given namespace with the given name and
 * comparing with the corresponding resource.
 * @param reconciliation The reconciliation.
 * @return A Future which is completed with the result of the reconciliation.
 */
@Override
@SuppressWarnings("unchecked")
public final Future<Void> reconcile(Reconciliation reconciliation) {
    String namespace = reconciliation.namespace();
    String name = reconciliation.name();
    reconciliationsCounter(reconciliation.namespace()).increment();
    Timer.Sample reconciliationTimerSample = Timer.start(metrics.meterRegistry());
    Future<Void> handler = withLock(reconciliation, LOCK_TIMEOUT_MS, () -> {
        T cr = resourceOperator.get(namespace, name);
        if (cr != null) {
            if (!Util.matchesSelector(selector(), cr)) {
                // When the labels matching the selector are removed from the custom resource, a DELETE event is
                // triggered by the watch even through the custom resource might not match the watch labels anymore
                // and might not be really deleted. We have to filter these situations out and ignore the
                // reconciliation because such resource might be already operated by another instance (where the
                // same change triggered ADDED event).
                LOGGER.debugCr(reconciliation, "{} {} in namespace {} does not match label selector {} and will be ignored", kind(), name, namespace, selector().get().getMatchLabels());
                return Future.succeededFuture();
            }
            Promise<Void> createOrUpdate = Promise.promise();
            if (Annotations.isReconciliationPausedWithAnnotation(cr)) {
                S status = createStatus();
                Set<Condition> conditions = validate(reconciliation, cr);
                conditions.add(StatusUtils.getPausedCondition());
                status.setConditions(new ArrayList<>(conditions));
                status.setObservedGeneration(cr.getStatus() != null ? cr.getStatus().getObservedGeneration() : 0);
                updateStatus(reconciliation, status).onComplete(statusResult -> {
                    if (statusResult.succeeded()) {
                        createOrUpdate.complete();
                    } else {
                        createOrUpdate.fail(statusResult.cause());
                    }
                });
                pausedResourceCounter(namespace).getAndIncrement();
                LOGGER.debugCr(reconciliation, "Reconciliation of {} {} is paused", kind, name);
                return createOrUpdate.future();
            } else if (cr.getSpec() == null) {
                InvalidResourceException exception = new InvalidResourceException("Spec cannot be null");
                S status = createStatus();
                Condition errorCondition = new ConditionBuilder().withLastTransitionTime(StatusUtils.iso8601Now()).withType("NotReady").withStatus("True").withReason(exception.getClass().getSimpleName()).withMessage(exception.getMessage()).build();
                status.setObservedGeneration(cr.getMetadata().getGeneration());
                status.addCondition(errorCondition);
                LOGGER.errorCr(reconciliation, "{} spec cannot be null", cr.getMetadata().getName());
                updateStatus(reconciliation, status).onComplete(notUsed -> {
                    createOrUpdate.fail(exception);
                });
                return createOrUpdate.future();
            }
            Set<Condition> unknownAndDeprecatedConditions = validate(reconciliation, cr);
            LOGGER.infoCr(reconciliation, "{} {} will be checked for creation or modification", kind, name);
            createOrUpdate(reconciliation, cr).onComplete(res -> {
                if (res.succeeded()) {
                    S status = res.result();
                    addWarningsToStatus(status, unknownAndDeprecatedConditions);
                    updateStatus(reconciliation, status).onComplete(statusResult -> {
                        if (statusResult.succeeded()) {
                            createOrUpdate.complete();
                        } else {
                            createOrUpdate.fail(statusResult.cause());
                        }
                    });
                } else {
                    if (res.cause() instanceof ReconciliationException) {
                        ReconciliationException e = (ReconciliationException) res.cause();
                        Status status = e.getStatus();
                        addWarningsToStatus(status, unknownAndDeprecatedConditions);
                        LOGGER.errorCr(reconciliation, "createOrUpdate failed", e.getCause());
                        updateStatus(reconciliation, (S) status).onComplete(statusResult -> {
                            createOrUpdate.fail(e.getCause());
                        });
                    } else {
                        LOGGER.errorCr(reconciliation, "createOrUpdate failed", res.cause());
                        createOrUpdate.fail(res.cause());
                    }
                }
            });
            return createOrUpdate.future();
        } else {
            LOGGER.infoCr(reconciliation, "{} {} should be deleted", kind, name);
            return delete(reconciliation).map(deleteResult -> {
                if (deleteResult) {
                    LOGGER.infoCr(reconciliation, "{} {} deleted", kind, name);
                } else {
                    LOGGER.infoCr(reconciliation, "Assembly {} or some parts of it will be deleted by garbage collection", name);
                }
                return (Void) null;
            }).recover(deleteResult -> {
                LOGGER.errorCr(reconciliation, "Deletion of {} {} failed", kind, name, deleteResult);
                return Future.failedFuture(deleteResult);
            });
        }
    });
    Promise<Void> result = Promise.promise();
    handler.onComplete(reconcileResult -> {
        try {
            handleResult(reconciliation, reconcileResult, reconciliationTimerSample);
        } finally {
            result.handle(reconcileResult);
        }
    });
    return result.future();
}
Also used : Condition(io.strimzi.api.kafka.model.status.Condition) ClusterRoleBinding(io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding) LabelSelector(io.fabric8.kubernetes.api.model.LabelSelector) Watch(io.fabric8.kubernetes.client.Watch) Callable(java.util.concurrent.Callable) ResourceVisitor(io.strimzi.operator.common.model.ResourceVisitor) ArrayList(java.util.ArrayList) WatcherException(io.fabric8.kubernetes.client.WatcherException) Timer(io.micrometer.core.instrument.Timer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) Status(io.strimzi.api.kafka.model.status.Status) ReconcileResult(io.strimzi.operator.common.operator.resource.ReconcileResult) AsyncResult(io.vertx.core.AsyncResult) LinkedHashSet(java.util.LinkedHashSet) Counter(io.micrometer.core.instrument.Counter) StatusUtils(io.strimzi.operator.common.operator.resource.StatusUtils) Tag(io.micrometer.core.instrument.Tag) Tags(io.micrometer.core.instrument.Tags) InvalidResourceException(io.strimzi.operator.cluster.model.InvalidResourceException) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ValidationVisitor(io.strimzi.operator.common.model.ValidationVisitor) Set(java.util.Set) Meter(io.micrometer.core.instrument.Meter) Spec(io.strimzi.api.kafka.model.Spec) Future(io.vertx.core.Future) Collectors(java.util.stream.Collectors) Util.async(io.strimzi.operator.common.Util.async) Consumer(java.util.function.Consumer) NamespaceAndName(io.strimzi.operator.common.model.NamespaceAndName) StatusDiff(io.strimzi.operator.cluster.model.StatusDiff) Labels(io.strimzi.operator.common.model.Labels) Lock(io.vertx.core.shareddata.Lock) ConditionBuilder(io.strimzi.api.kafka.model.status.ConditionBuilder) AbstractWatchableStatusedResourceOperator(io.strimzi.operator.common.operator.resource.AbstractWatchableStatusedResourceOperator) Optional(java.util.Optional) Condition(io.strimzi.api.kafka.model.status.Condition) Handler(io.vertx.core.Handler) Collections(java.util.Collections) CustomResource(io.fabric8.kubernetes.client.CustomResource) TimeoutException(io.strimzi.operator.common.operator.resource.TimeoutException) Status(io.strimzi.api.kafka.model.status.Status) InvalidResourceException(io.strimzi.operator.cluster.model.InvalidResourceException) ConditionBuilder(io.strimzi.api.kafka.model.status.ConditionBuilder) Timer(io.micrometer.core.instrument.Timer)

Example 2 with ConditionBuilder

use of io.fabric8.kubernetes.api.model.ConditionBuilder in project cos-fleetshard by bf2fc6cc711aee1a0c2a.

the class KameletBindingSteps method klb_phase_and_conditions.

@SuppressWarnings("unchecked")
@When("the klb phase is {string} with conditions:")
public void klb_phase_and_conditions(String phase, DataTable table) {
    // TODO: investigate using KubernetesClient.resources(KameletBinding.class) result in a bad patch
    kubernetesClient.genericKubernetesResources(KameletBinding.RESOURCE_DEFINITION).inNamespace(ctx.connector().getMetadata().getNamespace()).withName(ctx.connector().getMetadata().getName()).editStatus(binding -> {
        Map<String, Object> status = (Map<String, Object>) binding.getAdditionalProperties().get("status");
        if (status == null) {
            status = new HashMap<>();
        }
        List<Map<String, String>> rows = table.asMaps(String.class, String.class);
        List<Condition> conditions = new ArrayList<>(rows.size());
        for (Map<String, String> columns : rows) {
            conditions.add(new ConditionBuilder().withMessage(columns.get("message")).withReason(columns.get("reason")).withStatus(columns.get("status")).withType(columns.get("type")).withLastTransitionTime(columns.get("lastTransitionTime")).build());
        }
        status.put("phase", phase);
        status.put("conditions", conditions);
        binding.getAdditionalProperties().put("status", status);
        return binding;
    });
// kubernetesClient.resources(KameletBinding.class)
// .inNamespace(ctx.connector().getMetadata().getNamespace())
// .withName(ctx.connector().getMetadata().getName())
// .editStatus(binding -> {
// if (binding.getStatus() == null) {
// binding.setStatus(new KameletBindingStatus());
// }
// 
// List<Map<String, String>> rows = table.asMaps(String.class, String.class);
// List<Condition> conditions = new ArrayList<>(rows.size());
// 
// for (Map<String, String> columns : rows) {
// conditions.add(new ConditionBuilder()
// .withMessage(columns.get("message"))
// .withReason(columns.get("reason"))
// .withStatus(columns.get("status"))
// .withType(columns.get("type"))
// .withLastTransitionTime(columns.get("lastTransitionTime"))
// .build());
// }
// 
// binding.getStatus().setPhase(phase);
// binding.getStatus().setConditions(conditions);
// 
// return binding;
// });
}
Also used : Condition(io.fabric8.kubernetes.api.model.Condition) ConditionBuilder(io.fabric8.kubernetes.api.model.ConditionBuilder) ArrayList(java.util.ArrayList) HashMap(java.util.HashMap) Map(java.util.Map) When(io.cucumber.java.en.When)

Example 3 with ConditionBuilder

use of io.fabric8.kubernetes.api.model.ConditionBuilder in project strimzi-kafka-operator by strimzi.

the class AbstractOperator method reconcile.

/**
 * Reconcile assembly resources in the given namespace having the given {@code name}.
 * Reconciliation works by getting the assembly resource (e.g. {@code KafkaUser})
 * in the given namespace with the given name and
 * comparing with the corresponding resource.
 * @param reconciliation The reconciliation.
 * @return A Future which is completed with the result of the reconciliation.
 */
@Override
@SuppressWarnings("unchecked")
public final Future<Void> reconcile(Reconciliation reconciliation) {
    String namespace = reconciliation.namespace();
    String name = reconciliation.name();
    reconciliationsCounter(reconciliation.namespace()).increment();
    Timer.Sample reconciliationTimerSample = Timer.start(metrics.meterRegistry());
    Future<Void> handler = withLock(reconciliation, LOCK_TIMEOUT_MS, () -> {
        T cr = resourceOperator.get(namespace, name);
        if (cr != null) {
            if (!Util.matchesSelector(selector(), cr)) {
                // When the labels matching the selector are removed from the custom resource, a DELETE event is
                // triggered by the watch even through the custom resource might not match the watch labels anymore
                // and might not be really deleted. We have to filter these situations out and ignore the
                // reconciliation because such resource might be already operated by another instance (where the
                // same change triggered ADDED event).
                LOGGER.debugCr(reconciliation, "{} {} in namespace {} does not match label selector {} and will be ignored", kind(), name, namespace, selector().get().getMatchLabels());
                return Future.succeededFuture();
            }
            Promise<Void> createOrUpdate = Promise.promise();
            if (Annotations.isReconciliationPausedWithAnnotation(cr)) {
                S status = createStatus();
                Set<Condition> conditions = validate(reconciliation, cr);
                conditions.add(StatusUtils.getPausedCondition());
                status.setConditions(new ArrayList<>(conditions));
                status.setObservedGeneration(cr.getStatus() != null ? cr.getStatus().getObservedGeneration() : 0);
                updateStatus(reconciliation, status).onComplete(statusResult -> {
                    if (statusResult.succeeded()) {
                        createOrUpdate.complete();
                    } else {
                        createOrUpdate.fail(statusResult.cause());
                    }
                });
                pausedResourceCounter(namespace).getAndIncrement();
                LOGGER.debugCr(reconciliation, "Reconciliation of {} {} is paused", kind, name);
                return createOrUpdate.future();
            } else if (cr.getSpec() == null) {
                InvalidResourceException exception = new InvalidResourceException("Spec cannot be null");
                S status = createStatus();
                Condition errorCondition = new ConditionBuilder().withLastTransitionTime(StatusUtils.iso8601Now()).withType("NotReady").withStatus("True").withReason(exception.getClass().getSimpleName()).withMessage(exception.getMessage()).build();
                status.setObservedGeneration(cr.getMetadata().getGeneration());
                status.addCondition(errorCondition);
                LOGGER.errorCr(reconciliation, "{} spec cannot be null", cr.getMetadata().getName());
                updateStatus(reconciliation, status).onComplete(notUsed -> {
                    createOrUpdate.fail(exception);
                });
                return createOrUpdate.future();
            }
            Set<Condition> unknownAndDeprecatedConditions = validate(reconciliation, cr);
            LOGGER.infoCr(reconciliation, "{} {} will be checked for creation or modification", kind, name);
            createOrUpdate(reconciliation, cr).onComplete(res -> {
                if (res.succeeded()) {
                    S status = res.result();
                    addWarningsToStatus(status, unknownAndDeprecatedConditions);
                    updateStatus(reconciliation, status).onComplete(statusResult -> {
                        if (statusResult.succeeded()) {
                            createOrUpdate.complete();
                        } else {
                            createOrUpdate.fail(statusResult.cause());
                        }
                    });
                } else {
                    if (res.cause() instanceof ReconciliationException) {
                        ReconciliationException e = (ReconciliationException) res.cause();
                        Status status = e.getStatus();
                        addWarningsToStatus(status, unknownAndDeprecatedConditions);
                        LOGGER.errorCr(reconciliation, "createOrUpdate failed", e.getCause());
                        updateStatus(reconciliation, (S) status).onComplete(statusResult -> {
                            createOrUpdate.fail(e.getCause());
                        });
                    } else {
                        LOGGER.errorCr(reconciliation, "createOrUpdate failed", res.cause());
                        createOrUpdate.fail(res.cause());
                    }
                }
            });
            return createOrUpdate.future();
        } else {
            LOGGER.infoCr(reconciliation, "{} {} should be deleted", kind, name);
            return delete(reconciliation).map(deleteResult -> {
                if (deleteResult) {
                    LOGGER.infoCr(reconciliation, "{} {} deleted", kind, name);
                } else {
                    LOGGER.infoCr(reconciliation, "Assembly {} or some parts of it will be deleted by garbage collection", name);
                }
                return (Void) null;
            }).recover(deleteResult -> {
                LOGGER.errorCr(reconciliation, "Deletion of {} {} failed", kind, name, deleteResult);
                return Future.failedFuture(deleteResult);
            });
        }
    });
    Promise<Void> result = Promise.promise();
    handler.onComplete(reconcileResult -> {
        try {
            handleResult(reconciliation, reconcileResult, reconciliationTimerSample);
        } finally {
            result.handle(reconcileResult);
        }
    });
    return result.future();
}
Also used : Condition(io.strimzi.api.kafka.model.status.Condition) ClusterRoleBinding(io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding) LabelSelector(io.fabric8.kubernetes.api.model.LabelSelector) Watch(io.fabric8.kubernetes.client.Watch) Callable(java.util.concurrent.Callable) ResourceVisitor(io.strimzi.operator.common.model.ResourceVisitor) ArrayList(java.util.ArrayList) WatcherException(io.fabric8.kubernetes.client.WatcherException) Timer(io.micrometer.core.instrument.Timer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) Status(io.strimzi.api.kafka.model.status.Status) ReconcileResult(io.strimzi.operator.common.operator.resource.ReconcileResult) AsyncResult(io.vertx.core.AsyncResult) LinkedHashSet(java.util.LinkedHashSet) Counter(io.micrometer.core.instrument.Counter) StatusUtils(io.strimzi.operator.common.operator.resource.StatusUtils) Tag(io.micrometer.core.instrument.Tag) Tags(io.micrometer.core.instrument.Tags) InvalidResourceException(io.strimzi.operator.cluster.model.InvalidResourceException) Promise(io.vertx.core.Promise) Vertx(io.vertx.core.Vertx) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ValidationVisitor(io.strimzi.operator.common.model.ValidationVisitor) Set(java.util.Set) Meter(io.micrometer.core.instrument.Meter) Spec(io.strimzi.api.kafka.model.Spec) Future(io.vertx.core.Future) Collectors(java.util.stream.Collectors) Util.async(io.strimzi.operator.common.Util.async) Consumer(java.util.function.Consumer) NamespaceAndName(io.strimzi.operator.common.model.NamespaceAndName) StatusDiff(io.strimzi.operator.cluster.model.StatusDiff) Labels(io.strimzi.operator.common.model.Labels) Lock(io.vertx.core.shareddata.Lock) ConditionBuilder(io.strimzi.api.kafka.model.status.ConditionBuilder) AbstractWatchableStatusedResourceOperator(io.strimzi.operator.common.operator.resource.AbstractWatchableStatusedResourceOperator) Optional(java.util.Optional) Condition(io.strimzi.api.kafka.model.status.Condition) Handler(io.vertx.core.Handler) Collections(java.util.Collections) CustomResource(io.fabric8.kubernetes.client.CustomResource) TimeoutException(io.strimzi.operator.common.operator.resource.TimeoutException) Status(io.strimzi.api.kafka.model.status.Status) InvalidResourceException(io.strimzi.operator.cluster.model.InvalidResourceException) ConditionBuilder(io.strimzi.api.kafka.model.status.ConditionBuilder) Timer(io.micrometer.core.instrument.Timer)

Aggregations

ArrayList (java.util.ArrayList)3 Map (java.util.Map)3 LabelSelector (io.fabric8.kubernetes.api.model.LabelSelector)2 ClusterRoleBinding (io.fabric8.kubernetes.api.model.rbac.ClusterRoleBinding)2 CustomResource (io.fabric8.kubernetes.client.CustomResource)2 Watch (io.fabric8.kubernetes.client.Watch)2 WatcherException (io.fabric8.kubernetes.client.WatcherException)2 Counter (io.micrometer.core.instrument.Counter)2 Meter (io.micrometer.core.instrument.Meter)2 Tag (io.micrometer.core.instrument.Tag)2 Tags (io.micrometer.core.instrument.Tags)2 Timer (io.micrometer.core.instrument.Timer)2 Spec (io.strimzi.api.kafka.model.Spec)2 Condition (io.strimzi.api.kafka.model.status.Condition)2 ConditionBuilder (io.strimzi.api.kafka.model.status.ConditionBuilder)2 Status (io.strimzi.api.kafka.model.status.Status)2 InvalidResourceException (io.strimzi.operator.cluster.model.InvalidResourceException)2 StatusDiff (io.strimzi.operator.cluster.model.StatusDiff)2 Util.async (io.strimzi.operator.common.Util.async)2 Labels (io.strimzi.operator.common.model.Labels)2