From a4db5c3ae8ee96c4fd40bbd008e5559919b3d979 Mon Sep 17 00:00:00 2001 From: Yuwei Zhou Date: Thu, 24 May 2018 09:45:29 +0800 Subject: [PATCH] Fixes #37330: support subnet can refer nsg in another resource group (#37627) * support subnet can refer nsg in another resource group * support 3 types of refer resources * fix * fix tyoe * update example --- .../modules/cloud/azure/azure_rm_subnet.py | 67 +++++++++++-------- .../targets/azure_rm_subnet/tasks/main.yml | 40 +++++++++++ 2 files changed, 80 insertions(+), 27 deletions(-) diff --git a/lib/ansible/modules/cloud/azure/azure_rm_subnet.py b/lib/ansible/modules/cloud/azure/azure_rm_subnet.py index 5157c13e72..ca22460fa1 100644 --- a/lib/ansible/modules/cloud/azure/azure_rm_subnet.py +++ b/lib/ansible/modules/cloud/azure/azure_rm_subnet.py @@ -39,11 +39,14 @@ options: required: true aliases: - address_prefix - security_group_name: + security_group: description: - - Name of an existing security group with which to associate the subnet. + - Existing security group with which to associate the subnet. + - It can be the security group name which is in the same resource group. + - It can be the resource Id. + - It can be a dict which contains C(name) and C(resource_group) of the security group. aliases: - - security_group + - security_group_name state: description: - Assert the state of the subnet. Use 'present' to create or update a subnet and @@ -77,6 +80,16 @@ EXAMPLES = ''' resource_group: Testing address_prefix_cidr: "10.1.0.0/24" + - name: Create a subnet refer nsg from other resource group + azure_rm_subnet: + name: foobar + virtual_network_name: My_Virtual_Network + resource_group: Testing + address_prefix_cidr: "10.1.0.0/16" + security_group: + name: secgroupfoo + resource_group: Testing1 + - name: Delete a subnet azure_rm_subnet: name: foobar @@ -120,7 +133,7 @@ state: example: "Succeeded" ''' # NOQA -from ansible.module_utils.azure_rm_common import AzureRMModuleBase, CIDR_PATTERN, azure_id_to_dict +from ansible.module_utils.azure_rm_common import AzureRMModuleBase, CIDR_PATTERN, azure_id_to_dict, format_resource_id try: from msrestazure.azure_exceptions import CloudError @@ -154,7 +167,7 @@ class AzureRMSubnet(AzureRMModuleBase): state=dict(type='str', default='present', choices=['present', 'absent']), virtual_network_name=dict(type='str', required=True, aliases=['virtual_network']), address_prefix_cidr=dict(type='str', aliases=['address_prefix']), - security_group_name=dict(type='str', aliases=['security_group']), + security_group=dict(type='raw', aliases=['security_group_name']) ) required_if = [ @@ -171,7 +184,7 @@ class AzureRMSubnet(AzureRMModuleBase): self.state = None self.virtual_network_name = None self.address_prefix_cidr = None - self.security_group_name = None + self.security_group = None super(AzureRMSubnet, self).__init__(self.module_arg_spec, supports_check_mode=True, @@ -188,8 +201,8 @@ class AzureRMSubnet(AzureRMModuleBase): if self.state == 'present' and not CIDR_PATTERN.match(self.address_prefix_cidr): self.fail("Invalid address_prefix_cidr value {0}".format(self.address_prefix_cidr)) - if self.security_group_name: - nsg = self.get_security_group(self.security_group_name) + if self.security_group: + nsg = self.parse_nsg() results = dict() changed = False @@ -209,12 +222,12 @@ class AzureRMSubnet(AzureRMModuleBase): changed = True results['address_prefix'] = self.address_prefix_cidr - if self.security_group_name: - if results['network_security_group'].get('id') != nsg.id: + if nsg: + if results['network_security_group'].get('id') != nsg.get('id'): self.log("CHANGED: subnet {0} network security group".format(self.name)) changed = True - results['network_security_group']['id'] = nsg.id - results['network_security_group']['name'] = nsg.name + results['network_security_group']['id'] = nsg.get('id') + results['network_security_group']['name'] = nsg.get('name') elif self.state == 'absent': changed = True except CloudError: @@ -235,9 +248,7 @@ class AzureRMSubnet(AzureRMModuleBase): address_prefix=self.address_prefix_cidr ) if nsg: - subnet.network_security_group = self.network_models.NetworkSecurityGroup(id=nsg.id, - location=nsg.location, - resource_guid=nsg.resource_guid) + subnet.network_security_group = self.network_models.NetworkSecurityGroup(id=nsg.get('id')) else: # update subnet @@ -246,10 +257,7 @@ class AzureRMSubnet(AzureRMModuleBase): address_prefix=results['address_prefix'] ) if results['network_security_group'].get('id'): - nsg = self.get_security_group(results['network_security_group']['name']) - subnet.network_security_group = self.network_models.NetworkSecurityGroup(id=nsg.id, - location=nsg.location, - resource_guid=nsg.resource_guid) + subnet.network_security_group = self.network_models.NetworkSecurityGroup(results['network_security_group'].get('id')) self.results['state'] = self.create_or_update_subnet(subnet) elif self.state == 'absent' and changed: @@ -285,14 +293,19 @@ class AzureRMSubnet(AzureRMModuleBase): return result - def get_security_group(self, name): - self.log("Fetching security group {0}".format(name)) - nsg = None - try: - nsg = self.network_client.network_security_groups.get(self.resource_group, name) - except Exception as exc: - self.fail("Error: fetching network security group {0} - {1}.".format(name, str(exc))) - return nsg + def parse_nsg(self): + nsg = self.security_group + resource_group = self.resource_group + if isinstance(self.security_group, dict): + nsg = self.security_group.get('name') + resource_group = self.security_group.get('resource_group', self.resource_group) + id = format_resource_id(val=nsg, + subscription_id=self.subscription_id, + namespace='Microsoft.Network', + types='networkSecurityGroups', + resource_group=resource_group) + name = azure_id_to_dict(id).get('name') + return dict(id=id, name=name) def main(): diff --git a/test/integration/targets/azure_rm_subnet/tasks/main.yml b/test/integration/targets/azure_rm_subnet/tasks/main.yml index a29df1fdd8..32ad0670d9 100644 --- a/test/integration/targets/azure_rm_subnet/tasks/main.yml +++ b/test/integration/targets/azure_rm_subnet/tasks/main.yml @@ -75,6 +75,46 @@ - assert: that: not output.changed +- name: Create network security group in another resource group + azure_rm_securitygroup: + name: secgroupfoo + resource_group: "{{ resource_group_secondary }}" + register: nsg + +- name: Update the subnet + azure_rm_subnet: + name: foobar + virtual_network_name: My_Virtual_Network + resource_group: "{{ resource_group }}" + address_prefix_cidr: "10.1.0.0/16" + security_group: + name: secgroupfoo + resource_group: "{{ resource_group_secondary }}" + tags: + testing: testing + delete: on-fini + register: output + +- assert: + that: + - output.changed + - output.state.network_security_group.id == nsg.state.id + +- name: Update the subnet (idempotent) + azure_rm_subnet: + name: foobar + virtual_network_name: My_Virtual_Network + resource_group: "{{ resource_group }}" + address_prefix_cidr: "10.1.0.0/16" + security_group: "{{ nsg.state.id }}" + tags: + testing: testing + delete: on-fini + register: output + +- assert: + that: not output.changed + - name: Remove subnet azure_rm_subnet: state: absent