DNS, DHCP & IP Address Management appliances
For Microsoft DNS & DHCP servers
For open source DNS & DHCP servers
Cloud-based visualization of analytics across DDI architecture
Manage multi-vendor cloud DNS servers centrally
RIR Declaration Management and Automation
Automated network device configuration and management
Centralized visibility over all your clouds
A single source of truth for your network automation
Why DDI is an Obvious Starting Point
DNS Threat Intelligence for proactive defense
Intelligence Insights for Threat Detection and Investigation
Adaptive DNS security for service continuity and data protection
Improve Application Access Control to prevent spread of attacks
Protect users and block DNS-based malware activity
Carrier-grade DNS DDoS attack protection
Optimize application delivery performance from the edge
for Proactive Network Security
Visibility, analytics and micro segmentation for effective Zero Trust strategy
Enable work from anywhere by controlling access, security and data privacy
Simplify management and control costs across AWS, Azure and GCP environments
Risk-free migration to reduce DDI complexity and cost
Move risk-free to improve performance, security and costs
Automate management, unify control and strengthen security of connected devices
Protect your network against all DNS attacks, data exfiltration and ransomware
Enable zero touch operations for network management and security
Improve resiliency, deployment velocity and user experience for SD-WAN projects
Integrated DNS, DHCP, IPAM services to simplify, automate and secure your network.
Simplify design, deployment and management of critical DDI services for telcos
Optimize administration and security of critical DDI services for healthcare
Simplify and automate management of critical DDI services for finance
Simplify and automate management of critical DDI services for higher education
Simplify and automate management of critical DDI services for retail
Simplify Management and Automation for Network Operations Teams
Elevate SecOps Efficiency by Simplifying Threat Response
Open architecture for DDI integration
Technology partnerships for network security & management ecosystems
Extend security perimeters and strengthen network defenses
Submit requests for temporary licenses
Submit access requests for EfficientIP knowledge platforms
Submit membership requests for EfficientIP Community
Strengthen Your Network Protection with Smart DNS Security
Customer-centric DDI project delivery and training
Acquire the skills needed to manage EfficientIP SOLIDserverโข
Identify vulnerabilities with an assessment of your DNS traffic
Test your protection against data breaches via DNS
Dedicated representation for your organization inside EfficientIP
Explore content which helps manage and automate your network and cloud operations
Read content which strengthens protection of your network, apps, users and data
Learn how to enhance your app delivery performance to improve resilience and UX
Why Using DNS Allow Lists is a No-Brainer
This enterprise-grade cloud platform allows you to improve visibility, enhance operational efficiency, and optimize network performance effortlessly.
Who we are and what we do
Meet the team of leaders guiding our global growth
Technology partnerships for network security and management ecosystems
Discover the benefits of the SmartPartner global channel program
Become a part of the innovation
The latest updates, release information, and global events
September 3, 2019 | Written by: Efficient IP | DDI, IPAM, Network Automation
APIApplication Traffic RoutingDDIDDI ManagementDDI ServicesDDI SolutionsDHCPDNSDNS ManagementDNS over TLSIP Address ManagementIPAMIPAM RepositoryNetwork AutomationSOLIDserverTerraform
In the infrastructure as code and orchestration spaces, engineers frequently use programmatic languages such as Python. When using higher level automation tools like Ansible or Puppet the underlying language used is mostly one which is well known Python, Ruby or Golang. Communication with the network and system components needs to be performed with simple methods, REST APIs are very well designed for this purpose, they are easy to manipulate, actions are atomic, require no complex session to set up and all languages are able to easily call web services. This is why EfficientIP has released its Python library for its SOLIDserver DDI solution, offering an easy way to integrate into the enterprise ecosystem mostly all the actions concerned with IP addressing plan, DNS, DHCP, devices and application traffic routing management.
The SOLIDserver DDI product is a complete repository of the IP information contained in the network, on-premise and in the cloud. It not only manages the IP plan, but also associated mandatory services like DNS and DHCP. As a central repository, it offers an easy way to obtain valid and up-to-date information without requiring access to a manually maintained database or complex querying of multiple services or devices. For real time or batch processes, using the DDI as the IP Golden Record is the key to powerful operations on an accurate inventory.
Access to the SOLIDserver can be performed through the graphical interface, but for automation purposes, REST API is the best method. The full set of SOLIDserver APIs can be used by any external tool having authorizations attached to the account. Communication is secured with TLS, a server certificate and basic authentication in the HTTP flow. The full information set stored in the database can be queried through the API on various types of objects like subnets, address, or DNS records. Any meta-data associated with objects are also available for performing more powerful actions and leverage embedded/specialized sub-orchestrations for maintaining consistency between IPAM/DNS and DHCP components.
In a previous blog, we presented an integration proposed by EfficientIP with a Terraform provider. Now let’s focus on the Python library allowing easy access to the SOLIDserver REST API. This project is offered via EfficientIP’s global open source approach. In addition to contributing widely to large projects, we like to propose ecosystem integration and smaller projects for partners and customers to develop their knowledge and bring value to the network integration.
The Python library is available at the EfficientIP GitLab source repository, for anyone wishing to automate their solution or environment with a leading DDI solution. It is also open to community contribution, bug fix and ideas for improvements. As we use it massively at EfficientIP for test, demo and automation, we maintain it on a regular basis. Contributions from the community are open, branching model follows gitflow principles and merge request should be proposed on the dev branch, a quality check is performed directly on GitLab using the CI/CD, mainly for Python style and coverage test using Python version 3.6 and 3.7. In addition to static tests, dynamic tests with an active SDS (SOLIDserver) are performed internally prior to merging with the master branch. We plan to automate this dynamic bench with a set of cloud instances that will be powered up only when necessary, thanks to our temporary license engine.
The library is composed of two flavors: the first one maps all the APIs in order to get a unified and simple way to call them, and the second more advanced (and still being improved) maps objects to Python classes in order to ease manipulation.
The following examples are really a starter kit for you to bootstrap your first Python script with SOLIDserver REST API. Many usages are possible, so donโt hesitate to participate within the community and tell us how it works for you.
from SOLIDserverRest import SOLIDserverRest SDS_CON = SOLIDserverRest('192.168.56.254') SDS_CON.set_ssl_verify(False) SDS_CON.use_basicauth_sds(user='api', password='apipwd') del(SDS_CON)
Here we do a simple and basic init with the standard library, specifying the IP address of the SOLIDserver management appliance and providing the credentials. The TLS certificate is not validated at connection time, avoiding having to provide the intermediate or CA certificate file (which is not recommended anyway).The last line (deleting the object) is not mandatory, but allows a clean close of all network connections if required in the middle of the script.
def get_space(name): """get a space by its name from the SDS""" parameters = { "WHERE": "site_name='{}'".format(name), "limit": "1" } rest_answer = SDS_CON.query("ip_site_list", parameters) if rest_answer.status_code != 200: logging.error("cannot find space %s", name) return None rjson = json.loads(rest_answer.content) return { 'type': 'space', 'name': name, 'is_default': rjson[0]['site_is_default'], 'id': rjson[0]['site_id'] } space = get_space("Local") print(space)
Here we introduce a simple way of interacting with the SOLIDserver through the API, a call to the API using the mapping interface. The function sets the parameters for the API call, in this case specifying the filter on the name of the space, and limiting the number of returns from the API call. Normally, we should not have more than one result since names are unique in the space list, but it is good practice to limit the return size and use pagination if large number of results are expected.
Then we call the ip_site_list API in order to query from the list of the spaces in the IPAM the one with the provided name. The result, if the status is correct, is converted from the JSON format in a Python dictionary format, easier to manipulate. Finally, we return a dictionary with specific values, here the name, the fact that this space is the default one (which is the case for the Local one) and its internal id. This id will be used as a context to limit further operations to this space only.
Result can be something like:
{'type': 'space', 'name': 'Local', 'is_default': '1', 'id': '2'}
def get_subnet_v4(name, space_id=None): """get a subnet by its name from the SDS""" parameters = { "WHERE": "subnet_name='{}' and is_terminal='1'".format(name), "TAGS": "network.gatewayโ } if space_id is not None: parameters['WHERE'] = parameters['WHERE'] + " and site_id='{}'".format(int(space_id)) rest_answer = SDS_CON.query("ip_subnet_list", parameters) if rest_answer.status_code != 200: logging.error("cannot find subnet %s", name) return None rjson = json.loads(rest_answer.content) return { 'type': 'terminal_subnet', 'name': name, 'addr': rjson[0]['start_hostaddr'], 'cidr': 32-int(math.log(int(rjson[0]['subnet_size']), 2)), 'gw': rjson[0]['tag_network_gateway'], 'used_addresses': rjson[0]['subnet_ip_used_size'], 'free_addresses': rjson[0]['subnet_ip_free_size'], 'space': rjson[0]['site_id'], 'id': rjson[0]['subnet_id'] } space = get_space("Local") subnet = get_subnet_v4("lab42", space_id=space['id']) print(subnet)
Using the same principle as for the space, here we look in the IPAM for a specific IPv4 subnet by its name. The result could look like:
{ 'type': 'terminal_subnet', 'name': 'home', 'addr': '192.168.16.0', 'cidr': 24, 'gw': '192.168.16.254', 'used_addresses': '1', 'free_addresses': '253', 'space': '2', 'id': '20' }
In orchestration, we obviously need IP addresses to build new resources in the cloud like servers and VMs. With SOLIDserver, we start asking for a free address in a specific subnet or address pool, during resource creation this IP address could be affected. In this example, we ask for the next 5 addresses which are free in a subnet starting at the 100th position of the subnet we previously chose. In order to validate availability of the addresses, we have already assigned the address in the middle of the result (192.168.16.102).
def get_next_free_address(subnet_id, number=1, start_address=None): """get a set of free address, by default one is returned""" parameters = { "subnet_id": str(subnet_id), "max_find": str(number), "begin_addr": "192.168.16.100", } if start_address is not None: parameters['begin_addr'] = str(ipaddress.IPv4Address(start_address)) rest_answer = SDS_CON.query("ip_address_find_free", parameters) if rest_answer.status_code != 200: logging.error("cannot find subnet %s", name) return None rjson = json.loads(rest_answer.content) result = { 'type': 'free_ip_address', 'available': len(rjson), 'address': [] } for address in rjson: result['address'].append(address['hostaddr']) return result ipstart = ipaddress.IPv4Address(subnet['addr'])+100 free_address = get_next_free_address(subnet['id'], 5, ipstart) pprint.pprint(free_address)
Note: for IP address manipulation, the Python library ip address is really interesting
The result can look like:
{ 'type': 'free_ip_address', 'available': 5, 'address': ['192.168.16.100', '192.168.16.101', '192.168.16.103', '192.168.16.104', '192.168.16.105'] }
Now that we have found some free IP addresses, letโs reserve one and add a node in the IPAM.
def add_ip_address(ip, name, space_id): """add an IP address and its name in the IPAM""" parameters = { "site_id": str(space_id), "hostaddr": str(ipaddress.IPv4Address(ip)), "name": str(name) } rest_answer = SDS_CON.query("ip_address_create", parameters) if rest_answer.status_code != 201: logging.error("cannot add IP node %s", name) return None rjson = json.loads(rest_answer.content) return { 'type': 'add_ipv4_address', 'name': str(name), 'id': rjson[0]['ret_oid'], } node = add_ip_address(free_address['address'][2], uuid.uuid4(), space['id']) print(node)
The node is created using one of the addresses returned previously and provided with a random name (thanks to the uuid library). Note here that the subnet is not provided, only the space. The SOLIDserver will automatically find the appropriate subnet to store this node based on the IP address provided, which we think is pretty cool! The result of the command can look like:
{ 'type': 'add_ipv4_address', 'name': '6951e073-6fa6-47e6-8cdb-dc1ae251f0b6', 'id': '39' }
The id returned here allows further modification if required.
When our goal is to help companies face the challenges of modern infrastructures and digital transformation, actions speak louder than words.
Explore content highlighting the value EfficientIP solutions bring to your network
We use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
We use cookies to enhance your browsing experience, serve personalized content, and analyze our traffic. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site.