Esempio n. 1
0
def do_cli(
    ctx,
    no_interactive,
    location,
    runtime,
    dependency_manager,
    output_dir,
    name,
    app_template,
    no_input,
    extra_context,
    auto_clone=True,
):
    from samcli.commands.init.init_generator import do_generate
    from samcli.commands.init.init_templates import InitTemplates
    from samcli.commands.init.interactive_init_flow import do_interactive

    # check for mutually exclusive parameters
    if location and app_template:
        msg = """
You must not provide both the --location and --app-template parameters.

You can run 'sam init' without any options for an interactive initialization flow, or you can provide one of the following required parameter combinations:
    --name and --runtime and --app-template and --dependency-manager
    --location
        """
        raise UserException(msg)
    # check for required parameters
    if location or (name and runtime and dependency_manager and app_template):
        # need to turn app_template into a location before we generate
        if app_template:
            templates = InitTemplates(no_interactive, auto_clone)
            location = templates.location_from_app_template(
                runtime, dependency_manager, app_template)
            no_input = True
            default_context = {"project_name": name, "runtime": runtime}
            if extra_context is None:
                extra_context = default_context
            else:
                extra_context = _merge_extra_context(default_context,
                                                     extra_context)
        if not output_dir:
            output_dir = "."
        do_generate(location, runtime, dependency_manager, output_dir, name,
                    no_input, extra_context)
    elif no_interactive:
        error_msg = """
ERROR: Missing required parameters, with --no-interactive set.

Must provide one of the following required parameter combinations:
    --name and --runtime and --dependency-manager and --app-template
    --location

You can also re-run without the --no-interactive flag to be prompted for required values.
        """
        raise UserException(error_msg)
    else:
        # proceed to interactive state machine, which will call do_generate
        do_interactive(location, runtime, dependency_manager, output_dir, name,
                       app_template, no_input)
Esempio n. 2
0
def do_cli(
        ctx,
        function_identifier,
        template,
        event,
        no_event,
        env_vars,
        debug_port,  # pylint: disable=R0914
        debug_args,
        debugger_path,
        docker_volume_basedir,
        docker_network,
        log_file,
        skip_pull_image,
        profile,
        region):
    """
    Implementation of the ``cli`` method, just separated out for unit testing purposes
    """

    LOG.debug("local invoke command is called")

    if no_event and event != STDIN_FILE_NAME:
        # Do not know what the user wants. no_event and event both passed in.
        raise UserException(
            "no_event and event cannot be used together. Please provide only one."
        )

    if no_event:
        event_data = "{}"
    else:
        event_data = _get_event(event)

    # Pass all inputs to setup necessary context to invoke function locally.
    # Handler exception raised by the processor for invalid args and print errors
    try:
        with InvokeContext(template_file=template,
                           function_identifier=function_identifier,
                           env_vars_file=env_vars,
                           docker_volume_basedir=docker_volume_basedir,
                           docker_network=docker_network,
                           log_file=log_file,
                           skip_pull_image=skip_pull_image,
                           aws_profile=profile,
                           debug_port=debug_port,
                           debug_args=debug_args,
                           debugger_path=debugger_path,
                           aws_region=region) as context:

            # Invoke the function
            context.local_lambda_runner.invoke(context.function_name,
                                               event=event_data,
                                               stdout=context.stdout,
                                               stderr=context.stderr)

    except FunctionNotFound:
        raise UserException(
            "Function {} not found in template".format(function_identifier))
    except InvalidSamDocumentException as ex:
        raise UserException(str(ex))
Esempio n. 3
0
def _check_sanity_of_stack(stack):
    tags = stack.get("Tags", None)
    outputs = stack.get("Outputs", None)

    # For some edge cases, stack could be in invalid state
    # Check if stack information contains the Tags and Outputs as we expected
    if tags is None or outputs is None:
        stack_state = stack.get("StackName", None)
        msg = (
            f"Stack {SAM_CLI_STACK_NAME} is missing Tags and/or Outputs information and therefore not in a "
            f"healthy state (Current state:{stack_state}). Failing as the stack was likely not created "
            f"by the AWS SAM CLI")
        raise UserException(msg)

    # Sanity check for non-none stack? Sanity check for tag?
    try:
        sam_cli_tag = next(t for t in tags if t["Key"] == "ManagedStackSource")
        if not sam_cli_tag["Value"] == "AwsSamCli":
            msg = (
                "Stack " + SAM_CLI_STACK_NAME +
                " ManagedStackSource tag shows " + sam_cli_tag["Value"] +
                " which does not match the AWS SAM CLI generated tag value of AwsSamCli. "
                "Failing as the stack was likely not created by the AWS SAM CLI."
            )
            raise UserException(msg)
    except StopIteration as ex:
        msg = (
            "Stack  " + SAM_CLI_STACK_NAME +
            " exists, but the ManagedStackSource tag is missing. "
            "Failing as the stack was likely not created by the AWS SAM CLI.")
        raise UserException(msg) from ex
