Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,17 @@ jobs:
- "3.11"
steps:
- uses: actions/checkout@v3
# @melasmar
# TODO: Revert back to use 3.7 to all operating systems after the regression issue in Python
# https://github.com/actions/setup-python/issues/682 in github action got resolved
- uses: actions/setup-python@v4
if: matrix.os != 'macos-latest' || ( matrix.os == 'macos-latest' && matrix.python != '3.7' )
with:
python-version: ${{ matrix.python }}
- uses: actions/setup-python@v4
if: matrix.os == 'macos-latest' && matrix.python == '3.7'
with:
python-version: "3.7.16"
- run: test -f "./.github/ISSUE_TEMPLATE/Bug_report.md" # prevent Bug_report.md from being renamed or deleted
- run: make init
- run: make pr
Expand Down
4 changes: 2 additions & 2 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jmespath~=1.0.1
ruamel_yaml~=0.17.21
PyYAML>=5.4.1,==5.*
cookiecutter~=2.1.1
aws-sam-translator==1.68.0
aws-sam-translator==1.69.0
#docker minor version updates can include breaking changes. Auto update micro version only.
docker~=6.1.0
dateparser~=1.1
Expand All @@ -28,4 +28,4 @@ regex!=2021.10.8
tzlocal==3.0

#Adding cfn-lint dependency for SAM validate
cfn-lint~=0.77.5
cfn-lint~=0.77.9
12 changes: 6 additions & 6 deletions requirements/reproducible-linux.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ aws-lambda-builders==1.34.0 \
--hash=sha256:0790f7e9b7ee7286b96fbcf49450c5be0341bb7cb852ca7d74beae190139eb48 \
--hash=sha256:20456a942a417407b42ecf8ab7fce6a47306fd063051e7cb09d02d1be24d5cf3
# via aws-sam-cli (setup.py)
aws-sam-translator==1.68.0 \
--hash=sha256:557d8080c9e6c1c609bfe806ea9545f7ea34144e2466c0ddc801806c2c05afdc \
--hash=sha256:d12a7bb3909142d32458f76818cb96a5ebc5f50fbd5943301d552679a893afcc
aws-sam-translator==1.69.0 \
--hash=sha256:bf26c061675f20367e87d48963ada1ec983a8d897e85db02d0f35913a6174bb0 \
--hash=sha256:c6ed7a25c77d30d3d31156049415d15fde46c0d3b77a4c5cdc0ef8b53ba9bca2
# via
# aws-sam-cli (setup.py)
# cfn-lint
Expand Down Expand Up @@ -112,9 +112,9 @@ cffi==1.15.1 \
--hash=sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01 \
--hash=sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0
# via cryptography
cfn-lint==0.77.5 \
--hash=sha256:4282d13ffe76a5dee6431b1f56e3641d87c28b1ef5be663afe7d8dbf13f28bdb \
--hash=sha256:b5126dffb834078a71341090d49669046076c09196f0d2bdca68dbace1bf357a
cfn-lint==0.77.9 \
--hash=sha256:7c1e631b723b521234d92d4081934291b256dba28d723ddb7ff105215fe40020 \
--hash=sha256:f95b503f7465ee1f2f89ddf32289ea03a517f08c366bb8e6a5d6773a11e5a1aa
# via aws-sam-cli (setup.py)
chardet==5.1.0 \
--hash=sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5 \
Expand Down
12 changes: 6 additions & 6 deletions requirements/reproducible-mac.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ aws-lambda-builders==1.34.0 \
--hash=sha256:0790f7e9b7ee7286b96fbcf49450c5be0341bb7cb852ca7d74beae190139eb48 \
--hash=sha256:20456a942a417407b42ecf8ab7fce6a47306fd063051e7cb09d02d1be24d5cf3
# via aws-sam-cli (setup.py)
aws-sam-translator==1.68.0 \
--hash=sha256:557d8080c9e6c1c609bfe806ea9545f7ea34144e2466c0ddc801806c2c05afdc \
--hash=sha256:d12a7bb3909142d32458f76818cb96a5ebc5f50fbd5943301d552679a893afcc
aws-sam-translator==1.69.0 \
--hash=sha256:bf26c061675f20367e87d48963ada1ec983a8d897e85db02d0f35913a6174bb0 \
--hash=sha256:c6ed7a25c77d30d3d31156049415d15fde46c0d3b77a4c5cdc0ef8b53ba9bca2
# via
# aws-sam-cli (setup.py)
# cfn-lint
Expand Down Expand Up @@ -130,9 +130,9 @@ cffi==1.15.1 \
--hash=sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01 \
--hash=sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0
# via cryptography
cfn-lint==0.77.5 \
--hash=sha256:4282d13ffe76a5dee6431b1f56e3641d87c28b1ef5be663afe7d8dbf13f28bdb \
--hash=sha256:b5126dffb834078a71341090d49669046076c09196f0d2bdca68dbace1bf357a
cfn-lint==0.77.9 \
--hash=sha256:7c1e631b723b521234d92d4081934291b256dba28d723ddb7ff105215fe40020 \
--hash=sha256:f95b503f7465ee1f2f89ddf32289ea03a517f08c366bb8e6a5d6773a11e5a1aa
# via aws-sam-cli (setup.py)
chardet==5.1.0 \
--hash=sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5 \
Expand Down
8 changes: 7 additions & 1 deletion samcli/commands/_utils/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,13 @@ def remote_invoke_parameter_click_option():
type=RemoteInvokeBotoApiParameterType(),
callback=remote_invoke_boto_parameter_callback,
required=False,
help="Additional parameters for the boto API call.\n" "Lambda APIs: invoke and invoke_with_response_stream",
help="Additional parameters that can be passed to invoke the resource.\n"
"The following additional parameters can be used to invoke a lambda resource and get a buffered response: "
"InvocationType='Event'|'RequestResponse'|'DryRun', LogType='None'|'Tail', "
"ClientContext='base64-encoded string' Qualifier='string'. "
"The following additional parameters can be used to invoke a lambda resource with response streaming: "
"InvocationType='RequestResponse'|'DryRun', LogType='None'|'Tail', "
"ClientContext='base64-encoded string', Qualifier='string'.",
)


