Skip to content

Commit 2d6077a

Browse files
authored
Add tagging support for the s3 mb command (aws#10119)
1 parent 4353c84 commit 2d6077a

File tree

4 files changed

+99
-3
lines changed

4 files changed

+99
-3
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": "``s3``",
4+
"description": "Add support for specifying tags on buckets during bucket creation using the ``aws s3 mb`` command via a new ``--tags`` flag."
5+
}

awscli/customizations/s3/subcommands.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,18 @@
483483
)
484484
}
485485

486+
TAGS = {
487+
'name': 'tags',
488+
'synopsis': '--tags <key> <value>',
489+
'action': 'append',
490+
'nargs': 2,
491+
'help_text': (
492+
'This flag specifies tags to be added to the bucket in the format of '
493+
'``--tags key value``. You can specify this flag multiple times, '
494+
'once for each tag.'
495+
),
496+
}
497+
486498
CASE_CONFLICT = {
487499
'name': 'case-conflict',
488500
'choices': [
@@ -876,7 +888,13 @@ class MbCommand(S3Command):
876888
NAME = 'mb'
877889
DESCRIPTION = "Creates an S3 bucket."
878890
USAGE = "<S3Uri>"
879-
ARG_TABLE = [{'name': 'path', 'positional_arg': True, 'synopsis': USAGE}]
891+
ARG_TABLE = [
892+
{
893+
'name': 'path',
894+
'positional_arg': True,
895+
'synopsis': USAGE,
896+
}
897+
] + [TAGS]
880898

881899
def _run_main(self, parsed_args, parsed_globals):
882900
super(MbCommand, self)._run_main(parsed_args, parsed_globals)
@@ -888,9 +906,17 @@ def _run_main(self, parsed_args, parsed_globals):
888906
if is_s3express_bucket(bucket):
889907
raise ValueError("Cannot use mb command with a directory bucket.")
890908

891-
bucket_config = {'LocationConstraint': self.client.meta.region_name}
892909
params = {'Bucket': bucket}
910+
bucket_config = {}
911+
bucket_tags = self._create_bucket_tags(parsed_args)
912+
913+
# Only set LocationConstraint when the region name is not us-east-1.
914+
# Sending LocationConstraint with value us-east-1 results in an error.
893915
if self.client.meta.region_name != 'us-east-1':
916+
bucket_config['LocationConstraint'] = self.client.meta.region_name
917+
if bucket_tags:
918+
bucket_config['Tags'] = bucket_tags
919+
if bucket_config:
894920
params['CreateBucketConfiguration'] = bucket_config
895921

896922
# TODO: Consolidate how we handle return codes and errors
@@ -905,6 +931,11 @@ def _run_main(self, parsed_args, parsed_globals):
905931
)
906932
return 1
907933

934+
def _create_bucket_tags(self, parsed_args):
935+
if parsed_args.tags is not None:
936+
return [{'Key': tag[0], 'Value': tag[1]} for tag in parsed_args.tags]
937+
return []
938+
908939

909940
class RbCommand(S3Command):
910941
NAME = 'rb'

awscli/examples/s3/mb.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,16 @@ user makes the bucket ``amzn-s3-demo-bucket`` in the region ``us-west-1``::
2020
Output::
2121

2222
make_bucket: s3://amzn-s3-demo-bucket
23+
24+
**Example 3: Create a bucket with specified tags**
25+
26+
The following ``mb`` command creates a bucket with specified tags using the ``--tags`` parameter. In this example, the
27+
user makes the bucket ``amzn-s3-demo-bucket`` with two tags with keys ``Key1`` and ``Key2``, respectively. ::
28+
29+
aws s3 mb s3://amzn-s3-demo-bucket \
30+
--tags Key1 Value1 \
31+
--tags Key2 Value2
32+
33+
Output::
34+
35+
make_bucket: s3://amzn-s3-demo-bucket

tests/functional/s3/test_mb_command.py

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,51 @@ def test_nonzero_exit_if_invalid_path_provided(self):
4949
def test_incompatible_with_express_directory_bucket(self):
5050
command = self.prefix + 's3://bucket--usw2-az1--x-s3/'
5151
stderr = self.run_cmd(command, expected_rc=255)[1]
52-
self.assertIn('Cannot use mb command with a directory bucket.', stderr)
52+
self.assertIn('Cannot use mb command with a directory bucket.', stderr)
53+
54+
def test_make_bucket_with_single_tag(self):
55+
command = self.prefix + 's3://bucket --tags Key1 Value1 --region us-west-2'
56+
expected_params = {
57+
'Bucket': 'bucket',
58+
'CreateBucketConfiguration': {
59+
'LocationConstraint': 'us-west-2',
60+
'Tags': [
61+
{'Key': 'Key1', 'Value': 'Value1'}
62+
]
63+
}
64+
}
65+
self.assert_params_for_cmd(command, expected_params)
66+
67+
def test_make_bucket_with_single_tag_us_east_1(self):
68+
command = self.prefix + 's3://bucket --tags Key1 Value1 --region us-east-1'
69+
expected_params = {
70+
'Bucket': 'bucket',
71+
'CreateBucketConfiguration': {
72+
'Tags': [
73+
{'Key': 'Key1', 'Value': 'Value1'}
74+
]
75+
}
76+
}
77+
self.assert_params_for_cmd(command, expected_params)
78+
79+
def test_make_bucket_with_multiple_tags(self):
80+
command = self.prefix + 's3://bucket --tags Key1 Value1 --tags Key2 Value2 --region us-west-2'
81+
expected_params = {
82+
'Bucket': 'bucket',
83+
'CreateBucketConfiguration': {
84+
'LocationConstraint': 'us-west-2',
85+
'Tags': [
86+
{'Key': 'Key1', 'Value': 'Value1'},
87+
{'Key': 'Key2', 'Value': 'Value2'}
88+
]
89+
}
90+
}
91+
self.assert_params_for_cmd(command, expected_params)
92+
93+
def test_tags_with_three_arguments_fails(self):
94+
command = self.prefix + 's3://bucket --tags Key1 Value1 ExtraArg'
95+
self.assert_params_for_cmd(
96+
command,
97+
expected_rc=255,
98+
stderr_contains='Unknown options: ExtraArg'
99+
)

0 commit comments

Comments
 (0)