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 Jan 10, 2024
2 parents 0d1797b + 335e529 commit 26c9291
Show file tree
Hide file tree
Showing 41 changed files with 1,407 additions and 767 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ jobs:
3.11
3.12
${{ matrix.python }}
- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: '1.19'
- uses: ruby/setup-ruby@v1
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/validate_pyinstaller.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
with:
python-version: "3.8"
- name: Set up Go
uses: actions/setup-go@v4
uses: actions/setup-go@v5
with:
go-version: "1.20"
- name: Build PyInstaller
Expand All @@ -66,7 +66,7 @@ jobs:
sudo ./sam-installation/install
sam-beta --version
./tests/sanity-check.sh
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: pyinstaller-macos-zip
path: .build/output/aws-sam-cli-macos-x86_64.zip
Expand Down
8 changes: 4 additions & 4 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ jmespath~=1.0.1
ruamel_yaml~=0.18.5
PyYAML~=6.0,>=6.0.1
cookiecutter~=2.5.0
aws-sam-translator==1.82.0
aws-sam-translator==1.83.0
#docker minor version updates can include breaking changes. Auto update micro version only.
docker~=6.1.0
docker~=7.0.0
dateparser~=1.2
requests~=2.31.0
aws_lambda_builders==1.45.0
Expand All @@ -28,7 +28,7 @@ regex!=2021.10.8
tzlocal==5.2

#Adding cfn-lint dependency for SAM validate
cfn-lint~=0.83.5
cfn-lint~=0.83.7

# Type checking boto3 objects
boto3-stubs[apigateway,cloudformation,ecr,iam,lambda,s3,schemas,secretsmanager,signer,stepfunctions,sts,xray,sqs,kinesis]==1.34.9
boto3-stubs[apigateway,cloudformation,ecr,iam,lambda,s3,schemas,secretsmanager,signer,stepfunctions,sts,xray,sqs,kinesis]==1.34.12
6 changes: 3 additions & 3 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ pytest-cov==4.1.0
# type checking and related stubs
# mypy adds new rules in new minor versions, which could cause our PR check to fail
# here we fix its version and upgrade it manually in the future
mypy==1.7.1
mypy==1.8.0
types-pywin32==306.0.0.8
types-PyYAML==6.0.12.12
types-chevron==0.14.2.5
Expand All @@ -24,7 +24,7 @@ types-requests==2.31.0.6
types-urllib3==1.26.25.14

# Test requirements
pytest~=7.4.3
pytest~=7.4.4
parameterized==0.9.0
pytest-xdist==3.5.0
pytest-forked==1.6.0
Expand All @@ -36,5 +36,5 @@ pytest-json-report==1.5.0
filelock==3.13.1

# formatter
black==23.12.0
black==23.12.1
psutil==5.9.7
2 changes: 1 addition & 1 deletion requirements/pre-dev.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ruff==0.1.8
ruff==0.1.11
441 changes: 221 additions & 220 deletions requirements/reproducible-linux.txt

Large diffs are not rendered by default.

441 changes: 221 additions & 220 deletions requirements/reproducible-mac.txt

Large diffs are not rendered by default.

441 changes: 221 additions & 220 deletions requirements/reproducible-win.txt

