Search in sources :

Example 1 with OperandReadiness

use of org.bf2.operator.operands.OperandReadiness in project kas-fleetshard by bf2fc6cc711aee1a0c2a.

the class AbstractKafkaCluster method getReadiness.

@Override
public OperandReadiness getReadiness(ManagedKafka managedKafka) {
    Kafka kafka = cachedKafka(managedKafka);
    if (kafka == null) {
        return new OperandReadiness(Status.False, Reason.Installing, String.format("Kafka %s does not exist", kafkaClusterName(managedKafka)));
    }
    Optional<Condition> notReady = kafkaCondition(kafka, c -> "NotReady".equals(c.getType()));
    if (notReady.filter(c -> "True".equals(c.getStatus())).isPresent()) {
        Condition c = notReady.get();
        return new OperandReadiness(Status.False, "Creating".equals(c.getReason()) ? Reason.Installing : Reason.Error, c.getMessage());
    }
    if (isStrimziUpdating(managedKafka)) {
        // the status here is actually unknown
        return new OperandReadiness(Status.True, Reason.StrimziUpdating, null);
    }
    if (isKafkaUpdating(managedKafka) || isKafkaUpgradeStabilityChecking(managedKafka)) {
        return new OperandReadiness(Status.True, Reason.KafkaUpdating, null);
    }
    if (isKafkaIbpUpdating(managedKafka)) {
        return new OperandReadiness(Status.True, Reason.KafkaIbpUpdating, null);
    }
    Optional<Condition> ready = kafkaCondition(kafka, c -> "Ready".equals(c.getType()));
    if (ready.filter(c -> "True".equals(c.getStatus())).isPresent()) {
        return new OperandReadiness(Status.True, null, null);
    }
    if (isReconciliationPaused(managedKafka)) {
        // strimzi may in the future report the status even when paused, but for now we don't know
        return new OperandReadiness(Status.Unknown, Reason.Paused, String.format("Kafka %s is paused for an unknown reason", kafkaClusterName(managedKafka)));
    }
    return new OperandReadiness(Status.False, Reason.Installing, String.format("Kafka %s is not providing status", kafkaClusterName(managedKafka)));
}
Also used : Condition(io.strimzi.api.kafka.model.status.Condition) Quantity(io.fabric8.kubernetes.api.model.Quantity) Context(io.javaoperatorsdk.operator.api.Context) KafkaStatus(io.strimzi.api.kafka.model.status.KafkaStatus) GenericKafkaListener(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListener) Arrays(java.util.Arrays) GenericSecretSource(io.strimzi.api.kafka.model.GenericSecretSource) Status(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition.Status) Logger(org.jboss.logging.Logger) KafkaListenerAuthentication(io.strimzi.api.kafka.model.listener.KafkaListenerAuthentication) StrimziManager(org.bf2.operator.managers.StrimziManager) GenericKafkaListenerConfigurationBrokerBuilder(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerConfigurationBrokerBuilder) GenericKafkaListenerConfigurationBootstrapBuilder(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerConfigurationBootstrapBuilder) Function(java.util.function.Function) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) CertAndKeySecretSourceBuilder(io.strimzi.api.kafka.model.CertAndKeySecretSourceBuilder) GenericKafkaListenerConfigurationBroker(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerConfigurationBroker) SecuritySecretManager(org.bf2.operator.managers.SecuritySecretManager) Map(java.util.Map) KafkaManager(org.bf2.operator.managers.KafkaManager) KafkaResourceClient(org.bf2.operator.clients.KafkaResourceClient) CertAndKeySecretSource(io.strimzi.api.kafka.model.CertAndKeySecretSource) CertSecretSource(io.strimzi.api.kafka.model.CertSecretSource) Predicate(java.util.function.Predicate) Pod(io.fabric8.kubernetes.api.model.Pod) InformerManager(org.bf2.operator.managers.InformerManager) GenericKafkaListenerBuilder(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerBuilder) Reason(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition.Reason) OpenShiftClient(io.fabric8.openshift.client.OpenShiftClient) ManagedKafkaAuthenticationOAuth(org.bf2.operator.resources.v1alpha1.ManagedKafkaAuthenticationOAuth) Objects(java.util.Objects) List(java.util.List) CertSecretSourceBuilder(io.strimzi.api.kafka.model.CertSecretSourceBuilder) GenericSecretSourceBuilder(io.strimzi.api.kafka.model.GenericSecretSourceBuilder) KafkaListenerType(io.strimzi.api.kafka.model.listener.arraylistener.KafkaListenerType) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) KafkaListenerAuthenticationOAuthBuilder(io.strimzi.api.kafka.model.listener.KafkaListenerAuthenticationOAuthBuilder) Optional(java.util.Optional) NetworkPolicyPeerBuilder(io.fabric8.kubernetes.api.model.networking.v1.NetworkPolicyPeerBuilder) Condition(io.strimzi.api.kafka.model.status.Condition) ConfigProperty(org.eclipse.microprofile.config.inject.ConfigProperty) Kafka(io.strimzi.api.kafka.model.Kafka) ManagedKafka(org.bf2.operator.resources.v1alpha1.ManagedKafka) Collections(java.util.Collections) GenericKafkaListenerConfigurationBuilder(io.strimzi.api.kafka.model.listener.arraylistener.GenericKafkaListenerConfigurationBuilder) Kafka(io.strimzi.api.kafka.model.Kafka) ManagedKafka(org.bf2.operator.resources.v1alpha1.ManagedKafka)

Example 2 with OperandReadiness

use of org.bf2.operator.operands.OperandReadiness in project kas-fleetshard by bf2fc6cc711aee1a0c2a.

the class KafkaInstance method getReadiness.

@Override
public OperandReadiness getReadiness(ManagedKafka managedKafka) {
    if (managedKafka.getSpec().isDeleted()) {
        // TODO: it may be a good idea to offer a message here as well
        return new OperandReadiness(isDeleted(managedKafka) ? Status.False : Status.Unknown, Reason.Deleted, null);
    }
    List<OperandReadiness> readiness = operands.stream().map(o -> o.getReadiness(managedKafka)).filter(Objects::nonNull).collect(Collectors.toList());
    // default to the first reason, with can come from the kafka by the order of the operands
    Reason reason = readiness.stream().map(OperandReadiness::getReason).filter(Objects::nonNull).findFirst().orElse(null);
    // default the status to false or unknown if any are unknown
    Status status = readiness.stream().anyMatch(r -> Status.Unknown.equals(r.getStatus())) ? Status.Unknown : Status.False;
    // combine all the messages
    String message = readiness.stream().map(OperandReadiness::getMessage).filter(Objects::nonNull).collect(Collectors.joining("; "));
    // override in particular scenarios
    if (readiness.stream().allMatch(r -> Status.True.equals(r.getStatus()))) {
        status = Status.True;
    } else if (readiness.stream().anyMatch(r -> Reason.Installing.equals(r.getReason()))) {
        // may mask other error states
        reason = Reason.Installing;
    } else if (readiness.stream().anyMatch(r -> Reason.Error.equals(r.getReason()))) {
        reason = Reason.Error;
    }
    return new OperandReadiness(status, reason, message);
}
Also used : Status(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition.Status) Context(io.javaoperatorsdk.operator.api.Context) Arrays(java.util.Arrays) ImagePullSecretManager(org.bf2.operator.managers.ImagePullSecretManager) Status(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition.Status) Reason(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition.Reason) Deque(java.util.Deque) Collectors(java.util.stream.Collectors) Inject(javax.inject.Inject) Objects(java.util.Objects) List(java.util.List) PostConstruct(javax.annotation.PostConstruct) ApplicationScoped(javax.enterprise.context.ApplicationScoped) ArrayDeque(java.util.ArrayDeque) ManagedKafka(org.bf2.operator.resources.v1alpha1.ManagedKafka) Objects(java.util.Objects) Reason(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition.Reason)

Example 3 with OperandReadiness

use of org.bf2.operator.operands.OperandReadiness in project kas-fleetshard by bf2fc6cc711aee1a0c2a.