Esempio n. 4
0
    def test_must_record_wrapped_user_exception(self, ContextMock):
        ContextMock.get_current_context.return_value = self.context_mock
        expected_exception = UserException("Something went wrong",
                                           wrapped_from="CustomException")
        expected_exception.exit_code = 1235

        def real_fn():
            raise expected_exception

        with self.assertRaises(UserException) as context:
            track_command(real_fn)()
            self.assertEqual(
                context.exception,
                expected_exception,
                "Must re-raise the original exception object "
                "without modification",
            )

        expected_attrs = _ignore_common_attributes({
            "exitReason": "CustomException",
            "exitCode": 1235
        })
        args, _ = self.telemetry_instance.emit.call_args_list[0]
        metric = args[0]
        assert metric.get_metric_name() == "commandRun"
        self.assertGreaterEqual(metric.get_data().items(),
                                expected_attrs.items())
def do_cli(ctx, template, semantic_version):
    """Publish the application based on command line inputs."""
    try:
        template_data = get_template_data(template)
    except ValueError as ex:
        click.secho("Publish Failed", fg="red")
        raise UserException(str(ex))

    # Override SemanticVersion in template metadata when provided in command input
    if semantic_version and SERVERLESS_REPO_APPLICATION in template_data.get(
            METADATA, {}):
        template_data.get(METADATA).get(
            SERVERLESS_REPO_APPLICATION)[SEMANTIC_VERSION] = semantic_version

    try:
        publish_output = publish_application(template_data)
        click.secho("Publish Succeeded", fg="green")
        click.secho(_gen_success_message(publish_output))
    except InvalidS3UriError:
        click.secho("Publish Failed", fg="red")
        raise UserException(
            "Your SAM template contains invalid S3 URIs. Please make sure that you have uploaded application "
            "artifacts to S3 by packaging the template. See more details in {}"
            .format(SAM_PACKAGE_DOC))
    except ServerlessRepoError as ex:
        click.secho("Publish Failed", fg="red")
        LOG.debug("Failed to publish application to serverlessrepo",
                  exc_info=True)
        error_msg = "{}\nPlease follow the instructions in {}".format(
            str(ex), SAM_PUBLISH_DOC)
        raise UserException(error_msg)

    application_id = publish_output.get("application_id")
    _print_console_link(ctx.region, application_id)
Esempio n. 6
0
def do_cli(ctx, host, port, static_dir, template, env_vars, debug_port, debug_args,  # pylint: disable=R0914
           debugger_path, docker_volume_basedir, docker_network, log_file, skip_pull_image, profile, region):
    """
    Implementation of the ``cli`` method, just separated out for unit testing purposes
    """

    LOG.debug("local start-api command is called")

    # Pass all inputs to setup necessary context to invoke function locally.
    # Handler exception raised by the processor for invalid args and print errors

    try:
        with InvokeContext(template_file=template,
                           function_identifier=None,  # Don't scope to one particular function
                           env_vars_file=env_vars,
                           docker_volume_basedir=docker_volume_basedir,
                           docker_network=docker_network,
                           log_file=log_file,
                           skip_pull_image=skip_pull_image,
                           aws_profile=profile,
                           debug_port=debug_port,
                           debug_args=debug_args,
                           debugger_path=debugger_path,
                           aws_region=region) as invoke_context:

            service = LocalApiService(lambda_invoke_context=invoke_context,
                                      port=port,
                                      host=host,
                                      static_dir=static_dir)
            service.start()

    except NoApisDefined:
        raise UserException("Template does not have any APIs connected to Lambda functions")
    except InvalidSamDocumentException as ex:
        raise UserException(str(ex))
