From 0d8a3eb76d071a2b8dc9be3e8d2e20ea8689a2b3 Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Tue, 3 Aug 2021 09:39:51 -0500 Subject: [PATCH 01/16] info module for webapp vnetintegration --- .../azure_rm_webapp_vnetintegration_info.py | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 plugins/modules/azure_rm_webapp_vnetintegration_info.py diff --git a/plugins/modules/azure_rm_webapp_vnetintegration_info.py b/plugins/modules/azure_rm_webapp_vnetintegration_info.py new file mode 100644 index 000000000..7e976bdd8 --- /dev/null +++ b/plugins/modules/azure_rm_webapp_vnetintegration_info.py @@ -0,0 +1,159 @@ +#!/usr/bin/python +# +# Copyright (c) 2021 Ross Bender (@l3ender) +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +DOCUMENTATION = ''' +--- +module: azure_rm_webapp_vnetintegration_info + +version_added: "1.9.0" + +short_description: Get Azure web app virtual network integration facts + +description: + - Get facts for a web app's virtual network integration. + +options: + name: + description: + - Name of the web app. + resource_group: + description: + - Resource group of the web app. + +extends_documentation_fragment: + - azure.azcollection.azure + +author: + - Ross Bender (@l3ender) +''' + +EXAMPLES = ''' + - name: Get web app virtual network integrations + azure_rm_webapp_vnetintegration_info: + name: "MyWebapp" + resource_group: "MyResourceGroup" +''' + +RETURN = ''' +integrations: + description: + - List of the web app's virtual network integrations. + returned: always + type: complex + contains: + id: + description: + - ID of the web app virtual network integration. + returned: always + type: str + sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Web/sites/myWebApp/virtualNetworkConnections/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_subnet + name: + description: + - Name of the web app virtual network integration. + returned: always + type: str + sample: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_subnet + subnet_name: + description: + - Name of the subnet connected to the web app. + returned: always + type: str + sample: mySubnet + vnet_name: + description: + - Name of the virtual network connected to the web app. + returned: always + type: str + sample: myVnet + vnet_resource_group: + description: + - Name of the resource group the virtual network is in. + returned: always + type: str + sample: myResourceGroup + vnet_resource_id: + description: + - ID of the virtual network/subnet connected to the web app. + returned: always + type: str + sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet +''' +try: + from msrestazure.azure_exceptions import CloudError + from msrest.polling import LROPoller + from azure.common import AzureMissingResourceHttpError, AzureHttpError +except Exception: + # This is handled in azure_rm_common + pass + +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase +try: + import xmltodict +except Exception: + pass + +AZURE_OBJECT_CLASS = 'WebApp' + + +class AzureRMWebAppVnetIntegrationInfo(AzureRMModuleBase): + + def __init__(self): + + self.module_arg_spec = dict( + name=dict(type='str', required=True), + resource_group=dict(type='str', required=True), + ) + + self.results = dict( + changed=False, + integrations=[], + ) + + self.name = None + self.resource_group = None + + super(AzureRMWebAppVnetIntegrationInfo, self).__init__(self.module_arg_spec, + supports_tags=False, + facts_module=True) + + def exec_module(self, **kwargs): + for key in self.module_arg_spec: + setattr(self, key, kwargs[key]) + + try: + vnets = self.web_client.web_apps.list_vnet_connections(resource_group_name=self.resource_group, name=self.name) + + self.results['integrations'] = [self.set_results(vnet) for vnet in vnets] + except CloudError: + pass + + return self.results + + def set_results(self, vnet): + vnet_dict = vnet.as_dict() + + output = dict() + output['id'] = vnet_dict['id'] + output['name'] = vnet_dict['name'] + output['vnet_resource_id'] = vnet_dict['vnet_resource_id'] + output['vnet_resource_group'] = vnet_dict['vnet_resource_id'].split('resourceGroups/')[1].split('/')[0] + vnet_detail = vnet_dict['vnet_resource_id'].split('/Microsoft.Network/virtualNetworks/')[1].split('/subnets/') + output['vnet_name'] = vnet_detail[0] + output['subnet_name'] = vnet_detail[1] + + return output + + +def main(): + AzureRMWebAppVnetIntegrationInfo() + + +if __name__ == '__main__': + main() From 6f3b094fe1322848f95ce00544135f40091c793f Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Tue, 3 Aug 2021 14:51:07 -0500 Subject: [PATCH 02/16] add module for configuring vnet connection --- plugins/module_utils/azure_rm_common.py | 8 + .../modules/azure_rm_webapp_vnetconnection.py | 223 ++++++++++++++++++ ...=> azure_rm_webapp_vnetconnection_info.py} | 74 +++--- 3 files changed, 269 insertions(+), 36 deletions(-) create mode 100644 plugins/modules/azure_rm_webapp_vnetconnection.py rename plugins/modules/{azure_rm_webapp_vnetintegration_info.py => azure_rm_webapp_vnetconnection_info.py} (64%) diff --git a/plugins/module_utils/azure_rm_common.py b/plugins/module_utils/azure_rm_common.py index 9c525d487..8e8d8794e 100644 --- a/plugins/module_utils/azure_rm_common.py +++ b/plugins/module_utils/azure_rm_common.py @@ -966,6 +966,14 @@ def get_data_svc_client(self, **kwags): config = self.add_user_agent(config) return ServiceClient(creds=config.credentials, config=config) + def get_subnet_detail(self, subnet_id): + vnet_detail = subnet_id.split('/Microsoft.Network/virtualNetworks/')[1].split('/subnets/') + return dict( + resource_group = subnet_id.split('resourceGroups/')[1].split('/')[0], + vnet_name = vnet_detail[0], + subnet_name = vnet_detail[1], + ) + # passthru methods to AzureAuth instance for backcompat @property def credentials(self): diff --git a/plugins/modules/azure_rm_webapp_vnetconnection.py b/plugins/modules/azure_rm_webapp_vnetconnection.py new file mode 100644 index 000000000..8a90cca4f --- /dev/null +++ b/plugins/modules/azure_rm_webapp_vnetconnection.py @@ -0,0 +1,223 @@ +#!/usr/bin/python +# +# Copyright (c) 2021 Ross Bender (@l3ender) +# +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +DOCUMENTATION = ''' +--- +module: azure_rm_webapp_vnetconnnection +version_added: "1.9.0" +short_description: Manage web app virtual network connection +description: + - Add, remove, or update the virtual network connection for a web app. +options: + name: + description: + - Name of the web app. + required: True + resource_group: + description: + - Resource group of the web app. + required: True + vnet_name: + description: + - Name of the virtual network. Required if adding or updating. + subnet: + description: + - Name of the virtual network's subnet. Required if adding or updating. + vnet_resource_group: + description: + - Name of the resource group for the virtual network. Defaults to main I(resource_group) value. + +extends_documentation_fragment: + - azure.azcollection.azure + +author: + - Ross Bender (@l3ender) +''' + +EXAMPLES = ''' + - name: Configure virtual network for web app + azure.azcollection.azure_rm_webapp_vnetconnnection: + name: "MyWebapp" + resource_group: "MyResourceGroup" + vnet_name: "MyVnetName" + subnet: "MySubnetName" +''' + +RETURN = ''' +connection: + description: + - The web app's virtual network connection. + returned: always + type: complex + contains: + id: + description: + - ID of the web app virtual network connection. + returned: always + type: str + sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Web/sites/myWebApp/virtualNetworkConnections/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_subnet + name: + description: + - Name of the web app virtual network connection. + returned: always + type: str + sample: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_subnet + subnet_name: + description: + - Name of the subnet connected to the web app. + returned: always + type: str + sample: mySubnet + vnet_name: + description: + - Name of the virtual network connected to the web app. + returned: always + type: str + sample: myVnet + vnet_resource_group: + description: + - Name of the resource group the virtual network is in. + returned: always + type: str + sample: myResourceGroup + vnet_resource_id: + description: + - ID of the virtual network/subnet connected to the web app. + returned: always + type: str + sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet +''' +try: + from azure.mgmt.web.models import SwiftVirtualNetwork +except Exception: + # This is handled in azure_rm_common + pass + +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase + +class AzureRMWebAppVnetConnection(AzureRMModuleBase): + + def __init__(self): + + self.module_arg_spec = dict( + name=dict(type='str', required=True), + resource_group=dict(type='str', required=True), + state=dict(type='str', default='present', choices=['present', 'absent']), + vnet_name=dict(type='str'), + subnet=dict(type='str'), + vnet_resource_group=dict(type='str'), + ) + + self.results = dict( + changed=False, + connection=dict(), + ) + + self.state = None + self.name = None + self.resource_group = None + self.vnet_name = None + self.subnet = None + self.vnet_resource_group = None + + super(AzureRMWebAppVnetConnection, self).__init__(self.module_arg_spec, + supports_check_mode=True, + supports_tags=False) + + def exec_module(self, **kwargs): + for key in self.module_arg_spec: + setattr(self, key, kwargs[key]) + + changed = False + vnet = self.get_vnet_connection() + if vnet: + self.results['connection'] = self.set_results(vnet) + + if self.state == 'absent' and vnet: + changed = True + if not self.check_mode: + self.delete_vnet_connection() + self.results['connection'] = dict() + elif self.state == 'present': + self.vnet_resource_group = self.vnet_resource_group or self.resource_group + + if not vnet: + changed = True # create new vnet connection + else: # check update + subnet_detail = self.get_subnet_detail(vnet.vnet_resource_id) + if subnet_detail['resource_group'] != self.vnet_resource_group or subnet_detail['vnet_name'] != self.vnet_name or subnet_detail['subnet_name'] != self.subnet: + changed = True + + if changed: + subnet = self.get_subnet() + param = SwiftVirtualNetwork(subnet_resource_id=subnet.id) + if not self.check_mode: + self.create_or_update_vnet_connection(param) + vnet = self.get_vnet_connection() + self.results['connection'] = self.set_results(vnet) + + self.results['changed'] = changed + + return self.results + + def get_vnet_connection(self): + connections = self.list_vnet_connections() + for connection in connections: + if connection.is_swift: + return connection + + return None + + def list_vnet_connections(self): + try: + return self.web_client.web_apps.list_vnet_connections(resource_group_name=self.resource_group, name=self.name) + except Exception as exc: + self.fail("Error getting webapp vnet connections {0} (rg={1}) - {2}".format(self.name, self.resource_group, str(exc))) + + def delete_vnet_connection(self): + try: + return self.web_client.web_apps.delete_swift_virtual_network(resource_group_name=self.resource_group, name=self.name) + except Exception as exc: + self.fail("Error deleting webapp vnet connection {0} (rg={1}) - {3}".format(self.name, self.resource_group, str(exc))) + + def create_or_update_vnet_connection(self, vnet): + try: + return self.web_client.web_apps.create_or_update_swift_virtual_network_connection(resource_group_name=self.resource_group, name=self.name, connection_envelope=vnet) + except Exception as exc: + self.fail("Error creating/updating webapp vnet connection {0} (vnet={1}, rg={2}) - {3}".format(self.name, self.vnet_name, self.resource_group, str(exc))) + + def get_subnet(self): + try: + return self.network_client.subnets.get(resource_group_name=self.vnet_resource_group, virtual_network_name=self.vnet_name, subnet_name=self.subnet) + except Exception as exc: + self.fail("Error getting subnet {0} in vnet={1} (rg={2}) - {3}".format(self.subnet, self.vnet_name, self.vnet_resource_group, str(exc))) + + def set_results(self, vnet): + vnet_dict = vnet.as_dict() + + output = dict() + output['id'] = vnet_dict['id'] + output['name'] = vnet_dict['name'] + subnet_id = vnet_dict.get('subnet_resource_id', vnet_dict.get('vnet_resource_id')) + output['vnet_resource_id'] = subnet_id + subnet_detail = self.get_subnet_detail(subnet_id) + output['vnet_resource_group'] = subnet_detail['resource_group'] + output['vnet_name'] = subnet_detail['vnet_name'] + output['subnet_name'] = subnet_detail['subnet_name'] + + return output + + +def main(): + AzureRMWebAppVnetConnection() + + +if __name__ == '__main__': + main() diff --git a/plugins/modules/azure_rm_webapp_vnetintegration_info.py b/plugins/modules/azure_rm_webapp_vnetconnection_info.py similarity index 64% rename from plugins/modules/azure_rm_webapp_vnetintegration_info.py rename to plugins/modules/azure_rm_webapp_vnetconnection_info.py index 7e976bdd8..9dbf4b7e7 100644 --- a/plugins/modules/azure_rm_webapp_vnetintegration_info.py +++ b/plugins/modules/azure_rm_webapp_vnetconnection_info.py @@ -10,22 +10,24 @@ DOCUMENTATION = ''' --- -module: azure_rm_webapp_vnetintegration_info +module: azure_rm_webapp_vnetconnection_info version_added: "1.9.0" -short_description: Get Azure web app virtual network integration facts +short_description: Get Azure web app virtual network connection facts description: - - Get facts for a web app's virtual network integration. + - Get facts for a web app's virtual network connection. options: name: description: - Name of the web app. + required: True resource_group: description: - Resource group of the web app. + required: True extends_documentation_fragment: - azure.azcollection.azure @@ -35,28 +37,28 @@ ''' EXAMPLES = ''' - - name: Get web app virtual network integrations - azure_rm_webapp_vnetintegration_info: + - name: Get web app virtual network connection + azure_rm_webapp_vnetconnection_info: name: "MyWebapp" resource_group: "MyResourceGroup" ''' RETURN = ''' -integrations: +connection: description: - - List of the web app's virtual network integrations. + - The web app's virtual network connection. returned: always type: complex contains: id: description: - - ID of the web app virtual network integration. + - ID of the web app virtual network connection. returned: always type: str sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Web/sites/myWebApp/virtualNetworkConnections/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_subnet name: description: - - Name of the web app virtual network integration. + - Name of the web app virtual network connection. returned: always type: str sample: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_subnet @@ -85,24 +87,11 @@ type: str sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet ''' -try: - from msrestazure.azure_exceptions import CloudError - from msrest.polling import LROPoller - from azure.common import AzureMissingResourceHttpError, AzureHttpError -except Exception: - # This is handled in azure_rm_common - pass from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase -try: - import xmltodict -except Exception: - pass -AZURE_OBJECT_CLASS = 'WebApp' - -class AzureRMWebAppVnetIntegrationInfo(AzureRMModuleBase): +class AzureRMWebAppVnetConnectionInfo(AzureRMModuleBase): def __init__(self): @@ -113,13 +102,13 @@ def __init__(self): self.results = dict( changed=False, - integrations=[], + connection=dict(), ) self.name = None self.resource_group = None - super(AzureRMWebAppVnetIntegrationInfo, self).__init__(self.module_arg_spec, + super(AzureRMWebAppVnetConnectionInfo, self).__init__(self.module_arg_spec, supports_tags=False, facts_module=True) @@ -127,32 +116,45 @@ def exec_module(self, **kwargs): for key in self.module_arg_spec: setattr(self, key, kwargs[key]) - try: - vnets = self.web_client.web_apps.list_vnet_connections(resource_group_name=self.resource_group, name=self.name) + vnet = self.get_vnet_connection() - self.results['integrations'] = [self.set_results(vnet) for vnet in vnets] - except CloudError: - pass + if vnet: + self.results['connection'] = self.set_results(vnet) return self.results + def get_vnet_connection(self): + connections = self.list_vnet_connections() + for connection in connections: + if connection.is_swift: + return connection + + return None + + def list_vnet_connections(self): + try: + return self.web_client.web_apps.list_vnet_connections(resource_group_name=self.resource_group, name=self.name) + except Exception as exc: + self.fail("Error getting webapp vnet connections {0} (rg={1}) - {2}".format(self.name, self.resource_group, str(exc))) + def set_results(self, vnet): vnet_dict = vnet.as_dict() output = dict() output['id'] = vnet_dict['id'] output['name'] = vnet_dict['name'] - output['vnet_resource_id'] = vnet_dict['vnet_resource_id'] - output['vnet_resource_group'] = vnet_dict['vnet_resource_id'].split('resourceGroups/')[1].split('/')[0] - vnet_detail = vnet_dict['vnet_resource_id'].split('/Microsoft.Network/virtualNetworks/')[1].split('/subnets/') - output['vnet_name'] = vnet_detail[0] - output['subnet_name'] = vnet_detail[1] + subnet_id = vnet_dict['vnet_resource_id'] + output['vnet_resource_id'] = subnet_id + subnet_detail = self.get_subnet_detail(subnet_id) + output['vnet_resource_group'] = subnet_detail['resource_group'] + output['vnet_name'] = subnet_detail['vnet_name'] + output['subnet_name'] = subnet_detail['subnet_name'] return output def main(): - AzureRMWebAppVnetIntegrationInfo() + AzureRMWebAppVnetConnectionInfo() if __name__ == '__main__': From 458e57320feb14c9e3a37bd1c41b4212cd0fcacc Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Tue, 3 Aug 2021 15:32:47 -0500 Subject: [PATCH 03/16] add coverage for webapp vnetconnection module --- .../azure_rm_webapp_vnetconnection/aliases | 3 + .../meta/main.yml | 2 + .../tasks/main.yml | 78 +++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 tests/integration/targets/azure_rm_webapp_vnetconnection/aliases create mode 100644 tests/integration/targets/azure_rm_webapp_vnetconnection/meta/main.yml create mode 100644 tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml diff --git a/tests/integration/targets/azure_rm_webapp_vnetconnection/aliases b/tests/integration/targets/azure_rm_webapp_vnetconnection/aliases new file mode 100644 index 000000000..759eafa2d --- /dev/null +++ b/tests/integration/targets/azure_rm_webapp_vnetconnection/aliases @@ -0,0 +1,3 @@ +cloud/azure +shippable/azure/group3 +destructive diff --git a/tests/integration/targets/azure_rm_webapp_vnetconnection/meta/main.yml b/tests/integration/targets/azure_rm_webapp_vnetconnection/meta/main.yml new file mode 100644 index 000000000..95e1952f9 --- /dev/null +++ b/tests/integration/targets/azure_rm_webapp_vnetconnection/meta/main.yml @@ -0,0 +1,2 @@ +dependencies: + - setup_azure diff --git a/tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml b/tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml new file mode 100644 index 000000000..c7b8c9196 --- /dev/null +++ b/tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml @@ -0,0 +1,78 @@ +- name: Prepare random number + set_fact: + rpfx: "{{ resource_group | hash('md5') | truncate(7, True, '') }}{{ 1000 | random }}" + run_once: true + +- name: Create a virtual network + azure_rm_virtualnetwork: + name: vnet{{ rpfx }} + resource_group: "{{ resource_group }}" + address_prefixes_cidr: + - 10.1.0.0/16 + - 172.100.0.0/16 + dns_servers: + - 127.0.0.1 + - 127.0.0.2 +- name: Create a subnet + azure_rm_subnet: + name: subnet{{ rpfx }} + virtual_network_name: vnet{{ rpfx }} + resource_group: "{{ resource_group }}" + address_prefix_cidr: 10.1.0.0/24 + delegations: + - name: 'mydeleg' + serviceName: 'Microsoft.Web/serverFarms' + register: subnet_output +- name: Create a web app + azure_rm_webapp: + resource_group: "{{ resource_group }}" + name: webapp{{ rpfx }} + plan: + resource_group: "{{ resource_group }}" + name: webappplan{{ rpfx }} + is_linux: false + sku: S1 + +- name: "Create webapp vnetconnection - check mode" + azure_rm_webapp_vnetconnection: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + vnet_name: vnet{{ rpfx }} + subnet: subnet{{ rpfx }} + check_mode: true + register: output +- name: Assert the resource is well created + assert: + that: output.changed + +- name: "Create webapp vnetconnection" + azure_rm_webapp_vnetconnection: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + vnet_name: vnet{{ rpfx }} + subnet: subnet{{ rpfx }} + register: output +- name: Assert the resource is well created + assert: + that: output.changed + +- name: "Create webapp vnetconnection - idempotent" + azure_rm_webapp_vnetconnection: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + vnet_name: vnet{{ rpfx }} + subnet: subnet{{ rpfx }} + register: output +- name: Assert the resource is not changed + assert: + that: not output.changed + +- name: "Delete webapp vnetconnection" + azure_rm_webapp_vnetconnection: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + state: "absent" + register: output +- name: Assert the resource is deleted + assert: + that: output.changed From 095035433c3a552e5ac366fd575995fd753294f1 Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Tue, 3 Aug 2021 15:43:20 -0500 Subject: [PATCH 04/16] add doc/examples --- .../modules/azure_rm_webapp_vnetconnection.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/plugins/modules/azure_rm_webapp_vnetconnection.py b/plugins/modules/azure_rm_webapp_vnetconnection.py index 8a90cca4f..5b635db72 100644 --- a/plugins/modules/azure_rm_webapp_vnetconnection.py +++ b/plugins/modules/azure_rm_webapp_vnetconnection.py @@ -42,12 +42,26 @@ ''' EXAMPLES = ''' - - name: Configure virtual network for web app + - name: Configure web app with virtual network azure.azcollection.azure_rm_webapp_vnetconnnection: name: "MyWebapp" resource_group: "MyResourceGroup" vnet_name: "MyVnetName" subnet: "MySubnetName" + + - name: Configure web app with virtual network in different resource group + azure.azcollection.azure_rm_webapp_vnetconnnection: + name: "MyWebapp" + resource_group: "MyResourceGroup" + vnet_name: "MyVnetName" + subnet: "MySubnetName" + vnet_resource_group: "MyOtherResourceGroup" + + - name: Delete web app virtual network + azure.azcollection.azure_rm_webapp_vnetconnnection: + name: "MyWebapp" + resource_group: "MyResourceGroup" + state: "absent" ''' RETURN = ''' From 39de2b5ba3f6e8d83ccce0e244b636d9b41148cb Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Tue, 3 Aug 2021 15:43:36 -0500 Subject: [PATCH 05/16] add delete idempotent test for webpp vnetconnection --- .../azure_rm_webapp_vnetconnection/tasks/main.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml b/tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml index c7b8c9196..3a5b151d7 100644 --- a/tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml +++ b/tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml @@ -76,3 +76,13 @@ - name: Assert the resource is deleted assert: that: output.changed + +- name: "Delete webapp vnetconnection - idempotent" + azure_rm_webapp_vnetconnection: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + state: "absent" + register: output +- name: Assert the resource is not changed + assert: + that: not output.changed From 28e68d5c939fba7b19300864224d570722592f79 Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Tue, 3 Aug 2021 16:00:19 -0500 Subject: [PATCH 06/16] formatting --- .../modules/azure_rm_webapp_vnetconnection.py | 26 ++++++++++++------- .../azure_rm_webapp_vnetconnection_info.py | 10 +++---- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/plugins/modules/azure_rm_webapp_vnetconnection.py b/plugins/modules/azure_rm_webapp_vnetconnection.py index 5b635db72..3a1b884b5 100644 --- a/plugins/modules/azure_rm_webapp_vnetconnection.py +++ b/plugins/modules/azure_rm_webapp_vnetconnection.py @@ -5,6 +5,7 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase __metaclass__ = type @@ -114,7 +115,6 @@ # This is handled in azure_rm_common pass -from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase class AzureRMWebAppVnetConnection(AzureRMModuleBase): @@ -123,7 +123,8 @@ def __init__(self): self.module_arg_spec = dict( name=dict(type='str', required=True), resource_group=dict(type='str', required=True), - state=dict(type='str', default='present', choices=['present', 'absent']), + state=dict(type='str', default='present', + choices=['present', 'absent']), vnet_name=dict(type='str'), subnet=dict(type='str'), vnet_resource_group=dict(type='str'), @@ -142,13 +143,13 @@ def __init__(self): self.vnet_resource_group = None super(AzureRMWebAppVnetConnection, self).__init__(self.module_arg_spec, - supports_check_mode=True, - supports_tags=False) + supports_check_mode=True, + supports_tags=False) def exec_module(self, **kwargs): for key in self.module_arg_spec: setattr(self, key, kwargs[key]) - + changed = False vnet = self.get_vnet_connection() if vnet: @@ -193,25 +194,29 @@ def list_vnet_connections(self): try: return self.web_client.web_apps.list_vnet_connections(resource_group_name=self.resource_group, name=self.name) except Exception as exc: - self.fail("Error getting webapp vnet connections {0} (rg={1}) - {2}".format(self.name, self.resource_group, str(exc))) + self.fail("Error getting webapp vnet connections {0} (rg={1}) - {2}".format( + self.name, self.resource_group, str(exc))) def delete_vnet_connection(self): try: return self.web_client.web_apps.delete_swift_virtual_network(resource_group_name=self.resource_group, name=self.name) except Exception as exc: - self.fail("Error deleting webapp vnet connection {0} (rg={1}) - {3}".format(self.name, self.resource_group, str(exc))) + self.fail("Error deleting webapp vnet connection {0} (rg={1}) - {3}".format( + self.name, self.resource_group, str(exc))) def create_or_update_vnet_connection(self, vnet): try: return self.web_client.web_apps.create_or_update_swift_virtual_network_connection(resource_group_name=self.resource_group, name=self.name, connection_envelope=vnet) except Exception as exc: - self.fail("Error creating/updating webapp vnet connection {0} (vnet={1}, rg={2}) - {3}".format(self.name, self.vnet_name, self.resource_group, str(exc))) + self.fail("Error creating/updating webapp vnet connection {0} (vnet={1}, rg={2}) - {3}".format( + self.name, self.vnet_name, self.resource_group, str(exc))) def get_subnet(self): try: return self.network_client.subnets.get(resource_group_name=self.vnet_resource_group, virtual_network_name=self.vnet_name, subnet_name=self.subnet) except Exception as exc: - self.fail("Error getting subnet {0} in vnet={1} (rg={2}) - {3}".format(self.subnet, self.vnet_name, self.vnet_resource_group, str(exc))) + self.fail("Error getting subnet {0} in vnet={1} (rg={2}) - {3}".format( + self.subnet, self.vnet_name, self.vnet_resource_group, str(exc))) def set_results(self, vnet): vnet_dict = vnet.as_dict() @@ -219,7 +224,8 @@ def set_results(self, vnet): output = dict() output['id'] = vnet_dict['id'] output['name'] = vnet_dict['name'] - subnet_id = vnet_dict.get('subnet_resource_id', vnet_dict.get('vnet_resource_id')) + subnet_id = vnet_dict.get( + 'subnet_resource_id', vnet_dict.get('vnet_resource_id')) output['vnet_resource_id'] = subnet_id subnet_detail = self.get_subnet_detail(subnet_id) output['vnet_resource_group'] = subnet_detail['resource_group'] diff --git a/plugins/modules/azure_rm_webapp_vnetconnection_info.py b/plugins/modules/azure_rm_webapp_vnetconnection_info.py index 9dbf4b7e7..66de6193f 100644 --- a/plugins/modules/azure_rm_webapp_vnetconnection_info.py +++ b/plugins/modules/azure_rm_webapp_vnetconnection_info.py @@ -5,6 +5,7 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase __metaclass__ = type @@ -88,8 +89,6 @@ sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet ''' -from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase - class AzureRMWebAppVnetConnectionInfo(AzureRMModuleBase): @@ -109,8 +108,8 @@ def __init__(self): self.resource_group = None super(AzureRMWebAppVnetConnectionInfo, self).__init__(self.module_arg_spec, - supports_tags=False, - facts_module=True) + supports_tags=False, + facts_module=True) def exec_module(self, **kwargs): for key in self.module_arg_spec: @@ -135,7 +134,8 @@ def list_vnet_connections(self): try: return self.web_client.web_apps.list_vnet_connections(resource_group_name=self.resource_group, name=self.name) except Exception as exc: - self.fail("Error getting webapp vnet connections {0} (rg={1}) - {2}".format(self.name, self.resource_group, str(exc))) + self.fail("Error getting webapp vnet connections {0} (rg={1}) - {2}".format( + self.name, self.resource_group, str(exc))) def set_results(self, vnet): vnet_dict = vnet.as_dict() From fa0acf03907c7dd97801f8006d5e59c7ec423735 Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Wed, 4 Aug 2021 16:06:51 -0500 Subject: [PATCH 07/16] formatting and logging --- .../modules/azure_rm_webapp_vnetconnection.py | 57 +++++++++++-------- .../azure_rm_webapp_vnetconnection_info.py | 11 ++-- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/plugins/modules/azure_rm_webapp_vnetconnection.py b/plugins/modules/azure_rm_webapp_vnetconnection.py index 3a1b884b5..9d9fa1e68 100644 --- a/plugins/modules/azure_rm_webapp_vnetconnection.py +++ b/plugins/modules/azure_rm_webapp_vnetconnection.py @@ -8,7 +8,6 @@ from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase __metaclass__ = type - DOCUMENTATION = ''' --- module: azure_rm_webapp_vnetconnnection @@ -20,20 +19,33 @@ name: description: - Name of the web app. - required: True + required: true + type: str resource_group: description: - Resource group of the web app. - required: True + required: true + type: str + state: + description: + - State of the virtual network connection. Use C(present) to create or update and C(absent) to delete. + type: str + default: present + choices: + - absent + - present vnet_name: description: - Name of the virtual network. Required if adding or updating. + type: str subnet: description: - Name of the virtual network's subnet. Required if adding or updating. + type: str vnet_resource_group: description: - - Name of the resource group for the virtual network. Defaults to main I(resource_group) value. + - Name of the resource group for the virtual network. Defaults to main C(resource_group) value. + type: str extends_documentation_fragment: - azure.azcollection.azure @@ -109,13 +121,13 @@ type: str sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet ''' + try: from azure.mgmt.web.models import SwiftVirtualNetwork except Exception: # This is handled in azure_rm_common pass - class AzureRMWebAppVnetConnection(AzureRMModuleBase): def __init__(self): @@ -123,8 +135,7 @@ def __init__(self): self.module_arg_spec = dict( name=dict(type='str', required=True), resource_group=dict(type='str', required=True), - state=dict(type='str', default='present', - choices=['present', 'absent']), + state=dict(type='str', default='present', choices=['present', 'absent']), vnet_name=dict(type='str'), subnet=dict(type='str'), vnet_resource_group=dict(type='str'), @@ -158,28 +169,33 @@ def exec_module(self, **kwargs): if self.state == 'absent' and vnet: changed = True if not self.check_mode: + self.log('Deleting vnet connection for webapp {0}'.format(self.name)) self.delete_vnet_connection() self.results['connection'] = dict() elif self.state == 'present': self.vnet_resource_group = self.vnet_resource_group or self.resource_group if not vnet: - changed = True # create new vnet connection - else: # check update + self.log('Adding vnet connection for webapp {0}'.format(self.name)) + changed = True + else: subnet_detail = self.get_subnet_detail(vnet.vnet_resource_id) - if subnet_detail['resource_group'] != self.vnet_resource_group or subnet_detail['vnet_name'] != self.vnet_name or subnet_detail['subnet_name'] != self.subnet: + if (subnet_detail['resource_group'] != self.vnet_resource_group + or subnet_detail['vnet_name'] != self.vnet_name + or subnet_detail['subnet_name'] != self.subnet): + self.log('Detected change in vnet connection for webapp {0}'.format(self.name)) changed = True if changed: - subnet = self.get_subnet() - param = SwiftVirtualNetwork(subnet_resource_id=subnet.id) if not self.check_mode: + self.log('Updating vnet connection for webapp {0}'.format(self.name)) + subnet = self.get_subnet() + param = SwiftVirtualNetwork(subnet_resource_id=subnet.id) self.create_or_update_vnet_connection(param) vnet = self.get_vnet_connection() self.results['connection'] = self.set_results(vnet) self.results['changed'] = changed - return self.results def get_vnet_connection(self): @@ -194,29 +210,25 @@ def list_vnet_connections(self): try: return self.web_client.web_apps.list_vnet_connections(resource_group_name=self.resource_group, name=self.name) except Exception as exc: - self.fail("Error getting webapp vnet connections {0} (rg={1}) - {2}".format( - self.name, self.resource_group, str(exc))) + self.fail("Error getting webapp vnet connections {0} (rg={1}) - {2}".format(self.name, self.resource_group, str(exc))) def delete_vnet_connection(self): try: return self.web_client.web_apps.delete_swift_virtual_network(resource_group_name=self.resource_group, name=self.name) except Exception as exc: - self.fail("Error deleting webapp vnet connection {0} (rg={1}) - {3}".format( - self.name, self.resource_group, str(exc))) + self.fail("Error deleting webapp vnet connection {0} (rg={1}) - {3}".format(self.name, self.resource_group, str(exc))) def create_or_update_vnet_connection(self, vnet): try: return self.web_client.web_apps.create_or_update_swift_virtual_network_connection(resource_group_name=self.resource_group, name=self.name, connection_envelope=vnet) except Exception as exc: - self.fail("Error creating/updating webapp vnet connection {0} (vnet={1}, rg={2}) - {3}".format( - self.name, self.vnet_name, self.resource_group, str(exc))) + self.fail("Error creating/updating webapp vnet connection {0} (vnet={1}, rg={2}) - {3}".format(self.name, self.vnet_name, self.resource_group, str(exc))) def get_subnet(self): try: return self.network_client.subnets.get(resource_group_name=self.vnet_resource_group, virtual_network_name=self.vnet_name, subnet_name=self.subnet) except Exception as exc: - self.fail("Error getting subnet {0} in vnet={1} (rg={2}) - {3}".format( - self.subnet, self.vnet_name, self.vnet_resource_group, str(exc))) + self.fail("Error getting subnet {0} in vnet={1} (rg={2}) - {3}".format(self.subnet, self.vnet_name, self.vnet_resource_group, str(exc))) def set_results(self, vnet): vnet_dict = vnet.as_dict() @@ -224,8 +236,7 @@ def set_results(self, vnet): output = dict() output['id'] = vnet_dict['id'] output['name'] = vnet_dict['name'] - subnet_id = vnet_dict.get( - 'subnet_resource_id', vnet_dict.get('vnet_resource_id')) + subnet_id = vnet_dict.get('subnet_resource_id', vnet_dict.get('vnet_resource_id')) output['vnet_resource_id'] = subnet_id subnet_detail = self.get_subnet_detail(subnet_id) output['vnet_resource_group'] = subnet_detail['resource_group'] diff --git a/plugins/modules/azure_rm_webapp_vnetconnection_info.py b/plugins/modules/azure_rm_webapp_vnetconnection_info.py index 66de6193f..8593d6a08 100644 --- a/plugins/modules/azure_rm_webapp_vnetconnection_info.py +++ b/plugins/modules/azure_rm_webapp_vnetconnection_info.py @@ -8,7 +8,6 @@ from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase __metaclass__ = type - DOCUMENTATION = ''' --- module: azure_rm_webapp_vnetconnection_info @@ -24,11 +23,13 @@ name: description: - Name of the web app. - required: True + required: true + type: str resource_group: description: - Resource group of the web app. - required: True + required: true + type: str extends_documentation_fragment: - azure.azcollection.azure @@ -89,7 +90,6 @@ sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet ''' - class AzureRMWebAppVnetConnectionInfo(AzureRMModuleBase): def __init__(self): @@ -134,8 +134,7 @@ def list_vnet_connections(self): try: return self.web_client.web_apps.list_vnet_connections(resource_group_name=self.resource_group, name=self.name) except Exception as exc: - self.fail("Error getting webapp vnet connections {0} (rg={1}) - {2}".format( - self.name, self.resource_group, str(exc))) + self.fail("Error getting webapp vnet connections {0} (rg={1}) - {2}".format(self.name, self.resource_group, str(exc))) def set_results(self, vnet): vnet_dict = vnet.as_dict() From 546fc9ae2e4cd0fb8916def4de334d7bc9f6b60c Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Thu, 5 Aug 2021 18:57:41 -0500 Subject: [PATCH 08/16] Apply suggestions from code review Co-authored-by: Fred-sun <37327967+Fred-sun@users.noreply.github.com> --- plugins/module_utils/azure_rm_common.py | 6 +++--- plugins/modules/azure_rm_webapp_vnetconnection.py | 3 ++- plugins/modules/azure_rm_webapp_vnetconnection_info.py | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/plugins/module_utils/azure_rm_common.py b/plugins/module_utils/azure_rm_common.py index 8e8d8794e..0bd861409 100644 --- a/plugins/module_utils/azure_rm_common.py +++ b/plugins/module_utils/azure_rm_common.py @@ -969,9 +969,9 @@ def get_data_svc_client(self, **kwags): def get_subnet_detail(self, subnet_id): vnet_detail = subnet_id.split('/Microsoft.Network/virtualNetworks/')[1].split('/subnets/') return dict( - resource_group = subnet_id.split('resourceGroups/')[1].split('/')[0], - vnet_name = vnet_detail[0], - subnet_name = vnet_detail[1], + resource_group=subnet_id.split('resourceGroups/')[1].split('/')[0], + vnet_name=vnet_detail[0], + subnet_name=vnet_detail[1], ) # passthru methods to AzureAuth instance for backcompat diff --git a/plugins/modules/azure_rm_webapp_vnetconnection.py b/plugins/modules/azure_rm_webapp_vnetconnection.py index 9d9fa1e68..68ba04511 100644 --- a/plugins/modules/azure_rm_webapp_vnetconnection.py +++ b/plugins/modules/azure_rm_webapp_vnetconnection.py @@ -10,7 +10,7 @@ DOCUMENTATION = ''' --- -module: azure_rm_webapp_vnetconnnection +module: azure_rm_webapp_vnetconnection version_added: "1.9.0" short_description: Manage web app virtual network connection description: @@ -128,6 +128,7 @@ # This is handled in azure_rm_common pass + class AzureRMWebAppVnetConnection(AzureRMModuleBase): def __init__(self): diff --git a/plugins/modules/azure_rm_webapp_vnetconnection_info.py b/plugins/modules/azure_rm_webapp_vnetconnection_info.py index 8593d6a08..8d25a38f1 100644 --- a/plugins/modules/azure_rm_webapp_vnetconnection_info.py +++ b/plugins/modules/azure_rm_webapp_vnetconnection_info.py @@ -90,6 +90,7 @@ sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet ''' + class AzureRMWebAppVnetConnectionInfo(AzureRMModuleBase): def __init__(self): From 50922c51ababce431c04342e31eea5ddc2be8253 Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Thu, 5 Aug 2021 19:04:54 -0500 Subject: [PATCH 09/16] rename module for collection consistency --- ...tconnection.py => azure_rm_webappvnetconnection.py} | 8 ++++---- ...n_info.py => azure_rm_webappvnetconnection_info.py} | 4 ++-- .../aliases | 0 .../meta/main.yml | 0 .../tasks/main.yml | 10 +++++----- 5 files changed, 11 insertions(+), 11 deletions(-) rename plugins/modules/{azure_rm_webapp_vnetconnection.py => azure_rm_webappvnetconnection.py} (97%) rename plugins/modules/{azure_rm_webapp_vnetconnection_info.py => azure_rm_webappvnetconnection_info.py} (98%) rename tests/integration/targets/{azure_rm_webapp_vnetconnection => azure_rm_webappvnetconnection}/aliases (100%) rename tests/integration/targets/{azure_rm_webapp_vnetconnection => azure_rm_webappvnetconnection}/meta/main.yml (100%) rename tests/integration/targets/{azure_rm_webapp_vnetconnection => azure_rm_webappvnetconnection}/tasks/main.yml (93%) diff --git a/plugins/modules/azure_rm_webapp_vnetconnection.py b/plugins/modules/azure_rm_webappvnetconnection.py similarity index 97% rename from plugins/modules/azure_rm_webapp_vnetconnection.py rename to plugins/modules/azure_rm_webappvnetconnection.py index 68ba04511..25dc361bc 100644 --- a/plugins/modules/azure_rm_webapp_vnetconnection.py +++ b/plugins/modules/azure_rm_webappvnetconnection.py @@ -10,7 +10,7 @@ DOCUMENTATION = ''' --- -module: azure_rm_webapp_vnetconnection +module: azure_rm_webappvnetconnection version_added: "1.9.0" short_description: Manage web app virtual network connection description: @@ -56,14 +56,14 @@ EXAMPLES = ''' - name: Configure web app with virtual network - azure.azcollection.azure_rm_webapp_vnetconnnection: + azure.azcollection.azure_rm_webappvnetconnection: name: "MyWebapp" resource_group: "MyResourceGroup" vnet_name: "MyVnetName" subnet: "MySubnetName" - name: Configure web app with virtual network in different resource group - azure.azcollection.azure_rm_webapp_vnetconnnection: + azure.azcollection.azure_rm_webappvnetconnection: name: "MyWebapp" resource_group: "MyResourceGroup" vnet_name: "MyVnetName" @@ -71,7 +71,7 @@ vnet_resource_group: "MyOtherResourceGroup" - name: Delete web app virtual network - azure.azcollection.azure_rm_webapp_vnetconnnection: + azure.azcollection.azure_rm_webappvnetconnection: name: "MyWebapp" resource_group: "MyResourceGroup" state: "absent" diff --git a/plugins/modules/azure_rm_webapp_vnetconnection_info.py b/plugins/modules/azure_rm_webappvnetconnection_info.py similarity index 98% rename from plugins/modules/azure_rm_webapp_vnetconnection_info.py rename to plugins/modules/azure_rm_webappvnetconnection_info.py index 8d25a38f1..50e66707e 100644 --- a/plugins/modules/azure_rm_webapp_vnetconnection_info.py +++ b/plugins/modules/azure_rm_webappvnetconnection_info.py @@ -10,7 +10,7 @@ DOCUMENTATION = ''' --- -module: azure_rm_webapp_vnetconnection_info +module: azure_rm_webappvnetconnection_info version_added: "1.9.0" @@ -40,7 +40,7 @@ EXAMPLES = ''' - name: Get web app virtual network connection - azure_rm_webapp_vnetconnection_info: + azure_rm_webappvnetconnection_info: name: "MyWebapp" resource_group: "MyResourceGroup" ''' diff --git a/tests/integration/targets/azure_rm_webapp_vnetconnection/aliases b/tests/integration/targets/azure_rm_webappvnetconnection/aliases similarity index 100% rename from tests/integration/targets/azure_rm_webapp_vnetconnection/aliases rename to tests/integration/targets/azure_rm_webappvnetconnection/aliases diff --git a/tests/integration/targets/azure_rm_webapp_vnetconnection/meta/main.yml b/tests/integration/targets/azure_rm_webappvnetconnection/meta/main.yml similarity index 100% rename from tests/integration/targets/azure_rm_webapp_vnetconnection/meta/main.yml rename to tests/integration/targets/azure_rm_webappvnetconnection/meta/main.yml diff --git a/tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml b/tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml similarity index 93% rename from tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml rename to tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml index 3a5b151d7..993e999b0 100644 --- a/tests/integration/targets/azure_rm_webapp_vnetconnection/tasks/main.yml +++ b/tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml @@ -34,7 +34,7 @@ sku: S1 - name: "Create webapp vnetconnection - check mode" - azure_rm_webapp_vnetconnection: + azure_rm_webappvnetconnection: name: webapp{{ rpfx }} resource_group: "{{ resource_group }}" vnet_name: vnet{{ rpfx }} @@ -46,7 +46,7 @@ that: output.changed - name: "Create webapp vnetconnection" - azure_rm_webapp_vnetconnection: + azure_rm_webappvnetconnection: name: webapp{{ rpfx }} resource_group: "{{ resource_group }}" vnet_name: vnet{{ rpfx }} @@ -57,7 +57,7 @@ that: output.changed - name: "Create webapp vnetconnection - idempotent" - azure_rm_webapp_vnetconnection: + azure_rm_webappvnetconnection: name: webapp{{ rpfx }} resource_group: "{{ resource_group }}" vnet_name: vnet{{ rpfx }} @@ -68,7 +68,7 @@ that: not output.changed - name: "Delete webapp vnetconnection" - azure_rm_webapp_vnetconnection: + azure_rm_webappvnetconnection: name: webapp{{ rpfx }} resource_group: "{{ resource_group }}" state: "absent" @@ -78,7 +78,7 @@ that: output.changed - name: "Delete webapp vnetconnection - idempotent" - azure_rm_webapp_vnetconnection: + azure_rm_webappvnetconnection: name: webapp{{ rpfx }} resource_group: "{{ resource_group }}" state: "absent" From e77260b7209083d13af35b5c60e3b67652444efe Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Thu, 5 Aug 2021 19:14:10 -0500 Subject: [PATCH 10/16] correct import location and line lengths --- .../modules/azure_rm_webappvnetconnection.py | 21 +++++++++++-------- .../azure_rm_webappvnetconnection_info.py | 11 +++++----- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/plugins/modules/azure_rm_webappvnetconnection.py b/plugins/modules/azure_rm_webappvnetconnection.py index 25dc361bc..45dadc53d 100644 --- a/plugins/modules/azure_rm_webappvnetconnection.py +++ b/plugins/modules/azure_rm_webappvnetconnection.py @@ -4,8 +4,6 @@ # # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -from __future__ import absolute_import, division, print_function -from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase __metaclass__ = type DOCUMENTATION = ''' @@ -89,13 +87,13 @@ - ID of the web app virtual network connection. returned: always type: str - sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Web/sites/myWebApp/virtualNetworkConnections/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_subnet + sample: /subscriptions/xxx-xxx/resourceGroups/myResourceGroup/providers/Microsoft.Web/sites/myWebApp/virtualNetworkConnections/yyy-yyy_subnet name: description: - Name of the web app virtual network connection. returned: always type: str - sample: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_subnet + sample: yyy-yyy_subnet subnet_name: description: - Name of the subnet connected to the web app. @@ -119,9 +117,12 @@ - ID of the virtual network/subnet connected to the web app. returned: always type: str - sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet + sample: /subscriptions/xxx-xxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet ''' +from __future__ import absolute_import, division, print_function +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase + try: from azure.mgmt.web.models import SwiftVirtualNetwork except Exception: @@ -182,8 +183,8 @@ def exec_module(self, **kwargs): else: subnet_detail = self.get_subnet_detail(vnet.vnet_resource_id) if (subnet_detail['resource_group'] != self.vnet_resource_group - or subnet_detail['vnet_name'] != self.vnet_name - or subnet_detail['subnet_name'] != self.subnet): + or subnet_detail['vnet_name'] != self.vnet_name + or subnet_detail['subnet_name'] != self.subnet): self.log('Detected change in vnet connection for webapp {0}'.format(self.name)) changed = True @@ -221,9 +222,11 @@ def delete_vnet_connection(self): def create_or_update_vnet_connection(self, vnet): try: - return self.web_client.web_apps.create_or_update_swift_virtual_network_connection(resource_group_name=self.resource_group, name=self.name, connection_envelope=vnet) + return self.web_client.web_apps.create_or_update_swift_virtual_network_connection( + resource_group_name=self.resource_group, name=self.name, connection_envelope=vnet) except Exception as exc: - self.fail("Error creating/updating webapp vnet connection {0} (vnet={1}, rg={2}) - {3}".format(self.name, self.vnet_name, self.resource_group, str(exc))) + self.fail("Error creating/updating webapp vnet connection {0} (vnet={1}, rg={2}) - {3}".format( + self.name, self.vnet_name, self.resource_group, str(exc))) def get_subnet(self): try: diff --git a/plugins/modules/azure_rm_webappvnetconnection_info.py b/plugins/modules/azure_rm_webappvnetconnection_info.py index 50e66707e..6109cead3 100644 --- a/plugins/modules/azure_rm_webappvnetconnection_info.py +++ b/plugins/modules/azure_rm_webappvnetconnection_info.py @@ -4,8 +4,6 @@ # # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) -from __future__ import absolute_import, division, print_function -from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase __metaclass__ = type DOCUMENTATION = ''' @@ -57,13 +55,13 @@ - ID of the web app virtual network connection. returned: always type: str - sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Web/sites/myWebApp/virtualNetworkConnections/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_subnet + sample: /subscriptions/xxx-xxx/resourceGroups/myResourceGroup/providers/Microsoft.Web/sites/myWebApp/virtualNetworkConnections/yyy-yyy_subnet name: description: - Name of the web app virtual network connection. returned: always type: str - sample: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy_subnet + sample: yyy-yyy_subnet subnet_name: description: - Name of the subnet connected to the web app. @@ -87,9 +85,12 @@ - ID of the virtual network/subnet connected to the web app. returned: always type: str - sample: /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet + sample: /subscriptions/xxx-xxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet ''' +from __future__ import absolute_import, division, print_function +from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase + class AzureRMWebAppVnetConnectionInfo(AzureRMModuleBase): From dcea73d2f86b362768f7ced9835441ac67523f29 Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Thu, 5 Aug 2021 19:22:32 -0500 Subject: [PATCH 11/16] __future__ imports needed at top --- plugins/modules/azure_rm_webappvnetconnection.py | 3 ++- plugins/modules/azure_rm_webappvnetconnection_info.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/plugins/modules/azure_rm_webappvnetconnection.py b/plugins/modules/azure_rm_webappvnetconnection.py index 45dadc53d..5ecac4056 100644 --- a/plugins/modules/azure_rm_webappvnetconnection.py +++ b/plugins/modules/azure_rm_webappvnetconnection.py @@ -4,8 +4,10 @@ # # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import absolute_import, division, print_function __metaclass__ = type + DOCUMENTATION = ''' --- module: azure_rm_webappvnetconnection @@ -120,7 +122,6 @@ sample: /subscriptions/xxx-xxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet ''' -from __future__ import absolute_import, division, print_function from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase try: diff --git a/plugins/modules/azure_rm_webappvnetconnection_info.py b/plugins/modules/azure_rm_webappvnetconnection_info.py index 6109cead3..d20d70446 100644 --- a/plugins/modules/azure_rm_webappvnetconnection_info.py +++ b/plugins/modules/azure_rm_webappvnetconnection_info.py @@ -4,8 +4,10 @@ # # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +from __future__ import absolute_import, division, print_function __metaclass__ = type + DOCUMENTATION = ''' --- module: azure_rm_webappvnetconnection_info @@ -88,7 +90,6 @@ sample: /subscriptions/xxx-xxx/resourceGroups/myResourceGroup/providers/Microsoft.Network/virtualNetworks/myVnet/subnets/mySubnet ''' -from __future__ import absolute_import, division, print_function from ansible_collections.azure.azcollection.plugins.module_utils.azure_rm_common import AzureRMModuleBase From 3bd7b6ca30d74c7a01cd9afe4c4f6d0265c893f9 Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Thu, 5 Aug 2021 19:34:39 -0500 Subject: [PATCH 12/16] add tests for _info module; add to asserts on main module tests --- .../tasks/main.yml | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml b/tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml index 993e999b0..fa80f8a71 100644 --- a/tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml +++ b/tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml @@ -45,6 +45,17 @@ assert: that: output.changed +- name: "Check webapp vnetconnection facts" + azure_rm_webappvnetconnection_info: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + register: output +- name: Assert the resource has no connections + assert: + that: + - not output.changed + - output.connection | length == 0 + - name: "Create webapp vnetconnection" azure_rm_webappvnetconnection: name: webapp{{ rpfx }} @@ -54,7 +65,24 @@ register: output - name: Assert the resource is well created assert: - that: output.changed + that: + - output.changed + - output.connection.vnet_name == 'vnet{{ rpfx }}' + - output.connection.subnet_name == 'subnet{{ rpfx }}' + - output.connection.vnet_resource_group == '{{ resource_group }}' + +- name: "Check webapp vnetconnection facts" + azure_rm_webappvnetconnection_info: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + register: output +- name: Assert the connection exists + assert: + that: + - not output.changed + - output.connection.vnet_name == 'vnet{{ rpfx }}' + - output.connection.subnet_name == 'subnet{{ rpfx }}' + - output.connection.vnet_resource_group == '{{ resource_group }}' - name: "Create webapp vnetconnection - idempotent" azure_rm_webappvnetconnection: @@ -75,7 +103,20 @@ register: output - name: Assert the resource is deleted assert: - that: output.changed + that: + - output.changed + - output.connection | length == 0 + +- name: "Check webapp vnetconnection facts" + azure_rm_webappvnetconnection_info: + name: webapp{{ rpfx }} + resource_group: "{{ resource_group }}" + register: output +- name: Assert the resource has no connections + assert: + that: + - not output.changed + - output.connection | length == 0 - name: "Delete webapp vnetconnection - idempotent" azure_rm_webappvnetconnection: From fcc75adb4dc6db14d16f5657fdb346b49d07131b Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Thu, 5 Aug 2021 20:04:46 -0500 Subject: [PATCH 13/16] add new module to build/test pipeline --- pr-pipelines.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/pr-pipelines.yml b/pr-pipelines.yml index 5bb9a7ac3..f37ddee21 100644 --- a/pr-pipelines.yml +++ b/pr-pipelines.yml @@ -103,6 +103,7 @@ parameters: - "azure_rm_recoveryservicesvault" - "azure_rm_vmbackuppolicy" - "azure_rm_webapp" + - "azure_rm_webappvnetconnection" - "azure_rm_workspace" - "inventory_azure" - "setup_azure" From 7377f1c45671f684e6744efded302bbc477bf9b6 Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Thu, 5 Aug 2021 20:34:59 -0500 Subject: [PATCH 14/16] clearer test names --- .../targets/azure_rm_webappvnetconnection/tasks/main.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml b/tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml index fa80f8a71..66a1b55cf 100644 --- a/tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml +++ b/tests/integration/targets/azure_rm_webappvnetconnection/tasks/main.yml @@ -45,7 +45,7 @@ assert: that: output.changed -- name: "Check webapp vnetconnection facts" +- name: "Check webapp vnetconnection facts 1" azure_rm_webappvnetconnection_info: name: webapp{{ rpfx }} resource_group: "{{ resource_group }}" @@ -71,7 +71,7 @@ - output.connection.subnet_name == 'subnet{{ rpfx }}' - output.connection.vnet_resource_group == '{{ resource_group }}' -- name: "Check webapp vnetconnection facts" +- name: "Check webapp vnetconnection facts 2" azure_rm_webappvnetconnection_info: name: webapp{{ rpfx }} resource_group: "{{ resource_group }}" @@ -101,13 +101,13 @@ resource_group: "{{ resource_group }}" state: "absent" register: output -- name: Assert the resource is deleted +- name: Assert the connection is deleted assert: that: - output.changed - output.connection | length == 0 -- name: "Check webapp vnetconnection facts" +- name: "Check webapp vnetconnection facts 3" azure_rm_webappvnetconnection_info: name: webapp{{ rpfx }} resource_group: "{{ resource_group }}" From a10992aaf7f37df0a767e2604aeb41a89a6e0733 Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Mon, 9 Aug 2021 20:11:10 -0500 Subject: [PATCH 15/16] Apply suggestions from code review Co-authored-by: Fred-sun <37327967+Fred-sun@users.noreply.github.com> --- plugins/modules/azure_rm_webappvnetconnection.py | 2 +- plugins/modules/azure_rm_webappvnetconnection_info.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/modules/azure_rm_webappvnetconnection.py b/plugins/modules/azure_rm_webappvnetconnection.py index 5ecac4056..41254ab54 100644 --- a/plugins/modules/azure_rm_webappvnetconnection.py +++ b/plugins/modules/azure_rm_webappvnetconnection.py @@ -11,7 +11,7 @@ DOCUMENTATION = ''' --- module: azure_rm_webappvnetconnection -version_added: "1.9.0" +version_added: "1.8.0" short_description: Manage web app virtual network connection description: - Add, remove, or update the virtual network connection for a web app. diff --git a/plugins/modules/azure_rm_webappvnetconnection_info.py b/plugins/modules/azure_rm_webappvnetconnection_info.py index d20d70446..ffced24b6 100644 --- a/plugins/modules/azure_rm_webappvnetconnection_info.py +++ b/plugins/modules/azure_rm_webappvnetconnection_info.py @@ -12,7 +12,7 @@ --- module: azure_rm_webappvnetconnection_info -version_added: "1.9.0" +version_added: "1.8.0" short_description: Get Azure web app virtual network connection facts From 0e37563b51d5e14ca110ee1fe1a4d9baedfd442e Mon Sep 17 00:00:00 2001 From: Ross Bender Date: Wed, 11 Aug 2021 08:17:16 -0500 Subject: [PATCH 16/16] Update plugins/modules/azure_rm_webappvnetconnection_info.py Co-authored-by: Fred-sun <37327967+Fred-sun@users.noreply.github.com> --- plugins/modules/azure_rm_webappvnetconnection_info.py | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/modules/azure_rm_webappvnetconnection_info.py b/plugins/modules/azure_rm_webappvnetconnection_info.py index ffced24b6..8ad772918 100644 --- a/plugins/modules/azure_rm_webappvnetconnection_info.py +++ b/plugins/modules/azure_rm_webappvnetconnection_info.py @@ -111,6 +111,7 @@ def __init__(self): self.resource_group = None super(AzureRMWebAppVnetConnectionInfo, self).__init__(self.module_arg_spec, + supports_check_mode=True, supports_tags=False, facts_module=True)