Ejemplo n.º 1
0
def create_handler(
    session: Optional[SessionProxy],
    request: ResourceHandlerRequest,
    callback_context: MutableMapping[str, Any],
) -> ProgressEvent:
    model = request.desiredResourceState
    progress: ProgressEvent = ProgressEvent(
        status=OperationStatus.IN_PROGRESS,
        resourceModel=model,
    )

    if callback_context.get('pending'):
        return read_handler(session, request, callback_context)
    
    try:
        client = session.client("transcribe")
        if model.Phrases is not None:
            client.create_vocabulary(
                VocabularyName=model.VocabularyName,
                LanguageCode=model.LanguageCode,
                Phrases=model.Phrases
            )
        else:
            client.create_vocabulary(
                VocabularyName=model.VocabularyName,
                LanguageCode=model.LanguageCode,
                VocabularyFileUri=model.VocabularyFileUri
            )
    except client.exceptions.ConflictException as e:
        raise exceptions.AlreadyExists(type_name=TYPE_NAME, identifier=model.VocabularyName)
    except Exception as e:
        raise exceptions.InternalFailure(f"{e}")

    return read_handler(session, request, callback_context)
def create_handler(
        session: Optional[SessionProxy],
        request: ResourceHandlerRequest,
        callback_context: MutableMapping[str, Any],  # pylint: disable=unused-argument
) -> ProgressEvent:
    """This function is triggered by the CloudFormation CREATE event
    and will set the StepConcurrency level from the default of 1
    to the new provided value within the up to the max of 256. It
    will also add a tag to the cluster in order to keep track of
    the resource.

    Attributes:
        session (Optional[SessionProxy]): The session proxy for connecting
            to the needed AWS API client
        cluster_id (str): The unique ID of the cluster to get details from
        callback_context (MutableMapping[str, Any]): Use to store any state
            between re-invocation via IN_PROGRESS

    Returns:
        ProgressEvent: An event with the status of the action
    """
    LOG.info("Create Handler")
    model = request.desiredResourceState
    progress: ProgressEvent = ProgressEvent(
        status=OperationStatus.IN_PROGRESS,
        resourceModel=model,
    )
    model.UID = "cluster:" + model.ClusterId
    model.StepConcurrencyLevel = int(model.StepConcurrencyLevel)
    uid = get_uid(session, model.ClusterId)
    LOG.info("UID: %s", uid)
    if uid == model.UID:
        raise exceptions.AlreadyExists(TYPE_NAME, model.ClusterId)
    if model.StepConcurrencyLevel < 1 or model.StepConcurrencyLevel > 256:
        raise exceptions.InvalidRequest(
            f"Step Concurency Level must be between 1 and 256, \
                {model.StepConcurrencyLevel} was given.")
    try:
        client = session.client('emr')
        LOG.info("Setting concurrency to %s for cluster %s",
                 model.StepConcurrencyLevel, model.ClusterId)
        response = client.modify_cluster(ClusterId=model.ClusterId,
                                         StepConcurrencyLevel=int(
                                             model.StepConcurrencyLevel))
        LOG.info("RESPONSE TO SET CONCURRENCY:")
        LOG.info(response)
        LOG.info("Setting UID tag to %s", model.ClusterId)
        tag_response = client.add_tags(ResourceId=model.ClusterId,
                                       Tags=[{
                                           "Key": "StepConcurrencyUID",
                                           "Value": model.UID
                                       }])
        LOG.info("RESPONSE TO ADD TAGS:")
        LOG.info(tag_response)
        progress.status = OperationStatus.SUCCESS
    except Exception as unexpected_exception:
        LOG.error(str(unexpected_exception))
        raise exceptions.InternalFailure(
            f"Failed Create: {str(unexpected_exception)}")
    return progress
Ejemplo n.º 3
0
def _validate_inline_label_for_create(afd_client, label):
    if label.Name is None:
        raise exceptions.InvalidRequest(
            "Error occurred: inline labels must include Name!")

    get_labels_worked, _ = validation_helpers.check_if_get_labels_succeeds(
        afd_client, label.Name)
    if get_labels_worked:
        raise exceptions.AlreadyExists("label", label.Name)

    common_helpers.put_inline_label(afd_client, label)