the class KafkaInstanceTest method statusInstallingTrumpsError.

@Test
void statusInstallingTrumpsError() {
    ManagedKafka managedKafka = DUMMY_MANAGED_KAFKA;
    when(kafkaCluster.getReadiness(managedKafka)).thenReturn(new OperandReadiness(Status.True, Reason.StrimziUpdating, null));
    when(canary.getReadiness(managedKafka)).thenReturn(new OperandReadiness(Status.False, Reason.Error, "I'm not well"));
    when(adminServer.getReadiness(managedKafka)).thenReturn(new OperandReadiness(Status.False, Reason.Installing, "I'm installing"));
    OperandReadiness readiness = kafkaInstance.getReadiness(managedKafka);
    assertEquals(Status.False, readiness.getStatus());
    assertEquals(Reason.Installing, readiness.getReason());
    assertEquals("I'm not well; I'm installing", readiness.getMessage());
}
Also used : ManagedKafka(org.bf2.operator.resources.v1alpha1.ManagedKafka) QuarkusTest(io.quarkus.test.junit.QuarkusTest) Test(org.junit.jupiter.api.Test)

Example 4 with OperandReadiness

use of org.bf2.operator.operands.OperandReadiness in project kas-fleetshard by bf2fc6cc711aee1a0c2a.

the class ManagedKafkaController method validity.

/**
 * Run a validity check on the ManagedKafka custom resource
 *
 * @param managedKafka ManagedKafka custom resource to validate
 * @return readiness indicating an error in the ManagedKafka custom resource, empty Optional otherwise
 */
private Optional<OperandReadiness> validity(ManagedKafka managedKafka) {
    String message = null;
    StrimziVersionStatus strimziVersion = this.strimziManager.getStrimziVersion(managedKafka.getSpec().getVersions().getStrimzi());
    if (strimziVersion == null) {
        message = String.format("The requested Strimzi version %s is not supported", managedKafka.getSpec().getVersions().getStrimzi());
    } else {
        if (!strimziVersion.getKafkaVersions().contains(managedKafka.getSpec().getVersions().getKafka())) {
            message = String.format("The requested Kafka version %s is not supported by the Strimzi version %s", managedKafka.getSpec().getVersions().getKafka(), strimziVersion.getVersion());
        } else if (managedKafka.getSpec().getVersions().getKafkaIbp() != null && !strimziVersion.getKafkaIbpVersions().contains(managedKafka.getSpec().getVersions().getKafkaIbp())) {
            message = String.format("The requested Kafka inter broker protocol version %s is not supported by the Strimzi version %s", managedKafka.getSpec().getVersions().getKafkaIbp(), strimziVersion.getVersion());
        }
    }
    if (message != null) {
        log.error(message);
        return Optional.of(new OperandReadiness(Status.False, Reason.Error, message));
    }
    return Optional.empty();
}
Also used : StrimziVersionStatus(org.bf2.operator.resources.v1alpha1.StrimziVersionStatus) OperandReadiness(org.bf2.operator.operands.OperandReadiness)

Example 5 with OperandReadiness

use of org.bf2.operator.operands.OperandReadiness in project kas-fleetshard by bf2fc6cc711aee1a0c2a.

the class ManagedKafkaController method updateManagedKafkaStatus.

/**
 * Extract from the current KafkaInstance overall status (Kafka, Canary and AdminServer)
 * a corresponding list of ManagedKafkaCondition(s) to set on the ManagedKafka status
 *
 * @param managedKafka ManagedKafka instance
 */
