.. versionadded:: 2019.2.0

    Ensure a subnet exists.

    :param name:
        Name of the subnet.

    :param address_prefix:
        A CIDR block used by the subnet within the virtual network.

    :param virtual_network:
        Name of the existing virtual network to contain the subnet.

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

    :param security_group:
        The name of the existing network security group to assign to the subnet.

    :param route_table:
        The name of the existing route table to assign to the subnet.

    :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 subnet exists:
            azurearm_network.subnet_present:
                - name: vnet1_sn1
                - virtual_network: vnet1
                - resource_group: group1
                - address_prefix: '192.168.1.0/24'
                - security_group: nsg1
                - route_table: rt1
                - connection_auth: {{ profile }}
                - require:
                  - azurearm_network: Ensure virtual network exists
                  - azurearm_network: Ensure network security group exists
                  - azurearm_network: Ensure route table exists

def subnet_present(name, address_prefix, virtual_network, resource_group,
                   security_group=None, route_table=None, connection_auth=None, **kwargs):
    '''
    .. versionadded:: 2019.2.0

    Ensure a subnet exists.

    :param name:
        Name of the subnet.

    :param address_prefix:
        A CIDR block used by the subnet within the virtual network.

    :param virtual_network:
        Name of the existing virtual network to contain the subnet.

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

    :param security_group:
        The name of the existing network security group to assign to the subnet.

    :param route_table:
        The name of the existing route table to assign to the subnet.

    :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 subnet exists:
            azurearm_network.subnet_present:
                - name: vnet1_sn1
                - virtual_network: vnet1
                - resource_group: group1
                - address_prefix: '192.168.1.0/24'
                - security_group: nsg1
                - route_table: rt1
                - connection_auth: {{ profile }}
                - require:
                  - azurearm_network: Ensure virtual network exists
                  - azurearm_network: Ensure network security group exists
                  - azurearm_network: Ensure route table 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

    snet = __salt__['azurearm_network.subnet_get'](
        name,
        virtual_network,
        resource_group,
        azurearm_log_level='info',
        **connection_auth
    )

    if 'error' not in snet:
        if address_prefix != snet.get('address_prefix'):
            ret['changes']['address_prefix'] = {
                'old': snet.get('address_prefix'),
                'new': address_prefix
            }

        nsg_name = None
        if snet.get('network_security_group'):
            nsg_name = snet['network_security_group']['id'].split('/')[-1]

        if security_group and (security_group != nsg_name):
            ret['changes']['network_security_group'] = {
                'old': nsg_name,
                'new': security_group
            }

        rttbl_name = None
        if snet.get('route_table'):
            rttbl_name = snet['route_table']['id'].split('/')[-1]

        if route_table and (route_table != rttbl_name):
            ret['changes']['route_table'] = {
                'old': rttbl_name,
                'new': route_table
            }

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

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

    else:
        ret['changes'] = {
            'old': {},
            'new': {
                'name': name,
                'address_prefix': address_prefix,
                'network_security_group': security_group,
                'route_table': route_table
            }
        }

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

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

    snet = __salt__['azurearm_network.subnet_create_or_update'](
        name=name,
        virtual_network=virtual_network,
        resource_group=resource_group,
        address_prefix=address_prefix,
        network_security_group=security_group,
        route_table=route_table,
        **snet_kwargs
    )

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

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