Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add custom create_tag method to ec2 resource #160

Merged
merged 3 commits into from
Jul 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions boto3/ec2/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
40 changes: 40 additions & 0 deletions boto3/ec2/createtags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.


def inject_create_tags(event_name, class_attributes, **kwargs):
"""This injects a custom create_tags method onto the ec2 service resource

This is needed because the resource model is not able to express
creating multiple tag resources based on the fact you can apply a set
of tags to multiple ec2 resources.
"""
class_attributes['create_tags'] = create_tags


def create_tags(self, **kwargs):
# Call the client method
self.meta.client.create_tags(**kwargs)
resources = kwargs.get('Resources', [])
tags = kwargs.get('Tags', [])
tag_resources = []

# Generate all of the tag resources that just were created with the
# preceding client call.
for resource in resources:
for tag in tags:
# Add each tag from the tag set for each resource to the list
# that is returned by the method.
tag_resource = self.Tag(resource, tag['Key'], tag['Value'])
tag_resources.append(tag_resource)
return tag_resources
5 changes: 3 additions & 2 deletions boto3/resources/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ def load_from_definition(self, service_name, resource_name, model,

# Create the name based on the requested service and resource
cls_name = resource_name
if service_name != resource_name:
cls_name = service_name + '.' + cls_name
if service_name == resource_name:
cls_name = 'ServiceResource'
cls_name = service_name + '.' + cls_name

base_classes = [ServiceResource]
if self._emitter is not None:
Expand Down
10 changes: 10 additions & 0 deletions boto3/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,8 @@ def resource(self, service_name, region_name=None, api_version=None,
return cls(client=client)

def _register_default_handlers(self):

# S3 customizations
self._session.register(
'creating-client-class.s3',
boto3.utils.lazy_call(
Expand All @@ -283,6 +285,8 @@ def _register_default_handlers(self):
'creating-resource-class.s3.Bucket',
boto3.utils.lazy_call(
'boto3.s3.inject.inject_bucket_load'))

# DynamoDb customizations
self._session.register(
'creating-resource-class.dynamodb',
boto3.utils.lazy_call(
Expand All @@ -293,3 +297,9 @@ def _register_default_handlers(self):
boto3.utils.lazy_call(
'boto3.dynamodb.table.register_table_methods'),
unique_id='high-level-dynamodb-table')

# EC2 Customizations
self._session.register(
'creating-resource-class.ec2.ServiceResource',
boto3.utils.lazy_call(
'boto3.ec2.createtags.inject_create_tags'))
12 changes: 12 additions & 0 deletions tests/unit/ec2/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License'). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the 'license' file accompanying this file. This file is
# distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
73 changes: 73 additions & 0 deletions tests/unit/ec2/test_createtags.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Copyright 2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the 'License'). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the 'license' file accompanying this file. This file is
# distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
from tests import unittest
import mock

import boto3.session
from boto3.ec2 import createtags


class TestCreateTags(unittest.TestCase):
def setUp(self):
self.client = mock.Mock()
self.resource = mock.Mock()
self.resource.meta.client = self.client
self.ref_tags = [
'tag1',
'tag2',
'tag3',
'tag4',
'tag5',
'tag6'
]
self.resource.Tag.side_effect = self.ref_tags

def test_create_tags(self):
ref_kwargs = {
'Resources': ['foo', 'bar'],
'Tags': [
{'Key': 'key1', 'Value': 'value1'},
{'Key': 'key2', 'Value': 'value2'},
{'Key': 'key3', 'Value': 'value3'}
]
}

result_tags = createtags.create_tags(self.resource, **ref_kwargs)

# Ensure the client method was called properly.
self.client.create_tags.assert_called_with(**ref_kwargs)

# Ensure the calls to the Tag reference were correct.
self.assertEqual(
self.resource.Tag.call_args_list,
[mock.call('foo', 'key1', 'value1'),
mock.call('foo', 'key2', 'value2'),
mock.call('foo', 'key3', 'value3'),
mock.call('bar', 'key1', 'value1'),
mock.call('bar', 'key2', 'value2'),
mock.call('bar', 'key3', 'value3')])

# Ensure the return values are as expected.
self.assertEqual(result_tags, self.ref_tags)


class TestCreateTagsInjection(unittest.TestCase):
def test_create_tags_injected_to_resource(self):
session = boto3.session.Session(region_name='us-west-2')
with mock.patch('boto3.ec2.createtags.create_tags') as mock_method:
resource = session.resource('ec2')
self.assertTrue(hasattr(resource, 'create_tags'),
'EC2 resource does not have create_tags method.')
self.assertIs(resource.create_tags, mock_method,
'custom create_tags method was not injected onto '
'EC2 service resource')
3 changes: 2 additions & 1 deletion tests/unit/resources/test_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,8 @@ def test_event_emitted_when_class_created(self):
self.assertTrue(self.emitter.emit.called)
call_args = self.emitter.emit.call_args
# Verify the correct event name emitted.
self.assertEqual(call_args[0][0], 'creating-resource-class.test')
self.assertEqual(call_args[0][0],
'creating-resource-class.test.ServiceResource')

# Verify we send out the class attributes dict.
actual_class_attrs = sorted(call_args[1]['class_attributes'])
Expand Down