Expand Down
42 changes: 30 additions & 12 deletions samcli/commands/remote/invoke/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
from samcli.cli.context import Context
from samcli.cli.main import aws_creds_options, common_options, pass_context, print_cmdline_args
from samcli.cli.types import RemoteInvokeOutputFormatType
from samcli.commands._utils.command_exception_handler import command_exception_handler
from samcli.commands._utils.options import remote_invoke_parameter_option
from samcli.commands.remote.invoke.core.command import RemoteInvokeCommand
from samcli.lib.cli_validation.remote_invoke_options_validations import (
event_and_event_file_options_validation,
stack_name_or_resource_id_atleast_one_option_validation,
Expand All @@ -20,30 +22,45 @@
LOG = logging.getLogger(__name__)

HELP_TEXT = """
Invoke or send an event to cloud resources in your CFN stack
Invoke or send an event to resources in the cloud.
"""
SHORT_HELP = "Invoke a deployed resource in the cloud"

DESCRIPTION = """
Invoke or send an event to resources in the cloud.
An event body can be passed using either -e (--event) or --event-file parameter.
Returned response will be written to stdout. Lambda logs will be written to stderr.
"""


@click.command("invoke", help=HELP_TEXT, short_help=SHORT_HELP)
@click.command(
"invoke",
cls=RemoteInvokeCommand,
help=HELP_TEXT,
description=DESCRIPTION,
short_help=SHORT_HELP,
requires_credentials=True,
context_settings={"max_content_width": 120},
)
@configuration_option(provider=TomlProvider(section="parameters"))
@click.option("--stack-name", required=False, help="Name of the stack to get the resource information from")
@click.option("--resource-id", required=False, help="Name of the resource that will be invoked")
@click.argument("resource-id", required=False)
@click.option(
"--event",
"-e",
help="The event that will be sent to the resource. The target parameter will depend on the resource type. "
"For instance: 'Payload' for Lambda",
"For instance: 'Payload' for Lambda which can be passed as a JSON string",
)
@click.option(
"--event-file",
type=click.File("r", encoding="utf-8"),
help="The file that contains the event that will be sent to the resource",
help="The file that contains the event that will be sent to the resource.",
)
@click.option(
"--output-format",
help="Output format for the boto API response",
default=RemoteInvokeOutputFormat.DEFAULT.name.lower(),
"--output",
help="Output the results from the command in a given output format. "
"The text format prints a readable AWS API response. The json format prints the full AWS API response.",
default=RemoteInvokeOutputFormat.TEXT.name.lower(),
type=RemoteInvokeOutputFormatType(RemoteInvokeOutputFormat),
)
@remote_invoke_parameter_option
Expand All @@ -55,13 +72,14 @@
@track_command
@check_newer_version
@print_cmdline_args
@command_exception_handler
def cli(
ctx: Context,
stack_name: str,
resource_id: str,
event: str,
event_file: TextIOWrapper,
output_format: RemoteInvokeOutputFormat,
output: RemoteInvokeOutputFormat,
parameter: dict,
config_file: str,
config_env: str,
Expand All @@ -75,7 +93,7 @@ def cli(
resource_id,
event,
event_file,
output_format,
output,
parameter,
ctx.region,
ctx.profile,
Expand All @@ -89,7 +107,7 @@ def do_cli(
resource_id: str,
event: str,
event_file: TextIOWrapper,
output_format: RemoteInvokeOutputFormat,
output: RemoteInvokeOutputFormat,
parameter: dict,
region: str,
profile: str,
Expand Down Expand Up @@ -120,7 +138,7 @@ def do_cli(
) as remote_invoke_context:

remote_invoke_input = RemoteInvokeExecutionInfo(
payload=event, payload_file=event_file, parameters=parameter, output_format=output_format
payload=event, payload_file=event_file, parameters=parameter, output_format=output
)

remote_invoke_context.run(remote_invoke_input=remote_invoke_input)
Expand Down
Empty file.
158 changes: 158 additions & 0 deletions samcli/commands/remote/invoke/core/command.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
"""
Invoke Command Class.
"""
import json

from click import Context, style

from samcli.cli.core.command import CoreCommand
from samcli.cli.row_modifiers import RowDefinition, ShowcaseRowModifier
from samcli.commands.remote.invoke.core.formatters import RemoteInvokeCommandHelpTextFormatter
from samcli.commands.remote.invoke.core.options import OPTIONS_INFO


class RemoteInvokeCommand(CoreCommand):
class CustomFormatterContext(Context):
formatter_class = RemoteInvokeCommandHelpTextFormatter

context_class = CustomFormatterContext

@staticmethod
def format_examples(ctx: Context, formatter: RemoteInvokeCommandHelpTextFormatter):
with formatter.indented_section(name="Examples", extra_indents=1):
with formatter.indented_section(name="Invoke default lambda function with empty event", extra_indents=1):
formatter.write_rd(
[
RowDefinition(
text="\n",
),
RowDefinition(
name=style(f"${ctx.command_path} --stack-name hello-world"),
extra_row_modifiers=[ShowcaseRowModifier()],
),
]
)
with formatter.indented_section(
name="Invoke default lambda function with event passed as text input", extra_indents=1
):
formatter.write_rd(
[
RowDefinition(
text="\n",
),
RowDefinition(
name=style(
f"${ctx.command_path} --stack-name hello-world -e '{json.dumps({'message':'hello!'})}'"
),
extra_row_modifiers=[ShowcaseRowModifier()],
),
]
)
with formatter.indented_section(name="Invoke named lambda function with an event file", extra_indents=1):
formatter.write_rd(
[
RowDefinition(
text="\n",
),
RowDefinition(
name=style(
f"${ctx.command_path} --stack-name "
f"hello-world HelloWorldFunction --event-file event.json"
),
extra_row_modifiers=[ShowcaseRowModifier()],
),
]
)
with formatter.indented_section(name="Invoke lambda function with event as stdin input", extra_indents=1):
formatter.write_rd(
[
RowDefinition(
text="\n",
),
RowDefinition(
name=style(
f"$ echo '{json.dumps({'message':'hello!'})}' | "
f"{ctx.command_path} HelloWorldFunction --event-file -"
),
extra_row_modifiers=[ShowcaseRowModifier()],
),
]
)
with formatter.indented_section(
name="Invoke lambda function using lambda ARN and get the full AWS API response", extra_indents=1
):
formatter.write_rd(
[
RowDefinition(
text="\n",
),
RowDefinition(
name=style(
f"${ctx.command_path} arn:aws:lambda:us-west-2:123456789012:function:my-function -e <>"
f" --output json"
),
extra_row_modifiers=[ShowcaseRowModifier()],
),
]
)
with formatter.indented_section(
name="Asynchronously invoke lambda function with additional boto parameters", extra_indents=1
):
formatter.write_rd(
[
RowDefinition(
text="\n",
),
RowDefinition(
name=style(
f"${ctx.command_path} HelloWorldFunction -e <> "
f"--parameter InvocationType=Event --parameter Qualifier=MyQualifier"
),
extra_row_modifiers=[ShowcaseRowModifier()],
),
]
)
with formatter.indented_section(
name="Dry invoke a lambda function to validate parameter values and user/role permissions",
extra_indents=1,
):
formatter.write_rd(
[
RowDefinition(
text="\n",
),
RowDefinition(
name=style(
f"${ctx.command_path} HelloWorldFunction -e <> --output json "
f"--parameter InvocationType=DryRun"
),
extra_row_modifiers=[ShowcaseRowModifier()],
),
]
)

@staticmethod
def format_acronyms(formatter: RemoteInvokeCommandHelpTextFormatter):
with formatter.indented_section(name="Acronyms", extra_indents=1):
formatter.write_rd(
[
RowDefinition(
name="ARN",
text="Amazon Resource Name",
extra_row_modifiers=[ShowcaseRowModifier()],
),
]
)

def format_options(self, ctx: Context, formatter: RemoteInvokeCommandHelpTextFormatter) -> None: # type:ignore
# NOTE: `ignore` is put in place here for mypy even though it is the correct behavior,
# as the `formatter_class` can be set in subclass of Command. If ignore is not set,
# mypy raises argument needs to be HelpFormatter as super class defines it.

self.format_description(formatter)
RemoteInvokeCommand.format_examples(ctx, formatter)
RemoteInvokeCommand.format_acronyms(formatter)

CoreCommand._format_options(
ctx=ctx, params=self.get_params(ctx), formatter=formatter, formatting_options=OPTIONS_INFO
)
21 changes: 21 additions & 0 deletions samcli/commands/remote/invoke/core/formatters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""
Remote Invoke Command Formatter.
"""
from samcli.cli.formatters import RootCommandHelpTextFormatter
from samcli.cli.row_modifiers import BaseLineRowModifier
from samcli.commands.remote.invoke.core.options import ALL_OPTIONS


class RemoteInvokeCommandHelpTextFormatter(RootCommandHelpTextFormatter):
ADDITIVE_JUSTIFICATION = 17

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# NOTE: Add Additional space after determining the longest option.
# However, do not justify with padding for more than half the width of
# the terminal to retain aesthetics.
self.left_justification_length = min(
max([len(option) for option in ALL_OPTIONS]) + self.ADDITIVE_JUSTIFICATION,
self.width // 2 - self.indent_increment,
)
self.modifiers = [BaseLineRowModifier()]
Loading