.. versionadded:: 2019.2.0

    Ensure a virtual network exists.

    :param name:
        Name of the virtual network.

    :param resource_group:
        The resource group assigned to the virtual network.

    :param address_prefixes:
        A list of CIDR blocks which can be used by subnets within the virtual network.

    :param dns_servers:
        A list of DNS server addresses.

    :param tags:
        A dictionary of strings can be passed as tag metadata to the virtual network object.

    :param connection_auth:
        A dict with subscription and authentication parameters to be used in connecting to the
        Azure Resource Manager API.

    Example usage:

    .. code-block:: yaml

        Ensure virtual network exists:
            azurearm_network.virtual_network_present:
                - name: vnet1
                - resource_group: group1
                - address_prefixes:
                    - '10.0.0.0/8'
                    - '192.168.0.0/16'
                - dns_servers:
                    - '8.8.8.8'
                - tags:
                    contact_name: Elmer Fudd Gantry
                - connection_auth: {{ profile }}
                - require:
                  - azurearm_resource: Ensure resource group exists

def virtual_network_present(name, address_prefixes, resource_group, dns_servers=None,
                            tags=None, connection_auth=None, **kwargs):
    '''
    .. versionadded:: 2019.2.0

    Ensure a virtual network exists.

    :param name:
        Name of the virtual network.

    :param resource_group:
        The resource group assigned to the virtual network.

    :param address_prefixes:
        A list of CIDR blocks which can be used by subnets within the virtual network.

    :param dns_servers:
        A list of DNS server addresses.

    :param tags:
        A dictionary of strings can be passed as tag metadata to the virtual network object.

    :param connection_auth:
        A dict with subscription and authentication parameters to be used in connecting to the
        Azure Resource Manager API.

    Example usage:

    .. code-block:: yaml

        Ensure virtual network exists:
            azurearm_network.virtual_network_present:
                - name: vnet1
                - resource_group: group1
                - address_prefixes:
                    - '10.0.0.0/8'
                    - '192.168.0.0/16'
                - dns_servers:
                    - '8.8.8.8'
                - tags:
                    contact_name: Elmer Fudd Gantry
                - connection_auth: {{ profile }}
                - require:
                  - azurearm_resource: Ensure resource group exists

    '''
    ret = {
        'name': name,
        'result': False,
        'comment': '',
        'changes': {}
    }

    if not isinstance(connection_auth, dict):
        ret['comment'] = 'Connection information must be specified via connection_auth dictionary!'
        return ret

    vnet = __salt__['azurearm_network.virtual_network_get'](
        name,
        resource_group,
        azurearm_log_level='info',
        **connection_auth
    )

    if 'error' not in vnet:
        tag_changes = __utils__['dictdiffer.deep_diff'](vnet.get('tags', {}), tags or {})
        if tag_changes:
            ret['changes']['tags'] = tag_changes

        dns_changes = set(dns_servers or []).symmetric_difference(
            set(vnet.get('dhcp_options', {}).get('dns_servers', [])))
        if dns_changes:
            ret['changes']['dns_servers'] = {
                'old': vnet.get('dhcp_options', {}).get('dns_servers', []),
                'new': dns_servers,
            }

        addr_changes = set(address_prefixes or []).symmetric_difference(
            set(vnet.get('address_space', {}).get('address_prefixes', [])))
        if addr_changes:
            ret['changes']['address_space'] = {
                'address_prefixes': {
                    'old': vnet.get('address_space', {}).get('address_prefixes', []),
                    'new': address_prefixes,
                }
            }

        if kwargs.get('enable_ddos_protection', False) != vnet.get('enable_ddos_protection'):
            ret['changes']['enable_ddos_protection'] = {
                'old': vnet.get('enable_ddos_protection'),
                'new': kwargs.get('enable_ddos_protection')
            }

        if kwargs.get('enable_vm_protection', False) != vnet.get('enable_vm_protection'):
            ret['changes']['enable_vm_protection'] = {
                'old': vnet.get('enable_vm_protection'),
                'new': kwargs.get('enable_vm_protection')
            }

        if not ret['changes']:
            ret['result'] = True
            ret['comment'] = 'Virtual network {0} is already present.'.format(name)
            return ret

        if __opts__['test']:
            ret['result'] = None
            ret['comment'] = 'Virtual network {0} would be updated.'.format(name)
            return ret

    else:
        ret['changes'] = {
            'old': {},
            'new': {
                'name': name,
                'resource_group': resource_group,
                'address_space': {'address_prefixes': address_prefixes},
                'dhcp_options': {'dns_servers': dns_servers},
                'enable_ddos_protection': kwargs.get('enable_ddos_protection', False),
                'enable_vm_protection': kwargs.get('enable_vm_protection', False),
                'tags': tags,
            }
        }

    if __opts__['test']:
        ret['comment'] = 'Virtual network {0} would be created.'.format(name)
        ret['result'] = None
        return ret

    vnet_kwargs = kwargs.copy()
    vnet_kwargs.update(connection_auth)

    vnet = __salt__['azurearm_network.virtual_network_create_or_update'](
        name=name,
        resource_group=resource_group,
        address_prefixes=address_prefixes,
        dns_servers=dns_servers,
        tags=tags,
        **vnet_kwargs
    )

    if 'error' not in vnet:
        ret['result'] = True
        ret['comment'] = 'Virtual network {0} has been created.'.format(name)
        return ret

    ret['comment'] = 'Failed to create virtual network {0}! ({1})'.format(name, vnet.get('error'))
    return ret