mirror of
https://github.com/ansible/awx.git
synced 2026-02-20 12:40:06 -03:30
AC-505 Work in progress on cloud inventory sync.
This commit is contained in:
@@ -77,10 +77,14 @@ class InventoryScript(object):
|
||||
'%s:%d' % (parts.hostname, port),
|
||||
parts.path, parts.query, parts.fragment])
|
||||
url_path = '/api/v1/inventories/%d/script/' % self.inventory_id
|
||||
q = {}
|
||||
if self.show_all:
|
||||
q['all'] = 1
|
||||
if self.hostname:
|
||||
url_path += '?%s' % urllib.urlencode({'host': self.hostname})
|
||||
q['host'] = self.hostname
|
||||
elif self.hostvars:
|
||||
url_path += '?%s' % urllib.urlencode({'hostvars': 1})
|
||||
q['hostvars'] = 1
|
||||
url_path += '?%s' % urllib.urlencode(q)
|
||||
url = urlparse.urljoin(url, url_path)
|
||||
response = requests.get(url, auth=auth)
|
||||
response.raise_for_status()
|
||||
@@ -112,6 +116,8 @@ class InventoryScript(object):
|
||||
self.list_ = self.options.get('list', False)
|
||||
self.hostvars = bool(self.options.get('hostvars', False) or
|
||||
os.getenv('INVENTORY_HOSTVARS', ''))
|
||||
self.show_all = bool(self.options.get('show_all', False) or
|
||||
os.getenv('INVENTORY_ALL', ''))
|
||||
self.indent = self.options.get('indent', None)
|
||||
if self.list_ and self.hostname:
|
||||
raise RuntimeError('Only --list or --host may be specified')
|
||||
@@ -154,6 +160,10 @@ def main():
|
||||
default=False, help='Return hostvars inline with --list,'
|
||||
' under ["_meta"]["hostvars"]. Can also be specified '
|
||||
'using INVENTORY_HOSTVARS environment variable.')
|
||||
parser.add_option('--all', action='store_true', dest='show_all',
|
||||
default=False, help='Return all hosts, including those '
|
||||
'marked as offline/disabled. Can also be specified '
|
||||
'using INVENTORY_ALL environment variable.')
|
||||
parser.add_option('--host', dest='hostname', default='',
|
||||
help='Return JSON hash of host vars.')
|
||||
parser.add_option('--indent', dest='indent', type='int', default=None,
|
||||
|
||||
224
awx/plugins/inventory/rax2.py
Executable file
224
awx/plugins/inventory/rax2.py
Executable file
@@ -0,0 +1,224 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# (c) 2013, Jesse Keating <jesse.keating@rackspace.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/>.
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
inventory: rax
|
||||
short_description: Rackspace Public Cloud external inventory script
|
||||
description:
|
||||
- Generates inventory that Ansible can understand by making API request to Rackspace Public Cloud API
|
||||
- |
|
||||
When run against a specific host, this script returns the following variables:
|
||||
rax_os-ext-sts_task_state
|
||||
rax_addresses
|
||||
rax_links
|
||||
rax_image
|
||||
rax_os-ext-sts_vm_state
|
||||
rax_flavor
|
||||
rax_id
|
||||
rax_rax-bandwidth_bandwidth
|
||||
rax_user_id
|
||||
rax_os-dcf_diskconfig
|
||||
rax_accessipv4
|
||||
rax_accessipv6
|
||||
rax_progress
|
||||
rax_os-ext-sts_power_state
|
||||
rax_metadata
|
||||
rax_status
|
||||
rax_updated
|
||||
rax_hostid
|
||||
rax_name
|
||||
rax_created
|
||||
rax_tenant_id
|
||||
rax__loaded
|
||||
|
||||
where some item can have nested structure.
|
||||
- credentials are set in a credentials file
|
||||
version_added: None
|
||||
options:
|
||||
creds_file:
|
||||
description:
|
||||
- File to find the Rackspace Public Cloud credentials in
|
||||
required: true
|
||||
default: null
|
||||
authors:
|
||||
- Jesse Keating <jesse.keating@rackspace.com>
|
||||
- Paul Durivage <paul.durivage@rackspace.com>
|
||||
notes:
|
||||
- One environment variable needs to be set: RAX_CREDS_FILE.
|
||||
- RAX_CREDS_FILE points to a credentials file appropriate for pyrax.
|
||||
- Another optional environment variable may be set: RAX_REGION.
|
||||
- RAX_REGION defines one or more Rackspace Public Cloud regions (DFW, ORD, LON, ...)
|
||||
as a comma-separated list of region names. If set to "all" or omitted, all
|
||||
regions in pyrax.regions will be used.
|
||||
- See https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating
|
||||
requirements: [ "pyrax" ]
|
||||
examples:
|
||||
- description: List server instances
|
||||
code: RAX_CREDS_FILE=~/.raxpub rax.py --list
|
||||
- description: List server instances only in DFW and ORD regions
|
||||
code: RAX_CREDS_FILE=~/.raxpub RAX_REGION=DFW,ORD rax.py --list
|
||||
'''
|
||||
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
import argparse
|
||||
import collections
|
||||
|
||||
try:
|
||||
import json
|
||||
except:
|
||||
import simplejson as json
|
||||
|
||||
try:
|
||||
import pyrax
|
||||
except ImportError:
|
||||
print('pyrax required for this module')
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def host(regions, hostname):
|
||||
hostvars = {}
|
||||
|
||||
for region in regions:
|
||||
# Connect to the region
|
||||
cs = pyrax.connect_to_cloudservers(region=region)
|
||||
for server in cs.servers.list():
|
||||
if server.name == hostname:
|
||||
keys = [key for key in vars(server) if key not in ('manager', '_info')]
|
||||
for key in keys:
|
||||
# Extract value
|
||||
value = getattr(server, key)
|
||||
|
||||
# Generate sanitized key
|
||||
key = 'rax_' + (re.sub("[^A-Za-z0-9\-]", "_", key)
|
||||
.lower()
|
||||
.lstrip("_"))
|
||||
hostvars[key] = value
|
||||
|
||||
# And finally, add an IP address
|
||||
hostvars['ansible_ssh_host'] = server.accessIPv4
|
||||
print(json.dumps(hostvars, sort_keys=True, indent=4))
|
||||
|
||||
|
||||
def _list(regions):
|
||||
groups = collections.defaultdict(list)
|
||||
hostvars = collections.defaultdict(dict)
|
||||
|
||||
# Go through all the regions looking for servers
|
||||
for region in regions:
|
||||
# Connect to the region
|
||||
cs = pyrax.connect_to_cloudservers(region=region)
|
||||
for server in cs.servers.list():
|
||||
# Create a group on region
|
||||
groups[region].append(server.name)
|
||||
|
||||
# Anything we can discern from the hostname?
|
||||
try:
|
||||
subdom = server.name.split('.')[0]
|
||||
except IndexError:
|
||||
pass
|
||||
else:
|
||||
for name in ('web', 'db', 'sql', 'lb', 'app'):
|
||||
if name in subdom:
|
||||
groups[name].append(server.name)
|
||||
|
||||
# Check if group metadata key in servers' metadata
|
||||
try:
|
||||
group = server.metadata['group']
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
# Create group if not exist and add the server
|
||||
groups[group].append(server.name)
|
||||
|
||||
# Add host metadata
|
||||
keys = [key for key in vars(server) if key not in ('manager', '_info')]
|
||||
for key in keys:
|
||||
# Extract value
|
||||
value = getattr(server, key)
|
||||
|
||||
# Generate sanitized key
|
||||
key = 'rax_' + (re.sub("[^A-Za-z0-9\-]", "_", key)
|
||||
.lower()
|
||||
.lstrip('_'))
|
||||
hostvars[server.name][key] = value
|
||||
|
||||
# And finally, add an IP address
|
||||
hostvars[server.name]['ansible_ssh_host'] = server.accessIPv4
|
||||
|
||||
if hostvars:
|
||||
groups['_meta'] = {'hostvars': hostvars}
|
||||
print(json.dumps(groups, sort_keys=True, indent=4))
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(description='Ansible Rackspace Cloud '
|
||||
'inventory module')
|
||||
group = parser.add_mutually_exclusive_group(required=True)
|
||||
group.add_argument('--list', action='store_true',
|
||||
help='List active servers')
|
||||
group.add_argument('--host', help='List details about the specific host')
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def setup():
|
||||
try:
|
||||
creds_file = os.environ['RAX_CREDS_FILE']
|
||||
region = os.getenv('RAX_REGION') or 'all'
|
||||
except KeyError, e:
|
||||
sys.stderr.write('Unable to load environment '
|
||||
'variable %s\n' % e.message)
|
||||
sys.exit(1)
|
||||
|
||||
pyrax.set_setting('identity_type', 'rackspace')
|
||||
|
||||
try:
|
||||
pyrax.set_credential_file(os.path.expanduser(creds_file))
|
||||
except Exception, e:
|
||||
sys.stderr.write("%s: %s\n" % (e, e.message))
|
||||
sys.exit(1)
|
||||
|
||||
regions = []
|
||||
for region in region.split(','):
|
||||
region = region.strip().upper()
|
||||
if region == 'ALL':
|
||||
regions = pyrax.regions
|
||||
break
|
||||
elif region not in pyrax.regions:
|
||||
sys.stderr.write('Unsupported region %s' % region)
|
||||
sys.exit(1)
|
||||
elif region not in regions:
|
||||
regions.append(region)
|
||||
|
||||
return regions
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
regions = setup()
|
||||
if args.list:
|
||||
_list(regions)
|
||||
elif args.host:
|
||||
host(regions, args.host)
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user