Skip to content

Commit

Permalink
Merge from aws/aws-sam-cli/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
aws-sam-cli-bot authored Jun 29, 2022
2 parents becc8c4 + 9d15aa8 commit d2ded65
Show file tree
Hide file tree
Showing 128 changed files with 3,403 additions and 656 deletions.
6 changes: 3 additions & 3 deletions requirements/base.txt
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
chevron~=0.12
click~=7.1
Flask~=1.1.2
Flask~=1.1.4
#Need to add Schemas latest SDK.
boto3>=1.19.5,==1.*
jmespath~=0.10.0
PyYAML~=5.3
cookiecutter~=1.7.2
cookiecutter~=2.1.1
aws-sam-translator==1.46.0
#docker minor version updates can include breaking changes. Auto update micro version only.
docker~=4.2.0
dateparser~=1.0
requests==2.25.1
serverlessrepo==0.1.10
aws_lambda_builders==1.17.0
aws_lambda_builders==1.18.0
tomlkit==0.7.2
watchdog==2.1.2

Expand Down
27 changes: 11 additions & 16 deletions requirements/reproducible-linux.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ attrs==20.3.0 \
--hash=sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6 \
--hash=sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700
# via jsonschema
aws-lambda-builders==1.17.0 \
--hash=sha256:1d296dc521f3f3f356ffbe290ca204713b1e8a24612262cf1c9283ffe34dc443 \
--hash=sha256:3eb7ca5ab71761766586db080a8b80ab81346b307fa72d5cea64ccd69fb41efe \
--hash=sha256:abae4ccfc419fc5cd8eebd4cc81e335ec7610f53804ce1aa2b655159ce339610
aws-lambda-builders==1.18.0 \
--hash=sha256:555c1bb72bab633deeb806cc347b40ed865d63166e536c89ff71f0ba739577b1 \
--hash=sha256:c0bd4b4288f0aa9cba27493065f5fb986425b5b49620b93a391620403eeb97e0 \
--hash=sha256:c5235699d36b8edda7e649fbc3a23ed868eda1e15c4a83528df33939bdb75754
# via aws-sam-cli (setup.py)
aws-sam-translator==1.46.0 \
--hash=sha256:03cb83135c98b1c47bf2b3c15507808c7e06d4717a3ca3da1cee6e7ebcb5282b \
Expand Down Expand Up @@ -78,9 +78,9 @@ click==7.1.2 \
# aws-sam-cli (setup.py)
# cookiecutter
# flask
cookiecutter==1.7.3 \
--hash=sha256:6b9a4d72882e243be077a7397d0f1f76fe66cf3df91f3115dbb5330e214fa457 \
--hash=sha256:f8671531fa96ab14339d0c59b4f662a4f12a2ecacd94a0f70a3500843da588e2
cookiecutter==2.1.1 \
--hash=sha256:9f3ab027cec4f70916e28f03470bdb41e637a3ad354b4d65c765d93aad160022 \
--hash=sha256:f3982be8d9c53dac1261864013fdec7f83afd2e42ede6f6dd069c5e149c540d5
# via aws-sam-cli (setup.py)
dateparser==1.0.0 \
--hash=sha256:159cc4e01a593706a15cd4e269a0b3345edf3aef8bf9278a57dac8adf5bf1e4a \
Expand All @@ -90,9 +90,9 @@ docker==4.2.2 \
--hash=sha256:03a46400c4080cb6f7aa997f881ddd84fef855499ece219d75fbdb53289c17ab \
--hash=sha256:26eebadce7e298f55b76a88c4f8802476c5eaddbdbe38dbc6cce8781c47c9b54
# via aws-sam-cli (setup.py)
flask==1.1.2 \
--hash=sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060 \
--hash=sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557
flask==1.1.4 \
--hash=sha256:0fbeb6180d383a9186d0d6ed954e0042ad9f18e0e8de088b2b419d526927d196 \
--hash=sha256:c34f04500f2cbbea882b1acb02002ad6fe6b7ffa64a6164577995657f50aed22
# via aws-sam-cli (setup.py)
idna==2.10 \
--hash=sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6 \
Expand Down Expand Up @@ -201,10 +201,6 @@ markupsafe==2.0.1 \
# via
# aws-sam-cli (setup.py)
# jinja2
poyo==0.5.0 \
--hash=sha256:3e2ca8e33fdc3c411cd101ca395668395dd5dc7ac775b8e809e3def9f9fe041a \
--hash=sha256:e26956aa780c45f011ca9886f044590e2d8fd8b61db7b1c1cf4e0869f48ed4dd
# via cookiecutter
pyrsistent==0.17.3 \
--hash=sha256:2e636185d9eb976a18a8a8e96efce62f2905fea90041958d8cc2a189756ebf3e
# via jsonschema
Expand Down Expand Up @@ -254,6 +250,7 @@ pyyaml==5.4.1 \
--hash=sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0
# via
# aws-sam-cli (setup.py)
# cookiecutter
# serverlessrepo
regex==2021.9.30 \
--hash=sha256:0de8ad66b08c3e673b61981b9e3626f8784d5564f8c3928e2ad408c0eb5ac38c \
Expand Down Expand Up @@ -319,8 +316,6 @@ six==1.15.0 \
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced
# via
# aws-lambda-builders
# cookiecutter
# docker
# jsonschema
# python-dateutil
Expand Down
2 changes: 1 addition & 1 deletion samcli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
SAM CLI version
"""

__version__ = "1.52.0"
__version__ = "1.53.0"
70 changes: 70 additions & 0 deletions samcli/commands/_utils/command_exception_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
"""
Contains method decorator which can be used to convert common exceptions into click exceptions
which will end exeecution gracefully
"""
from functools import wraps
from typing import Callable, Dict, Any, Optional

from botocore.exceptions import NoRegionError, ClientError

from samcli.commands._utils.options import parameterized_option
from samcli.commands.exceptions import CredentialsError, RegionError
from samcli.lib.utils.boto_utils import get_client_error_code


@parameterized_option
def command_exception_handler(f, additional_mapping: Optional[Dict[Any, Callable[[Any], None]]] = None):
"""
This function returns a wrapped function definition, which handles configured exceptions gracefully
"""

def decorator_command_exception_handler(func):
@wraps(func)
def wrapper_command_exception_handler(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as ex:
exception_type = type(ex)

# check if there is a custom handling defined
exception_handler = (additional_mapping or {}).get(exception_type)
if exception_handler:
exception_handler(ex)

# if no custom handling defined search for default handlers
exception_handler = COMMON_EXCEPTION_HANDLER_MAPPING.get(exception_type)
if exception_handler:
exception_handler(ex)

# if no handler defined, raise the exception
raise ex

return wrapper_command_exception_handler

return decorator_command_exception_handler(f)


def _handle_no_region_error(ex: NoRegionError) -> None:
raise RegionError(
"No region information found. Please provide --region parameter or configure default region settings. "
"\nFor more information please visit https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/"
"setup-credentials.html#setup-credentials-setting-region"
)


def _handle_client_errors(ex: ClientError) -> None:
error_code = get_client_error_code(ex)

if error_code in ("ExpiredToken", "ExpiredTokenException"):
raise CredentialsError(
"Your credential configuration is invalid or has expired token value. \nFor more information please "
"visit: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html"
)

raise ex


COMMON_EXCEPTION_HANDLER_MAPPING: Dict[Any, Callable] = {
NoRegionError: _handle_no_region_error,
ClientError: _handle_client_errors,
}
3 changes: 1 addition & 2 deletions samcli/commands/_utils/experimental.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class ExperimentalFlag:
"""Class for storing all experimental related ConfigEntries"""

All = ExperimentalEntry("experimentalAll", EXPERIMENTAL_ENV_VAR_PREFIX + "FEATURES")
Accelerate = ExperimentalEntry("experimentalAccelerate", EXPERIMENTAL_ENV_VAR_PREFIX + "ACCELERATE")
Esbuild = ExperimentalEntry("experimentalEsbuild", EXPERIMENTAL_ENV_VAR_PREFIX + "ESBUILD")


Expand Down Expand Up @@ -240,7 +239,7 @@ def prompt_experimental(
if is_experimental_enabled(config_entry):
update_experimental_context()
return True
confirmed = click.confirm(prompt, default=False)
confirmed = click.confirm(Colored().yellow(prompt), default=False)
if confirmed:
set_experimental(config_entry=config_entry, enabled=True)
update_experimental_context()
Expand Down
14 changes: 7 additions & 7 deletions samcli/commands/_utils/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,12 +367,11 @@ def common_observability_click_options():
"-t",
is_flag=True,
help="Tail events. This will ignore the end time argument and continue to fetch events as they "
"become available. [Beta Feature] If in beta --tail without a --name will pull from all possible resources",
"become available. If option --tail without a --name will pull from all possible resources",
),
click.option(
"--output",
help="""
[Beta Feature]
The formatting style of the command output. Following options are available:\n
TEXT: Prints information as regular text with some formatting (default option)\n
JSON: Prints each line as JSON without formatting
Expand Down Expand Up @@ -474,19 +473,20 @@ def stack_name_option(f, required=False, callback=None):
return stack_name_click_option(required, callback)(f)


