This section explains the steps to configure a custom IPAM profile.

NSX Advanced Load Balancer supports integration with third-party IPAM providers such as NS1, TCPWave, so on, for providing automatic IP address allocation for virtual services.

Configuring Custom IPAM

The following are the steps to configure custom IPAM:

  1. Upload Python Script

  2. Create a Custom IPAM Profile

  3. Attach a Custom IPAM Profile to the Cloud

  4. Create a Virtual Service

Step 1: Upload Python Script

A python script with some expected functions (explained in the Python Script section below) is uploaded to the Controller. The functions defined in this script will be invoked by NSX Advanced Load Balancer for IP address management from the third party providers.

Along with the script, you can add the following key-value parameters, which are used by the functions in the script to communicate with the IPAM provider:

  • username: <username>

  • password: <password> with the is_sensitive flag set to True

  • server: 1.2.3.4

These parameters (provider-specific information) are used to communicate with IPAM providers.

Note:
  • The above parameters are provided for example purpose only. Based on the method used in the script, the parameters are passed to the script.

  • The file-name must have a .py extension and conform to PEP8 naming convention.

Configuring using UI

  1. Navigate to Templates > Profiles > Custom IPAM/DNS, and click Create.

  2. Specify the Name, upload the .py file in Script.



  3. Click ADD SCRIPT PARAMS and enter the below details:

    username:

    <username>

    password:

    <password> with the Sensitive checkbox selected.

    server:

    1.2.3.4

    wapi_version:

    network_view:

    default

    dns_view:

    default

  4. Click Save

Configuring using CLI

  1. Copy script to the/var/lib/avi/ipamdnsscripts/ location on the Controller.

  2. Use configure customipamdnsprofile. For instance, the custom_ipam_script.py script is uploaded with the following attributes as shown below:



Step 2: Create a Custom IPAM Profile

Configuring using CLI

  1. Use configure ipamdnsproviderprofile <profile name> command to create the IPAM provider profile.

    Note:

    Parameters used for the profile configuration depend on the environment.



  2. Provide the desired name, for instance, custom-ipam-profile.

  3. Select Type as IPAMDNS_TYPE_CUSTOM.

  4. Provide the custom_ipam_dns_profile_ref value as custom-ipam-script (name of the script object created in the Step 1).



Add usable subnets if required. If it is set, while provisioning the virtual service, the option to choose among multiple usable subnets are available under Network for VIP Address Allocation as shown in Step 4: Create a Virtual Service section. If it is not set, all the available networks/ subnets from the provider are listed.

Step 3: Attach a Custom IPAM Profile to the Cloud

Configuring using UI

  1. To associate the custom IPAM option for the cloud, navigate to Infrastructure > Cloud, and use the custom IPAM profile created in the Step 2.

Configuring using CLI

  1. Use the configure cloud <cloud name> to attach the IPAM profile to the cloud.

  2. Provide the ipam_provider_ref value as custom-ipam-profile.



Step 4: Create a Virtual Service

  1. Creating a new virtual service will use the Custom IPAM profile and the script for creating an IPAM record with the provider automatically.

  2. Provide the following mandatory attributes for the virtual service:

    Name:

    Name of the virtual service.

    Network for VIP Address Allocation:

    Select the network/ subnets for IP allocation (mandatory only through UI).

    Servers:

    IP address of the back-end server.

Configuring using UI

  1. Navigate to Applications > Virtual Service and click Create button.

  2. Once the virtual service creation is successful, the IP is allocated for virtual service as shown below. Also an IPAM record will be created with the provider for the same.

Configuring using CLI

  1. Use the configure vsvsip <vsvip name> command and configure virtualservice <vs name> command to create vsvip and vs respectively.

Python Script

  1. The script must have all the required functions and exception classes defined, else the system displays the following error message during IPAM profile creation: “Custom IPAM profile script is missing required functions/ exception classes {function_or_exception_names}.”

  2. The following are the required functions:

    1. TestLogin

    2. GetAvailableNetworksAndSubnets

    3. GetIpamRecord

    4. CreateIpamRecord

    5. DeleteIpamRecord

    6. UpdateIpamRecord

  3. The following are the required exception classes:

    1. CustomIpamAuthenticationErrorException

    2. CustomIpamRecordNotFoundException

    3. CustomIpamNoFreeIpException

    4. CustomIpamNotImplementedException

    5. CustomIpamGeneralException

  4. CustomIpamNotImplementedException can be raised when the function/ functionality is not implemented in the script.

  5. It is recommended to use logger_name(of auth_params) for script logging. Tenant-specific debug log files (named custom_ipam_script_<tenant_name>.log) are created to save the log statements from the script. For admin tenant, log statements can be found in this location: /var/lib/avi/log/custom_ipam_script.log

  6. A separate Python script will also be provided to validate the provider script.

Note:

Example scripts for various IPAM providers are being developed and will be made available once done.