Large diffs are not rendered by default.

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.106.0"
__version__ = "1.107.0"
6 changes: 6 additions & 0 deletions samcli/commands/deploy/auth_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from samcli.commands.local.lib.swagger.reader import SwaggerReader
from samcli.lib.providers.provider import Stack
from samcli.lib.providers.sam_function_provider import SamFunctionProvider
from samcli.lib.utils.resources import AWS_APIGATEWAY_RESTAPI, AWS_APIGATEWAY_V2_API

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -101,6 +102,11 @@ def _auth_id(resources_dict, event_properties, identifier):
"""
resource_name = event_properties.get(identifier, "")
api_resource = resources_dict.get(resource_name, {})

# Auth does not apply to ApiGateway::RestApi or ApiGatwayV2::Api resources so return true and continue
if api_resource and (api_resource.get("Type") in [AWS_APIGATEWAY_RESTAPI, AWS_APIGATEWAY_V2_API]):
return True

return any(
[
api_resource.get("Properties", {}).get("Auth", False),
Expand Down
3 changes: 1 addition & 2 deletions samcli/commands/local/lib/swagger/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,6 @@ def get_routes(self, event_type=Route.API) -> List[Route]:

authorizer_name = None
use_default_authorizer = True

if authorizers is not None:
if not isinstance(authorizers, list):
raise InvalidSecurityDefinition(
Expand All @@ -373,7 +372,7 @@ def get_routes(self, event_type=Route.API) -> List[Route]:
f"for path='{full_path}' method='{method}', found '{len(authorizers)}'"
)

if len(authorizers) == 1:
if len(authorizers) == 1 and authorizers[0] != {}:
# user has authorizer defined
authorizer_object = authorizers[0]
authorizer_object = list(authorizers[0])
Expand Down
18 changes: 14 additions & 4 deletions samcli/commands/publish/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,18 @@
SERVERLESSREPO_CONSOLE_URL = "https://console.aws.amazon.com/serverlessrepo/home?region={}#/published-applications/{}"
SEMANTIC_VERSION_HELP = "Optional. The value provided here overrides SemanticVersion in the template metadata."
SEMANTIC_VERSION = "SemanticVersion"
FAIL_ON_SAME_VERSION = """
If set, AWS SAM CLI will prevent a publish and return a non-zero exit code
if the publish is attempted with a semantic version that already exists on the SAR application.
Default is False.
"""


@click.command("publish", help=HELP_TEXT, short_help=SHORT_HELP)
@configuration_option(provider=ConfigProvider(section="parameters"))
@template_common_option
@click.option("--semantic-version", help=SEMANTIC_VERSION_HELP)
@click.option("--fail-on-same-version", default=False, required=False, is_flag=True, help=FAIL_ON_SAME_VERSION)
@aws_creds_options
@cli_framework_options
@save_params_option
Expand All @@ -59,21 +65,25 @@ def cli(
ctx,
template_file,
semantic_version,
fail_on_same_version,
save_params,
config_file,
config_env,
):
# All logic must be implemented in the ``do_cli`` method. This helps with easy unit testing

do_cli(ctx, template_file, semantic_version) # pragma: no cover
do_cli(ctx, template_file, semantic_version, fail_on_same_version) # pragma: no cover


def do_cli(ctx, template, semantic_version):
def do_cli(ctx, template, semantic_version, fail_on_same_version):
"""Publish the application based on command line inputs."""

from samcli.commands.exceptions import UserException
from samcli.vendor.serverlessrepo import publish_application
from samcli.vendor.serverlessrepo.exceptions import InvalidS3UriError, ServerlessRepoError
from samcli.vendor.serverlessrepo.exceptions import (
InvalidS3UriError,
ServerlessRepoError,
)
from samcli.vendor.serverlessrepo.parser import METADATA, SERVERLESS_REPO_APPLICATION

try:
Expand All @@ -87,7 +97,7 @@ def do_cli(ctx, template, semantic_version):
template_data.get(METADATA).get(SERVERLESS_REPO_APPLICATION)[SEMANTIC_VERSION] = semantic_version

try:
publish_output = publish_application(template_data)
publish_output = publish_application(template=template_data, fail_on_same_version=fail_on_same_version)
click.secho("Publish Succeeded", fg="green")
click.secho(_gen_success_message(publish_output))
except InvalidS3UriError as ex:
Expand Down
14 changes: 14 additions & 0 deletions samcli/lib/build/build_strategy.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from samcli.lib.build.exceptions import MissingBuildMethodException
from samcli.lib.build.utils import warn_on_invalid_architecture

from samcli.lib.utils.architecture import X86_64, ARM64

LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -218,6 +219,19 @@ def build_single_layer_definition(self, layer_definition: LayerBuildDefinition)
if layer.build_method == "makefile":
warn_on_invalid_architecture(layer_definition)

# There are two cases where we'd like to warn the customer
# 1. Compatible Architectures is only x86 (or not present) but Build Architecture is arm64
# 2. Build Architecture is x86 (or not present) but Compatible Architectures is only arm64

build_architecture = layer.build_architecture or X86_64
compatible_architectures = layer.compatible_architectures or [X86_64]

if build_architecture not in compatible_architectures:
LOG.warning(
"WARNING: Layer '%s' has BuildArchitecture %s, which is not listed in CompatibleArchitectures",
layer.layer_id,
build_architecture,
)
single_build_dir = layer.get_build_dir(self._build_dir)
# when a layer is passed here, it is ZIP function, codeuri and runtime are not None
# codeuri and compatible_runtimes are not None
Expand Down
13 changes: 0 additions & 13 deletions samcli/lib/providers/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -244,22 +244,9 @@ def __init__(
self._compatible_runtimes = compatible_runtimes
self._custom_layer_id = metadata.get(SAM_RESOURCE_ID_KEY)

if "BuildArchitecture" not in metadata:
LOG.warning(
"WARNING: No BuildArchitecture specifed in Layer `%s`" + " Metadata. Defaulting to x86_64.",
self._custom_layer_id,
)

self._build_architecture = cast(str, metadata.get("BuildArchitecture", X86_64))
self._compatible_architectures = compatible_architectures

if self._compatible_architectures and self._build_architecture not in self._compatible_architectures:
LOG.warning(
"WARNING: Layer `%s` has BuildArchitecture `%s`," + " which is not listed in CompatibleArchitectures.",
self._custom_layer_id,
self._build_architecture,
)

self._skip_build = bool(metadata.get(SAM_METADATA_SKIP_BUILD_KEY, False))

@staticmethod
Expand Down
8 changes: 6 additions & 2 deletions samcli/local/apigw/event_constructor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from typing import Any, Dict

from samcli.local.apigw.path_converter import PathConverter
from samcli.local.apigw.route import Route
from samcli.local.events.api_event import (
ApiGatewayLambdaEvent,
ApiGatewayV2LambdaEvent,
Expand All @@ -22,16 +23,18 @@


def construct_v1_event(
flask_request, port, binary_types, stage_name=None, stage_variables=None, operation_name=None
flask_request, port, binary_types, stage_name=None, stage_variables=None, operation_name=None, api_type=Route.API
) -> Dict[str, Any]:
"""
Helper method that constructs the Event to be passed to Lambda
Helper method that constructs the Event to be passed to Lambda.
Used for Http apis with payload v1 and Rest apis because the payloads are almost identical
:param request flask_request: Flask Request
:param port: the port number
:param binary_types: list of binary types
:param stage_name: Optional, the stage name string
:param stage_variables: Optional, API Gateway Stage Variables
:param api_type: Optional, the type of api payload being constructed
:return: JSON object
"""

Expand Down Expand Up @@ -86,6 +89,7 @@ def construct_v1_event(
path=flask_request.path,
is_base_64_encoded=is_base_64,
stage_variables=stage_variables,
api_type=api_type,
)

event_dict = event.to_dict()
Expand Down
1 change: 1 addition & 0 deletions samcli/local/apigw/local_apigw_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ def _generate_lambda_event(self, flask_request: Request, route: Route, method: s
stage_name=self.api.stage_name,
stage_variables=self.api.stage_variables,
operation_name=route_key,
api_type=route.event_type,
)

def _build_v1_context(self, route: Route) -> Dict[str, Any]:
Expand Down
2 changes: 1 addition & 1 deletion samcli/local/docker/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def __init__(
self.docker_client = docker_client or docker.from_env(version=DOCKER_MIN_API_VERSION)

# Runtime properties of the container. They won't have value until container is created or started
self.id = None
self.id: Optional[str] = None

# aws-lambda-rie defaults to 8080 as the port, however that's a common port. A port is chosen by
# selecting the first free port in a range that's not ephemeral.
Expand Down
48 changes: 48 additions & 0 deletions samcli/local/docker/container_analyzer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
"""
Class for handling the analysis and inspection of Docker containers
"""
import logging
from dataclasses import dataclass

from samcli.local.docker.container import Container
from samcli.local.docker.manager import ContainerManager

LOG = logging.getLogger(__name__)

DEFAULT_OUT_OF_MEMORY = False


@dataclass
class ContainerState:
out_of_memory: bool


class ContainerAnalyzer:
def __init__(self, container_manager: ContainerManager, container: Container):
self.container_manager = container_manager
self.container = container

def inspect(self) -> ContainerState:
"""
Inspect the state of a container by calling the "inspect()" API that Docker provides.
Extract relevant information into a ContainerState object.
Returns
-------
ContainerState:
Returns a ContainerState object with relevant container data
"""
if not self.container.id:
LOG.debug("Container ID not defined, unable to fetch container state")
return ContainerState(DEFAULT_OUT_OF_MEMORY)

state = self.container_manager.inspect(self.container.id)

if isinstance(state, bool):
LOG.debug("Unable to fetch container state")
return ContainerState(DEFAULT_OUT_OF_MEMORY)

container_state = ContainerState(state.get("State", {}).get("OOMKilled", DEFAULT_OUT_OF_MEMORY))
LOG.debug("[Container state] OOMKilled %s", container_state.out_of_memory)

return container_state
7 changes: 7 additions & 0 deletions samcli/local/docker/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Docker container related exceptions
"""
from samcli.commands.exceptions import UserException


class ContainerNotStartableException(Exception):
Expand All @@ -17,3 +18,9 @@ class PortAlreadyInUse(Exception):
"""
Exception to raise when the provided port is not available for use.
"""


class ContainerFailureError(UserException):
"""
Raised when the invoke container fails execution
"""
21 changes: 21 additions & 0 deletions samcli/local/docker/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import logging
import sys
import threading
from typing import Union, cast

import docker

Expand Down Expand Up @@ -193,6 +194,26 @@ def has_image(self, image_name):
except docker.errors.ImageNotFound:
return False

def inspect(self, container: str) -> Union[bool, dict]:
"""
Low-level Docker API for inspecting the container state
Parameters
----------
container: str
ID of the container
Returns
-------
Union[bool, dict]
Container inspection state if successful, False otherwise
"""
try:
return cast(dict, self.docker_client.api.inspect_container(container))
except (docker.errors.APIError, docker.errors.NullResource) as ex:
LOG.debug("Failed to call Docker inspect: %s", str(ex))
return False


class DockerImagePullFailedException(Exception):
pass
Loading

0 comments on commit 26c9291

Please sign in to comment.