Esempio n. 7
0
def _create_or_get_stack(cloudformation_client):
    try:
        stack = None
        try:
            ds_resp = cloudformation_client.describe_stacks(
                StackName=SAM_CLI_STACK_NAME)
            stacks = ds_resp["Stacks"]
            stack = stacks[0]
            click.echo(
                "\n\tLooking for resources needed for deployment: Found!")
        except ClientError:
            click.echo(
                "\n\tLooking for resources needed for deployment: Not found.")
            stack = _create_stack(
                cloudformation_client
            )  # exceptions are not captured from subcommands
        # Sanity check for non-none stack? Sanity check for tag?
        tags = stack["Tags"]
        try:
            sam_cli_tag = next(t for t in tags
                               if t["Key"] == "ManagedStackSource")
            if not sam_cli_tag["Value"] == "AwsSamCli":
                msg = (
                    "Stack " + SAM_CLI_STACK_NAME +
                    " ManagedStackSource tag shows " + sam_cli_tag["Value"] +
                    " which does not match the AWS SAM CLI generated tag value of AwsSamCli. "
                    "Failing as the stack was likely not created by the AWS SAM CLI."
                )
                raise UserException(msg)
        except StopIteration:
            msg = (
                "Stack  " + SAM_CLI_STACK_NAME +
                " exists, but the ManagedStackSource tag is missing. "
                "Failing as the stack was likely not created by the AWS SAM CLI."
            )
            raise UserException(msg)
        outputs = stack["Outputs"]
        try:
            bucket_name = next(
                o for o in outputs
                if o["OutputKey"] == "SourceBucket")["OutputValue"]
        except StopIteration:
            msg = (
                "Stack " + SAM_CLI_STACK_NAME +
                " exists, but is missing the managed source bucket key. "
                "Failing as this stack was likely not created by the AWS SAM CLI."
            )
            raise UserException(msg)
        # This bucket name is what we would write to a config file
        return bucket_name
    except (ClientError, BotoCoreError) as ex:
        LOG.debug("Failed to create managed resources", exc_info=ex)
        raise ManagedStackError(str(ex))
Esempio n. 8
0
 def location_from_app_template(self, runtime, dependency_manager, app_template):
     options = self.init_options(runtime, dependency_manager)
     try:
         template = next(item for item in options if self._check_app_template(item, app_template))
         if template.get("init_location") is not None:
             return template["init_location"]
         if template.get("directory") is not None:
             return os.path.join(self.repo_path, template["directory"])
         raise UserException("Invalid template. This should not be possible, please raise an issue.")
     except StopIteration:
         msg = "Can't find application template " + app_template + " - check valid values in interactive init."
         raise UserException(msg)
Esempio n. 9
0
 def prompt_for_location(self, runtime, dependency_manager):
     options = self.init_options(runtime, dependency_manager)
     if len(options) == 1:
         template_md = options[0]
     else:
         choices = list(map(str, range(1, len(options) + 1)))
         choice_num = 1
         click.echo("\nAWS quick start application templates:")
         for o in options:
             if o.get("displayName") is not None:
                 msg = "\t" + str(choice_num) + " - " + o.get("displayName")
                 click.echo(msg)
             else:
                 msg = ("\t" + str(choice_num) +
                        " - Default Template for runtime " + runtime +
                        " with dependency manager " + dependency_manager)
                 click.echo(msg)
             choice_num = choice_num + 1
         choice = click.prompt("Template selection",
                               type=click.Choice(choices),
                               show_choices=False)
         template_md = options[int(choice) - 1]  # zero index
     if template_md.get("init_location") is not None:
         return (template_md["init_location"], "hello-world")
     if template_md.get("directory") is not None:
         return (os.path.join(self.repo_path, template_md["directory"]),
                 template_md["appTemplate"])
     raise UserException(
         "Invalid template. This should not be possible, please raise an issue."
     )
def do_cli(args, template_file, stack_name):
    args = args + ("--stack-name", stack_name)

    try:
        execute_command("deploy", args, template_file=template_file)
    except OSError as ex:
        raise UserException(str(ex))
Esempio n. 11
0
def do_cli(args, template_file, s3_bucket):
    args = args + ('--s3-bucket', s3_bucket)

    try:
        execute_command("package", args, template_file)
    except OSError as ex:
        raise UserException(str(ex))
