From 10c0ffc2f2709f475e3fae4b1b8a03d0603ca3b5 Mon Sep 17 00:00:00 2001 From: Mike Fuller Date: Wed, 28 Jan 2015 10:17:55 +1100 Subject: [PATCH] Added remove_tags_from_resource for rds db and add_tags_to_resource for rds db. --- moto/rds2/models.py | 30 +++++++++++++++++++++ moto/rds2/responses.py | 51 ++++++++++++++++++++++++++++++------ tests/test_rds2/test_rds2.py | 40 ++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 8 deletions(-) diff --git a/moto/rds2/models.py b/moto/rds2/models.py index 63f0c07af..74f5efef7 100644 --- a/moto/rds2/models.py +++ b/moto/rds2/models.py @@ -248,6 +248,14 @@ class Database(object): def get_tags(self): return self.tags + def add_tags(self, tags): + new_keys = [tag_set['Key'] for tag_set in tags] + self.tags = [tag_set for tag_set in self.tags if tag_set['Key'] not in new_keys] + self.tags.extend(tags) + + def remove_tags(self, tag_keys): + self.tags = [tag_set for tag_set in self.tags if tag_set['Key'] not in tag_keys] + class SecurityGroup(object): def __init__(self, group_name, description): @@ -602,6 +610,28 @@ class RDS2Backend(BaseBackend): raise RDSClientError('InvalidParameterValue', 'Invalid resource name: {}'.format(arn)) + def remove_tags_from_resource(self, arn, tag_keys): + if self.arn_regex.match(arn): + arn_breakdown = arn.split(':') + db_instance_name = arn_breakdown[len(arn_breakdown)-1] + if db_instance_name in self.databases: + self.databases[db_instance_name].remove_tags(tag_keys) + else: + raise RDSClientError('InvalidParameterValue', + 'Invalid resource name: {}'.format(arn)) + + def add_tags_to_resource(self, arn, tags): + if self.arn_regex.match(arn): + arn_breakdown = arn.split(':') + db_instance_name = arn_breakdown[len(arn_breakdown)-1] + if db_instance_name in self.databases: + return self.databases[db_instance_name].add_tags(tags) + else: + return [] + else: + raise RDSClientError('InvalidParameterValue', + 'Invalid resource name: {}'.format(arn)) + class OptionGroup(object): def __init__(self, name, engine_name, major_engine_version, description=None): self.engine_name = engine_name diff --git a/moto/rds2/responses.py b/moto/rds2/responses.py index eb75ba1f4..bade4a4f3 100644 --- a/moto/rds2/responses.py +++ b/moto/rds2/responses.py @@ -39,15 +39,9 @@ class RDS2Response(BaseResponse): "security_groups": self._get_multi_param('DBSecurityGroups.member'), "storage_type": self._get_param("StorageType"), # VpcSecurityGroupIds.member.N - "tags": [] + "tags": list() } - count = 1 - while self._get_param('Tags.member.{}.Key'.format(count)): - args["tags"].append({ - "Key": self._get_param('Tags.member.{}.Key'.format(count)), - "Value": self._get_param('Tags.member.{}.Value'.format(count)) - }) - count += 1 + args['tags'] = self.unpack_complex_list_params('Tags.member', ('Key', 'Value')) return args def _get_db_replica_kwargs(self): @@ -73,6 +67,25 @@ class RDS2Response(BaseResponse): 'name': self._get_param('OptionGroupName') } + def unpack_complex_list_params(self, label, names): + unpacked_list = list() + count = 1 + while self._get_param('{0}.{1}.{2}'.format(label, count, names[0])): + param = dict() + for i in range(len(names)): + param[names[i]] = self._get_param('{0}.{1}.{2}'.format(label, count, names[i])) + unpacked_list.append(param) + count += 1 + return unpacked_list + + def unpack_list_params(self, label): + unpacked_list = list() + count = 1 + while self._get_param('{0}.{1}'.format(label, count)): + unpacked_list.append(self._get_param('{0}.{1}'.format(label, count))) + count += 1 + return unpacked_list + def create_dbinstance(self): return self.create_db_instance() @@ -135,6 +148,21 @@ class RDS2Response(BaseResponse): tags = self.backend.list_tags_for_resource(arn) return template.render(tags=tags) + def add_tags_to_resource(self): + arn = self._get_param('ResourceName') + tags = self.unpack_complex_list_params('Tags.member', ('Key', 'Value')) + self.backend.add_tags_to_resource(arn, tags) + template = self.response_template(ADD_TAGS_TO_RESOURCE_TEMPLATE) + return template.render() + + + def remove_tags_from_resource(self): + arn = self._get_param('ResourceName') + tag_keys = self.unpack_list_params('TagKeys.member') + self.backend.remove_tags_from_resource(arn, tag_keys) + template = self.response_template(REMOVE_TAGS_FROM_RESOURCE_TEMPLATE) + return template.render() + # TODO: Update function to new method def create_dbsecurity_group(self): group_name = self._get_param('DBSecurityGroupName') @@ -437,3 +465,10 @@ LIST_TAGS_FOR_RESOURCE_TEMPLATE = \ } } }""" + +ADD_TAGS_TO_RESOURCE_TEMPLATE = \ + """{"ListTagsForResourceResponse": {"ListTagsForResourceResult": {"TagList": [{"Value": "production", "Key": "workload-type"}, {"Value": "testvalue", "Key": "testkey"}]}, "ResponseMetadata": {"RequestId": "b194d9ca-a664-11e4-b688-194eaf8658fa"}}}""" + +REMOVE_TAGS_FROM_RESOURCE_TEMPLATE = \ + """{"RemoveTagsFromResourceResponse": {"ResponseMetadata": {"RequestId": "c6499a01-a664-11e4-8069-fb454b71a80e"}}} + """ \ No newline at end of file diff --git a/tests/test_rds2/test_rds2.py b/tests/test_rds2/test_rds2.py index 7e50d1edf..07ee8aa5d 100644 --- a/tests/test_rds2/test_rds2.py +++ b/tests/test_rds2/test_rds2.py @@ -291,6 +291,46 @@ def test_list_tags(): {'Value': 'bar1', 'Key': 'foo1'}]) + +@disable_on_py3() +@mock_rds2 +def test_add_tags(): + conn = boto.rds2.connect_to_region("us-west-2") + conn.create_db_instance(db_instance_identifier='db-without-tags', + allocated_storage=10, + engine='postgres', + db_instance_class='db.m1.small', + master_username='root', + master_user_password='hunter2', + db_security_groups=["my_sg"], + tags=[('foo', 'bar'), ('foo1', 'bar1')]) + result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:db-without-tags') + list(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.have.length_of(2) + conn.add_tags_to_resource('arn:aws:rds:us-west-2:1234567890:db:db-without-tags', + [('foo', 'fish'), ('foo2', 'bar2')]) + result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:db-without-tags') + list(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.have.length_of(3) + + +@disable_on_py3() +@mock_rds2 +def test_remove_tags(): + conn = boto.rds2.connect_to_region("us-west-2") + conn.create_db_instance(db_instance_identifier='db-with-tags', + allocated_storage=10, + engine='postgres', + db_instance_class='db.m1.small', + master_username='root', + master_user_password='hunter2', + db_security_groups=["my_sg"], + tags=[('foo', 'bar'), ('foo1', 'bar1')]) + result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:db-with-tags') + len(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.equal(2) + conn.remove_tags_from_resource('arn:aws:rds:us-west-2:1234567890:db:db-with-tags', ['foo']) + result = conn.list_tags_for_resource('arn:aws:rds:us-west-2:1234567890:db:db-with-tags') + len(result['ListTagsForResourceResponse']['ListTagsForResourceResult']['TagList']).should.equal(1) + + #@disable_on_py3() #@mock_rds2 #def test_create_database_security_group():