Search in sources :

Example 1 with Conditions

use of org.bf2.cos.fleetshard.api.Conditions in project kas-fleetshard by bf2fc6cc711aee1a0c2a.

the class StrimziBundleManager method updateStatus.

/**
 * Update status of ManagedKafkaAgent resource about approval of Strimzi bundle installation
 * NOTE: it creates a condition if Strimzi bundle installation was not approved. The condition is taken out if approved.
 *
 * @param approval the status of the approval
 */
private void updateStatus(Approval approval) {
    ManagedKafkaAgent resource = this.agentClient.getByName(this.agentClient.getNamespace(), ManagedKafkaAgentResourceClient.RESOURCE_NAME);
    if (resource != null && resource.getStatus() != null) {
        List<ManagedKafkaCondition> conditions = resource.getStatus().getConditions();
        ManagedKafkaCondition bundleReadyCondition = ConditionUtils.findManagedKafkaCondition(conditions, ManagedKafkaCondition.Type.StrimziBundleReady).orElse(null);
        ManagedKafkaCondition.Reason reason = ManagedKafkaCondition.Reason.OrphanedKafkas;
        ManagedKafkaCondition.Status status = ManagedKafkaCondition.Status.False;
        if (approval != Approval.ORPHANED) {
            if (bundleReadyCondition == null) {
                return;
            }
            conditions.remove(bundleReadyCondition);
        } else {
            if (bundleReadyCondition == null) {
                bundleReadyCondition = ConditionUtils.buildCondition(ManagedKafkaCondition.Type.StrimziBundleReady, status);
                bundleReadyCondition.reason(reason);
                conditions.add(bundleReadyCondition);
            } else {
                ConditionUtils.updateConditionStatus(bundleReadyCondition, status, reason, null);
            }
        }
        this.agentClient.replaceStatus(resource);
    }
}
Also used : ManagedKafkaCondition(org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition) ManagedKafkaAgent(org.bf2.operator.resources.v1alpha1.ManagedKafkaAgent)

Example 2 with Conditions

use of org.bf2.cos.fleetshard.api.Conditions in project srs-fleet-manager by bf2fc6cc711aee1a0c2a.

the class AccountManagementServiceImpl method createResource.

@Timed(value = Constants.AMS_CREATE_TIMER, description = Constants.AMS_TIMER_DESCRIPTION)
@Audited(extractResult = KEY_AMS_SUBSCRIPTION_ID)
// but AMS still performs the reservation.
@Override
public String createResource(AccountInfo accountInfo, ResourceType resourceType) throws TermsRequiredException, ResourceLimitReachedException, AccountManagementServiceException {
    try {
        boolean termsAccepted = false;
        String siteCode = amsProperties.termsSiteCode;
        List<String> eventCodes = amsProperties.termsEventCode;
        for (String eventCode : eventCodes) {
            final TermsReview termsReview = new TermsReview();
            termsReview.setAccountUsername(accountInfo.getAccountUsername());
            termsReview.setSiteCode(siteCode);
            termsReview.setEventCode(eventCode);
            // Check if the user has accepted the Terms & Conditions
            final ResponseTermsReview responseTermsReview = restClient.termsReview(termsReview);
            boolean accepted = !responseTermsReview.getTermsRequired();
            // Terms are accepted if *any* of the T&C checks come back as "accepted"
            termsAccepted = termsAccepted || accepted;
        }
        if (!termsAccepted) {
            throw new TermsRequiredException(accountInfo.getAccountUsername());
        }
        // TODO Workaround: Remove this once we have RHOSRTrial working.
        if (resourceType == ResourceType.REGISTRY_INSTANCE_EVAL) {
            log.debug("Creating an eval instance for '{}' in org '{}' without calling AMS.", accountInfo.getAccountUsername(), accountInfo.getOrganizationId());
            return null;
        }
        // Set the productId and resourceName based on if it's an Eval or Standard instance
        String productId = amsProperties.standardProductId;
        String resourceName = amsProperties.standardResourceName;
        if (resourceType == ResourceType.REGISTRY_INSTANCE_EVAL) {
            productId = amsProperties.evalProductId;
            resourceName = amsProperties.evalResourceName;
        }
        // Build a quota resource ID to pass to AMS
        final var quotaResource = ReservedResource.builder().resourceType(amsProperties.resourceType).byoc(false).resourceName(resourceName).billingModel("marketplace").availabilityZone("single").count(1).build();
        // Create the cluster authorization REST operation input
        final ClusterAuthorization clusterAuthorization = ClusterAuthorization.builder().accountUsername(accountInfo.getAccountUsername()).productId(productId).managed(true).byoc(false).cloudProviderId("aws").reserve(true).availabilityZone("single").clusterId(UUID.randomUUID().toString()).resources(Collections.singletonList(quotaResource)).build();
        // Consume quota from AMS via the AMS REST API
        final ClusterAuthorizationResponse clusterAuthorizationResponse = restClient.clusterAuthorization(clusterAuthorization);
        if (clusterAuthorizationResponse.getAllowed()) {
            return clusterAuthorizationResponse.getSubscription().getId();
        } else {
            // User not allowed to create resource
            throw new ResourceLimitReachedException();
        }
    } catch (AccountManagementSystemClientException ex) {
        ExceptionConvert.convert(ex);
        // Never returns
        return null;
    }
}
Also used : ResponseTermsReview(org.bf2.srs.fleetmanager.spi.ams.impl.model.response.ResponseTermsReview) TermsReview(org.bf2.srs.fleetmanager.spi.ams.impl.model.request.TermsReview) ClusterAuthorization(org.bf2.srs.fleetmanager.spi.ams.impl.model.request.ClusterAuthorization) ClusterAuthorizationResponse(org.bf2.srs.fleetmanager.spi.ams.impl.model.response.ClusterAuthorizationResponse) TermsRequiredException(org.bf2.srs.fleetmanager.spi.ams.TermsRequiredException) AccountManagementSystemClientException(org.bf2.srs.fleetmanager.spi.ams.impl.exception.AccountManagementSystemClientException) ResourceLimitReachedException(org.bf2.srs.fleetmanager.spi.ams.ResourceLimitReachedException) ResponseTermsReview(org.bf2.srs.fleetmanager.spi.ams.impl.model.response.ResponseTermsReview) Audited(org.bf2.srs.fleetmanager.common.operation.auditing.Audited) Timed(io.micrometer.core.annotation.Timed)

Example 3 with Conditions

use of org.bf2.cos.fleetshard.api.Conditions in project cos-fleetshard by bf2fc6cc711aee1a0c2a.

the class ConnectorStatusExtractorTest method extractFromConnectorStatus.

/*
     * Test that if the status sub resource is provided and the phase is
     * "monitor", then the status extractor compute the phase according
     * to the reported deployment status
     */
@ParameterizedTest
@MethodSource
void extractFromConnectorStatus(String statusDesiredState, String connectorPhase, String expectedState, List<Condition> conditions) {
    var status = ConnectorStatusExtractor.extract(new ManagedConnectorBuilder().withSpec(new ManagedConnectorSpecBuilder().withOperatorSelector(new OperatorSelectorBuilder().withId("1").build()).build()).withStatus(new ManagedConnectorStatusBuilder().withPhase(ManagedConnectorStatus.PhaseType.Monitor).withDeployment(new DeploymentSpecBuilder().withDeploymentResourceVersion(1L).withDesiredState(statusDesiredState).build()).withConnectorStatus(new ConnectorStatusSpecBuilder().withPhase(connectorPhase).withConditions(conditions).build()).build()).build());
    var v1Conditions = conditions.stream().map(ConnectorStatusExtractor::toMetaV1Condition).collect(Collectors.toList());
    assertThat(status.getPhase()).isEqualTo(expectedState);
    assertThat(status.getConditions()).hasSameSizeAs(conditions).hasSameElementsAs(v1Conditions);
    assertThat(status.getResourceVersion()).isEqualTo(1L);
    assertThat(status).extracting(ConnectorDeploymentStatus::getOperators).extracting(ConnectorDeploymentStatusOperators::getAssigned).hasAllNullFieldsOrProperties();
    assertThat(status).extracting(ConnectorDeploymentStatus::getOperators).extracting(ConnectorDeploymentStatusOperators::getAvailable).hasAllNullFieldsOrProperties();
}
Also used : DeploymentSpecBuilder(org.bf2.cos.fleetshard.api.DeploymentSpecBuilder) ManagedConnectorBuilder(org.bf2.cos.fleetshard.api.ManagedConnectorBuilder) ManagedConnectorStatusBuilder(org.bf2.cos.fleetshard.api.ManagedConnectorStatusBuilder) ManagedConnectorSpecBuilder(org.bf2.cos.fleetshard.api.ManagedConnectorSpecBuilder) ConnectorStatusSpecBuilder(org.bf2.cos.fleetshard.api.ConnectorStatusSpecBuilder) ConnectorDeploymentStatus(org.bf2.cos.fleet.manager.model.ConnectorDeploymentStatus) OperatorSelectorBuilder(org.bf2.cos.fleetshard.api.OperatorSelectorBuilder) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 4 with Conditions

