use of io.strimzi.operator.common.model.Labels in project strimzi-kafka-operator by strimzi.
the class KafkaAssemblyOperatorTest method testReconcileAllNamespaces.
@SuppressWarnings("unchecked")
@ParameterizedTest
@MethodSource("data")
@Timeout(value = 2, timeUnit = TimeUnit.MINUTES)
public void testReconcileAllNamespaces(Params params, VertxTestContext context) {
setFields(params);
// create CM, Service, headless service, statefulset
ResourceOperatorSupplier supplier = ResourceUtils.supplierWithMocks(openShift);
ClusterOperatorConfig config = ResourceUtils.dummyClusterOperatorConfig(VERSIONS);
var mockKafkaOps = supplier.kafkaOperator;
StatefulSetOperator mockStsOps = supplier.stsOperations;
SecretOperator mockSecretOps = supplier.secretOperations;
Kafka foo = getKafkaAssembly("foo");
foo.getMetadata().setNamespace("namespace1");
Kafka bar = getKafkaAssembly("bar");
bar.getMetadata().setNamespace("namespace2");
when(mockKafkaOps.listAsync(eq("*"), any(Optional.class))).thenReturn(Future.succeededFuture(asList(foo, bar)));
// when requested Custom Resource for a specific Kafka cluster
when(mockKafkaOps.get(eq("namespace1"), eq("foo"))).thenReturn(foo);
when(mockKafkaOps.get(eq("namespace2"), eq("bar"))).thenReturn(bar);
when(mockKafkaOps.getAsync(eq("namespace1"), eq("foo"))).thenReturn(Future.succeededFuture(foo));
when(mockKafkaOps.getAsync(eq("namespace2"), eq("bar"))).thenReturn(Future.succeededFuture(bar));
when(mockKafkaOps.updateStatusAsync(any(), any(Kafka.class))).thenReturn(Future.succeededFuture());
// providing certificates Secrets for existing clusters
List<Secret> barSecrets = ResourceUtils.createKafkaSecretsWithReplicas("namespace2", "bar", bar.getSpec().getKafka().getReplicas(), bar.getSpec().getZookeeper().getReplicas());
ClusterCa barClusterCa = ResourceUtils.createInitialClusterCa(Reconciliation.DUMMY_RECONCILIATION, "bar", findSecretWithName(barSecrets, AbstractModel.clusterCaCertSecretName("bar")), findSecretWithName(barSecrets, AbstractModel.clusterCaKeySecretName("bar")));
ClientsCa barClientsCa = ResourceUtils.createInitialClientsCa(Reconciliation.DUMMY_RECONCILIATION, "bar", findSecretWithName(barSecrets, KafkaResources.clientsCaCertificateSecretName("bar")), findSecretWithName(barSecrets, KafkaResources.clientsCaKeySecretName("bar")));
// providing the list of ALL StatefulSets for all the Kafka clusters
Labels newLabels = Labels.forStrimziKind(Kafka.RESOURCE_KIND);
when(mockStsOps.list(eq("*"), eq(newLabels))).thenReturn(List.of(KafkaCluster.fromCrd(Reconciliation.DUMMY_RECONCILIATION, bar, VERSIONS).generateStatefulSet(openShift, null, null, null)));
// providing the list StatefulSets for already "existing" Kafka clusters
Labels barLabels = Labels.forStrimziCluster("bar");
KafkaCluster barCluster = KafkaCluster.fromCrd(Reconciliation.DUMMY_RECONCILIATION, bar, VERSIONS);
when(mockStsOps.list(eq("*"), eq(barLabels))).thenReturn(List.of(barCluster.generateStatefulSet(openShift, null, null, null)));
when(mockSecretOps.list(eq("*"), eq(barLabels))).thenAnswer(invocation -> new ArrayList<>(asList(barClientsCa.caKeySecret(), barClientsCa.caCertSecret(), barCluster.generateCertificatesSecret(barClusterCa, barClientsCa, Set.of(), Map.of(), true), barClusterCa.caCertSecret())));
Checkpoint fooAsync = context.checkpoint();
Checkpoint barAsync = context.checkpoint();
KafkaAssemblyOperator ops = new KafkaAssemblyOperator(vertx, new PlatformFeaturesAvailability(openShift, kubernetesVersion), certManager, passwordGenerator, supplier, config) {
@Override
public Future<KafkaStatus> createOrUpdate(Reconciliation reconciliation, Kafka kafkaAssembly) {
String name = kafkaAssembly.getMetadata().getName();
if ("foo".equals(name)) {
fooAsync.flag();
} else if ("bar".equals(name)) {
barAsync.flag();
} else {
context.failNow(new AssertionError("Unexpected name " + name));
}
return Future.succeededFuture();
}
};
Checkpoint async = context.checkpoint();
// Now try to reconcile all the Kafka clusters
ops.reconcileAll("test", "*", context.succeeding(v -> async.flag()));
}
use of io.strimzi.operator.common.model.Labels in project strimzi-kafka-operator by strimzi.
the class KafkaConnectAssemblyOperatorTest method testReconcile.
@Test
public void testReconcile(VertxTestContext context) {
// Must create all needed checkpoints before flagging any, to avoid premature test success
Checkpoint asyncCreated = context.checkpoint(2);
Checkpoint async = context.checkpoint();
ResourceOperatorSupplier supplier = ResourceUtils.supplierWithMocks(true);
var mockConnectOps = supplier.connectOperator;
var mockConnectorOps = supplier.kafkaConnectorOperator;
DeploymentOperator mockDcOps = supplier.deploymentOperations;
SecretOperator mockSecretOps = supplier.secretOperations;
PodDisruptionBudgetOperator mockPdbOps = supplier.podDisruptionBudgetOperator;
NetworkPolicyOperator mockNetPolOps = supplier.networkPolicyOperator;
when(mockConnectorOps.listAsync(any(), any(Optional.class))).thenReturn(Future.succeededFuture(List.of()));
String kcNamespace = "test";
KafkaConnect foo = ResourceUtils.createEmptyKafkaConnect(kcNamespace, "foo");
KafkaConnect bar = ResourceUtils.createEmptyKafkaConnect(kcNamespace, "bar");
when(mockConnectOps.listAsync(eq(kcNamespace), any(Optional.class))).thenReturn(Future.succeededFuture(asList(foo, bar)));
// when requested ConfigMap for a specific Kafka Connect cluster
when(mockConnectOps.get(eq(kcNamespace), eq("foo"))).thenReturn(foo);
when(mockConnectOps.get(eq(kcNamespace), eq("bar"))).thenReturn(bar);
// providing the list of ALL Deployments for all the Kafka Connect clusters
Labels newLabels = Labels.forStrimziKind(KafkaConnect.RESOURCE_KIND);
when(mockDcOps.list(eq(kcNamespace), eq(newLabels))).thenReturn(List.of(KafkaConnectCluster.fromCrd(Reconciliation.DUMMY_RECONCILIATION, bar, VERSIONS).generateDeployment(Map.of(), true, null, null)));
// providing the list Deployments for already "existing" Kafka Connect clusters
Labels barLabels = Labels.forStrimziCluster("bar");
when(mockDcOps.list(eq(kcNamespace), eq(barLabels))).thenReturn(List.of(KafkaConnectCluster.fromCrd(Reconciliation.DUMMY_RECONCILIATION, bar, VERSIONS).generateDeployment(Map.of(), true, null, null)));
when(mockDcOps.readiness(any(), anyString(), anyString(), anyLong(), anyLong())).thenReturn(Future.succeededFuture());
when(mockDcOps.waitForObserved(any(), anyString(), anyString(), anyLong(), anyLong())).thenReturn(Future.succeededFuture());
when(mockNetPolOps.reconcile(any(), eq(kcNamespace), eq(KafkaConnectResources.deploymentName(bar.getMetadata().getName())), any())).thenReturn(Future.succeededFuture(ReconcileResult.created(new NetworkPolicy())));
when(mockSecretOps.reconcile(any(), eq(kcNamespace), any(), any())).thenReturn(Future.succeededFuture());
when(mockPdbOps.reconcile(any(), eq(kcNamespace), any(), any())).thenReturn(Future.succeededFuture());
Set<String> createdOrUpdated = new CopyOnWriteArraySet<>();
KafkaConnectAssemblyOperator ops = new KafkaConnectAssemblyOperator(vertx, new PlatformFeaturesAvailability(true, kubernetesVersion), supplier, ResourceUtils.dummyClusterOperatorConfig(VERSIONS)) {
@Override
public Future<KafkaConnectStatus> createOrUpdate(Reconciliation reconciliation, KafkaConnect kafkaConnectAssembly) {
createdOrUpdated.add(kafkaConnectAssembly.getMetadata().getName());
asyncCreated.flag();
return Future.succeededFuture();
}
};
Promise<Void> reconciled = Promise.promise();
// Now try to reconcile all the Kafka Connect clusters
ops.reconcileAll("test", kcNamespace, ignored -> reconciled.complete());
reconciled.future().onComplete(context.succeeding(v -> context.verify(() -> {
assertThat(createdOrUpdated, is(Set.of("foo", "bar")));
async.flag();
})));
}
use of io.strimzi.operator.common.model.Labels in project strimzi-kafka-operator by strimzi.
the class KafkaRebalanceAssemblyOperatorTest method testKafkaClusterNotMatchingLabelSelector.
/**
* When the Kafka cluster does not match the selector labels in the cluster operator configuration, the
* KafkaRebalance resource should be ignored and not reconciled.
*/
@Test
public void testKafkaClusterNotMatchingLabelSelector(VertxTestContext context) {
KafkaRebalance kr = createKafkaRebalance(CLUSTER_NAMESPACE, CLUSTER_NAME, RESOURCE_NAME, EMPTY_KAFKA_REBALANCE_SPEC);
ResourceOperatorSupplier supplier = ResourceUtils.supplierWithMocks(true);
mockKafkaOps = supplier.kafkaOperator;
mockRebalanceOps = supplier.kafkaRebalanceOperator;
when(mockKafkaOps.getAsync(CLUSTER_NAMESPACE, CLUSTER_NAME)).thenReturn(Future.succeededFuture(kafka));
ClusterOperatorConfig config = new ClusterOperatorConfig(singleton(CLUSTER_NAMESPACE), 60_000, 120_000, 300_000, false, true, KafkaVersionTestUtils.getKafkaVersionLookup(), null, null, null, null, Labels.fromMap(Map.of("selectorLabel", "value")), "", 10, 10_000, 30, false, 1024);
kcrao = new KafkaRebalanceAssemblyOperator(Vertx.vertx(), supplier, config);
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 labels of the Kafka resource do not match the => the KafkaRebalance should not be reconciled and the
// rebalance ops should have no interactions.
verifyNoInteractions(mockRebalanceOps);
checkpoint.flag();
})));
}
use of io.strimzi.operator.common.model.Labels in project strimzi-kafka-operator by strimzi.
the class CaReconciler method rollingUpdateForNewCaKey.
/**
* Perform a rolling update of the cluster so that CA certificates get added to their truststores, or expired CA
* certificates get removed from their truststores. Note this is only necessary when the CA certificate has changed
* due to a new CA key. It is not necessary when the CA certificate is replace while retaining the existing key.
*/
Future<Void> rollingUpdateForNewCaKey() {
List<String> reason = new ArrayList<>(2);
if (clusterCa.keyReplaced()) {
reason.add("trust new cluster CA certificate signed by new key");
}
if (clientsCa.keyReplaced()) {
reason.add("trust new clients CA certificate signed by new key");
}
if (!reason.isEmpty()) {
Future<Void> zkRollFuture;
Function<Pod, List<String>> rollPodAndLogReason = pod -> {
LOGGER.debugCr(reconciliation, "Rolling Pod {} to {}", pod.getMetadata().getName(), reason);
return reason;
};
if (clusterCa.keyReplaced()) {
// ZooKeeper is rolled only for new Cluster CA key
Labels zkSelectorLabels = Labels.EMPTY.withStrimziKind(reconciliation.kind()).withStrimziCluster(reconciliation.name()).withStrimziName(KafkaResources.zookeeperStatefulSetName(reconciliation.name()));
zkRollFuture = new ZooKeeperRoller(podOperator, zookeeperLeaderFinder, operationTimeoutMs).maybeRollingUpdate(reconciliation, zkSelectorLabels, rollPodAndLogReason, clusterCa.caCertSecret(), oldCoSecret);
} else {
zkRollFuture = Future.succeededFuture();
}
return zkRollFuture.compose(i -> {
if (featureGates.useStrimziPodSetsEnabled()) {
return strimziPodSetOperator.getAsync(reconciliation.namespace(), KafkaResources.kafkaStatefulSetName(reconciliation.name())).compose(podSet -> {
if (podSet != null) {
return Future.succeededFuture(KafkaCluster.generatePodList(reconciliation.name(), podSet.getSpec().getPods().size()));
} else {
return Future.succeededFuture(List.<String>of());
}
});
} else {
return stsOperator.getAsync(reconciliation.namespace(), KafkaResources.kafkaStatefulSetName(reconciliation.name())).compose(sts -> {
if (sts != null) {
return Future.succeededFuture(KafkaCluster.generatePodList(reconciliation.name(), sts.getSpec().getReplicas()));
} else {
return Future.succeededFuture(List.<String>of());
}
});
}
}).compose(replicas -> new KafkaRoller(reconciliation, vertx, podOperator, 1_000, operationTimeoutMs, () -> new BackOff(250, 2, 10), replicas, clusterCa.caCertSecret(), oldCoSecret, adminClientProvider, brokerId -> null, null, null, false).rollingRestart(rollPodAndLogReason)).compose(i -> {
if (clusterCa.keyReplaced()) {
// EO, KE and CC need to be rolled only for new Cluster CA key.
return rollDeploymentIfExists(KafkaResources.entityOperatorDeploymentName(reconciliation.name()), reason.toString()).compose(i2 -> rollDeploymentIfExists(KafkaExporterResources.deploymentName(reconciliation.name()), reason.toString())).compose(i2 -> rollDeploymentIfExists(CruiseControlResources.deploymentName(reconciliation.name()), reason.toString()));
} else {
return Future.succeededFuture();
}
});
} else {
return Future.succeededFuture();
}
}
use of io.strimzi.operator.common.model.Labels in project strimzi-kafka-operator by strimzi.
the class KafkaCluster method generateExternalServices.
/**
* Generates list of service for pod. These services are used for exposing it externally.
*
* @param pod Number of the pod for which this service should be generated
* @return The list with generated Services
*/
public List<Service> generateExternalServices(int pod) {
List<GenericKafkaListener> externalListeners = ListenersUtils.externalListeners(listeners);
List<Service> services = new ArrayList<>(externalListeners.size());
for (GenericKafkaListener listener : externalListeners) {
String serviceName = ListenersUtils.backwardsCompatibleBrokerServiceName(cluster, pod, listener);
List<ServicePort> ports = Collections.singletonList(createServicePort(ListenersUtils.backwardsCompatiblePortName(listener), listener.getPort(), listener.getPort(), ListenersUtils.brokerNodePort(listener, pod), "TCP"));
Labels selector = getSelectorLabels().withStatefulSetPod(KafkaResources.kafkaPodName(cluster, pod));
Service service = createService(serviceName, ListenersUtils.serviceType(listener), ports, getLabelsWithStrimziName(name, Util.mergeLabelsOrAnnotations(templatePerPodServiceLabels, ListenersUtils.brokerLabels(listener, pod))), selector, Util.mergeLabelsOrAnnotations(ListenersUtils.brokerAnnotations(listener, pod), templatePerPodServiceAnnotations), ListenersUtils.ipFamilyPolicy(listener), ListenersUtils.ipFamilies(listener));
if (KafkaListenerType.LOADBALANCER == listener.getType()) {
String loadBalancerIP = ListenersUtils.brokerLoadBalancerIP(listener, pod);
if (loadBalancerIP != null) {
service.getSpec().setLoadBalancerIP(loadBalancerIP);
}
List<String> loadBalancerSourceRanges = ListenersUtils.loadBalancerSourceRanges(listener);
if (loadBalancerSourceRanges != null && !loadBalancerSourceRanges.isEmpty()) {
service.getSpec().setLoadBalancerSourceRanges(loadBalancerSourceRanges);
}
List<String> finalizers = ListenersUtils.finalizers(listener);
if (finalizers != null && !finalizers.isEmpty()) {
service.getMetadata().setFinalizers(finalizers);
}
}
if (KafkaListenerType.LOADBALANCER == listener.getType() || KafkaListenerType.NODEPORT == listener.getType()) {
ExternalTrafficPolicy etp = ListenersUtils.externalTrafficPolicy(listener);
if (etp != null) {
service.getSpec().setExternalTrafficPolicy(etp.toValue());
} else {
service.getSpec().setExternalTrafficPolicy(ExternalTrafficPolicy.CLUSTER.toValue());
}
}
services.add(service);
}
return services;
}
Aggregations