def do_cli(ctx, template):
    """
    Implementation of the ``cli`` method, just separated out for unit testing purposes
    """
    from samtranslator.translator.managed_policy_translator import ManagedPolicyLoader

    from samcli.commands.exceptions import UserException
    from samcli.commands.local.cli_common.user_exceptions import InvalidSamTemplateException
    from .lib.exceptions import InvalidSamDocumentException
    from .lib.sam_template_validator import SamTemplateValidator

    sam_template = _read_sam_file(template)

    iam_client = boto3.client("iam")
    validator = SamTemplateValidator(sam_template,
                                     ManagedPolicyLoader(iam_client))

    try:
        validator.is_valid()
    except InvalidSamDocumentException as e:
        click.secho(
            "Template provided at '{}' was invalid SAM Template.".format(
                template),
            bg="red")
        raise InvalidSamTemplateException(str(e))
    except NoCredentialsError as e:
        raise UserException(
            "AWS Credentials are required. Please configure your credentials.",
            wrapped_from=e.__class__.__name__)

    click.secho("{} is a valid SAM Template".format(template), fg="green")
Esempio n. 13
0
    def _parse_time(time_str, property_name):
        """
        Parse the time from the given string, convert to UTC, and return the datetime object

        Parameters
        ----------
        time_str : str
            The time to parse

        property_name : str
            Name of the property where this time came from. Used in the exception raised if time is not parseable

        Returns
        -------
        datetime.datetime
            Parsed datetime object

        Raises
        ------
        samcli.commands.exceptions.UserException
            If the string cannot be parsed as a timestamp
        """
        if not time_str:
            return None

        parsed = parse_date(time_str)
        if not parsed:
            raise UserException(
                "Unable to parse the time provided by '{}'".format(
                    property_name))

        return to_utc(parsed)
Esempio n. 14
0
 def prompt_for_location(self, runtime, dependency_manager):
     options = self.init_options(runtime, dependency_manager)
     choices = map(str, range(1, len(options) + 1))
     choice_num = 1
     for o in options:
         if o.get("displayName") is not None:
             msg = str(choice_num) + " - " + o.get("displayName")
             click.echo(msg)
         else:
             msg = (str(choice_num) + " - Default Template for runtime " +
                    runtime + " with dependency manager " +
                    dependency_manager)
             click.echo(msg)
         choice_num = choice_num + 1
     choice = click.prompt("Template Selection",
                           type=click.Choice(choices),
                           show_choices=False)
     template_md = options[int(choice) - 1]  # zero index
     if template_md.get("init_location") is not None:
         return template_md["init_location"]
     if template_md.get("directory") is not None:
         return os.path.join(self.repo_path, template_md["directory"])
     raise UserException(
         "Invalid template. This should not be possible, please raise an issue."
     )
Esempio n. 15
0
def do_generate(location, runtime, dependency_manager, output_dir, name,
                no_input, extra_context):
    try:
        generate_project(location, runtime, dependency_manager, output_dir,
                         name, no_input, extra_context)
    except (GenerateProjectFailedError, ArbitraryProjectDownloadFailed) as e:
        raise UserException(str(e))
Esempio n. 16
0
def _merge_extra_context(default_context, extra_context):
    try:
        extra_context_dict = json.loads(extra_context)
    except JSONDecodeError:
        raise UserException(
            "Parse error reading the --extra-content parameter. The value of this parameter must be valid JSON."
        )
    return {**extra_context_dict, **default_context}
Esempio n. 17
0
def do_cli(
        template,  # pylint: disable=too-many-locals
        base_dir,
        build_dir,
        clean,
        use_container,
        manifest_path,
        docker_network,
        skip_pull_image,
        parameter_overrides):
    """
    Implementation of the ``cli`` method
    """

    LOG.debug("'build' command is called")

    if use_container:
        LOG.info("Starting Build inside a container")

    with BuildContext(template,
                      base_dir,
                      build_dir,
                      clean=clean,
                      manifest_path=manifest_path,
                      use_container=use_container,
                      parameter_overrides=parameter_overrides,
                      docker_network=docker_network,
                      skip_pull_image=skip_pull_image) as ctx:

        builder = ApplicationBuilder(
            ctx.function_provider,
            ctx.build_dir,
            ctx.base_dir,
            manifest_path_override=ctx.manifest_path_override,
            container_manager=ctx.container_manager)
        try:
            artifacts = builder.build()
            modified_template = builder.update_template(
                ctx.template_dict, ctx.original_template_path, artifacts)

            move_template(ctx.original_template_path, ctx.output_template_path,
                          modified_template)

            click.secho("\nBuild Succeeded", fg="green")

            msg = gen_success_msg(
                os.path.relpath(ctx.build_dir),
                os.path.relpath(ctx.output_template_path),
                os.path.abspath(
                    ctx.build_dir) == os.path.abspath(DEFAULT_BUILD_DIR))

            click.secho(msg, fg="yellow")

        except (UnsupportedRuntimeException, BuildError,
                UnsupportedBuilderLibraryVersionError) as ex:
            click.secho("Build Failed", fg="red")
            raise UserException(str(ex))
