Allocates a new virtual network in OpenNebula.

    .. versionadded:: 2016.3.0

    path
        The path to a file containing the template of the virtual network to allocate.
        Syntax within the file can be the usual attribute=value or XML. Can be used
        instead of ``data``.

    data
        Contains the template of the virtual network to allocate. Syntax can be the
        usual attribute=value or XML. Can be used instead of ``path``.

    cluster_id
        The ID of the cluster for which to add the new virtual network. Can be used
        instead of ``cluster_name``. If neither ``cluster_id`` nor ``cluster_name``
        are provided, the virtual network won’t be added to any cluster.

    cluster_name
        The name of the cluster for which to add the new virtual network. Can be used
        instead of ``cluster_id``. If neither ``cluster_name`` nor ``cluster_id`` are
        provided, the virtual network won't be added to any cluster.

    CLI Example:

    .. code-block:: bash

        salt-cloud -f vn_allocate opennebula path=/path/to/vn_file.txt

def vn_allocate(call=None, kwargs=None):
    '''
    Allocates a new virtual network in OpenNebula.

    .. versionadded:: 2016.3.0

    path
        The path to a file containing the template of the virtual network to allocate.
        Syntax within the file can be the usual attribute=value or XML. Can be used
        instead of ``data``.

    data
        Contains the template of the virtual network to allocate. Syntax can be the
        usual attribute=value or XML. Can be used instead of ``path``.

    cluster_id
        The ID of the cluster for which to add the new virtual network. Can be used
        instead of ``cluster_name``. If neither ``cluster_id`` nor ``cluster_name``
        are provided, the virtual network won’t be added to any cluster.

    cluster_name
        The name of the cluster for which to add the new virtual network. Can be used
        instead of ``cluster_id``. If neither ``cluster_name`` nor ``cluster_id`` are
        provided, the virtual network won't be added to any cluster.

    CLI Example:

    .. code-block:: bash

        salt-cloud -f vn_allocate opennebula path=/path/to/vn_file.txt
    '''
    if call != 'function':
        raise SaltCloudSystemExit(
            'The vn_allocate function must be called with -f or --function.'
        )

    if kwargs is None:
        kwargs = {}

    cluster_id = kwargs.get('cluster_id', None)
    cluster_name = kwargs.get('cluster_name', None)
    path = kwargs.get('path', None)
    data = kwargs.get('data', None)

    if data:
        if path:
            log.warning(
                'Both the \'data\' and \'path\' arguments were provided. '
                '\'data\' will take precedence.'
            )
    elif path:
        with salt.utils.files.fopen(path, mode='r') as rfh:
            data = rfh.read()
    else:
        raise SaltCloudSystemExit(
            'The vn_allocate function requires either \'data\' or a file \'path\' '
            'to be provided.'
        )

    if cluster_id:
        if cluster_name:
            log.warning(
                'Both the \'cluster_id\' and \'cluster_name\' arguments were provided. '
                '\'cluster_id\' will take precedence.'
             )
    elif cluster_name:
        cluster_id = get_cluster_id(kwargs={'name': cluster_name})
    else:
        cluster_id = '-1'

    server, user, password = _get_xml_rpc()
    auth = ':'.join([user, password])
    response = server.one.vn.allocate(auth, data, int(cluster_id))

    ret = {
        'action': 'vn.allocate',
        'allocated': response[0],
        'vn_id': response[1],
        'error_code': response[2],
    }

    return ret