From 3583a98f300c0f1bad12e6b59028d36e67ffeac6 Mon Sep 17 00:00:00 2001 From: audevbot Date: Mon, 30 Sep 2019 03:31:32 +0000 Subject: [PATCH] Code generation for Ansible. --- .../cloud/azure/azure_rm_privateendpoint.py | 438 +++++++++ .../azure/azure_rm_privatelinkservice.py | 902 ++++++++++++++++++ .../cloud/azure/azure_rm_virtualhub.py | 451 +++++++++ 3 files changed, 1791 insertions(+) create mode 100644 lib/ansible/modules/cloud/azure/azure_rm_privateendpoint.py create mode 100644 lib/ansible/modules/cloud/azure/azure_rm_privatelinkservice.py create mode 100644 lib/ansible/modules/cloud/azure/azure_rm_virtualhub.py diff --git a/lib/ansible/modules/cloud/azure/azure_rm_privateendpoint.py b/lib/ansible/modules/cloud/azure/azure_rm_privateendpoint.py new file mode 100644 index 00000000000000..f452bd2ed67a75 --- /dev/null +++ b/lib/ansible/modules/cloud/azure/azure_rm_privateendpoint.py @@ -0,0 +1,438 @@ +#!/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_privateendpoint +version_added: "2.9" +short_description: Manage Azure PrivateEndpoint instance. +description: + - Create, update and delete instance of Azure Private Endpoint. + +options: + resource_group: + description: + - The name of the resource group. + required: true + type: str + name: + description: + - The name of the private endpoint. + required: true + type: str + location: + description: + - Resource location. + type: str + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + type: str + manual_private_link_service_connections: + description: + - "A grouping of information about the connection to the remote resource. Used when the network admin does not have access to approve + connections to the remote resource." + type: list + suboptions: + private_link_service_id: + description: + - The resource id of private link service. + - It can be the TBD name which is in the same resource group. + - "It can be the TBD ID. e.g., /subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group + }}/providers/Microsoft.Network/privateLinkServices/{{ name }}." + - It can be a dict which contains C(name) and C(resource_group) of the TBD. + required: true + type: raw + group_ids: + description: + - The ID(s) of the group(s) obtained from the remote resource that this private endpoint should connect to. + type: list + request_message: + description: + - A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars. + type: str + name: + description: + - The name of the resource that is unique within a resource group. This name can be used to access the resource. + required: true + type: str + private_link_service_connections: + description: + - A grouping of information about the connection to the remote resource. + type: list + suboptions: + private_link_service_id: + description: + - The resource id of private link service. + - It can be the TBD name which is in the same resource group. + - "It can be the TBD ID. e.g., /subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group + }}/providers/Microsoft.Network/privateLinkServices/{{ name }}." + - It can be a dict which contains C(name) and C(resource_group) of the TBD. + required: true + type: raw + group_ids: + description: + - The ID(s) of the group(s) obtained from the remote resource that this private endpoint should connect to. + type: list + request_message: + description: + - A message passed to the owner of the remote resource with this connection request. Restricted to 140 chars. + type: str + name: + description: + - The name of the resource that is unique within a resource group. This name can be used to access the resource. + required: true + type: str + subnet_id: + description: + - The ID of the subnet from which the private IP will be allocated. + - It can be the TBD name which is in the same resource group. + - "It can be the TBD ID. e.g., /subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group + }}/providers/Microsoft.Network/virtualNetworks/{{ virtual_network_name }}/subnets/{{ name }}." + - It can be a dict which contains C(name) and C(resource_group) of the TBD. + required: true + type: raw + state: + description: + - Assert the state of the Private Endpoint. + - Use 'present' to create or update a Private Endpoint and 'absent' to delete it. + default: present + choices: + - present + - absent + +extends_documentation_fragment: + - azure + - azure_tags + +author: + - audevbot +''' + + +RETURN = ''' +network_interfaces: + description: + - Gets an array of references to the network interfaces created for this private endpoint. + returned: always + type: complex + contains: + id: + description: + - Resource ID. + returned: always + type: str +type: + description: + - Resource type. + 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 AzureRMPrivateEndpoint(AzureRMModuleBaseExt): + """Configuration class for an Azure RM Private Endpoint 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='/' + ), + etag=dict( + type='str', + updatable=False, + disposition='/' + ), + manual_private_link_service_connections=dict( + type='list', + elements='dict', + options=dict( + private_link_service_id=dict( + required=True, + type='raw' + ), + group_ids=dict( + type='list', + elements='str' + ), + request_message=dict( + type='str' + ), + name=dict( + required=True, + type='str' + ), + private_link_service_connection_state=dict( + type='dict', + options=dict( + status=dict( + type='str' + ), + description=dict( + type='str' + ), + action_required=dict( + type='str' + ) + ) + ) + ) + ), + private_link_service_connections=dict( + type='list', + elements='dict', + options=dict( + private_link_service_id=dict( + required=True, + type='raw' + ), + group_ids=dict( + type='list', + elements='str' + ), + request_message=dict( + type='str' + ), + name=dict( + required=True, + type='str' + ), + private_link_service_connection_state=dict( + type='dict', + options=dict( + status=dict( + type='str' + ), + description=dict( + type='str' + ), + action_required=dict( + type='str' + ) + ) + ) + ) + ), + subnet_id=dict( + required=True, + type='raw' + ), + 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(AzureRMPrivateEndpoint, 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('manual_private_link_service_connections') is not None: + self.parameters['manual_private_link_service_connections']['private_link_service_id'] = self.normalize_resource_id( + self.parameters['manual_private_link_service_connections']['private_link_service_id'], + '/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}/providers/Microsoft.Network/privateLinkServices/{{ name }}') + if self.parameters.get('private_link_service_connections') is not None: + self.parameters['private_link_service_connections']['private_link_service_id'] = self.normalize_resource_id( + self.parameters['private_link_service_connections']['private_link_service_id'], + '/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}/providers/Microsoft.Network/privateLinkServices/{{ name }}') + self.parameters['subnet'] = { + 'id': self.normalize_resource_id( + self.parameters.pop('subnet_id'), + '/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}/providers/Microsoft.Network/virtualNetworks/{{ virtual_network_name }}/subnets/{{ name }}') + } + + response = None + + self.mgmt_client = self.get_mgmt_svc_client(NetworkManagementClient, + base_url=self._cloud_environment.endpoints.resource_manager) + + old_response = self.get_privateendpoint() + + if not old_response: + self.log("Private Endpoint instance doesn't exist") + if self.state == 'absent': + self.log("Old instance didn't exist") + else: + self.to_do = Actions.Create + else: + self.log("Private Endpoint 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 Private Endpoint instance") + + self.results['changed'] = True + if self.check_mode: + return self.results + + response = self.create_update_privateendpoint() + + self.log("Creation / Update done") + elif self.to_do == Actions.Delete: + self.log("Private Endpoint instance deleted") + self.results['changed'] = True + + if self.check_mode: + return self.results + + self.delete_privateendpoint() + else: + self.log("Private Endpoint instance unchanged") + self.results['changed'] = False + response = old_response + + if self.state == 'present': + self.results.update({ + 'network_interfaces': response.get('network_interfaces', None), + 'type': response.get('type', None) + }) + return self.results + + def create_update_privateendpoint(self): + ''' + Creates or updates Private Endpoint with the specified configuration. + + :return: deserialized Private Endpoint instance state dictionary + ''' + self.log("Creating / Updating the Private Endpoint instance {0}".format(self.name)) + + try: + response = self.mgmt_client.private_endpoints.create_or_update(resource_group_name=self.resource_group, + private_endpoint_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 Private Endpoint instance.') + self.fail("Error creating the Private Endpoint instance: {0}".format(str(exc))) + return response.as_dict() + + def delete_privateendpoint(self): + ''' + Deletes specified Private Endpoint instance in the specified subscription and resource group. + + :return: True + ''' + self.log("Deleting the Private Endpoint instance {0}".format(self.name)) + try: + response = self.mgmt_client.private_endpoints.delete(resource_group_name=self.resource_group, + private_endpoint_name=self.name) + except CloudError as e: + self.log('Error attempting to delete the Private Endpoint instance.') + self.fail("Error deleting the Private Endpoint instance: {0}".format(str(e))) + + if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller): + response = self.get_poller_result(response) + return True + + def get_privateendpoint(self): + ''' + Gets the properties of the specified Private Endpoint + :return: deserialized Private Endpoint instance state dictionary + ''' + self.log("Checking if the Private Endpoint instance {0} is present".format(self.name)) + found = False + try: + response = self.mgmt_client.private_endpoints.get(resource_group_name=self.resource_group, + private_endpoint_name=self.name, + =self.) + found = True + self.log("Response : {0}".format(response)) + self.log("Private Endpoint instance : {0} found".format(response.name)) + except CloudError as e: + self.log('Did not find the Private Endpoint instance.') + if found is True: + return response.as_dict() + return False + + +def main(): + """Main execution""" + AzureRMPrivateEndpoint() + + +if __name__ == '__main__': + main() diff --git a/lib/ansible/modules/cloud/azure/azure_rm_privatelinkservice.py b/lib/ansible/modules/cloud/azure/azure_rm_privatelinkservice.py new file mode 100644 index 00000000000000..ee720d42dfc446 --- /dev/null +++ b/lib/ansible/modules/cloud/azure/azure_rm_privatelinkservice.py @@ -0,0 +1,902 @@ +#!/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_privatelinkservice +version_added: "2.9" +short_description: Manage Azure PrivateLinkService instance. +description: + - Create, update and delete instance of Azure Private Link Service. + +options: + resource_group: + description: + - The name of the resource group. + required: true + type: str + name: + description: + - The name of the private link service. + required: true + type: str + location: + description: + - Resource location. + type: str + auto_approval: + description: + - The auto-approval list of the private link service. + type: dict + suboptions: + subscriptions: + description: + - The list of subscriptions. + type: list + fqdns: + description: + - The list of Fqdn. + type: list + ip_configurations: + description: + - An array of references to the private link service IP configuration. + type: list + suboptions: + private_ip_address: + description: + - The private IP address of the IP configuration. + type: str + private_ipallocation_method: + description: + - The private IP address allocation method. + default: static + type: str + choices: + - static + - dynamic + subnet: + description: + - The reference of the subnet resource. + type: dict + suboptions: + id: + description: + - Resource ID. + - It can be the TBD name which is in the same resource group. + - "It can be the TBD ID. e.g., /subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group + }}/providers/Microsoft.Network/virtualNetworks/{{ virtual_network_name }}/subnets/{{ name }}." + - It can be a dict which contains C(name) and C(resource_group) of the TBD. + type: raw + name: + description: + - The name of the resource that is unique within a resource group. This name can be used to access the resource. + type: str + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + type: str + private_ip_address_version: + description: + - Available from Api-Version 2016-03-30 onwards, it represents whether the specific ipconfiguration is IPv4 or IPv6. Default is taken as IPv4. + default: i_pv4 + type: str + choices: + - i_pv4 + - i_pv6 + name: + description: + - The name of private link service ip configuration. + type: str + load_balancer_frontend_ip_configurations: + description: + - An array of references to the load balancer IP configurations. + type: list + suboptions: + id: + description: + - Resource ID. + - It can be the TBD name which is in the same resource group. + - "It can be the TBD ID. e.g., /subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group + }}/providers/Microsoft.Network/loadBalancers/{{ load_balancer_name }}/frontendIPConfigurations/{{ name }}." + - It can be a dict which contains C(name) and C(resource_group) of the TBD. + type: raw + private_ip_address: + description: + - The private IP address of the IP configuration. + type: str + subnet: + description: + - The reference of the subnet resource. + type: dict + suboptions: + id: + description: + - Resource ID. + type: str + name: + description: + - The name of the resource that is unique within a resource group. This name can be used to access the resource. + type: str + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + type: str + public_ip_address: + description: + - The reference of the Public IP resource. + type: dict + suboptions: + id: + description: + - Resource ID. + type: str + location: + description: + - Resource location. + type: str + tags: + description: + - Resource tags. + type: list + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + type: str + zones: + description: + - A list of availability zones denoting the IP allocated for the resource needs to come from. + type: list + public_ipprefix: + description: + - The reference of the Public IP Prefix resource. + type: dict + suboptions: + id: + description: + - Resource ID. + type: str + name: + description: + - "The name of the resource that is unique within the set of frontend IP configurations used by the load balancer. This name + can be used to access the resource." + type: str + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + type: str + private_endpoint_connections: + description: + - An array of list about connections to the private endpoint. + type: list + suboptions: + id: + description: + - Resource ID. + type: str + private_endpoint: + description: + - The resource of private end point. + type: dict + suboptions: + id: + description: + - Resource ID. + type: str + location: + description: + - Resource location. + type: str + tags: + description: + - Resource tags. + type: list + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + type: str + private_link_service_connection_state: + description: + - A collection of information about the state of the connection between service consumer and provider. + type: dict + suboptions: + status: + description: + - Indicates whether the connection has been Approved/Rejected/Removed by the owner of the service. + type: str + description: + description: + - The reason for approval/rejection of the connection. + type: str + action_required: + description: + - A message indicating if changes on the service provider require any updates on the consumer. + type: str + name: + description: + - The name of the resource that is unique within a resource group. This name can be used to access the resource. + type: str + visibility: + description: + - The visibility list of the private link service. + type: dict + suboptions: + subscriptions: + description: + - The list of subscriptions. + type: list + state: + description: + - Assert the state of the Private Link Service. + - Use 'present' to create or update a Private Link Service and 'absent' to delete it. + default: present + choices: + - present + - absent + +extends_documentation_fragment: + - azure + - azure_tags + +author: + - audevbot +''' + + +RETURN = ''' +network_interfaces: + description: + - Gets an array of references to the network interfaces created for this private link service. + returned: always + type: complex + contains: + id: + description: + - Resource ID. + returned: always + type: str + name: + description: + - Resource name. + returned: always + type: str + type: + description: + - Resource type. + returned: always + type: str + location: + description: + - Resource location. + returned: always + type: str + tags: + description: + - Resource tags. + returned: always + type: dict + virtual_machine: + description: + - The reference of a virtual machine. + returned: always + type: complex + contains: + id: + description: + - Resource ID. + returned: always + type: str + network_security_group: + description: + - The reference of the NetworkSecurityGroup resource. + returned: always + type: complex + contains: + id: + description: + - Resource ID. + returned: always + type: str + name: + description: + - Resource name. + returned: always + type: str + type: + description: + - Resource type. + returned: always + type: str + location: + description: + - Resource location. + returned: always + type: str + tags: + description: + - Resource tags. + returned: always + type: dict + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + returned: always + type: str + private_endpoint: + description: + - A reference to the private endpoint to which the network interface is linked. + returned: always + type: complex + contains: + id: + description: + - Resource ID. + returned: always + type: str + name: + description: + - Resource name. + returned: always + type: str + type: + description: + - Resource type. + returned: always + type: str + location: + description: + - Resource location. + returned: always + type: str + tags: + description: + - Resource tags. + returned: always + type: dict + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + returned: always + type: str + ip_configurations: + description: + - A list of IPConfigurations of the network interface. + returned: always + type: complex + contains: + id: + description: + - Resource ID. + returned: always + type: str + name: + description: + - The name of the resource that is unique within a resource group. This name can be used to access the resource. + returned: always + type: str + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + returned: always + type: str + tap_configurations: + description: + - A list of TapConfigurations of the network interface. + returned: always + type: complex + contains: + id: + description: + - Resource ID. + returned: always + type: str + name: + description: + - The name of the resource that is unique within a resource group. This name can be used to access the resource. + returned: always + type: str + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + returned: always + type: str + type: + description: + - Sub Resource type. + returned: always + type: str + dns_settings: + description: + - The DNS settings in network interface. + returned: always + type: complex + contains: + dns_servers: + description: + - "List of DNS servers IP addresses. Use 'AzureProvidedDNS' to switch to azure provided DNS resolution. + 'AzureProvidedDNS' value cannot be combined with other IPs, it must be the only value in dnsServers collection." + returned: always + type: str + applied_dns_servers: + description: + - "If the VM that uses this NIC is part of an Availability Set, then this list will have the union of all DNS servers + from all NICs that are part of the Availability Set. This property is what is configured on each of those VMs." + returned: always + type: str + internal_dns_name_label: + description: + - Relative DNS name for this NIC used for internal communications between VMs in the same virtual network. + returned: always + type: str + internal_fqdn: + description: + - Fully qualified DNS name supporting internal communications between VMs in the same virtual network. + returned: always + type: str + internal_domain_name_suffix: + description: + - "Even if internalDnsNameLabel is not specified, a DNS entry is created for the primary NIC of the VM. This DNS name + can be constructed by concatenating the VM name with the value of internalDomainNameSuffix." + returned: always + type: str + mac_address: + description: + - The MAC address of the network interface. + returned: always + type: str + primary: + description: + - Gets whether this is a primary network interface on a virtual machine. + returned: always + type: bool + enable_accelerated_networking: + description: + - If the network interface is accelerated networking enabled. + returned: always + type: bool + enable_ipforwarding: + description: + - Indicates whether IP forwarding is enabled on this network interface. + returned: always + type: bool + hosted_workloads: + description: + - A list of references to linked BareMetal resources. + returned: always + type: str + resource_guid: + description: + - The resource GUID property of the network interface resource. + returned: always + type: str + provisioning_state: + description: + - 'The provisioning state of the public IP resource. Possible values are: ''Updating'', ''Deleting'', and ''Failed''.' + returned: always + type: str + etag: + description: + - A unique read-only string that changes whenever the resource is updated. + returned: always + type: str +alias: + description: + - The alias of the private link service. + returned: always + type: str +type: + description: + - Resource type. + 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 AzureRMPrivateLinkService(AzureRMModuleBaseExt): + """Configuration class for an Azure RM Private Link Service 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='/' + ), + auto_approval=dict( + type='dict', + options=dict( + subscriptions=dict( + type='list', + elements='str' + ) + ) + ), + fqdns=dict( + type='list', + elements='str' + ), + ip_configurations=dict( + type='list', + elements='dict', + options=dict( + private_ip_address=dict( + type='str' + ), + private_ipallocation_method=dict( + default='static', + type='str', + choices=['static', 'dynamic'] + ), + subnet=dict( + type='dict', + options=dict( + id=dict( + type='raw' + ), + name=dict( + type='str' + ), + etag=dict( + type='str' + ) + ) + ), + private_ip_address_version=dict( + default='i_pv4', + type='str', + choices=['i_pv4', 'i_pv6'] + ), + name=dict( + type='str' + ) + ) + ), + load_balancer_frontend_ip_configurations=dict( + type='list', + elements='dict', + options=dict( + id=dict( + type='raw' + ), + private_ip_address=dict( + type='str' + ), + private_ipallocation_method=dict( + type='str', + choices=['static', 'dynamic'] + ), + private_ip_address_version=dict( + type='str', + choices=['i_pv4', 'i_pv6'] + ), + subnet=dict( + type='dict', + options=dict( + id=dict( + type='str' + ), + name=dict( + type='str' + ), + etag=dict( + type='str' + ) + ) + ), + public_ip_address=dict( + type='dict', + options=dict( + id=dict( + type='str' + ), + location=dict( + type='str', + updatable=False, + disposition='/' + ), + tags=dict( + type='list' + ), + etag=dict( + type='str' + ), + zones=dict( + type='list', + elements='str' + ) + ) + ), + public_ipprefix=dict( + type='dict', + options=dict( + id=dict( + type='str' + ) + ) + ), + name=dict( + type='str' + ), + etag=dict( + type='str' + ), + zones=dict( + type='list', + elements='str' + ) + ) + ), + private_endpoint_connections=dict( + type='list', + elements='dict', + options=dict( + id=dict( + type='str' + ), + private_endpoint=dict( + type='dict', + options=dict( + id=dict( + type='str' + ), + location=dict( + type='str', + updatable=False, + disposition='/' + ), + tags=dict( + type='list' + ), + etag=dict( + type='str' + ) + ) + ), + private_link_service_connection_state=dict( + type='dict', + options=dict( + status=dict( + type='str' + ), + description=dict( + type='str' + ), + action_required=dict( + type='str' + ) + ) + ), + name=dict( + type='str' + ) + ) + ), + visibility=dict( + type='dict', + options=dict( + subscriptions=dict( + type='list', + elements='str' + ) + ) + ), + 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(AzureRMPrivateLinkService, 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('ip_configurations') is not None: + self.parameters['ip_configurations']['private_ipallocation_method'] = _snake_to_camel(self.parameters['ip_configurations']['private_ipallocation_method'], True) + if self.parameters['ip_configurations'].get('subnet') is not None: + if self.parameters['ip_configurations']['subnet'].get('id') is not None: + self.parameters['ip_configurations']['subnet']['id'] = self.normalize_resource_id( + self.parameters['ip_configurations']['subnet']['id'], + '/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}/providers/Microsoft.Network/virtualNetworks/{{ virtual_network_name }}/subnets/{{ name }}') + self.parameters['ip_configurations']['private_ip_address_version'] = _snake_to_camel(self.parameters['ip_configurations']['private_ip_address_version'], True) + if self.parameters.get('load_balancer_frontend_ip_configurations') is not None: + if self.parameters['load_balancer_frontend_ip_configurations'].get('id') is not None: + self.parameters['load_balancer_frontend_ip_configurations']['id'] = self.normalize_resource_id( + self.parameters['load_balancer_frontend_ip_configurations']['id'], + '/subscriptions/{{ subscription_id }}/resourceGroups/{{ resource_group }}/providers/Microsoft.Network/loadBalancers/{{ load_balancer_name }}/frontendIPConfigurations/{{ name }}') + if self.parameters['load_balancer_frontend_ip_configurations'].get('private_ipallocation_method') is not None: + self.parameters['load_balancer_frontend_ip_configurations']['private_ipallocation_method'] = _snake_to_camel(self.parameters['load_balancer_frontend_ip_configurations']['private_ipallocation_method'], True) + if self.parameters['load_balancer_frontend_ip_configurations'].get('private_ip_address_version') is not None: + self.parameters['load_balancer_frontend_ip_configurations']['private_ip_address_version'] = _snake_to_camel(self.parameters['load_balancer_frontend_ip_configurations']['private_ip_address_version'], True) + + response = None + + self.mgmt_client = self.get_mgmt_svc_client(NetworkManagementClient, + base_url=self._cloud_environment.endpoints.resource_manager) + + old_response = self.get_privatelinkservice() + + if not old_response: + self.log("Private Link Service instance doesn't exist") + if self.state == 'absent': + self.log("Old instance didn't exist") + else: + self.to_do = Actions.Create + else: + self.log("Private Link Service 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 Private Link Service instance") + + self.results['changed'] = True + if self.check_mode: + return self.results + + response = self.create_update_privatelinkservice() + + self.log("Creation / Update done") + elif self.to_do == Actions.Delete: + self.log("Private Link Service instance deleted") + self.results['changed'] = True + + if self.check_mode: + return self.results + + self.delete_privatelinkservice() + else: + self.log("Private Link Service instance unchanged") + self.results['changed'] = False + response = old_response + + if self.state == 'present': + self.results.update({ + 'network_interfaces': response.get('network_interfaces', None), + 'alias': response.get('alias', None), + 'type': response.get('type', None) + }) + return self.results + + def create_update_privatelinkservice(self): + ''' + Creates or updates Private Link Service with the specified configuration. + + :return: deserialized Private Link Service instance state dictionary + ''' + self.log("Creating / Updating the Private Link Service instance {0}".format(self.name)) + + try: + response = self.mgmt_client.private_link_services.create_or_update(resource_group_name=self.resource_group, + service_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 Private Link Service instance.') + self.fail("Error creating the Private Link Service instance: {0}".format(str(exc))) + return response.as_dict() + + def delete_privatelinkservice(self): + ''' + Deletes specified Private Link Service instance in the specified subscription and resource group. + + :return: True + ''' + self.log("Deleting the Private Link Service instance {0}".format(self.name)) + try: + response = self.mgmt_client.private_link_services.delete(resource_group_name=self.resource_group, + service_name=self.name) + except CloudError as e: + self.log('Error attempting to delete the Private Link Service instance.') + self.fail("Error deleting the Private Link Service instance: {0}".format(str(e))) + + if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller): + response = self.get_poller_result(response) + return True + + def get_privatelinkservice(self): + ''' + Gets the properties of the specified Private Link Service + :return: deserialized Private Link Service instance state dictionary + ''' + self.log("Checking if the Private Link Service instance {0} is present".format(self.name)) + found = False + try: + response = self.mgmt_client.private_link_services.get(resource_group_name=self.resource_group, + service_name=self.name) + found = True + self.log("Response : {0}".format(response)) + self.log("Private Link Service instance : {0} found".format(response.name)) + except CloudError as e: + self.log('Did not find the Private Link Service instance.') + if found is True: + return response.as_dict() + return False + + +def main(): + """Main execution""" + AzureRMPrivateLinkService() + + +if __name__ == '__main__': + main() diff --git a/lib/ansible/modules/cloud/azure/azure_rm_virtualhub.py b/lib/ansible/modules/cloud/azure/azure_rm_virtualhub.py new file mode 100644 index 00000000000000..c9c3d52310c229 --- /dev/null +++ b/lib/ansible/modules/cloud/azure/azure_rm_virtualhub.py @@ -0,0 +1,451 @@ +#!/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_virtualhub +version_added: "2.9" +short_description: Manage Azure VirtualHub instance. +description: + - Create, update and delete instance of Azure Virtual Hub. + +options: + resource_group: + description: + - The resource group name of the VirtualHub. + required: true + type: str + name: + description: + - The name of the VirtualHub. + required: true + type: str + location: + description: + - Resource location. + type: str + address_prefix: + description: + - Address-prefix for this VirtualHub. + type: str + express_route_gateway: + description: + - The expressRouteGateway associated with this VirtualHub. + type: dict + suboptions: + id: + description: + - Resource ID. + type: str + p2svpn_gateway: + description: + - The P2SVpnGateway associated with this VirtualHub. + type: dict + suboptions: + id: + description: + - Resource ID. + type: str + route_table: + description: + - The routeTable associated with this virtual hub. + type: dict + suboptions: + routes: + description: + - List of all routes. + type: list + suboptions: + address_prefixes: + description: + - List of all addressPrefixes. + type: list + next_hop_ip_address: + description: + - NextHop ip address. + type: str + virtual_network_connections: + description: + - List of all vnet connections with this VirtualHub. + type: list + suboptions: + id: + description: + - Resource ID. + type: str + remote_virtual_network: + description: + - Reference to the remote virtual network. + type: dict + suboptions: + id: + description: + - Resource ID. + type: str + allow_hub_to_remote_vnet_transit: + description: + - VirtualHub to RemoteVnet transit to enabled or not. + type: bool + allow_remote_vnet_to_use_hub_vnet_gateways: + description: + - Allow RemoteVnet to use Virtual Hub's gateways. + type: bool + enable_internet_security: + description: + - Enable internet security. + type: bool + name: + description: + - The name of the resource that is unique within a resource group. This name can be used to access the resource. + type: str + virtual_wan: + description: + - The VirtualWAN to which the VirtualHub belongs. + type: dict + suboptions: + id: + description: + - Resource ID. + type: str + vpn_gateway: + description: + - The VpnGateway associated with this VirtualHub. + type: dict + suboptions: + id: + description: + - Resource ID. + type: str + state: + description: + - Assert the state of the Virtual Hub. + - Use 'present' to create or update a Virtual Hub and 'absent' to delete it. + default: present + choices: + - present + - absent + +extends_documentation_fragment: + - azure + - azure_tags + +author: + - audevbot +''' + + +RETURN = ''' +provisioning_state: + description: + - The provisioning state of the resource. + returned: always + type: str +type: + description: + - Resource type. + returned: always + type: str +etag: + description: + - Gets a unique read-only string that changes whenever the resource is updated. + 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 AzureRMVirtualHub(AzureRMModuleBaseExt): + """Configuration class for an Azure RM Virtual Hub 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='/' + ), + address_prefix=dict( + type='str' + ), + express_route_gateway=dict( + type='dict', + options=dict( + id=dict( + type='str' + ) + ) + ), + p2svpn_gateway=dict( + type='dict', + options=dict( + id=dict( + type='str' + ) + ) + ), + route_table=dict( + type='dict', + options=dict( + routes=dict( + type='list', + elements='dict', + options=dict( + address_prefixes=dict( + type='list', + elements='str' + ), + next_hop_ip_address=dict( + type='str' + ) + ) + ) + ) + ), + virtual_network_connections=dict( + type='list', + elements='dict', + options=dict( + id=dict( + type='str' + ), + remote_virtual_network=dict( + type='dict', + options=dict( + id=dict( + type='str' + ) + ) + ), + allow_hub_to_remote_vnet_transit=dict( + type='bool' + ), + allow_remote_vnet_to_use_hub_vnet_gateways=dict( + type='bool' + ), + enable_internet_security=dict( + type='bool' + ), + name=dict( + type='str' + ) + ) + ), + virtual_wan=dict( + type='dict', + options=dict( + id=dict( + type='str' + ) + ) + ), + vpn_gateway=dict( + type='dict', + options=dict( + id=dict( + type='str' + ) + ) + ), + state=dict( + type='str', + default='present', + choices=['present', 'absent'] + ) + ) + + self.resource_group = None + self.name = None + self.virtual_hub_parameters = dict() + self.tags = None + + self.results = dict(changed=False) + self.mgmt_client = None + self.state = None + self.to_do = Actions.NoAction + + super(AzureRMVirtualHub, 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.virtual_hub_parameters[key] = kwargs[key] + + resource_group = self.get_resource_group(self.resource_group) + if self.virtual_hub_parameters.get('location') is None: + self.virtual_hub_parameters['location'] = resource_group.location + + response = None + + self.mgmt_client = self.get_mgmt_svc_client(NetworkManagementClient, + base_url=self._cloud_environment.endpoints.resource_manager) + + old_response = self.get_virtualhub() + + if not old_response: + self.log("Virtual Hub instance doesn't exist") + if self.state == 'absent': + self.log("Old instance didn't exist") + else: + self.to_do = Actions.Create + else: + self.log("Virtual Hub 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.virtual_hub_parameters + if not self.idempotency_check(old_response, self.virtual_hub_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 Virtual Hub instance") + + self.results['changed'] = True + if self.check_mode: + return self.results + + response = self.create_update_virtualhub() + + self.log("Creation / Update done") + elif self.to_do == Actions.Delete: + self.log("Virtual Hub instance deleted") + self.results['changed'] = True + + if self.check_mode: + return self.results + + self.delete_virtualhub() + else: + self.log("Virtual Hub instance unchanged") + self.results['changed'] = False + response = old_response + + if self.state == 'present': + self.results.update({ + 'provisioning_state': response.get('provisioning_state', None), + 'type': response.get('type', None), + 'etag': response.get('etag', None) + }) + return self.results + + def create_update_virtualhub(self): + ''' + Creates or updates Virtual Hub with the specified configuration. + + :return: deserialized Virtual Hub instance state dictionary + ''' + self.log("Creating / Updating the Virtual Hub instance {0}".format(self.name)) + + try: + response = self.mgmt_client.virtual_hubs.create_or_update(resource_group_name=self.resource_group, + virtual_hub_name=self.name, + virtual_hub_parameters=self.virtual_hub_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 Virtual Hub instance.') + self.fail("Error creating the Virtual Hub instance: {0}".format(str(exc))) + return response.as_dict() + + def delete_virtualhub(self): + ''' + Deletes specified Virtual Hub instance in the specified subscription and resource group. + + :return: True + ''' + self.log("Deleting the Virtual Hub instance {0}".format(self.name)) + try: + response = self.mgmt_client.virtual_hubs.delete(resource_group_name=self.resource_group, + virtual_hub_name=self.name) + except CloudError as e: + self.log('Error attempting to delete the Virtual Hub instance.') + self.fail("Error deleting the Virtual Hub instance: {0}".format(str(e))) + + if isinstance(response, LROPoller) or isinstance(response, AzureOperationPoller): + response = self.get_poller_result(response) + return True + + def get_virtualhub(self): + ''' + Gets the properties of the specified Virtual Hub + :return: deserialized Virtual Hub instance state dictionary + ''' + self.log("Checking if the Virtual Hub instance {0} is present".format(self.name)) + found = False + try: + response = self.mgmt_client.virtual_hubs.get(resource_group_name=self.resource_group, + virtual_hub_name=self.name) + found = True + self.log("Response : {0}".format(response)) + self.log("Virtual Hub instance : {0} found".format(response.name)) + except CloudError as e: + self.log('Did not find the Virtual Hub instance.') + if found is True: + return response.as_dict() + return False + + +def main(): + """Main execution""" + AzureRMVirtualHub() + + +if __name__ == '__main__': + main()