Esempio n. 18
0
def do_cli(ctx, location, runtime, dependency_manager, output_dir, name, no_input):
    """
    Implementation of the ``cli`` method, just separated out for unit testing purposes
    """
    from samcli.commands.exceptions import UserException
    from samcli.local.init import generate_project
    from samcli.local.init.exceptions import GenerateProjectFailedError

    LOG.debug("Init command")
    click.secho("[+] Initializing project structure...", fg="green")

    no_build_msg = """
Project generated: {output_dir}/{name}

Steps you can take next within the project folder
===================================================
[*] Invoke Function: sam local invoke HelloWorldFunction --event event.json
[*] Start API Gateway locally: sam local start-api
""".format(
        output_dir=output_dir, name=name
    )

    build_msg = """
Project generated: {output_dir}/{name}

Steps you can take next within the project folder
===================================================
[*] Install dependencies
[*] Invoke Function: sam local invoke HelloWorldFunction --event event.json
[*] Start API Gateway locally: sam local start-api
""".format(
        output_dir=output_dir, name=name
    )

    no_build_step_required = (
        "python",
        "python3.7",
        "python3.6",
        "python2.7",
        "nodejs",
        "nodejs4.3",
        "nodejs6.10",
        "nodejs8.10",
        "nodejs10.x",
        "ruby2.5",
    )
    next_step_msg = no_build_msg if runtime in no_build_step_required else build_msg

    try:
        generate_project(location, runtime, dependency_manager, output_dir, name, no_input)
        if not location:
            click.secho(next_step_msg, bold=True)
            click.secho("Read {name}/README.md for further instructions\n".format(name=name), bold=True)
        click.secho("[*] Project initialization is now complete", fg="green")
    except GenerateProjectFailedError as e:
        raise UserException(str(e))
Esempio n. 19
0
 def _init_options_from_bundle(self, runtime, dependency_manager):
     for mapping in list(itertools.chain(*(RUNTIME_DEP_TEMPLATE_MAPPING.values()))):
         if runtime in mapping["runtimes"] or any([r.startswith(runtime) for r in mapping["runtimes"]]):
             if not dependency_manager or dependency_manager == mapping["dependency_manager"]:
                 mapping["appTemplate"] = "hello-world"  # when bundled, use this default template name
                 return [mapping]
     msg = "Lambda Runtime {} and dependency manager {} does not have an available initialization template.".format(
         runtime, dependency_manager
     )
     raise UserException(msg)
Esempio n. 20
0
    def test_must_record_user_exception(self, ContextMock):
        ContextMock.get_current_context.return_value = self.context_mock
        expected_exception = UserException("Something went wrong")
        expected_exception.exit_code = 1235

        def real_fn():
            raise expected_exception

        with self.assertRaises(UserException) as context:
            track_command(real_fn)()
            self.assertEquals(context.exception, expected_exception, "Must re-raise the original exception object "
                                                                     "without modification")

        expected_attrs = _cmd_run_attrs({
            "exitReason": "UserException",
            "exitCode": 1235
        })
        self.telemetry_instance.emit.assert_has_calls([
            call("commandRun", expected_attrs)
        ])