Ejemplo n.º 4
0
def _validate_inline_entity_type_for_create(afd_client, entity_type):
    if entity_type.Name is None:
        raise exceptions.InvalidRequest(
            "Error occurred: inline entity types must include Name!")

    get_entity_types_worked, _ = validation_helpers.check_if_get_entity_types_succeeds(
        afd_client, entity_type.Name)
    if get_entity_types_worked:
        raise exceptions.AlreadyExists("entity_type", entity_type.Name)

    common_helpers.put_inline_entity_type(afd_client, entity_type)
Ejemplo n.º 5
0
def _validate_inline_event_variable_for_create(afd_client, event_variable):
    if event_variable.Name is None:
        raise exceptions.InvalidRequest(
            "Error occurred: inline event variables must include Name!")

    get_variables_worked, _ = validation_helpers.check_if_get_variables_succeeds(
        afd_client, event_variable.Name)
    if get_variables_worked:
        raise exceptions.AlreadyExists("event_variable", event_variable.Name)

    common_helpers.create_inline_event_variable(
        frauddetector_client=afd_client, event_variable=event_variable)
def execute_create_detector_handler_work(session: SessionProxy,
                                         model: models.ResourceModel,
                                         progress: ProgressEvent):
    afd_client = client_helpers.get_afd_client(session)

    # For contract_create_duplicate, we need to fail if the resource already exists
    get_detectors_works, _ = validation_helpers.check_if_get_detectors_succeeds(
        afd_client, model.DetectorId)
    if get_detectors_works:
        raise exceptions.AlreadyExists("detector", model.DetectorId)

    # For contract_invalid_create, fail if any read-only properties are present
    if model.Arn is not None or model.CreatedTime is not None or model.LastUpdatedTime is not None:
        raise exceptions.InvalidRequest(
            "Error occurred: cannot create read-only properties.")

    # Validate existence of referenced resources, validate and create inline resources (except for Rules, Detector, DV)
    #   Also check existence of external models
    # TODO: split out creation from validation
    create_worker_helpers.validate_dependencies_for_detector_create(
        afd_client, model)

    # Create Detector, Rules, Detector Version ID
    model_helpers.put_detector_for_model(afd_client, model)
    rule_dicts = create_worker_helpers.create_rules_for_detector_resource(
        afd_client, model)
    detector_version_response = create_worker_helpers.create_detector_version_for_detector_resource(
        afd_client, model, rule_dicts)

    # The DV will be created as draft by default, so if the desired status is not draft, update DV status
    if model.DetectorVersionStatus != DRAFT_STATUS:
        api_helpers.call_update_detector_version_status(
            frauddetector_client=afd_client,
            detector_id=model.DetectorId,
            detector_version_id=detector_version_response.get(
                "detectorVersionId", "1"),  # version here should be 1
            status=model.DetectorVersionStatus,
        )

    # after satisfying all contract tests and AFD requirements, get the resulting model
    model = read_worker_helpers.validate_detector_exists_and_return_detector_resource_model(
        afd_client, model)
    progress.resourceModel = model
    progress.status = OperationStatus.SUCCESS

    LOG.info(f"Returning Progress with status: {progress.status}")
    return progress
def execute_create_label_handler_work(session, model, progress):
    afd_client = client_helpers.get_afd_client(session)

    # For contract_create_duplicate, we need to fail if resource already exists
    get_labels_works, _ = validation_helpers.check_if_get_labels_succeeds(afd_client, model.Name)
    if get_labels_works:
        raise exceptions.AlreadyExists("label", model.Name)

    # For contract_invalid_create, fail if any read-only properties are present
    if model.Arn is not None or model.CreatedTime is not None or model.LastUpdatedTime is not None:
        raise exceptions.InvalidRequest("Error occurred: cannot create read-only properties.")

    # API does not handle 'None' property gracefully
    if model.Tags is None:
        del model.Tags

    # after satisfying contract call put label
    return common_helpers.put_label_and_return_progress(afd_client, model, progress)
def execute_create_event_type_handler_work(session, model, progress):
    afd_client = client_helpers.get_afd_client(session)

    # For contract_create_duplicate, we need to fail if the resource already exists
    get_event_type_works, _ = validation_helpers.check_if_get_event_types_succeeds(
        afd_client, model.Name)
    if get_event_type_works:
        raise exceptions.AlreadyExists("event_type", model.Name)

    # For contract_invalid_create, fail if any read-only properties are present
    if model.Arn is not None or model.CreatedTime is not None or model.LastUpdatedTime is not None:
        raise exceptions.InvalidRequest(
            "Error occurred: cannot create read-only properties.")

    # Validate existence of referenced resources, validate and create inline resources
    create_worker_helpers.validate_dependencies_for_create(afd_client, model)

    # after satisfying contract call put event_type
    return common_helpers.put_event_type_and_return_progress(
        afd_client, model, progress)
