Skip to content

Commit ad0e67c

Browse files
committed
Apply runtime patch to aws-cli to enable --s3-endpoint-url CloudFormation parameter
1 parent 5aa02db commit ad0e67c

3 files changed

Lines changed: 62 additions & 1 deletion

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ with `USE_SSL=true` enabled). Defaults to `false`.
4141

4242
## Change Log
4343

44+
* v0.7: Apply runtime patch to aws-cli to enable `--s3-endpoint-url` CloudFormation parameter
4445
* v0.6: Start `aws` CLI command in-memory instead of calling external process
4546
* v0.5: Support piping binary files to stdout; add .bat file for Windows
4647
* v0.4: Minor fix for Python 3 compatibility

bin/awslocal

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def main():
7474
import awscli.clidriver # noqa: F401
7575
except Exception:
7676
return run_as_separate_process()
77+
patch_awscli_libs()
7778
run_in_process()
7879

7980

@@ -139,5 +140,64 @@ def run_in_process():
139140
sys.exit(awscli.clidriver.main())
140141

141142

143+
def patch_awscli_libs():
144+
# TODO: Temporary fix until this PR is merged: https://github.com/aws/aws-cli/pull/3309
145+
146+
import inspect
147+
from awscli import paramfile
148+
from awscli.customizations.cloudformation import deploy, package
149+
150+
# add parameter definitions
151+
paramfile.PARAMFILE_DISABLED.add('custom.package.s3-endpoint-url')
152+
paramfile.PARAMFILE_DISABLED.add('custom.deploy.s3-endpoint-url')
153+
s3_endpoint_arg = {
154+
'name': 's3-endpoint-url',
155+
'help_text': (
156+
'URL of storage service where packaged templates and artifacts'
157+
' will be uploaded. Useful for testing and local development'
158+
' or when uploading to a non-AWS storage service that is'
159+
' nonetheless S3-compatible.'
160+
)
161+
}
162+
163+
# add argument definition for S3 endpoint to use for CF package/deploy
164+
for arg_table in [deploy.DeployCommand.ARG_TABLE, package.PackageCommand.ARG_TABLE]:
165+
existing = [a for a in arg_table if a.get('name') == 's3-endpoint-url']
166+
if not existing:
167+
arg_table.append(s3_endpoint_arg)
168+
169+
170+
def wrap_create_client(_init_orig):
171+
""" Returns a new constructor that wraps the S3 client creation to use the custom endpoint for CF. """
172+
173+
def new_init(self, session, *args, **kwargs):
174+
def create_client(*args, **kwargs):
175+
if args and args[0] == 's3':
176+
# get stack frame of caller
177+
curframe = inspect.currentframe()
178+
calframe = inspect.getouterframes(curframe, 2)
179+
fname = calframe[1].filename
180+
181+
# check if we are executing within the target method
182+
is_target = (os.path.join('cloudformation', 'deploy.py') in fname or
183+
os.path.join('cloudformation', 'package.py') in fname)
184+
if is_target:
185+
if 'endpoint_url' not in kwargs:
186+
args_passed = inspect.getargvalues(calframe[1].frame).locals
187+
kwargs['endpoint_url'] = args_passed['parsed_args'].s3_endpoint_url
188+
return create_client_orig(*args, **kwargs)
189+
190+
if not hasattr(session, '_s3_endpoint_patch_applied'):
191+
create_client_orig = session.create_client
192+
session.create_client = create_client
193+
session._s3_endpoint_patch_applied = True
194+
_init_orig(self, session, *args, **kwargs)
195+
196+
return new_init
197+
198+
deploy.DeployCommand.__init__ = wrap_create_client(deploy.DeployCommand.__init__)
199+
package.PackageCommand.__init__ = wrap_create_client(package.PackageCommand.__init__)
200+
201+
142202
if __name__ == '__main__':
143203
main()

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
setup(
88
name='awscli-local',
9-
version='0.6',
9+
version='0.7',
1010
description='Thin wrapper around the "aws" command line interface for use with LocalStack',
1111
author='Waldemar Hummer',
1212
author_email='waldemar.hummer@gmail.com',

0 commit comments

Comments
 (0)