use of io.fabric8.kubernetes.api.model.Condition in project strimzi-kafka-operator by strimzi.
the class KafkaMirrorMaker2AssemblyOperator method createOrUpdate.
@Override
protected Future<KafkaMirrorMaker2Status> createOrUpdate(Reconciliation reconciliation, KafkaMirrorMaker2 kafkaMirrorMaker2) {
KafkaMirrorMaker2Cluster mirrorMaker2Cluster;
KafkaMirrorMaker2Status kafkaMirrorMaker2Status = new KafkaMirrorMaker2Status();
try {
mirrorMaker2Cluster = KafkaMirrorMaker2Cluster.fromCrd(reconciliation, kafkaMirrorMaker2, versions);
} catch (Exception e) {
LOGGER.warnCr(reconciliation, e);
StatusUtils.setStatusConditionAndObservedGeneration(kafkaMirrorMaker2, kafkaMirrorMaker2Status, Future.failedFuture(e));
return Future.failedFuture(new ReconciliationException(kafkaMirrorMaker2Status, e));
}
Promise<KafkaMirrorMaker2Status> createOrUpdatePromise = Promise.promise();
String namespace = reconciliation.namespace();
Map<String, String> annotations = new HashMap<>(1);
final AtomicReference<String> desiredLogging = new AtomicReference<>();
boolean mirrorMaker2HasZeroReplicas = mirrorMaker2Cluster.getReplicas() == 0;
LOGGER.debugCr(reconciliation, "Updating Kafka MirrorMaker 2.0 cluster");
connectServiceAccount(reconciliation, namespace, KafkaMirrorMaker2Resources.serviceAccountName(mirrorMaker2Cluster.getCluster()), mirrorMaker2Cluster).compose(i -> connectNetworkPolicy(reconciliation, namespace, mirrorMaker2Cluster, true)).compose(i -> deploymentOperations.scaleDown(reconciliation, namespace, mirrorMaker2Cluster.getName(), mirrorMaker2Cluster.getReplicas())).compose(i -> serviceOperations.reconcile(reconciliation, namespace, mirrorMaker2Cluster.getServiceName(), mirrorMaker2Cluster.generateService())).compose(i -> generateMetricsAndLoggingConfigMap(reconciliation, namespace, mirrorMaker2Cluster)).compose(logAndMetricsConfigMap -> {
String logging = logAndMetricsConfigMap.getData().get(AbstractModel.ANCILLARY_CM_KEY_LOG_CONFIG);
annotations.put(Annotations.ANNO_STRIMZI_LOGGING_DYNAMICALLY_UNCHANGEABLE_HASH, Util.stringHash(Util.getLoggingDynamicallyUnmodifiableEntries(logging)));
desiredLogging.set(logging);
return configMapOperations.reconcile(reconciliation, namespace, mirrorMaker2Cluster.getAncillaryConfigMapName(), logAndMetricsConfigMap);
}).compose(i -> kafkaConnectJmxSecret(reconciliation, namespace, mirrorMaker2Cluster.getName(), mirrorMaker2Cluster)).compose(i -> pfa.hasPodDisruptionBudgetV1() ? podDisruptionBudgetOperator.reconcile(reconciliation, namespace, mirrorMaker2Cluster.getName(), mirrorMaker2Cluster.generatePodDisruptionBudget()) : Future.succeededFuture()).compose(i -> !pfa.hasPodDisruptionBudgetV1() ? podDisruptionBudgetV1Beta1Operator.reconcile(reconciliation, namespace, mirrorMaker2Cluster.getName(), mirrorMaker2Cluster.generatePodDisruptionBudgetV1Beta1()) : Future.succeededFuture()).compose(i -> generateAuthHash(namespace, kafkaMirrorMaker2.getSpec())).compose(hash -> {
if (hash != null) {
annotations.put(Annotations.ANNO_STRIMZI_AUTH_HASH, Integer.toString(hash));
}
Deployment deployment = mirrorMaker2Cluster.generateDeployment(annotations, pfa.isOpenshift(), imagePullPolicy, imagePullSecrets);
return deploymentOperations.reconcile(reconciliation, namespace, mirrorMaker2Cluster.getName(), deployment);
}).compose(i -> deploymentOperations.scaleUp(reconciliation, namespace, mirrorMaker2Cluster.getName(), mirrorMaker2Cluster.getReplicas())).compose(i -> deploymentOperations.waitForObserved(reconciliation, namespace, mirrorMaker2Cluster.getName(), 1_000, operationTimeoutMs)).compose(i -> mirrorMaker2HasZeroReplicas ? Future.succeededFuture() : deploymentOperations.readiness(reconciliation, namespace, mirrorMaker2Cluster.getName(), 1_000, operationTimeoutMs)).compose(i -> mirrorMaker2HasZeroReplicas ? Future.succeededFuture() : reconcileConnectors(reconciliation, kafkaMirrorMaker2, mirrorMaker2Cluster, kafkaMirrorMaker2Status, desiredLogging.get())).map((Void) null).onComplete(reconciliationResult -> {
List<Condition> conditions = kafkaMirrorMaker2Status.getConditions();
StatusUtils.setStatusConditionAndObservedGeneration(kafkaMirrorMaker2, kafkaMirrorMaker2Status, reconciliationResult);
if (!mirrorMaker2HasZeroReplicas) {
kafkaMirrorMaker2Status.setUrl(KafkaMirrorMaker2Resources.url(mirrorMaker2Cluster.getCluster(), namespace, KafkaMirrorMaker2Cluster.REST_API_PORT));
}
if (conditions != null && !conditions.isEmpty()) {
kafkaMirrorMaker2Status.addConditions(conditions);
}
kafkaMirrorMaker2Status.setReplicas(mirrorMaker2Cluster.getReplicas());
kafkaMirrorMaker2Status.setLabelSelector(mirrorMaker2Cluster.getSelectorLabels().toSelectorString());
if (reconciliationResult.succeeded()) {
createOrUpdatePromise.complete(kafkaMirrorMaker2Status);
} else {
createOrUpdatePromise.fail(new ReconciliationException(kafkaMirrorMaker2Status, reconciliationResult.cause()));
}
});
return createOrUpdatePromise.future();
}
use of io.fabric8.kubernetes.api.model.Condition in project strimzi-kafka-operator by strimzi.
the class KafkaRebalanceAssemblyOperator method buildRebalanceStatus.
private MapAndStatus<ConfigMap, KafkaRebalanceStatus> buildRebalanceStatus(KafkaRebalance kafkaRebalance, String sessionID, KafkaRebalanceState cruiseControlState, JsonObject proposalJson, Set<Condition> validation) {
List<Condition> conditions = new ArrayList<>();
conditions.add(StatusUtils.buildRebalanceCondition(cruiseControlState.toString()));
conditions.addAll(validation);
MapAndStatus<ConfigMap, Map<String, Object>> optimizationProposalMapAndStatus = processOptimizationProposal(kafkaRebalance, proposalJson);
return new MapAndStatus<>(optimizationProposalMapAndStatus.getLoadMap(), new KafkaRebalanceStatusBuilder().withSessionId(sessionID).withConditions(conditions).withOptimizationResult(optimizationProposalMapAndStatus.getStatus()).build());
}
use of io.fabric8.kubernetes.api.model.Condition in project strimzi-kafka-operator by strimzi.
the class KafkaRebalanceAssemblyOperatorTest method testNewWithMissingHardGoalsAndRefresh.
/**
* Tests the transition from 'New' to 'NotReady' due to "missing hard goals" error
* The KafkaRebalance resource is updated with "skip hard goals check" and refreshed; it then moves to the 'ProposalReady' state
*
* 1. A new KafkaRebalance resource is created with some specified not hard goals; it is in the New state
* 2. The operator requests a rebalance proposal through the Cruise Control REST API
* 3. The operator receives a "missing hard goals" error instead of a proposal
* 4. The KafkaRebalance resource moves to the 'NotReady' state
* 5. The rebalance is updated with the 'skip hard goals check' field to "true" and annotated with 'strimzi.io/rebalance=refresh'
* 6. The operator requests a rebalance proposal through the Cruise Control REST API
* 7. The rebalance proposal is ready on the first call
* 8. The KafkaRebalance resource moves to the 'ProposalReady' state
*/
@Test
public void testNewWithMissingHardGoalsAndRefresh(VertxTestContext context) throws IOException, URISyntaxException {
// Setup the rebalance endpoint to get error about hard goals
MockCruiseControl.setupCCRebalanceBadGoalsError(ccServer);
KafkaRebalanceSpec kafkaRebalanceSpec = new KafkaRebalanceSpecBuilder().withGoals("DiskCapacityGoal", "CpuCapacityGoal").build();
KafkaRebalance kr = createKafkaRebalance(CLUSTER_NAMESPACE, CLUSTER_NAME, RESOURCE_NAME, kafkaRebalanceSpec);
Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).create(kr);
// the Kafka cluster isn't deployed in the namespace
when(mockKafkaOps.getAsync(CLUSTER_NAMESPACE, CLUSTER_NAME)).thenReturn(Future.succeededFuture(kafka));
mockSecretResources();
mockRebalanceOperator(mockRebalanceOps, mockCmOps, CLUSTER_NAMESPACE, RESOURCE_NAME, kubernetesClient);
Checkpoint checkpoint = context.checkpoint();
kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), kr).onComplete(context.succeeding(v -> context.verify(() -> {
// the resource moved from New to NotReady due to the error
KafkaRebalance kr1 = Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).withName(RESOURCE_NAME).get();
assertThat(kr1, StateMatchers.hasState());
Condition condition = kcrao.rebalanceStateCondition(kr1.getStatus());
assertThat(condition, StateMatchers.hasStateInCondition(KafkaRebalanceState.NotReady, CruiseControlRestException.class, "Error processing POST request '/rebalance' due to: " + "'java.lang.IllegalArgumentException: Missing hard goals [NetworkInboundCapacityGoal, DiskCapacityGoal, RackAwareGoal, NetworkOutboundCapacityGoal, CpuCapacityGoal, ReplicaCapacityGoal] " + "in the provided goals: [RackAwareGoal, ReplicaCapacityGoal]. " + "Add skip_hard_goal_check=true parameter to ignore this sanity check.'."));
}))).compose(v -> {
ccServer.reset();
try {
// Setup the rebalance endpoint with the number of pending calls before a response is received.
MockCruiseControl.setupCCRebalanceResponse(ccServer, 0);
} catch (IOException | URISyntaxException e) {
context.failNow(e);
}
// set the skip hard goals check flag
KafkaRebalance kr2 = Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).withName(RESOURCE_NAME).get();
KafkaRebalance patchedKr = new KafkaRebalanceBuilder(kr2).editSpec().withSkipHardGoalCheck(true).endSpec().build();
Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).withName(RESOURCE_NAME).patch(patchedKr);
// apply the "refresh" annotation to the resource in the NotReady state
patchedKr = annotate(kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceAnnotation.refresh);
// trigger another reconcile to process the NotReady state
return kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), patchedKr);
}).onComplete(context.succeeding(v -> {
// the resource transitioned from 'NotReady' to 'ProposalReady'
assertState(context, kubernetesClient, CLUSTER_NAMESPACE, RESOURCE_NAME, KafkaRebalanceState.ProposalReady);
checkpoint.flag();
}));
}
use of io.fabric8.kubernetes.api.model.Condition in project strimzi-kafka-operator by strimzi.
the class KafkaRebalanceAssemblyOperatorTest method testUnknownPropertyInSpec.
@Test
public void testUnknownPropertyInSpec(VertxTestContext context) throws IOException, URISyntaxException {
MockCruiseControl.setupCCRebalanceResponse(ccServer, 2);
String yaml = "apiVersion: kafka.strimzi.io/v1alpha1\n" + "kind: KafkaRebalance\n" + "metadata:\n" + " name: " + RESOURCE_NAME + "\n" + " namespace: " + CLUSTER_NAMESPACE + "\n" + " labels:\n" + " strimzi.io/cluster: " + CLUSTER_NAME + "\n" + "spec:\n" + " unknown: \"property\"\n" + " goals:\n" + " - CpuCapacityGoal\n" + " - NetworkInboundCapacityGoal\n" + " - DiskCapacityGoal\n" + " - RackAwareGoal\n" + " - NetworkOutboundCapacityGoal\n" + " - ReplicaCapacityGoal\n";
KafkaRebalance kr = TestUtils.fromYamlString(yaml, KafkaRebalance.class);
Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).create(kr);
// the Kafka cluster isn't deployed in the namespace
when(mockKafkaOps.getAsync(CLUSTER_NAMESPACE, CLUSTER_NAME)).thenReturn(Future.succeededFuture(kafka));
mockSecretResources();
mockRebalanceOperator(mockRebalanceOps, mockCmOps, CLUSTER_NAMESPACE, RESOURCE_NAME, kubernetesClient);
Checkpoint checkpoint = context.checkpoint();
kcrao.reconcileRebalance(new Reconciliation("test-trigger", KafkaRebalance.RESOURCE_KIND, CLUSTER_NAMESPACE, RESOURCE_NAME), kr).onComplete(context.succeeding(v -> context.verify(() -> {
KafkaRebalance kr1 = Crds.kafkaRebalanceOperation(kubernetesClient).inNamespace(CLUSTER_NAMESPACE).withName(RESOURCE_NAME).get();
assertThat(kr1, StateMatchers.hasState());
Optional<Condition> condition = kr1.getStatus().getConditions().stream().filter(cond -> "UnknownFields".equals(cond.getReason())).findFirst();
assertTrue(condition.isPresent());
assertThat(condition.get().getStatus(), is("True"));
assertThat(condition.get().getMessage(), is("Contains object at path spec with an unknown property: unknown"));
assertThat(condition.get().getType(), is("Warning"));
checkpoint.flag();
})));
}
use of io.fabric8.kubernetes.api.model.Condition in project strimzi-kafka-operator by strimzi.
the class KafkaMirrorMaker2AssemblyOperatorMockTest method testPauseReconcile.
@Test
public void testPauseReconcile(VertxTestContext context) {
setMirrorMaker2Resource(new KafkaMirrorMaker2Builder().withMetadata(new ObjectMetaBuilder().withName(CLUSTER_NAME).withNamespace(NAMESPACE).withLabels(TestUtils.map("foo", "bar")).withAnnotations(singletonMap("strimzi.io/pause-reconciliation", "true")).build()).withNewSpec().withReplicas(replicas).endSpec().build());
KafkaConnectApi mock = mock(KafkaConnectApi.class);
when(mock.list(anyString(), anyInt())).thenReturn(Future.succeededFuture(emptyList()));
when(mock.updateConnectLoggers(any(), anyString(), anyInt(), anyString(), any(OrderedProperties.class))).thenReturn(Future.succeededFuture());
Checkpoint async = context.checkpoint();
createMirrorMaker2Cluster(context, mock, true).onComplete(context.succeeding(v -> {
LOGGER.info("Reconciling again -> update");
kco.reconcile(new Reconciliation("test-trigger", KafkaMirrorMaker2.RESOURCE_KIND, NAMESPACE, CLUSTER_NAME));
})).onComplete(context.succeeding(v -> context.verify(() -> {
Resource<KafkaMirrorMaker2> resource = Crds.kafkaMirrorMaker2Operation(mockClient).inNamespace(NAMESPACE).withName(CLUSTER_NAME);
if (resource.get().getStatus() == null) {
fail();
}
List<Condition> conditions = resource.get().getStatus().getConditions();
boolean conditionFound = false;
if (conditions != null && !conditions.isEmpty()) {
for (Condition condition : conditions) {
if ("ReconciliationPaused".equals(condition.getType())) {
conditionFound = true;
break;
}
}
}
assertTrue(conditionFound);
async.flag();
})));
}
Aggregations