Skip to content

Commit b258d01

Browse files
rrverma-amzkdaily
authored andcommitted
Add --tags parameter to gamelift upload-build command
cr: https://code.amazon.com/reviews/CR-237293169
1 parent 6fb04d0 commit b258d01

File tree

4 files changed

+126
-1
lines changed

4 files changed

+126
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "enhancement",
3+
"category": "``gamelift``",
4+
"description": "Add ``--tags`` parameter to ``upload-build`` command."
5+
}

awscli/customizations/gamelift/uploadbuild.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@
2424
from awscli.utils import create_nested_client
2525

2626

27+
def parse_tags(raw_tags_list):
28+
"""Parse tags from Key=Value format to GameLift API format."""
29+
tags_list = []
30+
if raw_tags_list:
31+
for tag in raw_tags_list:
32+
if '=' in tag:
33+
key, value = tag.split('=', 1)
34+
else:
35+
key, value = tag, ''
36+
tags_list.append({'Key': key, 'Value': value})
37+
return tags_list
38+
39+
2740
class UploadBuildCommand(BasicCommand):
2841
NAME = 'upload-build'
2942
DESCRIPTION = 'Upload a new build to AWS GameLift.'
@@ -40,7 +53,9 @@ class UploadBuildCommand(BasicCommand):
4053
'The version of the GameLift server SDK used to '
4154
'create the game server'},
4255
{'name': 'operating-system', 'required': False,
43-
'help_text': 'The operating system the build runs on'}
56+
'help_text': 'The operating system the build runs on'},
57+
{'name': 'tags', 'required': False, 'nargs': '+',
58+
'help_text': 'Tags to assign to the build. Format: Key=Value'}
4459
]
4560

4661
def _run_main(self, args, parsed_globals):
@@ -67,6 +82,8 @@ def _run_main(self, args, parsed_globals):
6782
create_build_kwargs['OperatingSystem'] = args.operating_system
6883
if args.server_sdk_version:
6984
create_build_kwargs['ServerSdkVersion'] = args.server_sdk_version
85+
if args.tags:
86+
create_build_kwargs['Tags'] = parse_tags(args.tags)
7087
response = gamelift_client.create_build(**create_build_kwargs)
7188
build_id = response['Build']['BuildId']
7289

tests/functional/gamelift/test_upload_build.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,60 @@ def test_upload_build_with_server_sdk_version_param(self):
247247
'Successfully uploaded %s to AWS GameLift' % self.files.rootdir,
248248
stdout)
249249
self.assertIn('Build ID: myid', stdout)
250+
251+
def test_upload_build_with_tags_param(self):
252+
self.files.create_file('tmpfile', 'Some contents')
253+
254+
expected_tags = [
255+
{'Key': 'Key1', 'Value': 'Value1'},
256+
{'Key': 'Key2', 'Value': 'Value2'}
257+
]
258+
259+
cmdline = self.prefix
260+
cmdline += ' --name mybuild --build-version myversion'
261+
cmdline += ' --build-root %s' % self.files.rootdir
262+
cmdline += ' --tags'
263+
for tag in expected_tags:
264+
cmdline += ' %s=%s' % (tag['Key'], tag['Value'])
265+
266+
self.parsed_responses = [
267+
{'Build': {'BuildId': 'myid'}},
268+
{'StorageLocation': {
269+
'Bucket': 'mybucket',
270+
'Key': 'mykey'},
271+
'UploadCredentials': {
272+
'AccessKeyId': 'myaccesskey',
273+
'SecretAccessKey': 'mysecretkey',
274+
'SessionToken': 'mytoken'}},
275+
{}
276+
]
277+
278+
stdout, stderr, rc = self.run_cmd(cmdline, expected_rc=0)
279+
280+
# First the build is created.
281+
self.assertEqual(len(self.operations_called), 3)
282+
self.assertEqual(self.operations_called[0][0].name, 'CreateBuild')
283+
self.assertEqual(
284+
self.operations_called[0][1],
285+
{'Name': 'mybuild', 'Version': 'myversion',
286+
'Tags': expected_tags}
287+
)
288+
289+
# Second the credentials are requested.
290+
self.assertEqual(
291+
self.operations_called[1][0].name, 'RequestUploadCredentials')
292+
self.assertEqual(
293+
self.operations_called[1][1], {'BuildId': 'myid'})
294+
295+
# The build is then uploaded to S3.
296+
self.assertEqual(self.operations_called[2][0].name, 'PutObject')
297+
self.assertEqual(
298+
self.operations_called[2][1],
299+
{'Body': mock.ANY, 'Bucket': 'mybucket', 'Key': 'mykey'}
300+
)
301+
302+
# Check the output of the command.
303+
self.assertIn(
304+
'Successfully uploaded %s to AWS GameLift' % self.files.rootdir,
305+
stdout)
306+
self.assertIn('Build ID: myid', stdout)

tests/unit/customizations/gamelift/test_uploadbuild.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from awscli.customizations.gamelift.uploadbuild import UploadBuildCommand
2323
from awscli.customizations.gamelift.uploadbuild import zip_directory
2424
from awscli.customizations.gamelift.uploadbuild import validate_directory
25+
from awscli.customizations.gamelift.uploadbuild import parse_tags
2526
from awscli.compat import StringIO
2627

2728

@@ -209,6 +210,51 @@ def test_upload_build_when_server_sdk_version_is_provided(self):
209210
Name=self.build_name, Version=self.build_version,
210211
ServerSdkVersion=server_sdk_version)
211212

213+
def test_upload_build_when_tags_are_provided(self):
214+
self.file_creator.create_file('tmpfile', 'Some contents')
215+
self.args = [
216+
'--name', self.build_name, '--build-version', self.build_version,
217+
'--build-root', self.build_root,
218+
'--tags', 'Environment=Production', 'Team=GameDev'
219+
]
220+
self.cmd(self.args, self.global_args)
221+
222+
self.gamelift_client.create_build.assert_called_once_with(
223+
Name=self.build_name, Version=self.build_version,
224+
Tags=[
225+
{'Key': 'Environment', 'Value': 'Production'},
226+
{'Key': 'Team', 'Value': 'GameDev'}
227+
])
228+
229+
230+
class TestParseTags(unittest.TestCase):
231+
def test_parse_tags_with_key_value_pairs(self):
232+
result = parse_tags(['Key1=Value1', 'Key2=Value2'])
233+
self.assertEqual(result, [
234+
{'Key': 'Key1', 'Value': 'Value1'},
235+
{'Key': 'Key2', 'Value': 'Value2'}
236+
])
237+
238+
def test_parse_tags_with_empty_value(self):
239+
result = parse_tags(['Key1='])
240+
self.assertEqual(result, [{'Key': 'Key1', 'Value': ''}])
241+
242+
def test_parse_tags_without_equals(self):
243+
result = parse_tags(['Key1'])
244+
self.assertEqual(result, [{'Key': 'Key1', 'Value': ''}])
245+
246+
def test_parse_tags_with_equals_in_value(self):
247+
result = parse_tags(['Key1=Value=WithEquals'])
248+
self.assertEqual(result, [{'Key': 'Key1', 'Value': 'Value=WithEquals'}])
249+
250+
def test_parse_tags_with_none(self):
251+
result = parse_tags(None)
252+
self.assertEqual(result, [])
253+
254+
def test_parse_tags_with_empty_list(self):
255+
result = parse_tags([])
256+
self.assertEqual(result, [])
257+
212258

213259
class TestZipDirectory(unittest.TestCase):
214260
def setUp(self):

0 commit comments

Comments
 (0)