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 delete_cluster(cluster_name, region=None): """ Initiate the deletion of a cluster. :param cluster_name: Name of the cluster :type cluster_name: str :param region: AWS Region that the operation corresponds to. :type region: str :rtype: DeleteClusterResponseContent """ try: cluster = Cluster(cluster_name) if not check_cluster_version(cluster): raise BadRequestException( f"Cluster '{cluster_name}' belongs to an incompatible ParallelCluster major version." ) if not cluster.status == CloudFormationStackStatus.DELETE_IN_PROGRESS: # TODO: remove keep_logs logic from delete cluster.delete(keep_logs=False) return DeleteClusterResponseContent( cluster=ClusterInfoSummary( cluster_name=cluster_name, cloudformation_stack_status=CloudFormationStackStatus.DELETE_IN_PROGRESS, cloudformation_stack_arn=cluster.stack.id, region=os.environ.get("AWS_DEFAULT_REGION"), version=cluster.stack.version, cluster_status=cloud_formation_status_to_cluster_status(CloudFormationStackStatus.DELETE_IN_PROGRESS), ) ) except StackNotFoundError: raise NotFoundException( f"Cluster '{cluster_name}' does not exist or belongs to an incompatible ParallelCluster major version. " "In case you have running instances belonging to a deleted cluster please use the DeleteClusterInstances " "API." )
def create_cluster( create_cluster_request_content: Dict, region: str = None, suppress_validators: List[str] = None, validation_failure_level: str = None, dryrun: bool = None, rollback_on_failure: bool = None, ) -> CreateClusterResponseContent: """ Create a managed cluster in a given region. :param create_cluster_request_content: :type create_cluster_request_content: dict | bytes :param region: AWS Region that the operation corresponds to. :type region: str :param suppress_validators: Identifies one or more config validators to suppress. Format: (ALL|type:[A-Za-z0-9]+) :param validation_failure_level: Min validation level that will cause the cluster creation to fail. (Defaults to 'ERROR'.) :param dryrun: Only perform request validation without creating any resource. May be used to validate the cluster configuration. (Defaults to 'false'.) :type dryrun: bool :param rollback_on_failure: When set it automatically initiates a cluster stack rollback on failures. (Defaults to 'true'.) :type rollback_on_failure: bool """ # Set defaults rollback_on_failure = rollback_on_failure in {True, None} validation_failure_level = validation_failure_level or ValidationLevel.ERROR dryrun = dryrun is True create_cluster_request_content = CreateClusterRequestContent.from_dict(create_cluster_request_content) cluster_config = create_cluster_request_content.cluster_configuration if not cluster_config: LOGGER.error("Failed: configuration is required and cannot be empty") raise BadRequestException("configuration is required and cannot be empty") try: cluster = Cluster(create_cluster_request_content.cluster_name, cluster_config) if dryrun: ignored_validation_failures = cluster.validate_create_request( get_validator_suppressors(suppress_validators), FailureLevel[validation_failure_level] ) validation_messages = validation_results_to_config_validation_errors(ignored_validation_failures) raise DryrunOperationException(validation_messages=validation_messages or None) stack_id, ignored_validation_failures = cluster.create( disable_rollback=not rollback_on_failure, validator_suppressors=get_validator_suppressors(suppress_validators), validation_failure_level=FailureLevel[validation_failure_level], ) return CreateClusterResponseContent( ClusterInfoSummary( cluster_name=create_cluster_request_content.cluster_name, cloudformation_stack_status=CloudFormationStackStatus.CREATE_IN_PROGRESS, cloudformation_stack_arn=stack_id, region=os.environ.get("AWS_DEFAULT_REGION"), version=get_installed_version(), cluster_status=cloud_formation_status_to_cluster_status(CloudFormationStackStatus.CREATE_IN_PROGRESS), ), validation_messages=validation_results_to_config_validation_errors(ignored_validation_failures) or None, ) except ConfigValidationError as e: config_validation_messages = validation_results_to_config_validation_errors(e.validation_failures) or None raise CreateClusterBadRequestException( CreateClusterBadRequestExceptionResponseContent( configuration_validation_errors=config_validation_messages, message=str(e) ) )
def update_cluster( update_cluster_request_content: Dict, cluster_name, suppress_validators=None, validation_failure_level=None, region=None, dryrun=None, force_update=None, ): """ Update a cluster managed in a given region. :param update_cluster_request_content: :param cluster_name: Name of the cluster :type cluster_name: str :param suppress_validators: Identifies one or more config validators to suppress. Format: (ALL|type:[A-Za-z0-9]+) :type suppress_validators: List[str] :param validation_failure_level: Min validation level that will cause the update to fail. (Defaults to 'error'.) :type validation_failure_level: dict | bytes :param region: AWS Region that the operation corresponds to. :type region: str :param dryrun: Only perform request validation without creating any resource. May be used to validate the cluster configuration and update requirements. Response code: 200 :type dryrun: bool :param force_update: Force update by ignoring the update validation errors. (Defaults to 'false'.) :type force_update: bool :rtype: UpdateClusterResponseContent """ # Set defaults validation_failure_level = validation_failure_level or ValidationLevel.ERROR dryrun = dryrun is True force_update = force_update is True update_cluster_request_content = UpdateClusterRequestContent.from_dict(update_cluster_request_content) cluster_config = update_cluster_request_content.cluster_configuration if not cluster_config: LOGGER.error("Failed: configuration is required and cannot be empty") raise BadRequestException("configuration is required and cannot be empty") try: cluster = Cluster(cluster_name) if not check_cluster_version(cluster, exact_match=True): raise BadRequestException( f"the update can be performed only with the same ParallelCluster version ({cluster.stack.version}) " "used to create the cluster." ) if dryrun: _, changes, ignored_validation_failures = cluster.validate_update_request( target_source_config=cluster_config, force=force_update, validator_suppressors=get_validator_suppressors(suppress_validators), validation_failure_level=FailureLevel[validation_failure_level], ) change_set, _ = _analyze_changes(changes) validation_messages = validation_results_to_config_validation_errors(ignored_validation_failures) raise DryrunOperationException(change_set=change_set, validation_messages=validation_messages or None) changes, ignored_validation_failures = cluster.update( target_source_config=cluster_config, validator_suppressors=get_validator_suppressors(suppress_validators), validation_failure_level=FailureLevel[validation_failure_level], force=force_update, ) change_set, _ = _analyze_changes(changes) return UpdateClusterResponseContent( cluster=ClusterInfoSummary( cluster_name=cluster_name, cloudformation_stack_status=CloudFormationStackStatus.UPDATE_IN_PROGRESS, cloudformation_stack_arn=cluster.stack.id, region=os.environ.get("AWS_DEFAULT_REGION"), version=cluster.stack.version, cluster_status=cloud_formation_status_to_cluster_status(CloudFormationStackStatus.UPDATE_IN_PROGRESS), ), validation_messages=validation_results_to_config_validation_errors(ignored_validation_failures) or None, change_set=change_set, ) except ConfigValidationError as e: config_validation_messages = validation_results_to_config_validation_errors(e.validation_failures) or None raise UpdateClusterBadRequestException( UpdateClusterBadRequestExceptionResponseContent( configuration_validation_errors=config_validation_messages, message=str(e) ) ) except ClusterUpdateError as e: raise _handle_cluster_update_error(e) except (NotFoundClusterActionError, StackNotFoundError): raise NotFoundException( f"Cluster '{cluster_name}' does not exist or belongs to an incompatible ParallelCluster major version." )