private void updateManagedKafkaStatus(ManagedKafka managedKafka) {
    // add status if not already available on the ManagedKafka resource
    ManagedKafkaStatus status = Objects.requireNonNullElse(managedKafka.getStatus(), new ManagedKafkaStatusBuilder().build());
    status.setUpdatedTimestamp(ConditionUtils.iso8601Now());
    managedKafka.setStatus(status);
    // add conditions if not already available
    List<ManagedKafkaCondition> managedKafkaConditions = managedKafka.getStatus().getConditions();
    if (managedKafkaConditions == null) {
        managedKafkaConditions = new ArrayList<>();
        status.setConditions(managedKafkaConditions);
    }
    Optional<ManagedKafkaCondition> optReady = ConditionUtils.findManagedKafkaCondition(managedKafkaConditions, ManagedKafkaCondition.Type.Ready);
    ManagedKafkaCondition ready = null;
    if (optReady.isPresent()) {
        ready = optReady.get();
    } else {
        ready = ConditionUtils.buildCondition(ManagedKafkaCondition.Type.Ready, Status.Unknown);
        managedKafkaConditions.add(ready);
    }
    // a not valid ManagedKafka skips the handling of it, so the status will report an error condition
    OperandReadiness readiness = this.validity(managedKafka).orElse(kafkaInstance.getReadiness(managedKafka));
    ConditionUtils.updateConditionStatus(ready, readiness.getStatus(), readiness.getReason(), readiness.getMessage());
    // routes should always be set on the CR status, even if it's just an empty list
    status.setRoutes(List.of());
    int replicas = kafkaCluster.getReplicas(managedKafka);
    if (ingressControllerManagerInstance.isResolvable()) {
        IngressControllerManager ingressControllerManager = ingressControllerManagerInstance.get();
        List<ManagedKafkaRoute> routes = ingressControllerManager.getManagedKafkaRoutesFor(managedKafka);
        // expect route for each broker + 1 for bootstrap URL + 1 for Admin API server
        int expectedNumRoutes = replicas + NUM_NON_BROKER_ROUTES;
        if (routes.size() >= expectedNumRoutes && routes.stream().noneMatch(r -> "".equals(r.getRouter()))) {
            status.setRoutes(routes);
        }
    }
    if (Status.True.equals(readiness.getStatus())) {
        status.setCapacity(new ManagedKafkaCapacityBuilder(managedKafka.getSpec().getCapacity()).withMaxDataRetentionSize(kafkaInstance.getKafkaCluster().calculateRetentionSize(managedKafka)).build());
        // the versions in the status are updated incrementally copying the spec only when each stage ends
        VersionsBuilder versionsBuilder = status.getVersions() != null ? new VersionsBuilder(status.getVersions()) : new VersionsBuilder(managedKafka.getSpec().getVersions());
        if (!Reason.StrimziUpdating.equals(readiness.getReason()) && !this.strimziManager.hasStrimziChanged(managedKafka)) {
            versionsBuilder.withStrimzi(managedKafka.getSpec().getVersions().getStrimzi());
        }
        if (!Reason.KafkaUpdating.equals(readiness.getReason()) && !this.kafkaManager.hasKafkaVersionChanged(managedKafka)) {
            versionsBuilder.withKafka(managedKafka.getSpec().getVersions().getKafka());
        }
        if (!Reason.KafkaIbpUpdating.equals(readiness.getReason()) && !this.kafkaManager.hasKafkaIbpVersionChanged(managedKafka)) {
            String kafkaIbp = managedKafka.getSpec().getVersions().getKafkaIbp() != null ? managedKafka.getSpec().getVersions().getKafkaIbp() : AbstractKafkaCluster.getKafkaIbpVersion(managedKafka.getSpec().getVersions().getKafka());
            versionsBuilder.withKafkaIbp(kafkaIbp);
        }
        status.setVersions(versionsBuilder.build());
        status.setAdminServerURI(kafkaInstance.getAdminServer().uri(managedKafka));
        status.setServiceAccounts(managedKafka.getSpec().getServiceAccounts());
    }
}
Also used : DeleteControl(io.javaoperatorsdk.operator.api.DeleteControl) ManagedKafkaResourceClient(org.bf2.common.ManagedKafkaResourceClient) Context(io.javaoperatorsdk.operator.api.Context) Status(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition.Status) Timed(io.micrometer.core.annotation.Timed) StrimziVersionStatus(org.bf2.operator.resources.v1alpha1.StrimziVersionStatus) Logger(org.jboss.logging.Logger) StrimziManager(org.bf2.operator.managers.StrimziManager) ManagedKafkaRoute(org.bf2.operator.resources.v1alpha1.ManagedKafkaRoute) ResourceEventSource(org.bf2.operator.events.ResourceEventSource) ArrayList(java.util.ArrayList) Controller(io.javaoperatorsdk.operator.api.Controller) VersionsBuilder(org.bf2.operator.resources.v1alpha1.VersionsBuilder) Inject(javax.inject.Inject) KafkaInstance(org.bf2.operator.operands.KafkaInstance) ManagedKafkaStatus(org.bf2.operator.resources.v1alpha1.ManagedKafkaStatus) UpdateControl(io.javaoperatorsdk.operator.api.UpdateControl) AbstractKafkaCluster(org.bf2.operator.operands.AbstractKafkaCluster) KafkaManager(org.bf2.operator.managers.KafkaManager) Instance(javax.enterprise.inject.Instance) NDC(org.jboss.logging.NDC) KafkaInstanceConfiguration(org.bf2.operator.operands.KafkaInstanceConfiguration) ManagedKafkaStatusBuilder(org.bf2.operator.resources.v1alpha1.ManagedKafkaStatusBuilder) IngressControllerManager(org.bf2.operator.managers.IngressControllerManager) ConditionUtils(org.bf2.common.ConditionUtils) Reason(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition.Reason) Objects(java.util.Objects) List(java.util.List) Counted(io.micrometer.core.annotation.Counted) ManagedKafkaCondition(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition) OperandReadiness(org.bf2.operator.operands.OperandReadiness) ManagedKafkaCapacityBuilder(org.bf2.operator.resources.v1alpha1.ManagedKafkaCapacityBuilder) Optional(java.util.Optional) ResourceController(io.javaoperatorsdk.operator.api.ResourceController) EventSourceManager(io.javaoperatorsdk.operator.processing.event.EventSourceManager) ManagedKafka(org.bf2.operator.resources.v1alpha1.ManagedKafka) ManagedKafkaCapacityBuilder(org.bf2.operator.resources.v1alpha1.ManagedKafkaCapacityBuilder) ManagedKafkaCondition(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition) VersionsBuilder(org.bf2.operator.resources.v1alpha1.VersionsBuilder) IngressControllerManager(org.bf2.operator.managers.IngressControllerManager) ManagedKafkaStatusBuilder(org.bf2.operator.resources.v1alpha1.ManagedKafkaStatusBuilder) ManagedKafkaRoute(org.bf2.operator.resources.v1alpha1.ManagedKafkaRoute) ManagedKafkaStatus(org.bf2.operator.resources.v1alpha1.ManagedKafkaStatus) OperandReadiness(org.bf2.operator.operands.OperandReadiness)

