summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchouseknecht <chousekn@redhat.com>2016-06-29 03:15:52 -0400
committernitzmahone <mdavis@ansible.com>2016-07-05 16:52:39 -0700
commit5e04dcf02673375747a130e7357a503f1d61ba69 (patch)
tree4da78077685426d69ff989b651fe12b93267b766
parent16c3fc5cec10836e034489e4454ca1e9b136bca2 (diff)
downloadansible-5e04dcf02673375747a130e7357a503f1d61ba69.tar.gz
Update and pin to azure-2.0.0rc5
(cherry picked from commit a076612b6365cc6d06869764e5af05692b358df0)
-rw-r--r--lib/ansible/module_utils/azure_rm_common.py134
-rw-r--r--lib/ansible/utils/module_docs_fragments/azure.py4
2 files changed, 62 insertions, 76 deletions
diff --git a/lib/ansible/module_utils/azure_rm_common.py b/lib/ansible/module_utils/azure_rm_common.py
index 751fbf588b..e7031cbd72 100644
--- a/lib/ansible/module_utils/azure_rm_common.py
+++ b/lib/ansible/module_utils/azure_rm_common.py
@@ -24,7 +24,10 @@ import os
import re
import sys
import copy
+import importlib
+import inspect
+from distutils.version import LooseVersion
from os.path import expanduser
from ansible.module_utils.basic import *
@@ -73,10 +76,13 @@ try:
from enum import Enum
from msrest.serialization import Serializer
from msrestazure.azure_exceptions import CloudError
-# from azure.mgmt.compute import __version__ as azure_compute_version
from azure.mgmt.network.models import PublicIPAddress, NetworkSecurityGroup, SecurityRule, NetworkInterface, \
NetworkInterfaceIPConfiguration, Subnet
from azure.common.credentials import ServicePrincipalCredentials, UserPassCredentials
+ from azure.mgmt.network.version import VERSION as network_client_version
+ from azure.mgmt.storage.version import VERSION as storage_client_version
+ from azure.mgmt.compute.version import VERSION as compute_client_version
+ from azure.mgmt.resource.version import VERSION as resource_client_version
from azure.mgmt.network.network_management_client import NetworkManagementClient
from azure.mgmt.resource.resources.resource_management_client import ResourceManagementClient
from azure.mgmt.storage.storage_management_client import StorageManagementClient
@@ -97,6 +103,23 @@ def azure_id_to_dict(id):
return result
+AZURE_EXPECTED_VERSIONS = dict(
+ storage_client_version="0.30.0rc5",
+ compute_client_version="0.30.0rc5",
+ network_client_version="0.30.0rc5",
+ resource_client_version="0.30.0rc5"
+)
+
+AZURE_MIN_RELEASE = '2.0.0rc5'
+
+
+def check_client_version(client_name, client_version, expected_version):
+ # Pinning Azure modules to 2.0.0rc5.
+ if LooseVersion(client_version) != LooseVersion(expected_version):
+ self.fail("Installed {0} client version is {1}. The supported version is {2}. Try "
+ "`pip install azure=={3}`".format(client_name, client_version, expected_version,
+ AZURE_MIN_RELEASE))
+
class AzureRMModuleBase(object):
def __init__(self, derived_arg_spec, bypass_checks=False, no_log=False,
@@ -128,12 +151,8 @@ class AzureRMModuleBase(object):
required_if=merged_required_if)
if not HAS_AZURE:
- self.fail("The Azure Python SDK is not installed (try 'pip install azure') - {0}".format(HAS_AZURE_EXC))
-
- # re-enable after SDK hits release
- # if azure_compute_version < AZURE_MIN_VERSION:
- # self.fail("Expecting azure.mgmt.compute.__version__ to be >= {0}. Found version {1} "
- # "Do you have Azure >= 2.0.0rc2 installed?".format(AZURE_MIN_VERSION, azure_compute_version))
+ self.fail("Do you have azure=={1} installed? Try `pip install azure=={1}`"
+ "- {0}".format(HAS_AZURE_EXC, AZURE_MIN_RELEASE))
self._network_client = None
self._storage_client = None
@@ -141,7 +160,7 @@ class AzureRMModuleBase(object):
self._compute_client = None
self.check_mode = self.module.check_mode
self.facts_module = facts_module
- self.debug = self.module.params.get('debug')
+ # self.debug = self.module.params.get('debug')
# authenticate
self.credentials = self._get_credentials(self.module.params)
@@ -189,12 +208,12 @@ class AzureRMModuleBase(object):
def log(self, msg, pretty_print=False):
pass
# Use only during module development
- # if self.debug:
- # log_file = open('azure_rm.log', 'a')
- # if pretty_print:
- # log_file.write(json.dumps(msg, indent=4, sort_keys=True))
- # else:
- # log_file.write(msg + u'\n')
+ #if self.debug:
+ # log_file = open('azure_rm.log', 'a')
+ # if pretty_print:
+ # log_file.write(json.dumps(msg, indent=4, sort_keys=True))
+ # else:
+ # log_file.write(msg + u'\n')
def validate_tags(self, tags):
'''
@@ -210,52 +229,6 @@ class AzureRMModuleBase(object):
if not isinstance(value, str):
self.fail("Tags values must be strings. Found {0}:{1}".format(str(key), str(value)))
- def _tag_purge(self, tags):
- '''
- Remove metadata tags not found in user provided tags parameter. Returns tuple
- with bool indicating something changed and dict of new tags to be assigned to
- the object.
-
- :param tags: object metadata tags
- :return: bool, dict of tags
- '''
- if not self.module.params.get('tags'):
- # purge all tags
- return True, dict()
- new_tags = copy.copy(tags)
- changed = False
- for key in tags:
- if not self.module.params['tags'].get(key):
- # key not found in user provided parameters
- new_tags.pop(key)
- changed = True
- if changed:
- self.log('CHANGED: purged tags')
- return changed, new_tags
-
- def _tag_update(self, tags):
- '''
- Update metadata tags with values in user provided tags parameter. Returns
- tuple with bool indicating something changed and dict of new tags to be
- assigned to the object.
-
- :param tags: object metadata tags
- :return: bool, dict of tags
- '''
- if isinstance(tags, dict):
- new_tags = copy.copy(tags)
- else:
- new_tags = dict()
- changed = False
- if self.module.params.get('tags'):
- for key, value in self.module.params['tags'].items():
- if not (new_tags.get(key) and new_tags[key] == value):
- changed = True
- new_tags[key] = value
- if changed:
- self.log('CHANGED: updated tags')
- return changed, new_tags
-
def update_tags(self, tags):
'''
Call from the module to update metadata tags. Returns tuple
@@ -265,15 +238,18 @@ class AzureRMModuleBase(object):
:param tags: metadata tags from the object
:return: bool, dict
'''
+ new_tags = copy.copy(tags) if isinstance(tags, dict) else dict()
changed = False
- updated, new_tags = self._tag_update(tags)
- if updated:
- changed = True
-
- if not self.module.params['append_tags']:
- purged, new_tags = self._tag_purge(new_tags)
- if purged:
- changed = True
+ if isinstance(self.module.params.get('tags'), dict):
+ for key, value in self.module.params['tags'].iteritems():
+ if not new_tags.get(key) or new_tags[key] != value:
+ changed = True
+ new_tags[key] = value
+ if isinstance(tags, dict):
+ for key, value in tags.iteritems():
+ if not self.module.params['tags'].get(key):
+ new_tags.pop(key)
+ changed = True
return changed, new_tags
def has_tags(self, obj_tags, tag_list):
@@ -389,15 +365,24 @@ class AzureRMModuleBase(object):
return None
- def serialize_obj(self, obj, class_name):
+ def serialize_obj(self, obj, class_name, enum_modules=[]):
'''
Return a JSON representation of an Azure object.
:param obj: Azure object
:param class_name: Name of the object's class
+ :param enum_modules: List of module names to build enum dependencies from.
:return: serialized result
'''
- serializer = Serializer()
+ dependencies = dict()
+ if enum_modules:
+ for module_name in enum_modules:
+ mod = importlib.import_module(module_name)
+ for mod_class_name, mod_class_obj in inspect.getmembers(mod, predicate=inspect.isclass):
+ dependencies[mod_class_name] = mod_class_obj
+ self.log("dependencies: ");
+ self.log(str(dependencies))
+ serializer = Serializer(classes=dependencies)
return serializer.body(obj, class_name)
def get_poller_result(self, poller, wait=5):
@@ -458,14 +443,12 @@ class AzureRMModuleBase(object):
# Get keys from the storage account
self.log('Getting keys')
account_keys = self.storage_client.storage_accounts.list_keys(resource_group_name, storage_account_name)
- keys['key1'] = account_keys.key1
- keys['key2'] = account_keys.key2
except Exception, exc:
self.fail("Error getting keys for account {0} - {1}".format(storage_account_name, str(exc)))
try:
self.log('Create blob service')
- return CloudStorageAccount(storage_account_name, keys['key1']).create_block_blob_service()
+ return CloudStorageAccount(storage_account_name, account_keys.keys[0].value).create_block_blob_service()
except Exception, exc:
self.fail("Error creating blob service client for storage account {0} - {1}".format(storage_account_name,
str(exc)))
@@ -591,7 +574,7 @@ class AzureRMModuleBase(object):
def storage_client(self):
self.log('Getting storage client...')
if not self._storage_client:
- config = StorageManagementClientConfiguration()
+ check_client_version('storage', storage_client_version, AZURE_EXPECTED_VERSIONS['storage_client_version'])
self._storage_client = StorageManagementClient(self.azure_credentials, self.subscription_id)
self._register('Microsoft.Storage')
return self._storage_client
@@ -600,6 +583,7 @@ class AzureRMModuleBase(object):
def network_client(self):
self.log('Getting network client')
if not self._network_client:
+ check_client_version('network', network_client_version, AZURE_EXPECTED_VERSIONS['network_client_version'])
self._network_client = NetworkManagementClient(self.azure_credentials, self.subscription_id)
self._register('Microsoft.Network')
return self._network_client
@@ -608,6 +592,7 @@ class AzureRMModuleBase(object):
def rm_client(self):
self.log('Getting resource manager client')
if not self._resource_client:
+ check_client_version('resource', resource_client_version, AZURE_EXPECTED_VERSIONS['resource_client_version'])
self._resource_client = ResourceManagementClient(self.azure_credentials, self.subscription_id)
return self._resource_client
@@ -615,6 +600,7 @@ class AzureRMModuleBase(object):
def compute_client(self):
self.log('Getting compute client')
if not self._compute_client:
+ check_client_version('compute', compute_client_version, AZURE_EXPECTED_VERSIONS['compute_client_version'])
self._compute_client = ComputeManagementClient(self.azure_credentials, self.subscription_id)
self._register('Microsoft.Compute')
return self._compute_client
diff --git a/lib/ansible/utils/module_docs_fragments/azure.py b/lib/ansible/utils/module_docs_fragments/azure.py
index 35ae92954a..8a2e0c5396 100644
--- a/lib/ansible/utils/module_docs_fragments/azure.py
+++ b/lib/ansible/utils/module_docs_fragments/azure.py
@@ -66,7 +66,7 @@ options:
requirements:
- "python >= 2.7"
- - "azure >= 2.0.0rc4"
+ - "azure == 2.0.0rc5"
notes:
- For authentication with Azure you can pass parameters, set environment variables or use a profile stored
@@ -79,4 +79,4 @@ notes:
a [default] section and the following keys: subscription_id, client_id, secret and tenant or
subscription_id, ad_user and password. It is also possible to add additional profiles. Specify the profile
by passing profile or setting AZURE_PROFILE in the environment."
- ''' \ No newline at end of file
+ '''