Custom IPAM script for Infoblox:

/opt/avi/sdk/python/avi/sdk/samples/custom_ipam_script_infoblox.py

Validation script for Custom IPAM script:

/opt/avi/sdk/python/avi/sdk/samples/validate_custom_ipam_script.py

The following is an example script template:

"""
This script allows the user to communicate with custom IPAM provider.

Required Functions
------------------
1. TestLogin: Function to verify provider credentials, used in the UI during IPAM profile configuration.
2. GetAvailableNetworksAndSubnets: Function to return available networks/subnets from the provider.
3. GetIpamRecord: Function to return the info of the given IPAM record.
4. CreateIpamRecord: Function to create an IPAM record with the provider.
5. DeleteIpamRecord: Funtion to delete a given IPAM record from the provider.
6. UpdateIpamRecord: Function to update a given IPAM record.

Required Exception Classes
--------------------------
1. CustomIpamAuthenticationErrorException: Raised when authentication fails.
2. CustomIpamRecordNotFoundException: Raised when given record not found.
3. CustomIpamNoFreeIpException: Raised when no free IP available in the given subnets/networks.
4. CustomIpamNotImplementedException: Raised when the functionality is not implemented.
5. CustomIpamGeneralException: Raised for other types of exceptions.
"""

class CustomIpamAuthenticationErrorException(Exception):
    """
    Raised when authentication fails.
    """
    pass

class CustomIpamRecordNotFoundException(Exception):
    """
    Raised when given record not found.
    """
    pass

class CustomIpamNoFreeIpException(Exception):
    """
    Raised when no free IP available in the given subnets/networks.
    """
    pass

class CustomIpamNotImplementedException(Exception):
    """
    Raised when the functionality is not implemented.
    """
    pass

class CustomIpamGeneralException(Exception):
    """
    Raised for other types of exceptions.
    """
    pass
    
    
def TestLogin(auth_params):
    """
    Function to validate user credentials. This function is called from IPAM profile 
    configuration UI page.
    Args
    ----
        auth_params: (dict of str: str)
            Parameters required for authentication. These are script parameters provided while 
            creating a Custom IPAM profile.
            Eg: auth_params can have following keys
            server: Server ip address of the custom IPAM provider
            username: self explanatory
            password: self explanatory 
            logger_name: logger name   
    Returns
    -------
        Return True on success    
    Raises
    ------
        CustomIpamNotImplementedException: if this function is not implemented.
        CustomIpamAuthenticationErrorException: if authentication fails.
    """
    1. Check all credentials params are given else raise an exception.
    2. Raise an exception if test login fails.
 
        
def GetAvailableNetworksAndSubnets(auth_params, ip_type):
    """ 
    Function to retrieve networks/subnets from the provider.
    Called from the IPAM profile configuration to populate usable subnets on the UI.
    Note: Subnets are represented in CIDR format.
    Args
    ----
        auth_params: (dict of str: str)
            Parameters required for authentication.
        ip_type: (str)
            IP type supported by the networks/subnets. Allowed values: V4_ONLY, V6_ONLY and V4_V6.
    Returns
    -------
        subnet_list: (list of dict of str : str)
            network (str): network id/name
            v4_subnet (str): V4 subnet
            v6_subnet (str): V6 subnet
            v4_available_ip_count (str): V4 free ips count of the network/v4_subnet
            v6_available_ip_count (str): V6 free ips count of the network/v6_subnet
        each dict has 5 keys: network, v4_subnet, v6_subnet, v4_available_ip_count, v6_available_ip_count
        v4_available_ip_count and v6_available_ip_count are optional, currenty this function returns the first 3 keys. returning counts is TBD.
    Raises
    ------
        None
    """
    1.  return all the available networks and subnets.     
 
    
def GetIpamRecord(auth_params, record_info):
    """
    Function to return the info of the given IPAM record.
    Args
    ----
        auth_params: (dict of str: str)
            Parameters required for authentication.
        record_info: (dict of str: str)
            id (str): uuid of vsvip.
            fqdns (list of str): list of fqdn from dns_info in vsvip. 
    Returns
    -------
        alloc_info(dict of str: str): 
            Dictionary of following keys
            v4_ip (str): IPv4 of the record
            v4_subnet (str): IPv4 subnet
            v6_ip (str): IPv6 of the record
            v6_subnet (str): IPv6 subnet
            network (str): network id/name
    Raises
    ------
        CustomIpamNotImplementedException: if this function is not implemented.
        CustomIpamGeneralException: if the api request fails.
    """
    1. Get the reference of the given IPAM record.
    2. Raise a valid error message if the given record not found.
    3. Return ipam record info like ipv4, ipv6, and its subnet/network name
    
    
