[cloud][contrib] Set missing default values for EC2 inventory (#28375)
* Set missing default values for EC2 inventory * Make it run even with no ec2.ini file * Fixing INI file reading * Refactor how defaults are handeled Define defaults in a dictionary and use .get rather than if statements with has_option * Removing double keys and fixing logic for instance_filter * Removing one more doubled key
This commit is contained in:
parent
916e6be888
commit
d35ef1fc21
1 changed files with 108 additions and 129 deletions
|
@ -139,7 +139,7 @@ from ansible.module_utils import ec2 as ec2_utils
|
||||||
|
|
||||||
HAS_BOTO3 = False
|
HAS_BOTO3 = False
|
||||||
try:
|
try:
|
||||||
import boto3
|
import boto3 # noqa
|
||||||
HAS_BOTO3 = True
|
HAS_BOTO3 = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
@ -152,6 +152,60 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
|
|
||||||
|
DEFAULTS = {
|
||||||
|
'all_elasticache_clusters': 'False',
|
||||||
|
'all_elasticache_nodes': 'False',
|
||||||
|
'all_elasticache_replication_groups': 'False',
|
||||||
|
'all_instances': 'False',
|
||||||
|
'all_rds_instances': 'False',
|
||||||
|
'aws_access_key_id': None,
|
||||||
|
'aws_secret_access_key': None,
|
||||||
|
'aws_security_token': None,
|
||||||
|
'boto_profile': None,
|
||||||
|
'cache_max_age': '300',
|
||||||
|
'cache_path': '~/.ansible/tmp',
|
||||||
|
'destination_variable': 'public_dns_name',
|
||||||
|
'elasticache': 'True',
|
||||||
|
'eucalyptus': 'False',
|
||||||
|
'eucalyptus_host': None,
|
||||||
|
'expand_csv_tags': 'False',
|
||||||
|
'group_by_ami_id': 'True',
|
||||||
|
'group_by_availability_zone': 'True',
|
||||||
|
'group_by_aws_account': 'False',
|
||||||
|
'group_by_elasticache_cluster': 'True',
|
||||||
|
'group_by_elasticache_engine': 'True',
|
||||||
|
'group_by_elasticache_parameter_group': 'True',
|
||||||
|
'group_by_elasticache_replication_group': 'True',
|
||||||
|
'group_by_instance_id': 'True',
|
||||||
|
'group_by_instance_state': 'False',
|
||||||
|
'group_by_instance_type': 'True',
|
||||||
|
'group_by_key_pair': 'True',
|
||||||
|
'group_by_platform': 'True',
|
||||||
|
'group_by_rds_engine': 'True',
|
||||||
|
'group_by_rds_parameter_group': 'True',
|
||||||
|
'group_by_region': 'True',
|
||||||
|
'group_by_route53_names': 'True',
|
||||||
|
'group_by_security_group': 'True',
|
||||||
|
'group_by_tag_keys': 'True',
|
||||||
|
'group_by_tag_none': 'True',
|
||||||
|
'group_by_vpc_id': 'True',
|
||||||
|
'hostname_variable': None,
|
||||||
|
'iam_role': None,
|
||||||
|
'include_rds_clusters': 'False',
|
||||||
|
'nested_groups': 'False',
|
||||||
|
'pattern_exclude': None,
|
||||||
|
'pattern_include': None,
|
||||||
|
'rds': 'False',
|
||||||
|
'regions': 'all',
|
||||||
|
'regions_exclude': 'us-gov-west-1, cn-north-1',
|
||||||
|
'replace_dash_in_groups': 'True',
|
||||||
|
'route53': 'False',
|
||||||
|
'route53_excluded_zones': '',
|
||||||
|
'route53_hostnames': None,
|
||||||
|
'stack_filters': 'False',
|
||||||
|
'vpc_destination_variable': 'ip_address'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Ec2Inventory(object):
|
class Ec2Inventory(object):
|
||||||
|
|
||||||
|
@ -232,24 +286,32 @@ class Ec2Inventory(object):
|
||||||
}
|
}
|
||||||
|
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser(DEFAULTS)
|
||||||
else:
|
else:
|
||||||
config = configparser.SafeConfigParser()
|
config = configparser.SafeConfigParser(DEFAULTS)
|
||||||
ec2_ini_path = os.environ.get('EC2_INI_PATH', defaults['ec2']['ini_path'])
|
ec2_ini_path = os.environ.get('EC2_INI_PATH', defaults['ec2']['ini_path'])
|
||||||
ec2_ini_path = os.path.expanduser(os.path.expandvars(ec2_ini_path))
|
ec2_ini_path = os.path.expanduser(os.path.expandvars(ec2_ini_path))
|
||||||
|
|
||||||
if not os.path.isfile(ec2_ini_path):
|
if not os.path.isfile(ec2_ini_path):
|
||||||
ec2_ini_path = os.path.expanduser(defaults['ec2']['ini_fallback'])
|
ec2_ini_path = os.path.expanduser(defaults['ec2']['ini_fallback'])
|
||||||
|
|
||||||
config.read(ec2_ini_path)
|
if os.path.isfile(ec2_ini_path):
|
||||||
|
config.read(ec2_ini_path)
|
||||||
|
|
||||||
|
# Add empty sections if they don't exist
|
||||||
|
try:
|
||||||
|
config.add_section('ec2')
|
||||||
|
except configparser.DuplicateSectionError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
config.add_section('credentials')
|
||||||
|
except configparser.DuplicateSectionError:
|
||||||
|
pass
|
||||||
|
|
||||||
# is eucalyptus?
|
# is eucalyptus?
|
||||||
self.eucalyptus_host = None
|
self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
|
||||||
self.eucalyptus = False
|
self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
|
||||||
if config.has_option('ec2', 'eucalyptus'):
|
|
||||||
self.eucalyptus = config.getboolean('ec2', 'eucalyptus')
|
|
||||||
if self.eucalyptus and config.has_option('ec2', 'eucalyptus_host'):
|
|
||||||
self.eucalyptus_host = config.get('ec2', 'eucalyptus_host')
|
|
||||||
|
|
||||||
# Regions
|
# Regions
|
||||||
self.regions = []
|
self.regions = []
|
||||||
|
@ -259,6 +321,7 @@ class Ec2Inventory(object):
|
||||||
self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name, **self.credentials)
|
self.regions.append(boto.connect_euca(host=self.eucalyptus_host).region.name, **self.credentials)
|
||||||
else:
|
else:
|
||||||
configRegions_exclude = config.get('ec2', 'regions_exclude')
|
configRegions_exclude = config.get('ec2', 'regions_exclude')
|
||||||
|
|
||||||
for regionInfo in ec2.regions():
|
for regionInfo in ec2.regions():
|
||||||
if regionInfo.name not in configRegions_exclude:
|
if regionInfo.name not in configRegions_exclude:
|
||||||
self.regions.append(regionInfo.name)
|
self.regions.append(regionInfo.name)
|
||||||
|
@ -273,11 +336,7 @@ class Ec2Inventory(object):
|
||||||
# Destination addresses
|
# Destination addresses
|
||||||
self.destination_variable = config.get('ec2', 'destination_variable')
|
self.destination_variable = config.get('ec2', 'destination_variable')
|
||||||
self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
|
self.vpc_destination_variable = config.get('ec2', 'vpc_destination_variable')
|
||||||
|
self.hostname_variable = config.get('ec2', 'hostname_variable')
|
||||||
if config.has_option('ec2', 'hostname_variable'):
|
|
||||||
self.hostname_variable = config.get('ec2', 'hostname_variable')
|
|
||||||
else:
|
|
||||||
self.hostname_variable = None
|
|
||||||
|
|
||||||
if config.has_option('ec2', 'destination_format') and \
|
if config.has_option('ec2', 'destination_format') and \
|
||||||
config.has_option('ec2', 'destination_format_tags'):
|
config.has_option('ec2', 'destination_format_tags'):
|
||||||
|
@ -289,36 +348,22 @@ class Ec2Inventory(object):
|
||||||
|
|
||||||
# Route53
|
# Route53
|
||||||
self.route53_enabled = config.getboolean('ec2', 'route53')
|
self.route53_enabled = config.getboolean('ec2', 'route53')
|
||||||
if config.has_option('ec2', 'route53_hostnames'):
|
self.route53_hostnames = config.get('ec2', 'route53_hostnames')
|
||||||
self.route53_hostnames = config.get('ec2', 'route53_hostnames')
|
|
||||||
else:
|
|
||||||
self.route53_hostnames = None
|
|
||||||
self.route53_excluded_zones = []
|
self.route53_excluded_zones = []
|
||||||
if config.has_option('ec2', 'route53_excluded_zones'):
|
self.route53_excluded_zones = [a for a in config.get('ec2', 'route53_excluded_zones').split(',') if a]
|
||||||
self.route53_excluded_zones.extend(
|
|
||||||
config.get('ec2', 'route53_excluded_zones', '').split(','))
|
|
||||||
|
|
||||||
# Include RDS instances?
|
# Include RDS instances?
|
||||||
self.rds_enabled = True
|
self.rds_enabled = config.get('ec2', 'rds')
|
||||||
if config.has_option('ec2', 'rds'):
|
|
||||||
self.rds_enabled = config.getboolean('ec2', 'rds')
|
|
||||||
|
|
||||||
# Include RDS cluster instances?
|
# Include RDS cluster instances?
|
||||||
if config.has_option('ec2', 'include_rds_clusters'):
|
self.include_rds_clusters = config.getboolean('ec2', 'include_rds_clusters')
|
||||||
self.include_rds_clusters = config.getboolean('ec2', 'include_rds_clusters')
|
|
||||||
else:
|
|
||||||
self.include_rds_clusters = False
|
|
||||||
|
|
||||||
# Include ElastiCache instances?
|
# Include ElastiCache instances?
|
||||||
self.elasticache_enabled = True
|
self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
|
||||||
if config.has_option('ec2', 'elasticache'):
|
|
||||||
self.elasticache_enabled = config.getboolean('ec2', 'elasticache')
|
|
||||||
|
|
||||||
# Return all EC2 instances?
|
# Return all EC2 instances?
|
||||||
if config.has_option('ec2', 'all_instances'):
|
self.all_instances = config.getboolean('ec2', 'all_instances')
|
||||||
self.all_instances = config.getboolean('ec2', 'all_instances')
|
|
||||||
else:
|
|
||||||
self.all_instances = False
|
|
||||||
|
|
||||||
# Instance states to be gathered in inventory. Default is 'running'.
|
# Instance states to be gathered in inventory. Default is 'running'.
|
||||||
# Setting 'all_instances' to 'yes' overrides this option.
|
# Setting 'all_instances' to 'yes' overrides this option.
|
||||||
|
@ -343,49 +388,30 @@ class Ec2Inventory(object):
|
||||||
self.ec2_instance_states = ['running']
|
self.ec2_instance_states = ['running']
|
||||||
|
|
||||||
# Return all RDS instances? (if RDS is enabled)
|
# Return all RDS instances? (if RDS is enabled)
|
||||||
if config.has_option('ec2', 'all_rds_instances') and self.rds_enabled:
|
self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
|
||||||
self.all_rds_instances = config.getboolean('ec2', 'all_rds_instances')
|
|
||||||
else:
|
|
||||||
self.all_rds_instances = False
|
|
||||||
|
|
||||||
# Return all ElastiCache replication groups? (if ElastiCache is enabled)
|
# Return all ElastiCache replication groups? (if ElastiCache is enabled)
|
||||||
if config.has_option('ec2', 'all_elasticache_replication_groups') and self.elasticache_enabled:
|
self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
|
||||||
self.all_elasticache_replication_groups = config.getboolean('ec2', 'all_elasticache_replication_groups')
|
|
||||||
else:
|
|
||||||
self.all_elasticache_replication_groups = False
|
|
||||||
|
|
||||||
# Return all ElastiCache clusters? (if ElastiCache is enabled)
|
# Return all ElastiCache clusters? (if ElastiCache is enabled)
|
||||||
if config.has_option('ec2', 'all_elasticache_clusters') and self.elasticache_enabled:
|
self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
|
||||||
self.all_elasticache_clusters = config.getboolean('ec2', 'all_elasticache_clusters')
|
|
||||||
else:
|
|
||||||
self.all_elasticache_clusters = False
|
|
||||||
|
|
||||||
# Return all ElastiCache nodes? (if ElastiCache is enabled)
|
# Return all ElastiCache nodes? (if ElastiCache is enabled)
|
||||||
if config.has_option('ec2', 'all_elasticache_nodes') and self.elasticache_enabled:
|
self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
|
||||||
self.all_elasticache_nodes = config.getboolean('ec2', 'all_elasticache_nodes')
|
|
||||||
else:
|
|
||||||
self.all_elasticache_nodes = False
|
|
||||||
|
|
||||||
# boto configuration profile (prefer CLI argument then environment variables then config file)
|
# boto configuration profile (prefer CLI argument then environment variables then config file)
|
||||||
self.boto_profile = self.args.boto_profile or os.environ.get('AWS_PROFILE')
|
self.boto_profile = self.args.boto_profile or \
|
||||||
if config.has_option('ec2', 'boto_profile') and not self.boto_profile:
|
os.environ.get('AWS_PROFILE') or \
|
||||||
self.boto_profile = config.get('ec2', 'boto_profile')
|
config.get('ec2', 'boto_profile')
|
||||||
|
|
||||||
# AWS credentials (prefer environment variables)
|
# AWS credentials (prefer environment variables)
|
||||||
if not (self.boto_profile or os.environ.get('AWS_ACCESS_KEY_ID') or
|
if not (self.boto_profile or os.environ.get('AWS_ACCESS_KEY_ID') or
|
||||||
os.environ.get('AWS_PROFILE')):
|
os.environ.get('AWS_PROFILE')):
|
||||||
if config.has_option('credentials', 'aws_access_key_id'):
|
|
||||||
aws_access_key_id = config.get('credentials', 'aws_access_key_id')
|
aws_access_key_id = config.get('credentials', 'aws_access_key_id')
|
||||||
else:
|
aws_secret_access_key = config.get('credentials', 'aws_secret_access_key')
|
||||||
aws_access_key_id = None
|
aws_security_token = config.get('credentials', 'aws_security_token')
|
||||||
if config.has_option('credentials', 'aws_secret_access_key'):
|
|
||||||
aws_secret_access_key = config.get('credentials', 'aws_secret_access_key')
|
|
||||||
else:
|
|
||||||
aws_secret_access_key = None
|
|
||||||
if config.has_option('credentials', 'aws_security_token'):
|
|
||||||
aws_security_token = config.get('credentials', 'aws_security_token')
|
|
||||||
else:
|
|
||||||
aws_security_token = None
|
|
||||||
if aws_access_key_id:
|
if aws_access_key_id:
|
||||||
self.credentials = {
|
self.credentials = {
|
||||||
'aws_access_key_id': aws_access_key_id,
|
'aws_access_key_id': aws_access_key_id,
|
||||||
|
@ -409,86 +435,39 @@ class Ec2Inventory(object):
|
||||||
self.cache_path_index = os.path.join(cache_dir, "%s.index" % cache_name)
|
self.cache_path_index = os.path.join(cache_dir, "%s.index" % cache_name)
|
||||||
self.cache_max_age = config.getint('ec2', 'cache_max_age')
|
self.cache_max_age = config.getint('ec2', 'cache_max_age')
|
||||||
|
|
||||||
if config.has_option('ec2', 'expand_csv_tags'):
|
self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
|
||||||
self.expand_csv_tags = config.getboolean('ec2', 'expand_csv_tags')
|
|
||||||
else:
|
|
||||||
self.expand_csv_tags = False
|
|
||||||
|
|
||||||
# Configure nested groups instead of flat namespace.
|
# Configure nested groups instead of flat namespace.
|
||||||
if config.has_option('ec2', 'nested_groups'):
|
self.nested_groups = config.getboolean('ec2', 'nested_groups')
|
||||||
self.nested_groups = config.getboolean('ec2', 'nested_groups')
|
|
||||||
else:
|
|
||||||
self.nested_groups = False
|
|
||||||
|
|
||||||
# Replace dash or not in group names
|
# Replace dash or not in group names
|
||||||
if config.has_option('ec2', 'replace_dash_in_groups'):
|
self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
|
||||||
self.replace_dash_in_groups = config.getboolean('ec2', 'replace_dash_in_groups')
|
|
||||||
else:
|
|
||||||
self.replace_dash_in_groups = True
|
|
||||||
|
|
||||||
# IAM role to assume for connection
|
# IAM role to assume for connection
|
||||||
if config.has_option('ec2', 'iam_role'):
|
self.iam_role = config.get('ec2', 'iam_role')
|
||||||
self.iam_role = config.get('ec2', 'iam_role')
|
|
||||||
else:
|
|
||||||
self.iam_role = None
|
|
||||||
|
|
||||||
# Configure which groups should be created.
|
# Configure which groups should be created.
|
||||||
group_by_options = [
|
|
||||||
'group_by_instance_id',
|
group_by_options = [a for a in DEFAULTS if a.startswith('group_by')]
|
||||||
'group_by_region',
|
|
||||||
'group_by_availability_zone',
|
|
||||||
'group_by_ami_id',
|
|
||||||
'group_by_instance_type',
|
|
||||||
'group_by_instance_state',
|
|
||||||
'group_by_platform',
|
|
||||||
'group_by_key_pair',
|
|
||||||
'group_by_vpc_id',
|
|
||||||
'group_by_security_group',
|
|
||||||
'group_by_tag_keys',
|
|
||||||
'group_by_tag_none',
|
|
||||||
'group_by_route53_names',
|
|
||||||
'group_by_rds_engine',
|
|
||||||
'group_by_rds_parameter_group',
|
|
||||||
'group_by_elasticache_engine',
|
|
||||||
'group_by_elasticache_cluster',
|
|
||||||
'group_by_elasticache_parameter_group',
|
|
||||||
'group_by_elasticache_replication_group',
|
|
||||||
'group_by_aws_account',
|
|
||||||
]
|
|
||||||
for option in group_by_options:
|
for option in group_by_options:
|
||||||
if config.has_option('ec2', option):
|
setattr(self, option, config.getboolean('ec2', option))
|
||||||
setattr(self, option, config.getboolean('ec2', option))
|
|
||||||
else:
|
|
||||||
setattr(self, option, True)
|
|
||||||
|
|
||||||
# Do we need to just include hosts that match a pattern?
|
# Do we need to just include hosts that match a pattern?
|
||||||
try:
|
self.pattern_include = config.get('ec2', 'pattern_include')
|
||||||
pattern_include = config.get('ec2', 'pattern_include')
|
if self.pattern_include:
|
||||||
if pattern_include and len(pattern_include) > 0:
|
self.pattern_include = re.compile(self.pattern_include)
|
||||||
self.pattern_include = re.compile(pattern_include)
|
|
||||||
else:
|
|
||||||
self.pattern_include = None
|
|
||||||
except configparser.NoOptionError:
|
|
||||||
self.pattern_include = None
|
|
||||||
|
|
||||||
# Do we need to exclude hosts that match a pattern?
|
# Do we need to exclude hosts that match a pattern?
|
||||||
try:
|
self.pattern_exclude = config.get('ec2', 'pattern_exclude')
|
||||||
pattern_exclude = config.get('ec2', 'pattern_exclude')
|
if self.pattern_exclude:
|
||||||
if pattern_exclude and len(pattern_exclude) > 0:
|
self.pattern_exclude = re.compile(self.pattern_exclude)
|
||||||
self.pattern_exclude = re.compile(pattern_exclude)
|
|
||||||
else:
|
|
||||||
self.pattern_exclude = None
|
|
||||||
except configparser.NoOptionError:
|
|
||||||
self.pattern_exclude = None
|
|
||||||
|
|
||||||
# Do we want to stack multiple filters?
|
# Do we want to stack multiple filters?
|
||||||
if config.has_option('ec2', 'stack_filters'):
|
self.stack_filters = config.getboolean('ec2', 'stack_filters')
|
||||||
self.stack_filters = config.getboolean('ec2', 'stack_filters')
|
|
||||||
else:
|
|
||||||
self.stack_filters = False
|
|
||||||
|
|
||||||
# Instance filters (see boto and EC2 API docs). Ignore invalid filters.
|
# Instance filters (see boto and EC2 API docs). Ignore invalid filters.
|
||||||
self.ec2_instance_filters = []
|
self.ec2_instance_filters = []
|
||||||
|
|
||||||
if config.has_option('ec2', 'instance_filters'):
|
if config.has_option('ec2', 'instance_filters'):
|
||||||
filters = config.get('ec2', 'instance_filters')
|
filters = config.get('ec2', 'instance_filters')
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue