summaryrefslogtreecommitdiff
path: root/plugins/inventory/rax.py
diff options
context:
space:
mode:
authorMatt Martz <matt@sivel.net>2014-10-22 14:40:20 -0500
committerMatt Martz <matt@sivel.net>2014-11-10 11:27:35 -0600
commit2bd927fd818c3cd645d5d21f4550a47b4ecb1dd2 (patch)
tree2329b6bd35ae8410c97cf8ad58f7b2a5d01f3985 /plugins/inventory/rax.py
parent7812c70d3b8a8fbab3127ee7033345a0fb455bfe (diff)
downloadansible-2bd927fd818c3cd645d5d21f4550a47b4ecb1dd2.tar.gz
Support RackConnect v3 by allowing a network to be specified for use in determining ansible_ssh_host
Diffstat (limited to 'plugins/inventory/rax.py')
-rw-r--r--[-rwxr-xr-x]plugins/inventory/rax.py149
1 files changed, 94 insertions, 55 deletions
diff --git a/plugins/inventory/rax.py b/plugins/inventory/rax.py
index 457c20962a..87b7f9cafc 100755..100644
--- a/plugins/inventory/rax.py
+++ b/plugins/inventory/rax.py
@@ -1,8 +1,10 @@
#!/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
# 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
# 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 Cloud Inventory
+
+Authors:
+ Jesse Keating <jesse.keating@rackspace.com,
+ 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
- - |
- When run against a specific host, this script returns the following
- variables:
+
+ When run against a specific host, this script returns variables similar to:
rax_os-ext-sts_task_state
rax_addresses
rax_links
@@ -50,63 +56,67 @@ description:
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
- 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
+Notes:
+ RAX_CREDS_FILE is an optional environment variable that points to a
pyrax-compatible credentials file.
- - If RAX_CREDS_FILE is not supplied, rax.py will look for a credentials file
- at ~/.rackspace_cloud_credentials.
- - See https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#authenticating
- - 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
+
+ If RAX_CREDS_FILE is not supplied, rax.py will look for a credentials file
+ at ~/.rackspace_cloud_credentials. It uses the Rackspace Python SDK, and
+ therefore requires a file formatted per the SDK's specifications. See
+ https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md
+ #authenticating
+
+ 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
- https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md#pyrax-configuration
- - RAX_META_PREFIX is an environment variable that changes the prefix used
+ https://github.com/rackspace/pyrax/blob/master/docs/getting_started.md
+
+ RAX_META_PREFIX is an environment variable that changes the prefix used
for meta key/value groups. For compatibility with ec2.py set to
RAX_META_PREFIX=tag
-requirements: [ "pyrax" ]
-examples:
- - description: List server instances
- code: RAX_CREDS_FILE=~/.raxpub rax.py --list
- - description: List servers in ORD datacenter only
- code: RAX_CREDS_FILE=~/.raxpub RAX_REGION=ORD rax.py --list
- - description: List servers in ORD and DFW datacenters
- code: RAX_CREDS_FILE=~/.raxpub RAX_REGION=ORD,DFW rax.py --list
- - description: Get server details for server named "server.example.com"
- code: RAX_CREDS_FILE=~/.raxpub rax.py --host server.example.com
-'''
+
+ RAX_ACCESS_NETWORK is an environment variable that will tell the inventory
+ script to use a specific server network to determine the ansible_ssh_host
+ value. If no address is found, ansible_ssh_host will not be set.
+
+ RAX_ACCESS_IP_VERSION is an environment variable related to
+ RAX_ACCESS_NETWORK that will attempt to determine the ansible_ssh_host
+ value for either IPv4 or IPv6. If no address is found, ansible_ssh_host
+ will not be set. Acceptable values are: 4 or 6. Values other than 4 or 6
+ 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 re
import sys
import argparse
+import warnings
import collections
from types import NoneType
try:
import json
-except:
+except ImportError:
import simplejson as json
try:
@@ -126,7 +136,7 @@ def to_dict(obj):
instance = {}
for key in dir(obj):
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)
instance[key] = value
@@ -154,10 +164,25 @@ def _list(regions):
hostvars = collections.defaultdict(dict)
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
for region in regions:
# Connect to the 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():
# Create a group on region
groups[region].append(server.name)
@@ -198,7 +223,21 @@ def _list(regions):
groups['image-%s' % server.image['id']].append(server.name)
# 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:
groups['_meta'] = {'hostvars': hostvars}