def create_handler(
    session: Optional[SessionProxy],
    request: ResourceHandlerRequest,
    callback_context: MutableMapping[str, Any],
) -> ProgressEvent:
    model = request.desiredResourceState
    progress: ProgressEvent = ProgressEvent(
        status=OperationStatus.IN_PROGRESS,
        resourceModel=model,
    )
    # TODO: put code here
    if model.Fingerprint:
        progress.status = OperationStatus.FAILED
        progress.errorCode = HandlerErrorCode.InvalidRequest
        progress.message = "Fingerprint is read-only - should not be specified in a request"
        progress.resourceModel.PublicKey = None
        return progress

    # Example:
    try:
        if isinstance(session, SessionProxy):
            ec2 = session.client('ec2')
            try:
                response = ec2.import_key_pair(
                    KeyName=model.KeyName, PublicKeyMaterial=model.PublicKey)
            except ClientError as e:
                if e.response.get(
                        "Error", {}).get("Code") == "InvalidKeyPair.Duplicate":
                    raise exceptions.AlreadyExists(TYPE_NAME, model.KeyName)
                else:
                    raise
            model.Fingerprint = response['KeyFingerprint']
            model.PublicKey = None
            progress.status = OperationStatus.SUCCESS
            return progress
    except TypeError as e:
        # exceptions module lets CloudFormation know the type of failure that occurred
        raise exceptions.InternalFailure(f"was not expecting type {e}")
        # this can also be done by returning a failed progress event
        # return ProgressEvent.failed(HandlerErrorCode.InternalFailure, f"was not expecting type {e}")
    return progress
Ejemplo n.º 10
0
def create_handler(
    session: Optional[SessionProxy],
    request: ResourceHandlerRequest,
    callback_context: MutableMapping[str, Any],
) -> ProgressEvent:
    model = request.desiredResourceState
    progress: ProgressEvent = ProgressEvent(
        status=OperationStatus.IN_PROGRESS, resourceModel=model,
    )
    LOG.debug(f"Create invoke \n\n{request.__dict__}\n\n{callback_context}")
    physical_resource_id, manifest_file, manifest_dict = handler_init(
        model, session, request.logicalResourceIdentifier, request.clientRequestToken
    )
    model.CfnId = encode_id(
        request.clientRequestToken,
        model.ClusterName,
        model.Namespace,
        manifest_dict["kind"],
    )
    if not callback_context:
        LOG.debug("1st invoke")
        progress.callbackDelaySeconds = 1
        progress.callbackContext = {"init": "complete"}
        return progress
    if "stabilizing" in callback_context:
        if (
            callback_context["stabilizing"].startswith("/apis/batch")
            and "cronjobs" not in callback_context["stabilizing"]
        ):
            if stabilize_job(
                model.Namespace, callback_context["name"], model.ClusterName, session
            ):
                progress.status = OperationStatus.SUCCESS
            progress.callbackContext = callback_context
            progress.callbackDelaySeconds = 30
            LOG.debug(f"stabilizing: {progress.__dict__}")
            return progress
    try:
        outp = run_command(
            "kubectl create --save-config -o json -f %s -n %s"
            % (manifest_file, model.Namespace),
            model.ClusterName,
            session,
        )
        build_model(json.loads(outp), model)
    except Exception as e:
        if "Error from server (AlreadyExists)" not in str(e):
            raise
        LOG.debug("checking whether this is a duplicate request....")
        if not get_model(model, session):
            raise exceptions.AlreadyExists(TYPE_NAME, model.CfnId)
    if model.SelfLink.startswith("/apis/batch") and "cronjobs" not in model.SelfLink:
        callback_context["stabilizing"] = model.SelfLink
        callback_context["name"] = model.Name
        progress.callbackContext = callback_context
        progress.callbackDelaySeconds = 30
        LOG.debug(f"need to stabilize: {progress.__dict__}")
        return progress
    progress.status = OperationStatus.SUCCESS
    LOG.debug(f"success {progress.__dict__}")
    return progress