Skip to content

Commit

Permalink
Merge pull request #1928 from danielgtaylor/emr-update
Browse files Browse the repository at this point in the history
EMR Service Update (Tags). Fixes #1928.
  • Loading branch information
danielgtaylor committed Dec 18, 2013
2 parents 32dac5b + 5f4912e commit b9749c6
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 3 deletions.
31 changes: 28 additions & 3 deletions boto/emr/connection.py
Expand Up @@ -269,10 +269,10 @@ def list_steps(self, cluster_id, step_states=None, marker=None):

def add_tags(self, resource_id, tags):
"""
Create new metadata tags for the specified resource ids.
Create new metadata tags for the specified resource id.
:type resource_ids: str
:param resource_ids: The cluster id
:type resource_id: str
:param resource_id: The cluster id
:type tags: dict
:param tags: A dictionary containing the name/value pairs.
Expand All @@ -287,6 +287,22 @@ def add_tags(self, resource_id, tags):
params.update(self._build_tag_list(tags))
return self.get_status('AddTags', params, verb='POST')

def remove_tags(self, resource_id, tags):
"""
Remove metadata tags for the specified resource id.
:type resource_id: str
:param resource_id: The cluster id
:type tags: list
:param tags: A list of tag names to remove.
"""
params = {
'ResourceId': resource_id,
}
params.update(self._build_string_list('TagKeys', tags))
return self.get_status('RemoveTags', params, verb='POST')

def terminate_jobflow(self, jobflow_id):
"""
Terminate an Elastic MapReduce job flow
Expand Down Expand Up @@ -643,6 +659,15 @@ def _build_step_list(self, steps):
params['Steps.member.%s.%s' % (i+1, key)] = value
return params

def _build_string_list(self, field, items):
if not isinstance(items, types.ListType):
items = [items]

params = {}
for i, item in enumerate(items):
params['%s.member.%s' % (field, i + 1)] = item
return params

def _build_tag_list(self, tags):
assert isinstance(tags, dict)

Expand Down
4 changes: 4 additions & 0 deletions boto/emr/emrobject.py
Expand Up @@ -256,6 +256,7 @@ def __init__(self, connection=None):
self.status = None
self.ec2instanceattributes = None
self.applications = None
self.tags = None

def startElement(self, name, attrs, connection):
if name == 'Status':
Expand All @@ -266,6 +267,9 @@ def startElement(self, name, attrs, connection):
return self.ec2instanceattributes
elif name == 'Applications':
self.applications = ResultSet([('member', Application)])
elif name == 'Tags':
self.tags = ResultSet([('member', KeyValue)])
return self.tags
else:
return None

Expand Down
42 changes: 42 additions & 0 deletions tests/unit/emr/test_connection.py
Expand Up @@ -368,3 +368,45 @@ def test_add_mix_of_tags_with_without_values(self):
'Tags.member.3.Key': 'ZzzNoValue',
'Version': '2009-03-31'
})


class TestRemoveTag(AWSMockServiceTestCase):
connection_class = EmrConnection

def default_body(self):
return """<RemoveTagsResponse
xmlns="http://elasticmapreduce.amazonaws.com/doc/2009-03-31">
<RemoveTagsResult/>
<ResponseMetadata>
<RequestId>88888888-8888-8888-8888-888888888888</RequestId>
</ResponseMetadata>
</RemoveTagsResponse>
"""

def test_remove_tags(self):
input_tags = {
'FirstKey': 'One',
'SecondKey': 'Two',
'ZzzNoValue': ''
}
self.set_http_response(200)

with self.assertRaises(TypeError):
self.service_connection.add_tags()

with self.assertRaises(TypeError):
self.service_connection.add_tags('j-123')

with self.assertRaises(AssertionError):
self.service_connection.add_tags('j-123', [])

response = self.service_connection.remove_tags('j-123', ['FirstKey', 'SecondKey'])

self.assertTrue(response)
self.assert_request_parameters({
'Action': 'RemoveTags',
'ResourceId': 'j-123',
'TagKeys.member.1': 'FirstKey',
'TagKeys.member.2': 'SecondKey',
'Version': '2009-03-31'
})

0 comments on commit b9749c6

Please sign in to comment.