Skip to content

Commit

Permalink
Add configurable option to support nested inventory groups.
Browse files Browse the repository at this point in the history
  • Loading branch information
cchurch committed Jul 1, 2014
1 parent 14cf3c4 commit 4036df1
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 13 deletions.
3 changes: 3 additions & 0 deletions plugins/inventory/ec2.ini
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,6 @@ cache_path = ~/.ansible/tmp
# seconds, a new API call will be made, and the cache file will be updated.
# To disable the cache, set this value to 0
cache_max_age = 300

# Organize groups into a nested/hierarchy instead of a flat namespace.
nested_groups = False
77 changes: 64 additions & 13 deletions plugins/inventory/ec2.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,12 @@ def read_settings(self):
self.cache_path_cache = cache_dir + "/ansible-ec2.cache"
self.cache_path_index = cache_dir + "/ansible-ec2.index"
self.cache_max_age = config.getint('ec2', 'cache_max_age')


# Configure nested groups instead of flat namespace.
if config.has_option('ec2', 'nested_groups'):
self.nested_groups = config.getboolean('ec2', 'nested_groups')
else:
self.nested_groups = False

def parse_cli_args(self):
''' Command line argument processing '''
Expand Down Expand Up @@ -321,7 +325,6 @@ def get_instance(self, region, instance_id):
for instance in reservation.instances:
return instance


def add_instance(self, instance, region):
''' Adds an instance to the inventory and index, as long as it is
addressable '''
Expand All @@ -345,25 +348,40 @@ def add_instance(self, instance, region):

# Inventory: Group by instance ID (always a group of 1)
self.inventory[instance.id] = [dest]
if self.nested_groups:
self.push_group(self.inventory, 'instances', instance.id)

# Inventory: Group by region
self.push(self.inventory, region, dest)
if self.nested_groups:
self.push_group(self.inventory, 'regions', region)
else:
self.push(self.inventory, region, dest)

# Inventory: Group by availability zone
self.push(self.inventory, instance.placement, dest)
if self.nested_groups:
self.push_group(self.inventory, region, instance.placement)

# Inventory: Group by instance type
self.push(self.inventory, self.to_safe('type_' + instance.instance_type), dest)
type_name = self.to_safe('type_' + instance.instance_type)
self.push(self.inventory, type_name, dest)
if self.nested_groups:
self.push_group(self.inventory, 'types', type_name)

# Inventory: Group by key pair
if instance.key_name:
self.push(self.inventory, self.to_safe('key_' + instance.key_name), dest)
key_name = self.to_safe('key_' + instance.key_name)
self.push(self.inventory, key_name, dest)
if self.nested_groups:
self.push_group(self.inventory, 'keys', key_name)

# Inventory: Group by security group
try:
for group in instance.groups:
key = self.to_safe("security_group_" + group.name)
self.push(self.inventory, key, dest)
if self.nested_groups:
self.push_group(self.inventory, 'security_groups', key)
except AttributeError:
print 'Package boto seems a bit older.'
print 'Please upgrade boto >= 2.3.0.'
Expand All @@ -373,12 +391,17 @@ def add_instance(self, instance, region):
for k, v in instance.tags.iteritems():
key = self.to_safe("tag_" + k + "=" + v)
self.push(self.inventory, key, dest)
if self.nested_groups:
self.push_group(self.inventory, 'tags', self.to_safe("tag_" + k))
self.push_group(self.inventory, self.to_safe("tag_" + k), key)

# Inventory: Group by Route53 domain names if enabled
if self.route53_enabled:
route53_names = self.get_instance_route53_names(instance)
for name in route53_names:
self.push(self.inventory, name, dest)
if self.nested_groups:
self.push_group(self.inventory, 'route53', name)

# Global Tag: tag all EC2 instances
self.push(self.inventory, 'ec2', dest)
Expand Down Expand Up @@ -410,35 +433,54 @@ def add_rds_instance(self, instance, region):

# Inventory: Group by instance ID (always a group of 1)
self.inventory[instance.id] = [dest]
if self.nested_groups:
self.push_group(self.inventory, 'instances', instance.id)

# Inventory: Group by region
self.push(self.inventory, region, dest)
if self.nested_groups:
self.push_group(self.inventory, 'regions', region)
else:
self.push(self.inventory, region, dest)

# Inventory: Group by availability zone
self.push(self.inventory, instance.availability_zone, dest)
if self.nested_groups:
self.push_group(self.inventory, region, instance.availability_zone)

# Inventory: Group by instance type
self.push(self.inventory, self.to_safe('type_' + instance.instance_class), dest)
type_name = self.to_safe('type_' + instance.instance_class)
self.push(self.inventory, type_name, dest)
if self.nested_groups:
self.push_group(self.inventory, 'types', type_name)

# Inventory: Group by security group
try:
if instance.security_group:
key = self.to_safe("security_group_" + instance.security_group.name)
self.push(self.inventory, key, dest)
if self.nested_groups:
self.push_group(self.inventory, 'security_groups', key)

except AttributeError:
print 'Package boto seems a bit older.'
print 'Please upgrade boto >= 2.3.0.'
sys.exit(1)

# Inventory: Group by engine
self.push(self.inventory, self.to_safe("rds_" + instance.engine), dest)
if self.nested_groups:
self.push_group(self.inventory, 'rds_engines', self.to_safe("rds_" + instance.engine))

# Inventory: Group by parameter group
self.push(self.inventory, self.to_safe("rds_parameter_group_" + instance.parameter_group.name), dest)
if self.nested_groups:
self.push_group(self.inventory, 'rds_parameter_groups', self.to_safe("rds_parameter_group_" + instance.parameter_group.name))

# Global Tag: all RDS instances
self.push(self.inventory, 'rds', dest)

self.inventory["_meta"]["hostvars"][dest] = self.get_host_info_dict_from_instance(instance)


def get_route53_records(self):
''' Get and store the map of resource records to domain names that
Expand Down Expand Up @@ -553,14 +595,23 @@ def get_host_info(self):
return self.json_format_dict(self.get_host_info_dict_from_instance(instance), True)

def push(self, my_dict, key, element):
''' Pushed an element onto an array that may not have been defined in
''' Push an element onto an array that may not have been defined in
the dict '''

if key in my_dict:
my_dict[key].append(element);
group_info = my_dict.setdefault(key, [])
if isinstance(group_info, dict):
host_list = group_info.setdefault('hosts', [])
host_list.append(element)
else:
my_dict[key] = [element]

group_info.append(element)

def push_group(self, my_dict, key, element):
''' Push a group as a child of another group. '''
parent_group = my_dict.setdefault(key, {})
if not isinstance(parent_group, dict):
parent_group = my_dict[key] = {'hosts': parent_group}
child_groups = parent_group.setdefault('children', [])
if element not in child_groups:
child_groups.append(element)

def get_inventory_from_cache(self):
''' Reads the inventory from the cache file and returns it as a JSON
Expand Down

0 comments on commit 4036df1

Please sign in to comment.