Esempio n. 21
0
def do_cli(ctx, template):
    """Publish the application based on command line inputs."""
    try:
        template_data = get_template_data(template)
    except ValueError as ex:
        click.secho("Publish Failed", fg='red')
        raise UserException(str(ex))

    try:
        publish_output = publish_application(template_data)
        click.secho("Publish Succeeded", fg="green")
        click.secho(_gen_success_message(publish_output), fg="yellow")
    except ServerlessRepoError as ex:
        click.secho("Publish Failed", fg='red')
        raise UserException(str(ex))
    except ClientError as ex:
        click.secho("Publish Failed", fg='red')
        raise _wrap_s3_uri_exception(ex)

    application_id = publish_output.get('application_id')
    _print_console_link(ctx.region, application_id)
Esempio n. 22
0
    def _get_resource_id_from_stack(cfn_client, stack_name, logical_id):
        """
        Given the LogicalID of a resource, call AWS CloudFormation to get physical ID of the resource within
        the specified stack.

        Parameters
        ----------
        cfn_client : boto3.session.Session.client
            CloudFormation client provided by AWS SDK

        stack_name : str
            Name of the stack to query

        logical_id : str
            LogicalId of the resource

        Returns
        -------
        str
            Physical ID of the resource

        Raises
        ------
        samcli.commands.exceptions.UserException
            If the stack or resource does not exist
        """

        LOG.debug(
            "Getting resource's PhysicalId from AWS CloudFormation stack. StackName=%s, LogicalId=%s",
            stack_name,
            logical_id,
        )

        try:
            response = cfn_client.describe_stack_resource(
                StackName=stack_name, LogicalResourceId=logical_id)

            LOG.debug("Response from AWS CloudFormation %s", response)
            return response["StackResourceDetail"]["PhysicalResourceId"]

        except botocore.exceptions.ClientError as ex:
            LOG.debug(
                "Unable to fetch resource name from CloudFormation Stack: "
                "StackName=%s, ResourceLogicalId=%s, Response=%s",
                stack_name,
                logical_id,
                ex.response,
            )

            # The exception message already has a well formatted error message that we can surface to user
            raise UserException(
                str(ex), wrapped_from=ex.response["Error"]["Code"]) from ex
Esempio n. 23
0
def do_cli(ctx, function_identifier, template, event, env_vars, debug_port,
           debug_args, docker_volume_basedir, docker_network, log_file,
           skip_pull_image, profile):
    """
    Implementation of the ``cli`` method, just separated out for unit testing purposes
    """

    LOG.debug("local invoke command is called")

    event_data = _get_event(event)

    # Pass all inputs to setup necessary context to invoke function locally.
    # Handler exception raised by the processor for invalid args and print errors
    try:

        with InvokeContext(template_file=template,
                           function_identifier=function_identifier,
                           env_vars_file=env_vars,
                           debug_port=debug_port,
                           debug_args=debug_args,
                           docker_volume_basedir=docker_volume_basedir,
                           docker_network=docker_network,
                           log_file=log_file,
                           skip_pull_image=skip_pull_image,
                           aws_profile=profile) as context:

            # Invoke the function
            context.local_lambda_runner.invoke(context.function_name,
                                               event=event_data,
                                               stdout=context.stdout,
                                               stderr=context.stderr)

    except FunctionNotFound:
        raise UserException(
            "Function {} not found in template".format(function_identifier))
    except InvalidSamDocumentException as ex:
        raise UserException(str(ex))
Esempio n. 24
0
def manage_stack(profile, region):
    outputs = manage_cloudformation_stack(profile=None,
                                          region=region,
                                          stack_name=SAM_CLI_STACK_NAME,
                                          template_body=_get_stack_template())

    try:
        bucket_name = next(o for o in outputs
                           if o["OutputKey"] == "SourceBucket")["OutputValue"]
    except StopIteration as ex:
        msg = (
            "Stack " + SAM_CLI_STACK_NAME +
            " exists, but is missing the managed source bucket key. "
            "Failing as this stack was likely not created by the AWS SAM CLI.")
        raise UserException(msg) from ex
    # This bucket name is what we would write to a config file
    return bucket_name
