use of org.bf2.cos.fleetshard.api.Version in project cos-fleetshard by bf2fc6cc711aee1a0c2a.
the class ConnectorClusterStatusSync method update.
private void update() {
ConnectorClusterStatus status = new ConnectorClusterStatus();
status.setPhase(ConnectorClusterState.READY);
fleetShardClient.getOperators().stream().map(o -> new ConnectorClusterStatusOperators().namespace(o.getMetadata().getNamespace()).operator(new ConnectorOperator().id(o.getMetadata().getName()).type(o.getSpec().getType()).version(o.getSpec().getVersion())).status(Operators.PHASE_READY)).forEach(status::addOperatorsItem);
fleetShardClient.getNamespaces().stream().map(n -> {
ConnectorNamespaceState phase = ConnectorNamespaceState.DISCONNECTED;
if (n.getStatus() != null) {
if (Objects.equals(Namespaces.STATUS_ACTIVE, n.getStatus().getPhase())) {
phase = ConnectorNamespaceState.READY;
} else if (Objects.equals(Namespaces.STATUS_TERMINATING, n.getStatus().getPhase())) {
phase = ConnectorNamespaceState.DELETING;
}
}
return new ConnectorNamespaceStatus().id(n.getMetadata().getLabels().get(Resources.LABEL_NAMESPACE_ID)).version(Resources.getLabel(n, Resources.LABEL_KUBERNETES_VERSION)).connectorsDeployed(fleetShardClient.getConnectors(n).size()).phase(phase);
}).forEach(status::addNamespacesItem);
controlPlane.updateClusterStatus(status);
}
use of org.bf2.cos.fleetshard.api.Version in project cos-fleetshard by bf2fc6cc711aee1a0c2a.
the class ConnectorNamespaceProvisioner method provisionNamespaces.
private void provisionNamespaces(Collection<ConnectorNamespace> namespaces, boolean sync) {
for (ConnectorNamespace namespace : namespaces) {
this.recorder.record(() -> provision(namespace), Tags.of(TAG_NAMESPACE_ID, namespace.getId()), e -> {
LOGGER.error("Failure while trying to provision connector namespace: id={}, revision={}", namespace.getId(), namespace.getResourceVersion(), e);
try {
MetaV1Condition condition = new MetaV1Condition();
condition.setType(Conditions.TYPE_READY);
condition.setStatus(Conditions.STATUS_FALSE);
condition.setReason(Conditions.FAILED_TO_CREATE_OR_UPDATE_RESOURCE_REASON);
condition.setMessage(e.getMessage());
ConnectorNamespaceStatus status = new ConnectorNamespaceStatus().id(namespace.getId()).version("" + namespace.getResourceVersion()).phase(ConnectorNamespaceState.DISCONNECTED).conditions(List.of(condition));
fleetManager.updateNamespaceStatus(fleetShard.getClusterId(), namespace.getId(), status);
} catch (Exception ex) {
LOGGER.warn("Error wile reporting failure to the control plane", e);
}
fleetShard.getConnectorCluster().ifPresent(cc -> {
fleetShard.broadcast("Warning", "FailedToCreateOrUpdateResource", String.format("Unable to create or update namespace %s, revision: %s, reason: %s", namespace.getId(), namespace.getResourceVersion(), e.getMessage()), cc);
});
});
}
if (sync) {
Set<String> knownIds = namespaces.stream().map(ConnectorNamespace::getId).collect(Collectors.toSet());
for (Namespace namespace : fleetShard.getNamespaces()) {
String nsId = Resources.getLabel(namespace, Resources.LABEL_NAMESPACE_ID);
if (nsId == null || knownIds.contains(nsId)) {
continue;
}
try {
Resources.setLabels(namespace, Resources.LABEL_NAMESPACE_STATE, Namespaces.PHASE_DELETED);
Resources.setLabels(namespace, Resources.LABEL_NAMESPACE_STATE_FORCED, "true");
fleetShard.getKubernetesClient().namespaces().withName(namespace.getMetadata().getName()).replace(namespace);
} catch (Exception e) {
LOGGER.warn("Error marking na {} for deletion (sync)", namespace.getMetadata().getName(), e);
}
}
}
}
use of org.bf2.cos.fleetshard.api.Version in project cos-fleetshard by bf2fc6cc711aee1a0c2a.
the class ConnectorStatusUpdaterTest method statusIsUpdated.
@Test
void statusIsUpdated() {
final String clusterUrl = "/api/connector_mgmt/v1/agent/kafka_connector_clusters/" + config.cluster().id();
final String statusUrl = clusterUrl + "/deployments/" + DEPLOYMENT_ID + "/status";
final Condition condition = new Condition(null, uid(), null, uid(), uid(), uid());
final Operator operator = new Operator(uid(), "operator-type", "1.2.3");
final ManagedConnector connector = new ManagedConnectorBuilder().withMetadata(new ObjectMetaBuilder().withName(Connectors.generateConnectorId(DEPLOYMENT_ID)).withNamespace(ns).addToLabels(LABEL_CLUSTER_ID, config.cluster().id()).addToLabels(LABEL_CONNECTOR_ID, CONNECTOR_ID).addToLabels(LABEL_DEPLOYMENT_ID, DEPLOYMENT_ID).build()).withSpec(new ManagedConnectorSpecBuilder().withClusterId(config.cluster().id()).withConnectorId(CONNECTOR_ID).withDeploymentId(DEPLOYMENT_ID).withOperatorSelector(new OperatorSelectorBuilder().withId(operator.getId()).build()).build()).build();
kubernetesClient.resources(ManagedConnector.class).inNamespace(ns).create(connector);
connector.getStatus().setConnectorStatus(new ConnectorStatusSpecBuilder().withPhase(DESIRED_STATE_READY).withConditions(condition).withAssignedOperator(operator).build());
kubernetesClient.resources(ManagedConnector.class).inNamespace(ns).withName(connector.getMetadata().getName()).replaceStatus(connector);
untilAsserted(() -> {
server.verify(putRequestedFor(urlEqualTo(statusUrl)).withHeader(ContentTypeHeader.KEY, equalTo(APPLICATION_JSON)).withRequestBody(matchingJsonPath("$.operators.assigned[?(@.version == '" + operator.getVersion() + "')]")).withRequestBody(matchingJsonPath("$.operators.assigned[?(@.type == '" + operator.getType() + "')]")).withRequestBody(matchingJsonPath("$.operators.assigned[?(@.id == '" + operator.getId() + "')]")).withRequestBody(matchingJsonPath("$[?($.phase == 'ready')]")));
});
}
use of org.bf2.cos.fleetshard.api.Version in project cos-fleetshard by bf2fc6cc711aee1a0c2a.
the class NamespaceProvisionerBadIdTestBase method namespaceIsProvisioned.
@Test
void namespaceIsProvisioned() {
final String deployment1 = ConfigProvider.getConfig().getValue("test.deployment.id.1", String.class);
final String deployment2 = ConfigProvider.getConfig().getValue("test.deployment.id.2", String.class);
given().contentType(MediaType.TEXT_PLAIN).body(0L).post("/test/provisioner/namespaces");
server.until(putRequestedFor(urlPathMatching("/api/connector_mgmt/v1/agent/kafka_connector_clusters/.*/namespaces/.*/status")).withHeader(ContentTypeHeader.KEY, equalTo(APPLICATION_JSON)).withRequestBody(jp("$.id", deployment1)).withRequestBody(jp("$.version", "1")).withRequestBody(jp("$.phase", ConnectorNamespaceState.DISCONNECTED.getValue())).withRequestBody(jp("$.conditions.size()", "1")).withRequestBody(jp("$.conditions[0].type", Conditions.TYPE_READY)).withRequestBody(jp("$.conditions[0].status", Conditions.STATUS_FALSE)).withRequestBody(jp("$.conditions[0].reason", Conditions.FAILED_TO_CREATE_OR_UPDATE_RESOURCE_REASON)));
untilAsserted(() -> {
assertThat(fleetShardClient.getKubernetesClient().v1().events().inNamespace(config.namespace()).list().getItems()).anySatisfy(e -> {
assertThat(e.getInvolvedObject().getKind()).isEqualTo(ManagedConnectorCluster.class.getSimpleName());
assertThat(e.getType()).isEqualTo("Warning");
assertThat(e.getReason()).isEqualTo("FailedToCreateOrUpdateResource");
assertThat(e.getMessage()).contains("Unable to create or update namespace " + deployment1);
});
});
Namespace ns2 = until(() -> fleetShardClient.getNamespace(deployment2), Objects::nonNull);
assertThat(ns2).satisfies(item -> {
assertThat(item.getMetadata().getName()).isEqualTo(client.generateNamespaceId(deployment2));
assertThat(item.getMetadata().getLabels()).containsEntry(Resources.LABEL_CLUSTER_ID, fleetShardClient.getClusterId()).containsEntry(Resources.LABEL_NAMESPACE_ID, deployment2).containsEntry(Resources.LABEL_KUBERNETES_MANAGED_BY, fleetShardClient.getClusterId()).containsEntry(Resources.LABEL_KUBERNETES_CREATED_BY, fleetShardClient.getClusterId()).containsEntry(Resources.LABEL_KUBERNETES_PART_OF, fleetShardClient.getClusterId()).containsEntry(Resources.LABEL_KUBERNETES_COMPONENT, Resources.COMPONENT_NAMESPACE).containsEntry(Resources.LABEL_KUBERNETES_INSTANCE, deployment2).containsEntry(Resources.LABEL_NAMESPACE_TENANT_KIND, ConnectorNamespaceTenantKind.ORGANISATION.getValue()).containsKey(Resources.LABEL_NAMESPACE_TENANT_ID);
});
}
use of org.bf2.cos.fleetshard.api.Version in project cos-fleetshard by bf2fc6cc711aee1a0c2a.
the class ConnectorProvisionerTest method updateAndCreateResources.
@Test
void updateAndCreateResources() {
//
// Given that the resources associated to the provided deployment exist
//
final ConnectorDeployment oldDeployment = createDeployment(0);
final List<ManagedConnector> connectors = List.of(new ManagedConnectorBuilder().withMetadata(new ObjectMetaBuilder().withName(Connectors.generateConnectorId(oldDeployment.getId())).addToLabels(LABEL_CLUSTER_ID, CLUSTER_ID).addToLabels(LABEL_CONNECTOR_ID, oldDeployment.getSpec().getConnectorId()).addToLabels(LABEL_DEPLOYMENT_ID, oldDeployment.getId()).build()).build());
final List<Secret> secrets = List.of(new SecretBuilder().withMetadata(new ObjectMetaBuilder().withName(Secrets.generateConnectorSecretId(oldDeployment.getId())).addToLabels(LABEL_CLUSTER_ID, CLUSTER_ID).addToLabels(LABEL_CONNECTOR_ID, oldDeployment.getSpec().getConnectorId()).addToLabels(LABEL_DEPLOYMENT_ID, oldDeployment.getId()).addToLabels(LABEL_DEPLOYMENT_RESOURCE_VERSION, "" + oldDeployment.getMetadata().getResourceVersion()).build()).build());
final FleetShardClient fleetShard = ConnectorTestSupport.fleetShard(CLUSTER_ID, connectors, secrets);
final FleetManagerClient fleetManager = ConnectorTestSupport.fleetManagerClient();
final FleetShardSyncConfig config = ConnectorTestSupport.config();
final MeterRegistry registry = Mockito.mock(MeterRegistry.class);
final ConnectorDeploymentProvisioner provisioner = new ConnectorDeploymentProvisioner(config, fleetShard, fleetManager, registry);
final ArgumentCaptor<Secret> sc = ArgumentCaptor.forClass(Secret.class);
final ArgumentCaptor<ManagedConnector> mcc = ArgumentCaptor.forClass(ManagedConnector.class);
//
// When a change to the deployment happen that ends up with a new resource version
//
final ConnectorDeployment newDeployment = createDeployment(1, d -> {
d.getMetadata().setResourceVersion(1L);
d.getSpec().getKafka().setUrl("my-kafka.acme.com:218");
((ObjectNode) d.getSpec().getConnectorSpec()).with("connector").put("foo", "connector-baz");
((ObjectNode) d.getSpec().getShardMetadata()).put("connector_image", "quay.io/mcs_dev/aws-s3-sink:0.1.0");
});
provisioner.provision(newDeployment);
verify(fleetShard).createSecret(sc.capture());
verify(fleetShard).createConnector(mcc.capture());
//
// Then the managed connector resource is expected to be updated to reflect the
// changes made to the deployment
//
assertThat(sc.getValue()).satisfies(val -> {
assertThat(val.getMetadata().getName()).isEqualTo(Secrets.generateConnectorSecretId(oldDeployment.getId()));
assertThat(val.getMetadata().getLabels()).containsEntry(LABEL_CLUSTER_ID, CLUSTER_ID).containsEntry(LABEL_CONNECTOR_ID, newDeployment.getSpec().getConnectorId()).containsEntry(LABEL_DEPLOYMENT_ID, newDeployment.getId()).containsEntry(LABEL_DEPLOYMENT_RESOURCE_VERSION, "" + newDeployment.getMetadata().getResourceVersion()).containsKey(LABEL_UOW);
assertThat(val.getData()).containsKey(Secrets.SECRET_ENTRY_SERVICE_ACCOUNT).containsKey(Secrets.SECRET_ENTRY_CONNECTOR);
var serviceAccountNode = Secrets.extract(val, Secrets.SECRET_ENTRY_SERVICE_ACCOUNT, ServiceAccount.class);
assertThat(serviceAccountNode.getClientSecret()).isEqualTo(newDeployment.getSpec().getServiceAccount().getClientSecret());
assertThat(serviceAccountNode.getClientId()).isEqualTo(newDeployment.getSpec().getServiceAccount().getClientId());
var connectorNode = Secrets.extract(val, Secrets.SECRET_ENTRY_CONNECTOR);
assertThatJson(Secrets.extract(val, Secrets.SECRET_ENTRY_CONNECTOR)).inPath("connector.foo").isEqualTo("connector-baz");
assertThatJson(connectorNode).inPath("kafka.topic").isEqualTo("kafka-foo");
var metaNode = Secrets.extract(val, Secrets.SECRET_ENTRY_META);
assertThatJson(metaNode).isObject().containsKey("connector_type").containsKey("connector_image").containsKey("kamelets").containsKey("operators");
});
assertThat(mcc.getValue()).satisfies(val -> {
assertThat(val.getMetadata().getName()).isEqualTo(Connectors.generateConnectorId(oldDeployment.getId()));
assertThat(val.getMetadata().getLabels()).containsEntry(LABEL_CLUSTER_ID, CLUSTER_ID).containsEntry(LABEL_CONNECTOR_ID, oldDeployment.getSpec().getConnectorId()).containsEntry(LABEL_DEPLOYMENT_ID, oldDeployment.getId()).containsKey(LABEL_UOW);
assertThat(val.getSpec().getDeployment()).satisfies(d -> {
assertThat(d.getDeploymentResourceVersion()).isEqualTo(newDeployment.getMetadata().getResourceVersion());
assertThat(d.getDeploymentResourceVersion()).isNotEqualTo(oldDeployment.getMetadata().getResourceVersion());
assertThat(d.getSecret()).isEqualTo(sc.getValue().getMetadata().getName());
assertThat(d.getUnitOfWork()).isNotEmpty().isEqualTo(sc.getValue().getMetadata().getLabels().get(LABEL_UOW));
assertThat(d.getKafka().getUrl()).isNotEmpty().isEqualTo(newDeployment.getSpec().getKafka().getUrl());
});
});
}
Aggregations