def s3_bucket_click_option(guided):
callback = None if guided else partial(artifact_callback, artifact=ZIP)
def s3_bucket_click_option(disable_callback):
callback = None if disable_callback else partial(artifact_callback, artifact=ZIP)

return click.option(
"--s3-bucket",
required=False,
callback=callback,
help="The name of the S3 bucket where this command uploads the artifacts that are referenced in your template.",
callback=callback,
)


@parameterized_option
def s3_bucket_option(f, guided=False):
return s3_bucket_click_option(guided)(f)
def s3_bucket_option(f, disable_callback=False):
return s3_bucket_click_option(disable_callback)(f)


def build_dir_click_option():
Expand Down
6 changes: 5 additions & 1 deletion samcli/commands/build/build_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,10 @@ def manifest_path_override(self) -> Optional[str]:
def mode(self) -> Optional[str]:
return self._mode

@property
def use_base_dir(self) -> bool:
return self._use_raw_codeuri

@property
def resources_to_build(self) -> ResourcesToBuildCollector:
"""
Expand Down Expand Up @@ -562,7 +566,7 @@ def _is_function_buildable(function: Function):
docker_context = cast(str, metadata.get("DockerContext", ""))
if not dockerfile or not docker_context:
LOG.debug(
"Skip Building %s function, as it does not contain either Dockerfile or DockerContext "
"Skip Building %s function, as it is missing either Dockerfile or DockerContext "
"metadata properties.",
function.full_path,
)
Expand Down
32 changes: 30 additions & 2 deletions samcli/commands/delete/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import logging

from typing import Optional
import click
from samcli.cli.main import aws_creds_options, common_options, pass_context, print_cmdline_args

Expand Down Expand Up @@ -63,12 +64,26 @@
is_flag=True,
required=False,
)
@click.option(
"--s3-bucket",
help=("The S3 bucket path you want to delete."),
type=click.STRING,
default=None,
required=False,
)
@click.option(
"--s3-prefix",
help=("The S3 prefix you want to delete"),
type=click.STRING,
default=None,
required=False,
)
@aws_creds_options
@common_options
@pass_context
@check_newer_version
@print_cmdline_args
def cli(ctx, stack_name: str, config_file: str, config_env: str, no_prompts: bool):
def cli(ctx, stack_name: str, config_file: str, config_env: str, no_prompts: bool, s3_bucket: str, s3_prefix: str):
"""
`sam delete` command entry point
"""
Expand All @@ -81,10 +96,21 @@ def cli(ctx, stack_name: str, config_file: str, config_env: str, no_prompts: boo
config_env=config_env,
profile=ctx.profile,
no_prompts=no_prompts,
s3_bucket=s3_bucket,
s3_prefix=s3_prefix,
) # pragma: no cover


def do_cli(stack_name: str, region: str, config_file: str, config_env: str, profile: str, no_prompts: bool):
def do_cli(
stack_name: str,
region: str,
config_file: str,
config_env: str,
profile: str,
no_prompts: bool,
s3_bucket: Optional[str],
s3_prefix: Optional[str],
):
"""
Implementation of the ``cli`` method
"""
Expand All @@ -97,5 +123,7 @@ def do_cli(stack_name: str, region: str, config_file: str, config_env: str, prof
config_file=config_file,
config_env=config_env,
no_prompts=no_prompts,
s3_bucket=s3_bucket,
s3_prefix=s3_prefix,
) as delete_context:
delete_context.run()
41 changes: 29 additions & 12 deletions samcli/commands/delete/delete_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import logging

import json
import boto3

from typing import Optional

import boto3

import click
from click import confirm
Expand Down Expand Up @@ -36,15 +38,25 @@

class DeleteContext:
# TODO: Separate this context into 2 separate contexts guided and non-guided, just like deploy.
def __init__(self, stack_name: str, region: str, profile: str, config_file: str, config_env: str, no_prompts: bool):
def __init__(
self,
stack_name: str,
region: str,
profile: str,
config_file: str,
config_env: str,
no_prompts: bool,
s3_bucket: Optional[str],
s3_prefix: Optional[str],
):
self.stack_name = stack_name
self.region = region
self.profile = profile
self.config_file = config_file
self.config_env = config_env
self.no_prompts = no_prompts
self.s3_bucket = None
self.s3_prefix = None
self.s3_bucket = s3_bucket
self.s3_prefix = s3_prefix
self.cf_utils = None
self.s3_uploader = None
self.ecr_uploader = None
Expand Down Expand Up @@ -95,8 +107,10 @@ def parse_config_file(self):
self.region = config_options.get("region", None)
if not self.profile:
self.profile = config_options.get("profile", None)
self.s3_bucket = config_options.get("s3_bucket", None)
self.s3_prefix = config_options.get("s3_prefix", None)
if not self.s3_bucket:
self.s3_bucket = config_options.get("s3_bucket", None)
if not self.s3_prefix:
self.s3_prefix = config_options.get("s3_prefix", None)

def init_clients(self):
"""
Expand Down Expand Up @@ -142,8 +156,9 @@ def s3_prompts(self):
Guided prompts asking user to delete s3 artifacts
"""
# Note: s3_bucket and s3_prefix information is only
# available if a local toml file is present or if
# this information is obtained from the template resources and so if this
# available if it is provided as an option flag, a
# local toml file or if this information is obtained
# from the template resources and so if this
# information is not found, warn the user that S3 artifacts
# will need to be manually deleted.

Expand Down Expand Up @@ -319,12 +334,14 @@ def delete(self):
self.cf_utils.delete_stack(stack_name=self.stack_name, retain_resources=retain_resources)
self.cf_utils.wait_for_delete(self.stack_name)

# If s3_bucket information is not available, warn the user
# Warn the user that s3 information is missing and to use --s3 options
if not self.s3_bucket:
LOG.debug("Cannot delete s3 files as no s3_bucket found")
LOG.debug("Cannot delete s3 objects as bucket is missing")
click.secho(
"\nWarning: s3_bucket and s3_prefix information could not be obtained from local config file"
" or cloudformation template, delete the s3 files manually if required",
"\nWarning: Cannot resolve s3 bucket information from command options"
" , local config file or cloudformation template. Please use"
" --s3-bucket next time and"
" delete s3 files manually if required.",
fg="yellow",
)

Expand Down
Loading

0 comments on commit d2ded65

Please sign in to comment.