The following cases work for me now:
- Create new ASG with tags
- Update tags on ASG (create/change/delete)

In short, the module should now work as expected
wrt tagging. The previous code did not work at all
with latest boto for me (serialization errors) and
the logic was buggy anyway; e.g. removed tags
would never get deleted from ec2.
This commit is contained in:
moe 2015-02-04 05:56:19 +01:00 committed by Matt Clay
parent cadfd56304
commit 5e1e1a4dff

View file

@ -224,6 +224,25 @@ def enforce_required_arguments(module):
def get_properties(autoscaling_group): def get_properties(autoscaling_group):
properties = dict((attr, getattr(autoscaling_group, attr)) for attr in ASG_ATTRIBUTES) properties = dict((attr, getattr(autoscaling_group, attr)) for attr in ASG_ATTRIBUTES)
#
# Ansible output is serialized to JSON but our
# tag list is sometimes a list of Tag-objects
# (as received by Boto).
#
# Since we can not easily teach python to serialize
# such a list we replace it with a dict-representation
# in those cases.
#
# Yes, this is an ugly hack. But at least it works,
# unlike the even uglier hack that was here previously...
#
if 'tags' in properties and properties['tags'] is list:
serializable_tags = {}
for tag in properties['tags']:
serializable_tags[tag.key] = [tag.value, tag.propagate_at_launch]
properties['tags'] = serializable_tags
properties['healthy_instances'] = 0 properties['healthy_instances'] = 0
properties['in_service_instances'] = 0 properties['in_service_instances'] = 0
properties['unhealthy_instances'] = 0 properties['unhealthy_instances'] = 0
@ -326,18 +345,12 @@ def create_autoscaling_group(connection, module):
asg_tags = [] asg_tags = []
for tag in set_tags: for tag in set_tags:
if tag.has_key('key') and tag.has_key('value'): # this block is to support depricated form for k,v in tag.iteritems():
asg_tags.append(Tag(key=tag.get('key'), if k !='propagate_at_launch':
value=tag.get('value'), asg_tags.append(Tag(key=k,
propagate_at_launch=bool(tag.get('propagate_at_launch', True)), value=v,
resource_id=group_name)) propagate_at_launch=bool(tag.get('propagate_at_launch', True)),
else: resource_id=group_name))
for k,v in tag.iteritems():
if k !='propagate_at_launch':
asg_tags.append(Tag(key=k,
value=v,
propagate_at_launch=bool(tag.get('propagate_at_launch', True)),
resource_id=group_name))
if not as_groups: if not as_groups:
if not vpc_zone_identifier and not availability_zones: if not vpc_zone_identifier and not availability_zones:
@ -393,30 +406,25 @@ def create_autoscaling_group(connection, module):
setattr(as_group, attr, module_attr) setattr(as_group, attr, module_attr)
if len(set_tags) > 0: if len(set_tags) > 0:
existing_tags = as_group.tags have_tags = {}
existing_tag_map = dict((tag.key, tag) for tag in existing_tags) want_tags = {}
for tag in set_tags:
if tag.has_key('key') and tag.has_key('value'): # this is to support deprecated method for tag in asg_tags:
if 'key' not in tag: want_tags[tag.key] = [tag.value, tag.propagate_at_launch]
continue
if ( not tag['key'] in existing_tag_map or for tag in as_group.tags:
existing_tag_map[tag['key']].value != tag['value'] or have_tags[tag.key] = [tag.value, tag.propagate_at_launch]
('propagate_at_launch' in tag and dead_tags = []
existing_tag_map[tag['key']].propagate_at_launch != tag['propagate_at_launch']) ): if not tag.key in want_tags:
changed = True changed = True
continue dead_tags.append(tag)
else:
for k,v in tag.iteritems(): if dead_tags != []:
if k !='propagate_at_launch': connection.delete_tags(dead_tags)
if ( not k in existing_tag_map or
existing_tag_map[k].value != v or if have_tags != want_tags:
('propagate_at_launch' in tag and changed = True
existing_tag_map[k].propagate_at_launch != tag['propagate_at_launch']) ):
changed = True
continue
if changed:
connection.create_or_update_tags(asg_tags) connection.create_or_update_tags(asg_tags)
as_group.tags = asg_tags
# handle loadbalancers separately because None != [] # handle loadbalancers separately because None != []
load_balancers = module.params.get('load_balancers') or [] load_balancers = module.params.get('load_balancers') or []