Support RackConnect v3 by allowing a network to be specified for use in determining ansible_ssh_host
This commit is contained in:
parent
7812c70d3b
commit
2bd927fd81
1 changed files with 94 additions and 55 deletions
149
plugins/inventory/rax.py
Executable file → Normal file
149
plugins/inventory/rax.py
Executable file → Normal file
|
@ -1,8 +1,10 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
# (c) 2013, Jesse Keating <jesse.keating@rackspace.com>
|
# (c) 2013, Jesse Keating <jesse.keating@rackspace.com,
|
||||||
|
# Paul Durivage <paul.durivage@rackspace.com>,
|
||||||
|
# Matt Martz <matt@sivel.net>
|
||||||
#
|
#
|
||||||
# This file is part of Ansible,
|
# This file is part of Ansible.
|
||||||
#
|
#
|
||||||
# Ansible is free software: you can redistribute it and/or modify
|
# Ansible is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU General Public License as published by
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
@ -17,16 +19,20 @@
|
||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
DOCUMENTATION = '''
|
"""
|
||||||
---
|
Rackspace Cloud Inventory
|
||||||
inventory: rax
|
|
||||||
short_description: Rackspace Public Cloud external inventory script
|
Authors:
|
||||||
description:
|
Jesse Keating <jesse.keating@rackspace.com,
|
||||||
- Generates inventory that Ansible can understand by making API request to
|
Paul Durivage <paul.durivage@rackspace.com>,
|
||||||
|
Matt Martz <matt@sivel.net>
|
||||||
|
|
||||||
|
|
||||||
|
Description:
|
||||||
|
Generates inventory that Ansible can understand by making API request to
|
||||||
Rackspace Public Cloud API
|
Rackspace Public Cloud API
|
||||||
- |
|
|
||||||
When run against a specific host, this script returns the following
|
When run against a specific host, this script returns variables similar to:
|
||||||
variables:
|
|
||||||
rax_os-ext-sts_task_state
|
rax_os-ext-sts_task_state
|
||||||
rax_addresses
|
rax_addresses
|
||||||
rax_links
|
rax_links
|
||||||
|
@ -50,63 +56,67 @@ description:
|
||||||
rax_tenant_id
|
rax_tenant_id
|
||||||
rax_loaded
|
rax_loaded
|
||||||
|
|
||||||
where some item can have nested structure.
|
Notes:
|
||||||
- credentials are set in a credentials file
|
RAX_CREDS_FILE is an optional environment variable that points to a
|
||||||
version_added: None
|
|
||||||
options:
|
|
||||||
creds_file:
|
|
||||||
description:
|
|
||||||
- File to find the Rackspace Public Cloud credentials in
|
|
||||||
required: true
|
|
||||||
default: null
|
|
||||||
region:
|
|
||||||
description:
|
|
||||||
- An optional value to narrow inventory scope, i.e. DFW, ORD, IAD, LON
|
|
||||||
required: false
|
|
||||||
default: null
|
|
||||||
authors:
|
|
||||||
- Jesse Keating <jesse.keating@rackspace.com>
|
|
||||||
- Paul Durivage <paul.durivage@rackspace.com>
|
|
||||||
- Matt Martz <matt@sivel.net>
|
|
||||||
notes:
|
|
||||||
- RAX_CREDS_FILE is an optional environment variable that points to a
|
|
||||||
pyrax-compatible credentials file.
|
pyrax-compatible credentials file.
|
||||||
- If RAX_CREDS_FILE is not supplied, rax.py will look for a credentials file
|
|
||||||
at ~/.rackspace_cloud_credentials.
|
If RAX_CREDS_FILE is not supplied, rax.py will look for a credentials file
|
||||||
- See https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating
|
at ~/.rackspace_cloud_credentials. It uses the Rackspace Python SDK, and
|
||||||
- RAX_REGION is an optional environment variable to narrow inventory search
|
therefore requires a file formatted per the SDK's specifications. See
|
||||||
scope
|
https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md
|
||||||
- RAX_REGION, if used, needs a value like ORD, DFW, SYD (a Rackspace
|
#authenticating
|
||||||
datacenter) and optionally accepts a comma-separated list
|
|
||||||
- RAX_ENV is an environment variable that will use an environment as
|
RAX_REGION is an optional environment variable to narrow inventory search
|
||||||
|
scope. RAX_REGION, if used, needs a value like ORD, DFW, SYD (a Rackspace
|
||||||
|
datacenter) and optionally accepts a comma-separated list.
|
||||||
|
|
||||||
|
RAX_ENV is an environment variable that will use an environment as
|
||||||
configured in ~/.pyrax.cfg, see
|
configured in ~/.pyrax.cfg, see
|
||||||
https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#pyrax-configuration
|
https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md
|
||||||
- RAX_META_PREFIX is an environment variable that changes the prefix used
|
|
||||||
|
RAX_META_PREFIX is an environment variable that changes the prefix used
|
||||||
for meta key/value groups. For compatibility with ec2.py set to
|
for meta key/value groups. For compatibility with ec2.py set to
|
||||||
RAX_META_PREFIX=tag
|
RAX_META_PREFIX=tag
|
||||||
requirements: [ "pyrax" ]
|
|
||||||
examples:
|
RAX_ACCESS_NETWORK is an environment variable that will tell the inventory
|
||||||
- description: List server instances
|
script to use a specific server network to determine the ansible_ssh_host
|
||||||
code: RAX_CREDS_FILE=~/.raxpub rax.py --list
|
value. If no address is found, ansible_ssh_host will not be set.
|
||||||
- description: List servers in ORD datacenter only
|
|
||||||
code: RAX_CREDS_FILE=~/.raxpub RAX_REGION=ORD rax.py --list
|
RAX_ACCESS_IP_VERSION is an environment variable related to
|
||||||
- description: List servers in ORD and DFW datacenters
|
RAX_ACCESS_NETWORK that will attempt to determine the ansible_ssh_host
|
||||||
code: RAX_CREDS_FILE=~/.raxpub RAX_REGION=ORD,DFW rax.py --list
|
value for either IPv4 or IPv6. If no address is found, ansible_ssh_host
|
||||||
- description: Get server details for server named "server.example.com"
|
will not be set. Acceptable values are: 4 or 6. Values other than 4 or 6
|
||||||
code: RAX_CREDS_FILE=~/.raxpub rax.py --host server.example.com
|
will be ignored, and 4 will be used.
|
||||||
'''
|
|
||||||
|
Examples:
|
||||||
|
List server instances
|
||||||
|
$ RAX_CREDS_FILE=~/.raxpub rax.py --list
|
||||||
|
|
||||||
|
List servers in ORD datacenter only
|
||||||
|
$ RAX_CREDS_FILE=~/.raxpub RAX_REGION=ORD rax.py --list
|
||||||
|
|
||||||
|
List servers in ORD and DFW datacenters
|
||||||
|
$ RAX_CREDS_FILE=~/.raxpub RAX_REGION=ORD,DFW rax.py --list
|
||||||
|
|
||||||
|
Get server details for server named "server.example.com"
|
||||||
|
$ RAX_CREDS_FILE=~/.raxpub rax.py --host server.example.com
|
||||||
|
|
||||||
|
Use the instance private IP to connect (instead of public IP)
|
||||||
|
$ RAX_CREDS_FILE=~/.raxpub RAX_PRIVATE_IP=yes rax.py --list
|
||||||
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import argparse
|
import argparse
|
||||||
|
import warnings
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
from types import NoneType
|
from types import NoneType
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import json
|
import json
|
||||||
except:
|
except ImportError:
|
||||||
import simplejson as json
|
import simplejson as json
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -126,7 +136,7 @@ def to_dict(obj):
|
||||||
instance = {}
|
instance = {}
|
||||||
for key in dir(obj):
|
for key in dir(obj):
|
||||||
value = getattr(obj, key)
|
value = getattr(obj, key)
|
||||||
if (isinstance(value, NON_CALLABLES) and not key.startswith('_')):
|
if isinstance(value, NON_CALLABLES) and not key.startswith('_'):
|
||||||
key = rax_slugify(key)
|
key = rax_slugify(key)
|
||||||
instance[key] = value
|
instance[key] = value
|
||||||
|
|
||||||
|
@ -154,10 +164,25 @@ def _list(regions):
|
||||||
hostvars = collections.defaultdict(dict)
|
hostvars = collections.defaultdict(dict)
|
||||||
images = {}
|
images = {}
|
||||||
|
|
||||||
|
network = os.getenv('RAX_ACCESS_NETWORK', 'public')
|
||||||
|
try:
|
||||||
|
ip_version = int(os.getenv('RAX_ACCESS_IP_VERSION', 4))
|
||||||
|
except:
|
||||||
|
ip_version = 4
|
||||||
|
else:
|
||||||
|
if ip_version not in [4, 6]:
|
||||||
|
ip_version = 4
|
||||||
|
|
||||||
# Go through all the regions looking for servers
|
# Go through all the regions looking for servers
|
||||||
for region in regions:
|
for region in regions:
|
||||||
# Connect to the region
|
# Connect to the region
|
||||||
cs = pyrax.connect_to_cloudservers(region=region)
|
cs = pyrax.connect_to_cloudservers(region=region)
|
||||||
|
if isinstance(cs, NoneType):
|
||||||
|
warnings.warn(
|
||||||
|
'Connecting to Rackspace region "%s" has caused Pyrax to '
|
||||||
|
'return a NoneType. Is this a valid region?' % region,
|
||||||
|
RuntimeWarning)
|
||||||
|
continue
|
||||||
for server in cs.servers.list():
|
for server in cs.servers.list():
|
||||||
# Create a group on region
|
# Create a group on region
|
||||||
groups[region].append(server.name)
|
groups[region].append(server.name)
|
||||||
|
@ -198,7 +223,21 @@ def _list(regions):
|
||||||
groups['image-%s' % server.image['id']].append(server.name)
|
groups['image-%s' % server.image['id']].append(server.name)
|
||||||
|
|
||||||
# And finally, add an IP address
|
# And finally, add an IP address
|
||||||
hostvars[server.name]['ansible_ssh_host'] = server.accessIPv4
|
ansible_ssh_host = None
|
||||||
|
# use accessIPv[46] instead of looping address for 'public'
|
||||||
|
if network == 'public':
|
||||||
|
if ip_version == 6 and server.accessIPv6:
|
||||||
|
ansible_ssh_host = server.accessIPv6
|
||||||
|
elif server.accessIPv4:
|
||||||
|
ansible_ssh_host = server.accessIPv4
|
||||||
|
else:
|
||||||
|
addresses = server.addresses.get(network, [])
|
||||||
|
for address in addresses:
|
||||||
|
if address.get('version') == ip_version:
|
||||||
|
ansible_ssh_host = address.get('addr')
|
||||||
|
break
|
||||||
|
if ansible_ssh_host:
|
||||||
|
hostvars[server.name]['ansible_ssh_host'] = ansible_ssh_host
|
||||||
|
|
||||||
if hostvars:
|
if hostvars:
|
||||||
groups['_meta'] = {'hostvars': hostvars}
|
groups['_meta'] = {'hostvars': hostvars}
|
||||||
|
|
Loading…
Reference in a new issue