def CreateIpamRecord(auth_params, record_info):
    """
    Implements a Custom Rest API to create an IPAM record.
    Args
    ----
        auth_params: (dict of str: str)
            Parameters required for authentication.
        record_info: (dict of str: str)
            New record information with following keys.
            id (str): uuid of vsvip.
            fqdns (list of str): list of fqdn from dns_info in vsvip.
            preferred_ip (str): the vsvip IPv4 if it's already configured by the user.
            preferred_ip6 (str): the vsvip IPv6 if it's already configured by the user.
            allocation_type (str): IP allocation type. Allowed values: V4_ONLY, V6_ONLY and V4_V6.
            nw_and_subnet_list (list of tuples : str): List of networks and subnets to use for new IPAM
            record IP allocation. Each tuple has 3 values (network, v4_subnet, v6_subnet).
    Returns
    -------
        alloc_info(dict of str: str): 
            Dictionary of following keys
            v4_ip (str): allocated IPv4
            v4_subnet (str): subnet used for IPv4 allocation.
            v6_ip (str): allocated IPv6
            v6_subnet (str): subnet used for IPv6 allocation.
            network (str): network used for IPv4/IPv6 allocation.
    Raises
    ------
        CustomIpamNoFreeIpException: if no free ip available.
        CustomIpamGeneralException: if create record fails for any other reason.
    """
    1. Either id or fqdns can be used as the name/identifier to create a new IPAM record, choose according to the requirements.
    2. If the preferred_ip/preferred_ip6 is set, call specific rest URL to create an IPAM record (according to the allocation_type).
    3. If the nw_and_subnet_list is empty call GetAvailableNetworksAndSubnets() to use any available
       subnets or networks for IP allocaton.
    4. Based on the allocation_type, build payload data and call specific rest URL to create an IPAM record.
    5. If create IPAM record fails, raise an exception.


def DeleteIpamRecord(auth_params, record_info):
    """
    Implements a Custom Rest API to delete an IPAM record.
    Args
    ----
        auth_params: (dict of str: str)
            Parameters required for authentication.
        record_info: (dict of str: str)
            Record to be deleted. Has following keys.
            id (str): uuid of vsvip.
            fqdns (list of str): list of fqdn from dns_info in vsvip.
    Returns
    -------
        True on successfully deleting the record.
    Raises
    ------
        CustomIpamRecordNotFoundException: if the given record not found
        CustomIpamGeneralException: if delete record request fails.
    """
    1. Get the reference of the given IPAM record.
    2. Raise a valid error message if the given record not found.
    3. Delete the record, if it fails, raise an exception.
              
              
def UpdateIpamRecord(auth_params, new_record_info, old_record_info):
    """
    Function to handle update IPAM record requests. Eg: Change of allocation_type from 
    V4_ONLY to V6_ONLY.
    Args
    ----
        auth_params: (dict of str: str)
            Parameters required for authentication.
        new_record_info: (dict of str: str)
            New record information with following keys.
            id (str): uuid of vsvip.
            fqdns (list of str): list of fqdn from dns_info in vsvip.
            preferred_ip (str): the vsvip IPv4 if it's already configured by the user.
            preferred_ip6 (str): the vsvip IPv6 if it's already configured by the user.
            allocation_type (str): IP allocation type. Allowed values: V4_ONLY, V6_ONLY and V4_V6.
            nw_and_subnet_list (list of tuples : str): List of networks and subnets to use for an 
                IPAM record IP allocation. Each tuple has 3 values (network, v4_subnet, v6_subnet)
        old_record_info: (dict of str: str)
            Old record information with following keys.
            id (str): uuid of vsvip.
            fqdns (list of str): list of fqdn from dns_info in vsvip of an old record.
            preferred_ip (str): old record's preferred IPv4.
            preferred_ip6 (str): old record's preferred IPv6.
            allocation_type (str): old record's IP allocation type. Allowed values: V4_ONLY, V6_ONLY and V4_V6.
            nw_and_subnet_list (list of tuples : str): List of networks and subnets used for an old IPAM
                record IP allocation. Each tuple has 3 values (network, v4_subnet, v6_subnet)
    Returns
    -------
        alloc_info(dict of str: str): 
            Dictionary of following keys
            v4_ip (str): allocated IPv4
            v4_subnet (str): subnet used for IPv4 allocation.
            v6_ip (str): allocated IPv6
            v6_subnet (str): subnet used for IPv6 allocation.
            network (str): network used for IPv4/IPv6 allocation.
    Raises
    ------
        CustomIpamNotImplementedException: if this function or specific update requests not implemented.
        CustomIpamRecordNotFoundException: if the given record not found
        CustomIpamGeneralException: if the api request fails for any other reason.
    """
    1. Raise CustomIpamNotImplementedException exception if the UpdateIpamRecord function or specific update request is not implemented.
    2. Get the reference of the given IPAM record.
    3. Raise a valid error message if the given record not found.
    4. Call specific rest URL based on the update type, if the update request fails, raise an exception.