|
|
@ -23,7 +23,7 @@
|
|
|
|
Azure External Inventory Script
|
|
|
|
Azure External Inventory Script
|
|
|
|
===============================
|
|
|
|
===============================
|
|
|
|
Generates dynamic inventory by making API requests to the Azure Resource
|
|
|
|
Generates dynamic inventory by making API requests to the Azure Resource
|
|
|
|
Manager using the AAzure Python SDK. For instruction on installing the
|
|
|
|
Manager using the Azure Python SDK. For instruction on installing the
|
|
|
|
Azure Python SDK see http://azure-sdk-for-python.readthedocs.org/
|
|
|
|
Azure Python SDK see http://azure-sdk-for-python.readthedocs.org/
|
|
|
|
|
|
|
|
|
|
|
|
Authentication
|
|
|
|
Authentication
|
|
|
@ -32,7 +32,7 @@ The order of precedence is command line arguments, environment variables,
|
|
|
|
and finally the [default] profile found in ~/.azure/credentials.
|
|
|
|
and finally the [default] profile found in ~/.azure/credentials.
|
|
|
|
|
|
|
|
|
|
|
|
If using a credentials file, it should be an ini formatted file with one or
|
|
|
|
If using a credentials file, it should be an ini formatted file with one or
|
|
|
|
more sections, which we refer to as profiles. The script looks for a
|
|
|
|
more sections, which we refer to as profiles. The script looks for a
|
|
|
|
[default] section, if a profile is not specified either on the command line
|
|
|
|
[default] section, if a profile is not specified either on the command line
|
|
|
|
or with an environment variable. The keys in a profile will match the
|
|
|
|
or with an environment variable. The keys in a profile will match the
|
|
|
|
list of command line arguments below.
|
|
|
|
list of command line arguments below.
|
|
|
@ -42,7 +42,7 @@ in your ~/.azure/credentials file, or a service principal or Active Directory
|
|
|
|
user.
|
|
|
|
user.
|
|
|
|
|
|
|
|
|
|
|
|
Command line arguments:
|
|
|
|
Command line arguments:
|
|
|
|
- profile
|
|
|
|
- profile
|
|
|
|
- client_id
|
|
|
|
- client_id
|
|
|
|
- secret
|
|
|
|
- secret
|
|
|
|
- subscription_id
|
|
|
|
- subscription_id
|
|
|
@ -61,7 +61,7 @@ Environment variables:
|
|
|
|
|
|
|
|
|
|
|
|
Run for Specific Host
|
|
|
|
Run for Specific Host
|
|
|
|
-----------------------
|
|
|
|
-----------------------
|
|
|
|
When run for a specific host using the --host option, a resource group is
|
|
|
|
When run for a specific host using the --host option, a resource group is
|
|
|
|
required. For a specific host, this script returns the following variables:
|
|
|
|
required. For a specific host, this script returns the following variables:
|
|
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -76,7 +76,7 @@ required. For a specific host, this script returns the following variables:
|
|
|
|
"version": "latest"
|
|
|
|
"version": "latest"
|
|
|
|
},
|
|
|
|
},
|
|
|
|
"location": "westus",
|
|
|
|
"location": "westus",
|
|
|
|
"mac_address": "00-0D-3A-31-2C-EC",
|
|
|
|
"mac_address": "00-00-5E-00-53-FE",
|
|
|
|
"name": "object-name",
|
|
|
|
"name": "object-name",
|
|
|
|
"network_interface": "interface-name",
|
|
|
|
"network_interface": "interface-name",
|
|
|
|
"network_interface_id": "/subscriptions/subscription-id/resourceGroups/galaxy-production/providers/Microsoft.Network/networkInterfaces/object-name1",
|
|
|
|
"network_interface_id": "/subscriptions/subscription-id/resourceGroups/galaxy-production/providers/Microsoft.Network/networkInterfaces/object-name1",
|
|
|
@ -142,11 +142,13 @@ If you don't need the powerstate, you can improve performance by turning off pow
|
|
|
|
AZURE_INCLUDE_POWERSTATE=no
|
|
|
|
AZURE_INCLUDE_POWERSTATE=no
|
|
|
|
|
|
|
|
|
|
|
|
azure_rm.ini
|
|
|
|
azure_rm.ini
|
|
|
|
----------------------
|
|
|
|
------------
|
|
|
|
As mentioned above you can control execution using environment variables or an .ini file. A sample
|
|
|
|
As mentioned above, you can control execution using environment variables or a .ini file. A sample
|
|
|
|
azure_rm.ini is included. The name of the .ini file is the basename of the inventory script (in this case
|
|
|
|
azure_rm.ini is included. The name of the .ini file is the basename of the inventory script (in this case
|
|
|
|
'azure_rm') with a .ini extension. This provides you with the flexibility of copying and customizing this
|
|
|
|
'azure_rm') with a .ini extension. It also assumes the .ini file is alongside the script. To specify
|
|
|
|
script and having matching .ini files. Go forth and customize your Azure inventory!
|
|
|
|
a different path for the .ini file, define the AZURE_INI_PATH environment variable:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export AZURE_INI_PATH=/path/to/custom.ini
|
|
|
|
|
|
|
|
|
|
|
|
Powerstate:
|
|
|
|
Powerstate:
|
|
|
|
-----------
|
|
|
|
-----------
|
|
|
@ -189,7 +191,7 @@ import os
|
|
|
|
import re
|
|
|
|
import re
|
|
|
|
import sys
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
|
|
from distutils.version import LooseVersion
|
|
|
|
from packaging.version import Version
|
|
|
|
|
|
|
|
|
|
|
|
from os.path import expanduser
|
|
|
|
from os.path import expanduser
|
|
|
|
|
|
|
|
|
|
|
@ -307,7 +309,7 @@ class AzureRM(object):
|
|
|
|
|
|
|
|
|
|
|
|
def _get_env_credentials(self):
|
|
|
|
def _get_env_credentials(self):
|
|
|
|
env_credentials = dict()
|
|
|
|
env_credentials = dict()
|
|
|
|
for attribute, env_variable in AZURE_CREDENTIAL_ENV_MAPPING.iteritems():
|
|
|
|
for attribute, env_variable in AZURE_CREDENTIAL_ENV_MAPPING.items():
|
|
|
|
env_credentials[attribute] = os.environ.get(env_variable, None)
|
|
|
|
env_credentials[attribute] = os.environ.get(env_variable, None)
|
|
|
|
|
|
|
|
|
|
|
|
if env_credentials['profile'] is not None:
|
|
|
|
if env_credentials['profile'] is not None:
|
|
|
@ -326,7 +328,7 @@ class AzureRM(object):
|
|
|
|
self.log('Getting credentials')
|
|
|
|
self.log('Getting credentials')
|
|
|
|
|
|
|
|
|
|
|
|
arg_credentials = dict()
|
|
|
|
arg_credentials = dict()
|
|
|
|
for attribute, env_variable in AZURE_CREDENTIAL_ENV_MAPPING.iteritems():
|
|
|
|
for attribute, env_variable in AZURE_CREDENTIAL_ENV_MAPPING.items():
|
|
|
|
arg_credentials[attribute] = getattr(params, attribute)
|
|
|
|
arg_credentials[attribute] = getattr(params, attribute)
|
|
|
|
|
|
|
|
|
|
|
|
# try module params
|
|
|
|
# try module params
|
|
|
@ -360,7 +362,11 @@ class AzureRM(object):
|
|
|
|
resource_client = self.rm_client
|
|
|
|
resource_client = self.rm_client
|
|
|
|
resource_client.providers.register(key)
|
|
|
|
resource_client.providers.register(key)
|
|
|
|
except Exception as exc:
|
|
|
|
except Exception as exc:
|
|
|
|
self.fail("One-time registration of {0} failed - {1}".format(key, str(exc)))
|
|
|
|
self.log("One-time registration of {0} failed - {1}".format(key, str(exc)))
|
|
|
|
|
|
|
|
self.log("You might need to register {0} using an admin account".format(key))
|
|
|
|
|
|
|
|
self.log(("To register a provider using the Python CLI: "
|
|
|
|
|
|
|
|
"https://docs.microsoft.com/azure/azure-resource-manager/"
|
|
|
|
|
|
|
|
"resource-manager-common-deployment-errors#noregisteredproviderfound"))
|
|
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
@property
|
|
|
|
def network_client(self):
|
|
|
|
def network_client(self):
|
|
|
@ -440,7 +446,7 @@ class AzureInventory(object):
|
|
|
|
def _parse_cli_args(self):
|
|
|
|
def _parse_cli_args(self):
|
|
|
|
# Parse command line arguments
|
|
|
|
# Parse command line arguments
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
parser = argparse.ArgumentParser(
|
|
|
|
description='Produce an Ansible Inventory file for an Azure subscription')
|
|
|
|
description='Produce an Ansible Inventory file for an Azure subscription')
|
|
|
|
parser.add_argument('--list', action='store_true', default=True,
|
|
|
|
parser.add_argument('--list', action='store_true', default=True,
|
|
|
|
help='List instances (default: True)')
|
|
|
|
help='List instances (default: True)')
|
|
|
|
parser.add_argument('--debug', action='store_true', default=False,
|
|
|
|
parser.add_argument('--debug', action='store_true', default=False,
|
|
|
@ -662,7 +668,7 @@ class AzureInventory(object):
|
|
|
|
self._inventory['azure'].append(host_name)
|
|
|
|
self._inventory['azure'].append(host_name)
|
|
|
|
|
|
|
|
|
|
|
|
if self.group_by_tag and vars.get('tags'):
|
|
|
|
if self.group_by_tag and vars.get('tags'):
|
|
|
|
for key, value in vars['tags'].iteritems():
|
|
|
|
for key, value in vars['tags'].items():
|
|
|
|
safe_key = self._to_safe(key)
|
|
|
|
safe_key = self._to_safe(key)
|
|
|
|
safe_value = safe_key + '_' + self._to_safe(value)
|
|
|
|
safe_value = safe_key + '_' + self._to_safe(value)
|
|
|
|
if not self._inventory.get(safe_key):
|
|
|
|
if not self._inventory.get(safe_key):
|
|
|
@ -722,13 +728,14 @@ class AzureInventory(object):
|
|
|
|
|
|
|
|
|
|
|
|
def _get_env_settings(self):
|
|
|
|
def _get_env_settings(self):
|
|
|
|
env_settings = dict()
|
|
|
|
env_settings = dict()
|
|
|
|
for attribute, env_variable in AZURE_CONFIG_SETTINGS.iteritems():
|
|
|
|
for attribute, env_variable in AZURE_CONFIG_SETTINGS.items():
|
|
|
|
env_settings[attribute] = os.environ.get(env_variable, None)
|
|
|
|
env_settings[attribute] = os.environ.get(env_variable, None)
|
|
|
|
return env_settings
|
|
|
|
return env_settings
|
|
|
|
|
|
|
|
|
|
|
|
def _load_settings(self):
|
|
|
|
def _load_settings(self):
|
|
|
|
basename = os.path.splitext(os.path.basename(__file__))[0]
|
|
|
|
basename = os.path.splitext(os.path.basename(__file__))[0]
|
|
|
|
path = basename + '.ini'
|
|
|
|
default_path = os.path.join(os.path.dirname(__file__), (basename + '.ini'))
|
|
|
|
|
|
|
|
path = os.path.expanduser(os.path.expandvars(os.environ.get('AZURE_INI_PATH', default_path)))
|
|
|
|
config = None
|
|
|
|
config = None
|
|
|
|
settings = None
|
|
|
|
settings = None
|
|
|
|
try:
|
|
|
|
try:
|
|
|
@ -783,11 +790,11 @@ class AzureInventory(object):
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
def main():
|
|
|
|
if not HAS_AZURE:
|
|
|
|
if not HAS_AZURE:
|
|
|
|
sys.exit("The Azure python sdk is not installed (try 'pip install azure==2.0.0rc5') - {0}".format(HAS_AZURE_EXC))
|
|
|
|
sys.exit("The Azure python sdk is not installed (try `pip install 'azure>=2.0.0rc5' --upgrade`) - {0}".format(HAS_AZURE_EXC))
|
|
|
|
|
|
|
|
|
|
|
|
if LooseVersion(azure_compute_version) != LooseVersion(AZURE_MIN_VERSION):
|
|
|
|
if Version(azure_compute_version) < Version(AZURE_MIN_VERSION):
|
|
|
|
sys.exit("Expecting azure.mgmt.compute.__version__ to be {0}. Found version {1} "
|
|
|
|
sys.exit("Expecting azure.mgmt.compute.__version__ to be {0}. Found version {1} "
|
|
|
|
"Do you have Azure == 2.0.0rc5 installed?".format(AZURE_MIN_VERSION, azure_compute_version))
|
|
|
|
"Do you have Azure >= 2.0.0rc5 installed? (try `pip install 'azure>=2.0.0rc5' --upgrade`)".format(AZURE_MIN_VERSION, azure_compute_version))
|
|
|
|
|
|
|
|
|
|
|
|
AzureInventory()
|
|
|
|
AzureInventory()
|
|
|
|
|
|
|
|
|
|
|
|