1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00
community.general/contrib/inventory/nova.py
Brian Coca d0c6d2ff1c poreted log_plays, syslog_json and osx_say callbacks to v2
renamed plugins to contrib (they are not really plugins)
rewrote README.md to reflect new usage
added new dir to setup.py so it gets copied with installation, in views
of making using inventory scripts easier in teh future
2015-07-10 10:30:33 -04:00

229 lines
6.8 KiB
Python

#!/usr/bin/env python
# (c) 2012, Marco Vito Moscaritolo <marco@agavee.com>
#
# This file is part of Ansible,
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# WARNING: This file is deprecated. New work should focus on the openstack.py
# inventory module, which properly handles multiple clouds as well as keystone
# v3 and keystone auth plugins
import sys
import re
import os
import ConfigParser
from novaclient import client as nova_client
try:
import json
except ImportError:
import simplejson as json
sys.stderr.write("WARNING: this inventory module is deprecated. please migrate usage to openstack.py\n")
###################################################
# executed with no parameters, return the list of
# all groups and hosts
NOVA_CONFIG_FILES = [os.getcwd() + "/nova.ini",
os.path.expanduser(os.environ.get('ANSIBLE_CONFIG', "~/nova.ini")),
"/etc/ansible/nova.ini"]
NOVA_DEFAULTS = {
'auth_system': None,
'region_name': None,
'service_type': 'compute',
}
def nova_load_config_file():
p = ConfigParser.SafeConfigParser(NOVA_DEFAULTS)
for path in NOVA_CONFIG_FILES:
if os.path.exists(path):
p.read(path)
return p
return None
def get_fallback(config, value, section="openstack"):
"""
Get value from config object and return the value
or false
"""
try:
return config.get(section, value)
except ConfigParser.NoOptionError:
return False
def push(data, key, element):
"""
Assist in items to a dictionary of lists
"""
if (not element) or (not key):
return
if key in data:
data[key].append(element)
else:
data[key] = [element]
def to_safe(word):
'''
Converts 'bad' characters in a string to underscores so they can
be used as Ansible groups
'''
return re.sub(r"[^A-Za-z0-9\-]", "_", word)
def get_ips(server, access_ip=True):
"""
Returns a list of the server's IPs, or the preferred
access IP
"""
private = []
public = []
address_list = []
# Iterate through each servers network(s), get addresses and get type
addresses = getattr(server, 'addresses', {})
if len(addresses) > 0:
for network in addresses.itervalues():
for address in network:
if address.get('OS-EXT-IPS:type', False) == 'fixed':
private.append(address['addr'])
elif address.get('OS-EXT-IPS:type', False) == 'floating':
public.append(address['addr'])
if not access_ip:
address_list.append(server.accessIPv4)
address_list.extend(private)
address_list.extend(public)
return address_list
access_ip = None
# Append group to list
if server.accessIPv4:
access_ip = server.accessIPv4
if (not access_ip) and public and not (private and prefer_private):
access_ip = public[0]
if private and not access_ip:
access_ip = private[0]
return access_ip
def get_metadata(server):
"""Returns dictionary of all host metadata"""
get_ips(server, False)
results = {}
for key in vars(server):
# Extract value
value = getattr(server, key)
# Generate sanitized key
key = 'os_' + re.sub(r"[^A-Za-z0-9\-]", "_", key).lower()
# Att value to instance result (exclude manager class)
#TODO: maybe use value.__class__ or similar inside of key_name
if key != 'os_manager':
results[key] = value
return results
config = nova_load_config_file()
if not config:
sys.exit('Unable to find configfile in %s' % ', '.join(NOVA_CONFIG_FILES))
# Load up connections info based on config and then environment
# variables
username = (get_fallback(config, 'username') or
os.environ.get('OS_USERNAME', None))
api_key = (get_fallback(config, 'api_key') or
os.environ.get('OS_PASSWORD', None))
auth_url = (get_fallback(config, 'auth_url') or
os.environ.get('OS_AUTH_URL', None))
project_id = (get_fallback(config, 'project_id') or
os.environ.get('OS_TENANT_NAME', None))
region_name = (get_fallback(config, 'region_name') or
os.environ.get('OS_REGION_NAME', None))
auth_system = (get_fallback(config, 'auth_system') or
os.environ.get('OS_AUTH_SYSTEM', None))
# Determine what type of IP is preferred to return
prefer_private = False
try:
prefer_private = config.getboolean('openstack', 'prefer_private')
except ConfigParser.NoOptionError:
pass
client = nova_client.Client(
version=config.get('openstack', 'version'),
username=username,
api_key=api_key,
auth_url=auth_url,
region_name=region_name,
project_id=project_id,
auth_system=auth_system,
service_type=config.get('openstack', 'service_type'),
)
# Default or added list option
if (len(sys.argv) == 2 and sys.argv[1] == '--list') or len(sys.argv) == 1:
groups = {'_meta': {'hostvars': {}}}
# Cycle on servers
for server in client.servers.list():
access_ip = get_ips(server)
# Push to name group of 1
push(groups, server.name, access_ip)
# Run through each metadata item and add instance to it
for key, value in server.metadata.iteritems():
composed_key = to_safe('tag_{0}_{1}'.format(key, value))
push(groups, composed_key, access_ip)
# Do special handling of group for backwards compat
# inventory groups
group = server.metadata['group'] if 'group' in server.metadata else 'undefined'
push(groups, group, access_ip)
# Add vars to _meta key for performance optimization in
# Ansible 1.3+
groups['_meta']['hostvars'][access_ip] = get_metadata(server)
# Return server list
print(json.dumps(groups, sort_keys=True, indent=2))
sys.exit(0)
#####################################################
# executed with a hostname as a parameter, return the
# variables for that host
elif len(sys.argv) == 3 and (sys.argv[1] == '--host'):
results = {}
ips = []
for server in client.servers.list():
if sys.argv[2] in (get_ips(server) or []):
results = get_metadata(server)
print(json.dumps(results, sort_keys=True, indent=2))
sys.exit(0)
else:
print "usage: --list ..OR.. --host <hostname>"
sys.exit(1)