use of org.bf2.cos.fleetshard.api.Conditions 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);
            }
        }
    }
}
Also used : ConnectorNamespace(org.bf2.cos.fleet.manager.model.ConnectorNamespace) MetaV1Condition(org.bf2.cos.fleet.manager.model.MetaV1Condition) ConnectorNamespaceStatus(org.bf2.cos.fleet.manager.model.ConnectorNamespaceStatus) ConnectorNamespace(org.bf2.cos.fleet.manager.model.ConnectorNamespace) Namespace(io.fabric8.kubernetes.api.model.Namespace)

Example 5 with Conditions

use of org.bf2.cos.fleetshard.api.Conditions 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);
    });
}
Also used : Objects(java.util.Objects) ManagedConnectorCluster(org.bf2.cos.fleetshard.api.ManagedConnectorCluster) ConnectorNamespace(org.bf2.cos.fleet.manager.model.ConnectorNamespace) Namespace(io.fabric8.kubernetes.api.model.Namespace) Test(org.junit.jupiter.api.Test)

Aggregations

Namespace (io.fabric8.kubernetes.api.model.Namespace)2 Timed (io.micrometer.core.annotation.Timed)2 ArrayList (java.util.ArrayList)2 Objects (java.util.Objects)2 ConnectorDeploymentStatus (org.bf2.cos.fleet.manager.model.ConnectorDeploymentStatus)2 ConnectorNamespace (org.bf2.cos.fleet.manager.model.ConnectorNamespace)2 ConnectorStatusSpecBuilder (org.bf2.cos.fleetshard.api.ConnectorStatusSpecBuilder)2 DeploymentSpecBuilder (org.bf2.cos.fleetshard.api.DeploymentSpecBuilder)2 ManagedConnectorBuilder (org.bf2.cos.fleetshard.api.ManagedConnectorBuilder)2 ManagedConnectorSpecBuilder (org.bf2.cos.fleetshard.api.ManagedConnectorSpecBuilder)2 ManagedConnectorStatusBuilder (org.bf2.cos.fleetshard.api.ManagedConnectorStatusBuilder)2 OperatorSelectorBuilder (org.bf2.cos.fleetshard.api.OperatorSelectorBuilder)2 ManagedKafkaCondition (org.bf2.operator.resources.v1alpha1.ManagedKafkaCondition)2 Then (io.cucumber.java.en.Then)1 Context (io.javaoperatorsdk.operator.api.Context)1 Controller (io.javaoperatorsdk.operator.api.Controller)1 DeleteControl (io.javaoperatorsdk.operator.api.DeleteControl)1 ResourceController (io.javaoperatorsdk.operator.api.ResourceController)1 UpdateControl (io.javaoperatorsdk.operator.api.UpdateControl)1 EventSourceManager (io.javaoperatorsdk.operator.processing.event.EventSourceManager)1