diff --git a/lib/ansible/modules/cloud/azure/azure_rm_applicationpackage.py b/lib/ansible/modules/cloud/azure/azure_rm_applicationpackage.py new file mode 100644 index 00000000000000..5bfd2d9f2377e4 --- /dev/null +++ b/lib/ansible/modules/cloud/azure/azure_rm_applicationpackage.py @@ -0,0 +1,316 @@ +#!/usr/bin/python +# +# Copyright (C) 2019 audevbot +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file at +# https://github.com/Azure/magic-module-specs +# +# ---------------------------------------------------------------------------- + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: azure_rm_applicationpackage +version_added: "2.9" +short_description: Manage Azure ApplicationPackage instance. +description: + - Create, update and delete instance of Azure Application Package. + +options: + resource_group: + description: + - The name of the resource group that contains the Batch account. + required: true + type: str + name: + description: + - The version of the application. + required: true + type: str + account_name: + description: + - The name of the Batch account. + required: true + type: str + application_name: + description: + - The name of the application. This must be unique within the account. + required: true + type: str + state: + description: + - Assert the state of the Application Package. + - Use 'present' to create or update a Application Package and 'absent' to delete it. + default: present + choices: + - present + - absent + +extends_documentation_fragment: + - azure + +author: + - audevbot +''' + + +RETURN = ''' +state: + description: + - The current state of the application package. + returned: always + type: str +format: + description: + - The format of the application package, if the package is active. + returned: always + type: str +storage_url: + description: + - The URL for the application package in Azure Storage. + returned: always + type: str +storage_url_expiry: + description: + - The UTC time at which the Azure Storage URL will expire. + returned: always + type: str +last_activation_time: + description: + - The time at which the package was last activated, if the package is active. + returned: always + type: str +id: + description: + - The ID of the resource. + returned: always + type: str +etag: + description: + - The ETag of the resource, used for concurrency statements. + returned: always + type: str +''' + +import time +from ansible.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt +from ansible.module_utils.common.dict_transformations import _snake_to_camel + +try: + from msrestazure.azure_exceptions import CloudError + from msrest.polling import LROPoller + from msrestazure.azure_operation import AzureOperationPoller + from msrest.serialization import Model + from azure.mgmt.batch import BatchManagementClient +except ImportError: + # This is handled in azure_rm_common + pass + + +class Actions: + NoAction, Create, Update, Delete = range(4) + + +class AzureRMApplicationPackage(AzureRMModuleBaseExt): + """Configuration class for an Azure RM Application Package resource""" + + def __init__(self): + self.module_arg_spec = dict( + resource_group=dict( + required=True, + type='str' + ), + name=dict( + required=True, + type='str' + ), + account_name=dict( + required=True, + type='str', + updatable=False, + disposition='/' + ), + application_name=dict( + required=True, + type='str', + updatable=False, + disposition='/' + ), + state=dict( + type='str', + default='present', + choices=['present', 'absent'] + ) + ) + + self.resource_group = None + self.account_name = None + self.application_name = None + self.name = None + self.parameters = dict() + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.to_do = Actions.NoAction + + super(AzureRMApplicationPackage, self).__init__(derived_arg_spec=self.module_arg_spec, + supports_check_mode=True, + supports_tags=False) + + def exec_module(self, **kwargs): + """Main module execution method""" + + for key in list(self.module_arg_spec.keys()): + if hasattr(self, key): + setattr(self, key, kwargs[key]) + elif kwargs[key] is not None: + self.parameters[key] = kwargs[key] + + + response = None + + self.mgmt_client = self.get_mgmt_svc_client(BatchManagementClient, + base_url=self._cloud_environment.endpoints.resource_manager) + + old_response = self.get_applicationpackage() + + if not old_response: + self.log("Application Package instance doesn't exist") + if self.state == 'absent': + self.log("Old instance didn't exist") + else: + self.to_do = Actions.Create + else: + self.log("Application Package instance already exists") + if self.state == 'absent': + self.to_do = Actions.Delete + elif self.state == 'present': + self.results['old'] = old_response + self.results['new'] = self.parameters + if not self.idempotency_check(old_response, self.parameters): + self.to_do = Actions.Update + + if (self.to_do == Actions.Create) or (self.to_do == Actions.Update): + self.log("Need to Create / Update the Application Package instance") + + self.results['changed'] = True + if self.check_mode: + return self.results + + response = self.create_update_applicationpackage() + + self.log("Creation / Update done") + elif self.to_do == Actions.Delete: + self.log("Application Package instance deleted") + self.results['changed'] = True + + if self.check_mode: + return self.results + + self.delete_applicationpackage() + else: + self.log("Application Package instance unchanged") + self.results['changed'] = False + response = old_response + + if self.state == 'present': + self.results.update({ + 'state': response.get('state', None), + 'format': response.get('format', None), + 'storage_url': response.get('storage_url', None), + 'storage_url_expiry': response.get('storage_url_expiry', None), + 'last_activation_time': response.get('last_activation_time', None), + 'id': response.get('id', None), + 'etag': response.get('etag', None) + }) + return self.results + + def create_update_applicationpackage(self): + ''' + Creates or updates Application Package with the specified configuration. + + :return: deserialized Application Package instance state dictionary + ''' + self.log("Creating / Updating the Application Package instance {0}".format(self.name)) + + try: + response = self.mgmt_client.application_package.create(resource_group_name=self.resource_group, + account_name=self.account_name, + application_name=self.application_name, + version_name=self.name, + parameters=self.parameters) + if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller): + response = self.get_poller_result(response) + except CloudError as exc: + self.log('Error attempting to create the Application Package instance.') + self.fail("Error creating the Application Package instance: {0}".format(str(exc))) + return response.as_dict() + + def delete_applicationpackage(self): + ''' + Deletes specified Application Package instance in the specified subscription and resource group. + + :return: True + ''' + self.log("Deleting the Application Package instance {0}".format(self.name)) + try: + response = self.mgmt_client.application_package.delete(resource_group_name=self.resource_group, + account_name=self.account_name, + application_name=self.application_name, + version_name=self.name) + except CloudError as e: + self.log('Error attempting to delete the Application Package instance.') + self.fail("Error deleting the Application Package instance: {0}".format(str(e))) + + if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller): + response = self.get_poller_result(response) + return True + + def get_applicationpackage(self): + ''' + Gets the properties of the specified Application Package + :return: deserialized Application Package instance state dictionary + ''' + self.log("Checking if the Application Package instance {0} is present".format(self.name)) + found = False + try: + response = self.mgmt_client.application_package.get(resource_group_name=self.resource_group, + account_name=self.account_name, + application_name=self.application_name, + version_name=self.name) + found = True + self.log("Response : {0}".format(response)) + self.log("Application Package instance : {0} found".format(response.name)) + except CloudError as e: + self.log('Did not find the Application Package instance.') + if found is True: + return response.as_dict() + return False + + +def main(): + """Main execution""" + AzureRMApplicationPackage() + + +if __name__ == '__main__': + main() diff --git a/lib/ansible/modules/cloud/azure/azure_rm_batchaccount.py b/lib/ansible/modules/cloud/azure/azure_rm_batchaccount.py index 73cc47ec60cd77..7c3f124ab6e16a 100644 --- a/lib/ansible/modules/cloud/azure/azure_rm_batchaccount.py +++ b/lib/ansible/modules/cloud/azure/azure_rm_batchaccount.py @@ -13,6 +13,8 @@ # This file is automatically generated by Magic Modules and manual # changes will be clobbered when the file is regenerated. # +# Please read more about how to change this file at +# https://github.com/Azure/magic-module-specs # # ---------------------------------------------------------------------------- @@ -37,31 +39,37 @@ description: - The name of the resource group in which to create the Batch Account. required: true + type: str name: description: - The name of the Batch Account. required: true + type: str location: description: - Specifies the supported Azure location where the resource exists. + type: str auto_storage_account: description: - Existing storage account with which to associate the Batch Account. - It can be the storage account name which is in the same resource group. - "It can be the storage account ID. e.g., - /subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Storage/storageAccounts/{name}." + /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount." - It can be a dict which contains C(name) and C(resource_group) of the storage account. + type: raw key_vault: description: - Existing key vault with which to associate the Batch Account. - It can be the key vault name which is in the same resource group. - "It can be the key vault ID. e.g., - /subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.KeyVault/vaults/{name}." + /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myKeyVault." - It can be a dict which contains C(name) and C(resource_group) of the key vault. + type: raw pool_allocation_mode: description: - The pool acclocation mode of the Batch Account. default: batch_service + type: str choices: - batch_service - user_subscription @@ -79,13 +87,13 @@ - azure_tags author: - - "Junyi Yi (@JunyiYi)" + - Junyi Yi (@JunyiYi) ''' EXAMPLES = ''' - name: Create Batch Account azure_rm_batchaccount: - resource_group: MyResGroup + resource_group: MyResourceGroup name: mybatchaccount location: eastus auto_storage_account: @@ -99,7 +107,7 @@ - The ID of the Batch account. returned: always type: str - sample: "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Batch/batchAccounts/sampleacct" + sample: "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Batch/batchAccounts/mybatchaccount" account_endpoint: description: - The account endpoint used to interact with the Batch service. @@ -200,14 +208,14 @@ def exec_module(self, **kwargs): self.batch_account.pop('auto_storage_account'), '/subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.Storage/storageAccounts/{name}') } - if self.batch_account.get('key_vault') is not None: - id = self.normalize_resource_id( - self.batch_account.pop('key_vault'), - '/subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.KeyVault/vaults/{name}') - url = 'https://' + id.split('/').pop() + '.vault.azure.net/' - self.batch_account['key_vault_reference'] = { - 'id': id, - 'url': url + if self.batch_account.get('key_vault') is not None: + id = self.normalize_resource_id( + self.batch_account.pop('key_vault'), + '/subscriptions/{subscription_id}/resourceGroups/{resource_group}/providers/Microsoft.KeyVault/vaults/{name}') + url = 'https://' + id.split('/').pop() + '.vault.azure.net/' + self.batch_account['key_vault_reference'] = { + 'id': id, + 'url': url } self.batch_account['pool_allocation_mode'] = _snake_to_camel(self.batch_account['pool_allocation_mode'], True) diff --git a/lib/ansible/modules/cloud/azure/azure_rm_batchaccount_info.py b/lib/ansible/modules/cloud/azure/azure_rm_batchaccount_info.py new file mode 100644 index 00000000000000..2b71343108d8c5 --- /dev/null +++ b/lib/ansible/modules/cloud/azure/azure_rm_batchaccount_info.py @@ -0,0 +1,253 @@ +#!/usr/bin/python +# +# Copyright (C) 2019 Junyi Yi (@JunyiYi) +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file at +# https://github.com/Azure/magic-module-specs +# +# ---------------------------------------------------------------------------- + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: azure_rm_batchaccount_info +version_added: "2.9" +short_description: Gather info for Azure Batch Account +description: + - Gather info for Azure Batch Account. + +options: + resource_group: + description: + - The name of the resource group in which to create the Batch Account. + required: true + type: str + name: + description: + - The name of the Batch Account. + type: str + tags: + description: + - Limit results by providing a list of tags. Format tags as 'key' or 'key:value'. + type: list + +extends_documentation_fragment: + - azure + +author: + - Junyi Yi (@JunyiYi) +''' + +EXAMPLES = ''' + - name: Get instance of Batch Account + azure_rm_batchaccount_info: + resource_group: MyResourceGroup + name: mybatchaccount + + - name: List instances of Batch Account + azure_rm_batchaccount_info: + resource_group: MyResourceGroup +''' + +RETURN = ''' +items: + description: + - List of items. + returned: always + type: complex + contains: + id: + description: + - The ID of the Batch account. + returned: always + type: str + sample: "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Batch/batchAccounts/mybatchaccount" + resource_group: + description: + - The name of the resource group in which to create the Batch Account. + returned: always + type: str + sample: myResourceGroup + name: + description: + - The name of the Batch Account. + returned: always + type: str + sample: mybatchaccount + location: + description: + - Specifies the supported Azure location where the resource exists. + returned: always + type: str + sample: eastus + account_endpoint: + description: + - The account endpoint used to interact with the Batch service. + returned: always + type: str + sample: sampleacct.westus.batch.azure.com + auto_storage_account: + description: + - Existing storage account with which to associate the Batch Account. + returned: always + type: str + sample: + "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount" + key_vault: + description: + - Existing key vault with which to associate the Batch Account. + returned: always + type: str + sample: "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.KeyVault/vaults/myKeyVault" + pool_allocation_mode: + description: + - The pool acclocation mode of the Batch Account. + returned: always + type: str + sample: batch_service + tags: + description: + - Resource tags. + returned: always + type: dict + sample: "{ 'key1': 'value1', 'key2': 'value2' }" +''' + +from ansible.module_utils.azure_rm_common import AzureRMModuleBase +from ansible.module_utils.common.dict_transformations import _camel_to_snake + +try: + from msrestazure.azure_exceptions import CloudError + from azure.mgmt.batch import BatchManagementClient + from msrest.serialization import Model +except ImportError: + # This is handled in azure_rm_common + pass + + +class AzureRMBatchAccountInfo(AzureRMModuleBase): + def __init__(self): + # define user inputs into argument + self.module_arg_spec = dict( + resource_group=dict( + required=True, + type='str' + ), + name=dict( + type='str' + ), + tags=dict( + type='list' + ) + ) + # store the results of the module operation + self.results = dict( + changed=False + ) + self.mgmt_client = None + self.resource_group = None + self.name = None + self.tags = None + super(AzureRMBatchAccountInfo, self).__init__(self.module_arg_spec, supports_tags=False) + + def exec_module(self, **kwargs): + for key in self.module_arg_spec: + setattr(self, key, kwargs[key]) + self.mgmt_client = self.get_mgmt_svc_client(BatchManagementClient, + base_url=self._cloud_environment.endpoints.resource_manager) + + if self.resource_group is not None and self.name is not None: + self.results['items'] = self.get() + elif self.resource_group is not None: + self.results['items'] = self.list_by_resource_group() + else: + self.results['items'] = self.list_by_subscription() + return self.results + + def get(self): + response = None + results = [] + try: + response = self.mgmt_client.batch_account.get(resource_group_name=self.resource_group, + account_name=self.name) + self.log("Response : {0}".format(response)) + except CloudError as e: + self.log('Could not get info for Batch Account.') + + if response and self.has_tags(response.tags, self.tags): + results.append(self.format_response(response)) + + return results + + def list_by_resource_group(self): + response = None + results = [] + try: + response = self.mgmt_client.batch_account.list_by_resource_group(resource_group_name=self.resource_group) + self.log("Response : {0}".format(response)) + except CloudError as e: + self.log('Could not get info for Batch Account.') + + if response is not None: + for item in response: + if self.has_tags(item.tags, self.tags): + results.append(self.format_response(item)) + + return results + + def list_by_subscription(self): + response = None + results = [] + try: + response = self.mgmt_client.batch_account.list() + self.log("Response : {0}".format(response)) + except CloudError as e: + self.log('Could not get info for Batch Account.') + + if response is not None: + for item in response: + if self.has_tags(item.tags, self.tags): + results.append(self.format_response(item)) + + return results + + def format_response(self, item): + d = item.as_dict() + d = { + 'id': d.get('id'), + 'resource_group': self.resource_group, + 'name': d.get('name'), + 'location': d.get('location'), + 'account_endpoint': d.get('account_endpoint'), + 'auto_storage_account': d.get('auto_storage', {}).get('storage_account_id'), + 'key_vault': d.get('key_vault_reference', {}).get('id'), + 'pool_allocation_mode': _camel_to_snake(d.get('pool_allocation_mode')), + 'tags': d.get('tags'), + } + return d + + +def main(): + AzureRMBatchAccountInfo() + + +if __name__ == "__main__": + main() diff --git a/lib/ansible/modules/cloud/azure/azure_rm_batchapplication.py b/lib/ansible/modules/cloud/azure/azure_rm_batchapplication.py new file mode 100644 index 00000000000000..ebffb62db327b5 --- /dev/null +++ b/lib/ansible/modules/cloud/azure/azure_rm_batchapplication.py @@ -0,0 +1,300 @@ +#!/usr/bin/python +# +# Copyright (C) 2019 Junyi Yi (@JunyiYi) +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file at +# https://github.com/Azure/magic-module-specs +# +# ---------------------------------------------------------------------------- + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: azure_rm_batchapplication +version_added: "2.9" +short_description: Manage Azure Application instance. +description: + - Create, update and delete instance of Azure Batch Application. + +options: + resource_group: + description: + - The name of the resource group that contains the Batch account. + required: true + type: str + name: + description: + - The name of the application. This must be unique within the account. + required: true + type: str + account_name: + description: + - The name of the Batch account. + required: true + type: str + allow_updates: + description: + - A value indicating whether packages within the application may be overwritten using the same version string. + type: bool + default_version: + description: + - "The package to use if a client requests the application but does not specify a version. This property can only be set to the name of an + existing package." + type: str + display_name: + description: + - The display name for the application. + type: str + state: + description: + - Assert the state of the Batch Application. + - Use 'present' to create or update a Batch Application and 'absent' to delete it. + default: present + choices: + - present + - absent + +extends_documentation_fragment: + - azure + +author: + - Junyi Yi (@JunyiYi) +''' + +EXAMPLES = ''' + - name: Create Batch Application + azure_rm_batchapplication: + resource_group: MyResGroup + name: mybatchapplication + account_name: mybatchaccount +''' + +RETURN = ''' +id: + description: + - The ID of the resource. + returned: always + type: str +''' + +import time +from ansible.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt +from ansible.module_utils.common.dict_transformations import _snake_to_camel + +try: + from msrestazure.azure_exceptions import CloudError + from msrest.polling import LROPoller + from msrestazure.azure_operation import AzureOperationPoller + from msrest.serialization import Model + from azure.mgmt.batch import BatchManagementClient +except ImportError: + # This is handled in azure_rm_common + pass + + +class Actions: + NoAction, Create, Update, Delete = range(4) + + +class AzureRMBatchApplication(AzureRMModuleBaseExt): + """Configuration class for an Azure RM Batch Application resource""" + + def __init__(self): + self.module_arg_spec = dict( + resource_group=dict( + required=True, + type='str' + ), + name=dict( + required=True, + type='str' + ), + account_name=dict( + required=True, + type='str', + updatable=False, + disposition='/' + ), + allow_updates=dict( + type='bool' + ), + default_version=dict( + type='str' + ), + display_name=dict( + type='str' + ), + state=dict( + type='str', + default='present', + choices=['present', 'absent'] + ) + ) + + self.resource_group = None + self.account_name = None + self.name = None + self.parameters = dict() + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.to_do = Actions.NoAction + + super(AzureRMBatchApplication, self).__init__(derived_arg_spec=self.module_arg_spec, + supports_check_mode=True, + supports_tags=False) + + def exec_module(self, **kwargs): + """Main module execution method""" + + for key in list(self.module_arg_spec.keys()): + if hasattr(self, key): + setattr(self, key, kwargs[key]) + elif kwargs[key] is not None: + self.parameters[key] = kwargs[key] + + + response = None + + self.mgmt_client = self.get_mgmt_svc_client(BatchManagementClient, + base_url=self._cloud_environment.endpoints.resource_manager) + + old_response = self.get_batchapplication() + + if not old_response: + self.log("Batch Application instance doesn't exist") + if self.state == 'absent': + self.log("Old instance didn't exist") + else: + self.to_do = Actions.Create + else: + self.log("Batch Application instance already exists") + if self.state == 'absent': + self.to_do = Actions.Delete + elif self.state == 'present': + self.results['old'] = old_response + self.results['new'] = self.parameters + if not self.idempotency_check(old_response, self.parameters): + self.to_do = Actions.Update + + if (self.to_do == Actions.Create) or (self.to_do == Actions.Update): + self.log("Need to Create / Update the Batch Application instance") + + self.results['changed'] = True + if self.check_mode: + return self.results + + response = self.create_update_batchapplication() + + self.log("Creation / Update done") + elif self.to_do == Actions.Delete: + self.log("Batch Application instance deleted") + self.results['changed'] = True + + if self.check_mode: + return self.results + + self.delete_batchapplication() + else: + self.log("Batch Application instance unchanged") + self.results['changed'] = False + response = old_response + + if self.state == 'present': + self.results.update({ + 'id': response.get('id', None) + }) + return self.results + + def create_update_batchapplication(self): + ''' + Creates or updates Batch Application with the specified configuration. + + :return: deserialized Batch Application instance state dictionary + ''' + self.log("Creating / Updating the Batch Application instance {0}".format(self.name)) + + try: + if self.to_do == Actions.Create: + response = self.mgmt_client.application.create(resource_group_name=self.resource_group, + account_name=self.account_name, + application_name=self.name, + parameters=self.parameters) + else: + response = self.mgmt_client.application.update(resource_group_name=self.resource_group, + account_name=self.account_name, + application_name=self.name, + parameters=self.parameters) + if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller): + response = self.get_poller_result(response) + except CloudError as exc: + self.log('Error attempting to create the Batch Application instance.') + self.fail("Error creating the Batch Application instance: {0}".format(str(exc))) + return response.as_dict() + + def delete_batchapplication(self): + ''' + Deletes specified Batch Application instance in the specified subscription and resource group. + + :return: True + ''' + self.log("Deleting the Batch Application instance {0}".format(self.name)) + try: + response = self.mgmt_client.application.delete(resource_group_name=self.resource_group, + account_name=self.account_name, + application_name=self.name) + except CloudError as e: + self.log('Error attempting to delete the Batch Application instance.') + self.fail("Error deleting the Batch Application instance: {0}".format(str(e))) + + if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller): + response = self.get_poller_result(response) + return True + + def get_batchapplication(self): + ''' + Gets the properties of the specified Batch Application + :return: deserialized Batch Application instance state dictionary + ''' + self.log("Checking if the Batch Application instance {0} is present".format(self.name)) + found = False + try: + response = self.mgmt_client.application.get(resource_group_name=self.resource_group, + account_name=self.account_name, + application_name=self.name) + found = True + self.log("Response : {0}".format(response)) + self.log("Batch Application instance : {0} found".format(response.name)) + except CloudError as e: + self.log('Did not find the Batch Application instance.') + if found is True: + return response.as_dict() + return False + + +def main(): + """Main execution""" + AzureRMBatchApplication() + + +if __name__ == '__main__': + main() diff --git a/lib/ansible/modules/cloud/azure/azure_rm_webapplicationfirewallpolicy.py b/lib/ansible/modules/cloud/azure/azure_rm_webapplicationfirewallpolicy.py new file mode 100644 index 00000000000000..5e3f51d9acb0c8 --- /dev/null +++ b/lib/ansible/modules/cloud/azure/azure_rm_webapplicationfirewallpolicy.py @@ -0,0 +1,455 @@ +#!/usr/bin/python +# +# Copyright (C) 2019 audevbot +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file at +# https://github.com/Azure/magic-module-specs +# +# ---------------------------------------------------------------------------- + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: azure_rm_webapplicationfirewallpolicy +version_added: "2.9" +short_description: Manage Azure WebApplicationFirewallPolicy instance. +description: + - Create, update and delete instance of Azure Web Application Firewall Policy. + +options: + resource_group: + description: + - The name of the resource group. + required: true + type: str + name: + description: + - The name of the policy. + required: true + type: str + location: + description: + - Resource location. + type: str + custom_rules: + description: + - Describes custom rules inside the policy. + type: list + suboptions: + name: + description: + - Gets name of the resource that is unique within a policy. This name can be used to access the resource. + type: str + priority: + description: + - Describes priority of the rule. Rules with a lower value will be evaluated before rules with a higher value. + required: true + type: int + rule_type: + description: + - Describes type of rule. + required: true + type: str + choices: + - match_rule + - invalid + match_conditions: + description: + - List of match conditions. + required: true + type: list + suboptions: + match_variables: + description: + - List of match variables. + required: true + type: list + suboptions: + variable_name: + description: + - Match Variable. + required: true + type: str + choices: + - remote_addr + - request_method + - query_string + - post_args + - request_uri + - request_headers + - request_body + - request_cookies + selector: + description: + - Describes field of the matchVariable collection. + type: str + operator: + description: + - Describes operator to be matched. + required: true + type: str + choices: + - ip_match + - equal + - contains + - less_than + - greater_than + - less_than_or_equal + - greater_than_or_equal + - begins_with + - ends_with + - regex + negation_conditon: + description: + - Describes if this is negate condition or not. + type: bool + match_values: + description: + - Match value. + required: true + type: list + action: + description: + - Type of Actions. + required: true + type: str + choices: + - allow + - block + - log + policy_settings: + description: + - Describes policySettings for policy. + type: dict + suboptions: + enabled_state: + description: + - Describes if the policy is in enabled state or disabled state. + default: disabled + type: str + choices: + - disabled + - enabled + mode: + description: + - Describes if it is in detection mode or prevention mode at policy level. + default: prevention + type: str + choices: + - prevention + - detection + state: + description: + - Assert the state of the Web Application Firewall Policy. + - Use 'present' to create or update a Web Application Firewall Policy and 'absent' to delete it. + default: present + choices: + - present + - absent + +extends_documentation_fragment: + - azure + - azure_tags + +author: + - audevbot +''' + + +RETURN = ''' +id: + description: + - Resource ID. + returned: always + type: str +''' + +import time +from ansible.module_utils.azure_rm_common import normalize_location_name +from ansible.module_utils.azure_rm_common_ext import AzureRMModuleBaseExt +from ansible.module_utils.common.dict_transformations import _snake_to_camel + +try: + from msrestazure.azure_exceptions import CloudError + from msrest.polling import LROPoller + from msrestazure.azure_operation import AzureOperationPoller + from msrest.serialization import Model + from azure.mgmt.network import NetworkManagementClient +except ImportError: + # This is handled in azure_rm_common + pass + + +class Actions: + NoAction, Create, Update, Delete = range(4) + + +class AzureRMWebApplicationFirewallPolicy(AzureRMModuleBaseExt): + """Configuration class for an Azure RM Web Application Firewall Policy resource""" + + def __init__(self): + self.module_arg_spec = dict( + resource_group=dict( + required=True, + type='str' + ), + name=dict( + required=True, + type='str' + ), + location=dict( + type='str', + updatable=False, + disposition='/' + ), + custom_rules=dict( + type='list', + elements='dict', + options=dict( + name=dict( + type='str' + ), + priority=dict( + required=True, + type='int' + ), + rule_type=dict( + required=True, + type='str', + choices=['match_rule', 'invalid'] + ), + match_conditions=dict( + required=True, + type='list', + elements='dict', + options=dict( + match_variables=dict( + required=True, + type='list', + elements='dict', + options=dict( + variable_name=dict( + required=True, + type='str', + choices=['remote_addr', 'request_method', 'query_string', 'post_args', 'request_uri', 'request_headers', 'request_body', 'request_cookies'] + ), + selector=dict( + type='str' + ) + ) + ), + operator=dict( + required=True, + type='str', + choices=['ip_match', 'equal', 'contains', 'less_than', 'greater_than', 'less_than_or_equal', 'greater_than_or_equal', 'begins_with', 'ends_with', 'regex'] + ), + negation_conditon=dict( + type='bool' + ), + match_values=dict( + required=True, + type='list', + elements='str' + ) + ) + ), + action=dict( + required=True, + type='str', + choices=['allow', 'block', 'log'] + ) + ) + ), + policy_settings=dict( + type='dict', + options=dict( + enabled_state=dict( + default='disabled', + type='str', + choices=['disabled', 'enabled'] + ), + mode=dict( + default='prevention', + type='str', + choices=['prevention', 'detection'] + ) + ) + ), + state=dict( + type='str', + default='present', + choices=['present', 'absent'] + ) + ) + + self.resource_group = None + self.name = None + self.parameters = dict() + self.tags = None + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.to_do = Actions.NoAction + + super(AzureRMWebApplicationFirewallPolicy, self).__init__(derived_arg_spec=self.module_arg_spec, + supports_check_mode=True, + supports_tags=True) + + def exec_module(self, **kwargs): + """Main module execution method""" + + for key in list(self.module_arg_spec.keys()) + ['tags']: + if hasattr(self, key): + setattr(self, key, kwargs[key]) + elif kwargs[key] is not None: + self.parameters[key] = kwargs[key] + + resource_group = self.get_resource_group(self.resource_group) + if self.parameters.get('location') is None: + self.parameters['location'] = resource_group.location + if self.parameters.get('custom_rules') is not None: + self.parameters['custom_rules']['rule_type'] = _snake_to_camel(self.parameters['custom_rules']['rule_type'], True) + if self.parameters['custom_rules'].get('match_conditions') is not None: + if self.parameters['custom_rules']['match_conditions'].get('match_variables') is not None: + self.parameters['custom_rules']['match_conditions']['match_variables']['variable_name'] = _snake_to_camel(self.parameters['custom_rules']['match_conditions']['match_variables']['variable_name'], True) + self.parameters['custom_rules']['match_conditions']['operator'] = _snake_to_camel(self.parameters['custom_rules']['match_conditions']['operator'], True) + self.parameters['custom_rules']['action'] = _snake_to_camel(self.parameters['custom_rules']['action'], True) + if self.parameters.get('policy_settings') is not None: + self.parameters['policy_settings']['enabled_state'] = _snake_to_camel(self.parameters['policy_settings']['enabled_state'], True) + self.parameters['policy_settings']['mode'] = _snake_to_camel(self.parameters['policy_settings']['mode'], True) + + response = None + + self.mgmt_client = self.get_mgmt_svc_client(NetworkManagementClient, + base_url=self._cloud_environment.endpoints.resource_manager) + + old_response = self.get_webapplicationfirewallpolicy() + + if not old_response: + self.log("Web Application Firewall Policy instance doesn't exist") + if self.state == 'absent': + self.log("Old instance didn't exist") + else: + self.to_do = Actions.Create + else: + self.log("Web Application Firewall Policy instance already exists") + if self.state == 'absent': + self.to_do = Actions.Delete + elif self.state == 'present': + self.results['old'] = old_response + self.results['new'] = self.parameters + if not self.idempotency_check(old_response, self.parameters): + self.to_do = Actions.Update + + if (self.to_do == Actions.Create) or (self.to_do == Actions.Update): + self.log("Need to Create / Update the Web Application Firewall Policy instance") + + self.results['changed'] = True + if self.check_mode: + return self.results + + response = self.create_update_webapplicationfirewallpolicy() + + self.log("Creation / Update done") + elif self.to_do == Actions.Delete: + self.log("Web Application Firewall Policy instance deleted") + self.results['changed'] = True + + if self.check_mode: + return self.results + + self.delete_webapplicationfirewallpolicy() + else: + self.log("Web Application Firewall Policy instance unchanged") + self.results['changed'] = False + response = old_response + + if self.state == 'present': + self.results.update({ + 'id': response.get('id', None) + }) + return self.results + + def create_update_webapplicationfirewallpolicy(self): + ''' + Creates or updates Web Application Firewall Policy with the specified configuration. + + :return: deserialized Web Application Firewall Policy instance state dictionary + ''' + self.log("Creating / Updating the Web Application Firewall Policy instance {0}".format(self.name)) + + try: + response = self.mgmt_client.web_application_firewall_policies.create_or_update(resource_group_name=self.resource_group, + policy_name=self.name, + parameters=self.parameters) + if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller): + response = self.get_poller_result(response) + except CloudError as exc: + self.log('Error attempting to create the Web Application Firewall Policy instance.') + self.fail("Error creating the Web Application Firewall Policy instance: {0}".format(str(exc))) + return response.as_dict() + + def delete_webapplicationfirewallpolicy(self): + ''' + Deletes specified Web Application Firewall Policy instance in the specified subscription and resource group. + + :return: True + ''' + self.log("Deleting the Web Application Firewall Policy instance {0}".format(self.name)) + try: + response = self.mgmt_client.web_application_firewall_policies.delete(resource_group_name=self.resource_group, + policy_name=self.name) + except CloudError as e: + self.log('Error attempting to delete the Web Application Firewall Policy instance.') + self.fail("Error deleting the Web Application Firewall Policy instance: {0}".format(str(e))) + + if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller): + response = self.get_poller_result(response) + return True + + def get_webapplicationfirewallpolicy(self): + ''' + Gets the properties of the specified Web Application Firewall Policy + :return: deserialized Web Application Firewall Policy instance state dictionary + ''' + self.log("Checking if the Web Application Firewall Policy instance {0} is present".format(self.name)) + found = False + try: + response = self.mgmt_client.web_application_firewall_policies.get(resource_group_name=self.resource_group, + policy_name=self.name) + found = True + self.log("Response : {0}".format(response)) + self.log("Web Application Firewall Policy instance : {0} found".format(response.name)) + except CloudError as e: + self.log('Did not find the Web Application Firewall Policy instance.') + if found is True: + return response.as_dict() + return False + + +def main(): + """Main execution""" + AzureRMWebApplicationFirewallPolicy() + + +if __name__ == '__main__': + main() diff --git a/test/integration/targets/azure_rm_batchaccount/tasks/main.yml b/test/integration/targets/azure_rm_batchaccount/tasks/main.yml index e62cb67cfc40f5..a9cff993a39243 100644 --- a/test/integration/targets/azure_rm_batchaccount/tasks/main.yml +++ b/test/integration/targets/azure_rm_batchaccount/tasks/main.yml @@ -8,6 +8,8 @@ # This file is automatically generated by Magic Modules and manual # changes will be clobbered when the file is regenerated. # +# Please read more about how to change this file at +# https://github.com/Azure/magic-module-specs # # ---------------------------------------------------------------------------- - name: Prepare random number @@ -53,14 +55,43 @@ that: - not output.changed +- name: Get instance of Batch Account + azure_rm_batchaccount_info: + resource_group: "{{ resource_group }}" + name: "{{ batch_account_name }}" + register: output + +- name: Assert that info is returned + assert: + that: + - not output.changed + - output['items'][0]['id'] != None + - output['items'][0]['resource_group'] != None + - output['items'][0]['name'] != None + - output['items'][0]['location'] != None + - output['items'][0]['auto_storage_account'] != None + - output['items'][0]['pool_allocation_mode'] != None + +- name: List instances of Batch Account + azure_rm_batchaccount_info: + resource_group: "{{ resource_group }}" + register: output + +- name: Assert that info is returned + assert: + that: + - not output.changed + - output['items'][0]['id'] != None + - output['items'][0]['resource_group'] != None + - output['items'][0]['name'] != None + - output['items'][0]['location'] != None + - output['items'][0]['auto_storage_account'] != None + - output['items'][0]['pool_allocation_mode'] != None + - name: Delete Batch Account azure_rm_batchaccount: resource_group: "{{ resource_group }}" name: "{{ batch_account_name }}" - location: eastus - auto_storage_account: - name: "{{ storage_account_name }}" - pool_allocation_mode: batch_service state: absent register: output @@ -69,7 +100,7 @@ that: - output.changed -- name: Clean up storage account +- name: Delete Storage Account azure_rm_storageaccount: resource_group: "{{ resource_group }}" name: "{{ storage_account_name }}" diff --git a/test/integration/targets/azure_rm_batchapplication/aliases b/test/integration/targets/azure_rm_batchapplication/aliases new file mode 100644 index 00000000000000..49acfee76c9085 --- /dev/null +++ b/test/integration/targets/azure_rm_batchapplication/aliases @@ -0,0 +1,3 @@ +cloud/azure +destructive +shippable/azure/group2 diff --git a/test/integration/targets/azure_rm_batchapplication/meta/main.yml b/test/integration/targets/azure_rm_batchapplication/meta/main.yml new file mode 100644 index 00000000000000..95e1952f98900b --- /dev/null +++ b/test/integration/targets/azure_rm_batchapplication/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - setup_azure diff --git a/test/integration/targets/azure_rm_batchapplication/tasks/main.yml b/test/integration/targets/azure_rm_batchapplication/tasks/main.yml new file mode 100644 index 00000000000000..a64019baf5aca1 --- /dev/null +++ b/test/integration/targets/azure_rm_batchapplication/tasks/main.yml @@ -0,0 +1,85 @@ +--- +# ---------------------------------------------------------------------------- +# +# *** AUTO GENERATED CODE *** AUTO GENERATED CODE *** +# +# ---------------------------------------------------------------------------- +# +# This file is automatically generated by Magic Modules and manual +# changes will be clobbered when the file is regenerated. +# +# Please read more about how to change this file at +# https://github.com/Azure/magic-module-specs +# +# ---------------------------------------------------------------------------- +- name: Prepare random number + set_fact: + storage_account_name: "st{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}" + batch_account_name: "ba{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}" + batch_application_name: "bap{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}" + run_once: yes + +- name: Create Storage Account + azure_rm_storageaccount: + resource_group: "{{ resource_group }}" + name: "{{ storage_account_name }}" + location: eastus + account_type: Standard_LRS + +- name: Create Batch Account + azure_rm_batchaccount: + resource_group: "{{ resource_group }}" + name: "{{ batch_account_name }}" + location: eastus + auto_storage_account: + name: "{{ storage_account_name }}" + pool_allocation_mode: batch_service + +- name: Create Batch Application + azure_rm_batchapplication: + resource_group: "{{ resource_group }}" + name: "{{ batch_application_name }}" + account_name: "{{ batch_account_name }}" + register: output + +- name: Assert the resource was created + assert: + that: + - output.changed + +- name: Create Batch Application -- idempotent + azure_rm_batchapplication: + resource_group: "{{ resource_group }}" + name: "{{ batch_application_name }}" + account_name: "{{ batch_account_name }}" + register: output + +- name: Assert the resource was created + assert: + that: + - not output.changed + +- name: Delete Batch Application + azure_rm_batchapplication: + resource_group: "{{ resource_group }}" + name: "{{ batch_application_name }}" + account_name: "{{ batch_account_name }}" + state: absent + register: output + +- name: Assert that state has changed + assert: + that: + - output.changed + +- name: Delete Batch Account + azure_rm_batchaccount: + resource_group: "{{ resource_group }}" + name: "{{ batch_account_name }}" + state: absent + +- name: Delete Storage Account + azure_rm_storageaccount: + resource_group: "{{ resource_group }}" + name: "{{ storage_account_name }}" + state: absent