Create a network interface.

def create_network_interface(call=None, kwargs=None):
    '''
    Create a network interface.
    '''
    if call != 'action':
        raise SaltCloudSystemExit(
            'The create_network_interface action must be called with -a or --action.'
        )

    # pylint: disable=invalid-name
    IPAllocationMethod = getattr(
        network_models,
        'IPAllocationMethod'
    )
    # pylint: disable=invalid-name
    NetworkInterface = getattr(
        network_models,
        'NetworkInterface'
    )
    # pylint: disable=invalid-name
    NetworkInterfaceIPConfiguration = getattr(
        network_models,
        'NetworkInterfaceIPConfiguration'
    )
    # pylint: disable=invalid-name
    PublicIPAddress = getattr(
        network_models,
        'PublicIPAddress'
    )

    if not isinstance(kwargs, dict):
        kwargs = {}

    vm_ = kwargs
    netconn = get_conn(client_type='network')

    if kwargs.get('location') is None:
        kwargs['location'] = get_location()

    if kwargs.get('network') is None:
        kwargs['network'] = config.get_cloud_config_value(
            'network', vm_, __opts__, search_global=False
        )

    if kwargs.get('subnet') is None:
        kwargs['subnet'] = config.get_cloud_config_value(
            'subnet', vm_, __opts__, search_global=False
        )

    if kwargs.get('network_resource_group') is None:
        kwargs['network_resource_group'] = config.get_cloud_config_value(
            'resource_group', vm_, __opts__, search_global=False
        )

    if kwargs.get('iface_name') is None:
        kwargs['iface_name'] = '{0}-iface0'.format(vm_['name'])

    try:
        subnet_obj = netconn.subnets.get(
            resource_group_name=kwargs['network_resource_group'],
            virtual_network_name=kwargs['network'],
            subnet_name=kwargs['subnet'],
        )
    except CloudError as exc:
        raise SaltCloudSystemExit(
            '{0} (Resource Group: "{1}", VNET: "{2}", Subnet: "{3}")'.format(
                exc.message,
                kwargs['network_resource_group'],
                kwargs['network'],
                kwargs['subnet']
            )
        )

    ip_kwargs = {}
    ip_configurations = None

    if 'load_balancer_backend_address_pools' in kwargs:
        pool_dicts = kwargs['load_balancer_backend_address_pools']
        if isinstance(pool_dicts, dict):
            pool_ids = []
            for load_bal, be_pools in pool_dicts.items():
                for pool in be_pools:
                    try:
                        lbbep_data = netconn.load_balancer_backend_address_pools.get(
                            kwargs['resource_group'],
                            load_bal,
                            pool,
                        )
                        pool_ids.append({'id': lbbep_data.as_dict()['id']})
                    except CloudError as exc:
                        log.error('There was a cloud error: %s', six.text_type(exc))
                    except KeyError as exc:
                        log.error('There was an error getting the Backend Pool ID: %s', six.text_type(exc))
            ip_kwargs['load_balancer_backend_address_pools'] = pool_ids

    if 'private_ip_address' in kwargs.keys():
        ip_kwargs['private_ip_address'] = kwargs['private_ip_address']
        ip_kwargs['private_ip_allocation_method'] = IPAllocationMethod.static
    else:
        ip_kwargs['private_ip_allocation_method'] = IPAllocationMethod.dynamic

    if kwargs.get('allocate_public_ip') is True:
        pub_ip_name = '{0}-ip'.format(kwargs['iface_name'])
        poller = netconn.public_ip_addresses.create_or_update(
            resource_group_name=kwargs['resource_group'],
            public_ip_address_name=pub_ip_name,
            parameters=PublicIPAddress(
                location=kwargs['location'],
                public_ip_allocation_method=IPAllocationMethod.static,
            ),
        )
        count = 0
        poller.wait()
        while True:
            try:
                pub_ip_data = netconn.public_ip_addresses.get(
                    kwargs['resource_group'],
                    pub_ip_name,
                )
                if pub_ip_data.ip_address:  # pylint: disable=no-member
                    ip_kwargs['public_ip_address'] = PublicIPAddress(
                        id=six.text_type(pub_ip_data.id),  # pylint: disable=no-member
                    )
                    ip_configurations = [
                        NetworkInterfaceIPConfiguration(
                            name='{0}-ip'.format(kwargs['iface_name']),
                            subnet=subnet_obj,
                            **ip_kwargs
                        )
                    ]
                    break
            except CloudError as exc:
                log.error('There was a cloud error: %s', exc)
            count += 1
            if count > 120:
                raise ValueError('Timed out waiting for public IP Address.')
            time.sleep(5)
    else:
        priv_ip_name = '{0}-ip'.format(kwargs['iface_name'])
        ip_configurations = [
            NetworkInterfaceIPConfiguration(
                name=priv_ip_name,
                subnet=subnet_obj,
                **ip_kwargs
            )
        ]

    network_security_group = None
    if kwargs.get('security_group') is not None:
        network_security_group = netconn.network_security_groups.get(
            resource_group_name=kwargs['resource_group'],
            network_security_group_name=kwargs['security_group'],
        )

    iface_params = NetworkInterface(
        location=kwargs['location'],
        network_security_group=network_security_group,
        ip_configurations=ip_configurations,
    )

    poller = netconn.network_interfaces.create_or_update(
        kwargs['resource_group'], kwargs['iface_name'], iface_params
    )
    try:
        poller.wait()
    except Exception as exc:
        log.warning('Network interface creation could not be polled. '
                 'It is likely that we are reusing an existing interface. (%s)', exc)

    count = 0
    while True:
        try:
            return _get_network_interface(kwargs['iface_name'], kwargs['resource_group'])
        except CloudError:
            count += 1
            if count > 120:
                raise ValueError('Timed out waiting for operation to complete.')
            time.sleep(5)