Aggregations

ManagedKafka (org.bf2.operator.resources.v1alpha1.ManagedKafka)5 Context (io.javaoperatorsdk.operator.api.Context)3 List (java.util.List)3 Objects (java.util.Objects)3 Inject (javax.inject.Inject)3 Reason (org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition.Reason)3 Status (org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition.Status)3 QuarkusTest (io.quarkus.test.junit.QuarkusTest)2 Kafka (io.strimzi.api.kafka.model.Kafka)2 ArrayList (java.util.ArrayList)2 Arrays (java.util.Arrays)2 Optional (java.util.Optional)2 OperandReadiness (org.bf2.operator.operands.OperandReadiness)2 StrimziVersionStatus (org.bf2.operator.resources.v1alpha1.StrimziVersionStatus)2 Pod (io.fabric8.kubernetes.api.model.Pod)1 Quantity (io.fabric8.kubernetes.api.model.Quantity)1 NetworkPolicyPeerBuilder (io.fabric8.kubernetes.api.model.networking.v1.NetworkPolicyPeerBuilder)1 KubernetesClient (io.fabric8.kubernetes.client.KubernetesClient)1 OpenShiftClient (io.fabric8.openshift.client.OpenShiftClient)1 Controller (io.javaoperatorsdk.operator.api.Controller)1