Esempio n. 25
0
def do_generate(location, runtime, dependency_manager, output_dir, name, no_input, extra_context):
    no_build_msg = """
Project generated: {output_dir}/{name}

Steps you can take next within the project folder
===================================================
[*] Invoke Function: sam local invoke HelloWorldFunction --event event.json
[*] Start API Gateway locally: sam local start-api
""".format(
        output_dir=output_dir, name=name
    )

    build_msg = """
Project generated: {output_dir}/{name}

Steps you can take next within the project folder
===================================================
[*] Install dependencies
[*] Invoke Function: sam local invoke HelloWorldFunction --event event.json
[*] Start API Gateway locally: sam local start-api
""".format(
        output_dir=output_dir, name=name
    )

    no_build_step_required = (
        "python",
        "python3.7",
        "python3.6",
        "python2.7",
        "nodejs",
        "nodejs4.3",
        "nodejs6.10",
        "nodejs8.10",
        "nodejs10.x",
        "ruby2.5",
    )
    next_step_msg = no_build_msg if runtime in no_build_step_required else build_msg
    try:
        generate_project(location, runtime, dependency_manager, output_dir, name, no_input, extra_context)
        if not location:
            click.secho(next_step_msg, bold=True)
            click.secho("Read {name}/README.md for further instructions\n".format(name=name), bold=True)
            click.secho("[*] Project initialization is now complete", fg="green")
    except GenerateProjectFailedError as e:
        raise UserException(str(e))
Esempio n. 26
0
def do_cli(ctx, location, runtime, output_dir, name, no_input):
    """
    Implementation of the ``cli`` method, just separated out for unit testing purposes
    """
    LOG.debug("Init command")
    click.secho("[+] Initializing project structure...", fg="green")

    try:
        generate_project(location, runtime, output_dir, name, no_input)
        # Custom templates can implement their own visual cues so let's not repeat the message
        if not location:
            click.secho(
                "[SUCCESS] - Read {name}/README.md for further instructions on how to proceed"
                .format(name=name),
                bold=True)
        click.secho("[*] Project initialization is now complete", fg="green")
    except GenerateProjectFailedError as e:
        raise UserException(str(e))
Esempio n. 27
0
    def __enter__(self):
        try:
            self._template_dict = get_template_data(self._template_file)
        except ValueError as ex:
            raise UserException(str(ex))

        self._function_provider = SamFunctionProvider(self._template_dict, self._parameter_overrides)

        if not self._base_dir:
            # Base directory, if not provided, is the directory containing the template
            self._base_dir = str(pathlib.Path(self._template_file).resolve().parent)

        self._build_dir = self._setup_build_dir(self._build_dir, self._clean)

        if self._use_container:
            self._container_manager = ContainerManager(docker_network_id=self._docker_network,
                                                       skip_pull_image=self._skip_pull_image)

        return self
Esempio n. 28
0
def _get_cookiecutter_template_context(name, runtime, extra_context):
    default_context = {}
    extra_context_dict = {}

    if runtime is not None:
        default_context["runtime"] = runtime

    if name is not None:
        default_context["project_name"] = name

    if extra_context is not None:
        try:
            extra_context_dict = json.loads(extra_context)
        except JSONDecodeError:
            raise UserException(
                "Parse error reading the --extra-context parameter. The value of this parameter must be valid JSON."
            )

    return {**extra_context_dict, **default_context}
Esempio n. 29
0
def do_cli(ctx, template):
    """
    Implementation of the ``cli`` method, just separated out for unit testing purposes
    """

    sam_template = _read_sam_file(template)

    iam_client = boto3.client('iam')
    validator = SamTemplateValidator(sam_template, ManagedPolicyLoader(iam_client))

    try:
        validator.is_valid()
    except InvalidSamDocumentException as e:
        click.secho("Template provided at '{}' was invalid SAM Template.".format(template), bg='red')
        raise InvalidSamTemplateException(str(e))
    except NoCredentialsError as e:
        raise UserException("AWS Credentials are required. Please configure your credentials.")

    click.secho("{} is a valid SAM Template".format(template), fg='green')
Esempio n. 30
0
    def run_interactive_flows(self) -> Dict:
        """
        prompt the user a series of questions' flows and gather the answers to create the cookiecutter context.
        The questions are identified by keys. If multiple questions, whether within the same flow or across
        different flows, have the same key, the last question will override the others and we will get only the
        answer of this question.

        Raises:
            UserException(ClickException) if anything went wrong.

        Returns:
            A Dictionary in the form of {question.key: answer} representing user's answers to the flows' questions
        """
        try:
            context: Dict[str, Any] = {}
            for flow in self._interactive_flows:
                context = flow.run(context)
            return context
        except Exception as e:
            raise UserException(str(e),
                                wrapped_from=e.__class__.__name__) from e