Beispiel #1
0
def list_clusters(region=None, next_token=None, cluster_status=None):
    """
    Retrieve the list of existing clusters managed by the API. Deleted clusters are not listed by default.

    :param region: List clusters deployed to a given AWS Region.
    :type region: str
    :param next_token: Token to use for paginated requests.
    :type next_token: str
    :param cluster_status: Filter by cluster status. (Defaults to all clusters.)
    :type cluster_status: list | bytes

    :rtype: ListClustersResponseContent
    """
    stacks, next_token = AWSApi.instance().cfn.list_pcluster_stacks(next_token=next_token)
    stacks = [ClusterStack(stack) for stack in stacks]

    clusters = []
    for stack in stacks:
        current_cluster_status = cloud_formation_status_to_cluster_status(stack.status)
        if not cluster_status or current_cluster_status in cluster_status:
            cluster_info = ClusterInfoSummary(
                cluster_name=stack.cluster_name,
                cloudformation_stack_status=stack.status,
                cloudformation_stack_arn=stack.id,
                region=os.environ.get("AWS_DEFAULT_REGION"),
                version=stack.version,
                cluster_status=current_cluster_status,
            )
            clusters.append(cluster_info)

    return ListClustersResponseContent(clusters=clusters, next_token=next_token)
    def test_validate_empty_change_set(self, mocker, force):
        mock_aws_api(mocker)
        cluster = Cluster(
            FAKE_NAME,
            stack=ClusterStack({
                "StackName": FAKE_NAME,
                "CreationTime": "2021-06-04 10:23:20.199000+00:00",
                "StackStatus": ClusterStatus.CREATE_COMPLETE,
            }),
            config=OLD_CONFIGURATION,
        )

        mocker.patch("pcluster.aws.cfn.CfnClient.stack_exists",
                     return_value=True)

        if force:
            _, changes, _ = cluster.validate_update_request(
                target_source_config=OLD_CONFIGURATION,
                validator_suppressors={AllValidatorsSuppressor()},
                force=force,
            )
            assert_that(changes).is_length(1)
        else:
            with pytest.raises(
                    BadRequestClusterActionError,
                    match="No changes found in your cluster configuration."):
                cluster.validate_update_request(
                    target_source_config=OLD_CONFIGURATION,
                    validator_suppressors={AllValidatorsSuppressor()},
                    force=force,
                )
 def cluster(self, mocker):
     mocker.patch(
         "pcluster.models.cluster.Cluster.bucket",
         new_callable=PropertyMock(
             return_value=S3Bucket(
                 service_name=FAKE_NAME, stack_name=FAKE_NAME, artifact_directory=ARTIFACT_DIRECTORY
             )
         ),
     )
     return Cluster(
         FAKE_NAME, stack=ClusterStack({"StackName": FAKE_NAME, "CreationTime": "2021-06-04 10:23:20.199000+00:00"})
     )
Beispiel #4
0
 def delete(self, keep_logs: bool = True):
     """Delete cluster preserving log groups."""
     try:
         if keep_logs:
             self._persist_cloudwatch_log_groups()
         self.stack.delete()
         self.__stack = ClusterStack(AWSApi.instance().cfn.describe_stack(
             self.stack_name))
     except StackNotFoundError:
         raise
     except Exception as e:
         self.terminate_nodes()
         raise _cluster_error_mapper(
             e, f"Cluster {self.name} did not delete successfully. {e}")
Beispiel #5
0
    def update(
        self,
        target_source_config: str,
        validator_suppressors: Set[ValidatorSuppressor] = None,
        validation_failure_level: FailureLevel = FailureLevel.ERROR,
        force: bool = False,
    ):
        """
        Update cluster.

        raises ClusterActionError: in case of generic error
        raises ConfigValidationError: if configuration is invalid
        raises ClusterUpdateError: if update is not allowed
        """
        try:
            target_config, changes, ignored_validation_failures = self.validate_update_request(
                target_source_config, validator_suppressors,
                validation_failure_level, force)

            self.config = target_config
            self.__source_config_text = target_source_config

            self._add_version_tag()
            self._upload_config()

            # Create template if not provided by the user
            if not (self.config.dev_settings
                    and self.config.dev_settings.cluster_template):
                self.template_body = CDKTemplateBuilder(
                ).build_cluster_template(
                    cluster_config=self.config,
                    bucket=self.bucket,
                    stack_name=self.stack_name,
                    log_group_name=self.stack.log_group_name,
                )

            # upload cluster artifacts and generated template
            self._upload_artifacts()

            LOGGER.info("Updating stack named: %s", self.stack_name)
            AWSApi.instance().cfn.update_stack_from_url(
                stack_name=self.stack_name,
                template_url=self.bucket.get_cfn_template_url(
                    template_name=PCLUSTER_S3_ARTIFACTS_DICT.get(
                        "template_name")),
                tags=self._get_cfn_tags(),
            )

            self.__stack = ClusterStack(AWSApi.instance().cfn.describe_stack(
                self.stack_name))
            LOGGER.debug("StackId: %s", self.stack.id)
            LOGGER.info("Status: %s", self.stack.status)

            return changes, ignored_validation_failures

        except ClusterActionError as e:
            # It can be a ConfigValidationError or ClusterUpdateError
            raise e
        except Exception as e:
            LOGGER.critical(e)
            raise _cluster_error_mapper(e, f"Cluster update failed.\n{e}")
Beispiel #6
0
 def stack(self):
     """Return the ClusterStack object."""
     if not self.__stack:
         self.__stack = ClusterStack(AWSApi.instance().cfn.describe_stack(
             self.stack_name))
     return self.__stack