Skip to content

Commit

Permalink
Move from netaddr to ipaddress
Browse files Browse the repository at this point in the history
netaddr is not actively maintained anymore, and
ipaddress has made its way into python3 standard library

Signed-off-by: Damien Claisse <[email protected]>
  • Loading branch information
dclaisse committed Jan 30, 2018
1 parent b862606 commit b62a042
Show file tree
Hide file tree
Showing 4 changed files with 260 additions and 147 deletions.
8 changes: 4 additions & 4 deletions ipam/client/abstractipam.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@ def get_description_by_ip(self, ip):
raise NotImplementedError()

@abstractmethod
def get_ipnetwork_list_by_desc(self, description):
def get_ip_interface_list_by_desc(self, description):
raise NotImplementedError()

@abstractmethod
def get_ipnetwork_list_by_subnet_name(self, subnet_name):
def get_ip_interface_list_by_subnet_name(self, subnet_name):
raise NotImplementedError()

@abstractmethod
def get_ipnetwork_by_subnet_name(self, subnet_name):
def get_ip_interface_by_subnet_name(self, subnet_name):
raise NotImplementedError()

@abstractmethod
def get_ipnetwork_by_desc(self, description):
def get_ip_interface_by_desc(self, description):
raise NotImplementedError()

@abstractmethod
Expand Down
99 changes: 67 additions & 32 deletions ipam/client/backends/phpipam.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
#!/usr/bin/env python

from __future__ import unicode_literals
import mysql.connector
import sqlite3
from ipam.client.abstractipam import AbstractIPAM
from netaddr import IPAddress, IPNetwork
from ipaddress import ip_address, ip_interface, ip_network

DEFAULT_IPAM_DB_TYPE = 'mysql'

Expand Down Expand Up @@ -50,22 +49,34 @@ def get_section_id(self):
return self.section_id

def find_subnet_id(self, subnet):
"""
Return subnet id from database
"""
if hasattr(subnet, 'network'):
# This is an interface
network = subnet.network
else:
# This is a subnet
network = subnet

self.cur.execute("SELECT id FROM subnets WHERE subnet='%d' \
AND mask='%d'"
% (subnet.network, subnet.prefixlen))
% (network.network_address,
network.prefixlen))
row = self.cur.fetchone()
if row is not None:
return int(row[0])
return None

def add_ip(self, ipaddress, dnsname, description):
""" Adds an IP address in IPAM. ipaddress must be an
instance of IPNetwork. Returns True """
instance of ip_interface. Returns True """
subnetid = self.find_subnet_id(ipaddress)
if subnetid is None:
raise ValueError("Unable to get subnet id from database "
"for subnet %s/%s"
% (ipaddress.network, ipaddress.prefixlen))
% (ipaddress.network.network_address,
ipaddress.network.prefixlen))
self.cur.execute("SELECT ip_addr FROM ipaddresses \
WHERE ip_addr='%d' AND subnetId=%d"
% (ipaddress.ip, subnetid))
Expand All @@ -83,7 +94,7 @@ def add_ip(self, ipaddress, dnsname, description):

def add_next_ip(self, subnet, dnsname, description):
""" Finds next free ip in subnet, and adds it in IPAM.
Returns IP address as IPNetwork """
Returns IP address as ip_interface """
try:
ipaddress = self.get_next_free_ip(subnet)
self.add_ip(ipaddress, dnsname, description)
Expand All @@ -93,24 +104,21 @@ def add_next_ip(self, subnet, dnsname, description):
subnet, str(e)))

def get_next_free_ip(self, subnet):
""" Finds next free ip in subnet. Returns IP address as IPNetwork """
"""
Finds next free ip in subnet. Returns IP address as ip_interface
"""
# Find PHPIPAM subnet id
subnetid = self.find_subnet_id(subnet)
if subnetid is None:
raise ValueError("Unable to get subnet id from database "
"for subnet %s/%s"
% (subnet.network, subnet.prefixlen))
% (subnet.network_address,
subnet.prefixlen))
# Create hosts list in subnet
subnetips = subnet.iter_hosts()
subnetips = subnet.hosts()
# Get allocated ip addresses from database
usedips = self.get_allocated_ips_by_subnet_id(subnetid)

# Dirty hack, as netaddr has no support for RFC 6164 /127 subnets
# https://github.com/drkjam/netaddr/pull/168
if subnet.prefixlen == 127:
subnetips = list(subnetips)
subnetips.append(subnet.network)

subnetips = set(subnetips)
usedips = set(usedips)
# Compute the difference between sets, aka available ip addresses set
Expand All @@ -120,26 +128,29 @@ def get_next_free_ip(self, subnet):
availableips.sort()
if len(availableips) <= 0:
raise ValueError("Subnet %s/%s is full"
% (subnet.network, subnet.prefixlen))
% (subnet.network_address,
subnet.prefixlen))
# Return first available ip address in the list
return IPNetwork("%s/%d" % (availableips[0], subnet.prefixlen))
return ip_interface("%s/%d" % (availableips[0],
subnet.prefixlen))

def get_allocated_ips_by_subnet_id(self, subnetid):
self.cur.execute("SELECT ip_addr FROM ipaddresses \
WHERE subnetId=%d ORDER BY ip_addr ASC"
% (subnetid))
iplist = [IPAddress(int(ip[0])) for ip in self.cur]
iplist = [ip_address(int(ip[0])) for ip in self.cur]
return iplist

def delete_ip(self, ipaddress):
"""Delete an IP address in IPAM. ipaddress must be an
instance of IPNetwork with correct prefix length.
instance of ip_interface with correct prefix length.
"""
subnetid = self.find_subnet_id(ipaddress)
if subnetid is None:
raise ValueError("Unable to get subnet id from database "
"for subnet %s/%s"
% (ipaddress.network, ipaddress.prefixlen))
% (ipaddress.network.network_address,
ipaddress.network.prefixlen))
self.cur.execute("SELECT ip_addr FROM ipaddresses \
WHERE ip_addr='%d' AND subnetId=%d"
% (ipaddress.ip, subnetid))
Expand Down Expand Up @@ -172,6 +183,12 @@ def get_description_by_ip(self, ip):
return None

def get_ipnetwork_list_by_desc(self, description):
"""
Wrapper for backward compatibility
"""
return self.get_ip_interface_list_by_desc(description)

def get_ip_interface_list_by_desc(self, description):
self.cur.execute("SELECT ip.ip_addr,ip.description,ip.dns_name,\
s.mask,s.description,v.number\
FROM ipaddresses ip\
Expand All @@ -185,8 +202,8 @@ def get_ipnetwork_list_by_desc(self, description):
iplist = list()
for row in self.cur:
item = {}
ip_address = IPAddress(int(row[0]))
item['ip'] = IPNetwork(str(ip_address) + "/" + row[3])
net_ip_address = ip_address(int(row[0]))
item['ip'] = ip_interface(str(net_ip_address) + "/" + row[3])
item['description'] = row[1]
item['dnsname'] = row[2]
item['subnet_name'] = row[4]
Expand All @@ -195,13 +212,25 @@ def get_ipnetwork_list_by_desc(self, description):
return iplist

def get_ipnetwork_by_desc(self, description):
iplist = self.get_ipnetwork_list_by_desc(description)
"""
Wrapper for backward compatibility
"""
return self.get_ip_interface_by_desc(description)

def get_ip_interface_by_desc(self, description):
iplist = self.get_ip_interface_list_by_desc(description)
if iplist == []:
return None
else:
return iplist[0]

def get_ipnetwork_list_by_subnet_name(self, subnet_name):
"""
Wrapper for backward compatibility
"""
return self.get_ip_interface_list_by_subnet_name(subnet_name)

def get_ip_interface_list_by_subnet_name(self, subnet_name):
self.cur.execute("SELECT ip.ip_addr,ip.description,ip.dns_name,\
s.mask,s.description\
FROM ipaddresses ip\
Expand All @@ -213,16 +242,22 @@ def get_ipnetwork_list_by_subnet_name(self, subnet_name):
iplist = list()
for row in self.cur:
item = {}
ip_address = IPAddress(int(row[0]))
item['ip'] = IPNetwork(str(ip_address) + "/" + row[3])
net_ip_address = ip_address(int(row[0]))
item['ip'] = ip_interface(str(net_ip_address) + "/" + row[3])
item['description'] = row[1]
item['dnsname'] = row[2]
item['subnet_name'] = row[4]
iplist.append(item)
return iplist

def get_ipnetwork_by_subnet_name(self, subnet_name):
iplist = self.get_ipnetwork_list_by_subnet_name(subnet_name)
"""
Wrapper for backward compatibility
"""
return self.get_ip_interface_by_subnet_name(subnet_name)

def get_ip_interface_by_subnet_name(self, subnet_name):
iplist = self.get_ip_interface_list_by_subnet_name(subnet_name)
if iplist == []:
return None
else:
Expand All @@ -237,7 +272,7 @@ def get_ip_list_by_desc(self, description):
iplist = list()
for row in self.cur:
item = {}
item['ip'] = IPAddress(int(row[0]))
item['ip'] = ip_address(int(row[0]))
item['description'] = row[1]
item['dnsname'] = row[2]
iplist.append(item)
Expand All @@ -257,8 +292,8 @@ def get_subnet_list_by_desc(self, description):
netlist = list()
for row in self.cur:
item = {}
subnet = str(IPAddress(int(row[0])))
item['subnet'] = IPNetwork("%s/%s" % (subnet, row[1]))
subnet = str(ip_address(int(row[0])))
item['subnet'] = ip_network("%s/%s" % (subnet, row[1]))
item['description'] = row[2]
netlist.append(item)
return netlist
Expand All @@ -277,8 +312,8 @@ def get_subnet_by_id(self, subnetid):
row = self.cur.fetchone()
if row is not None:
item = {}
subnet = str(IPAddress(int(row[0])))
item['subnet'] = IPNetwork("%s/%s" % (subnet, row[1]))
subnet = str(ip_address(int(row[0])))
item['subnet'] = ip_network("%s/%s" % (subnet, row[1]))
item['description'] = row[2]
return item
return None
Expand Down
Loading

0 comments on commit b62a042

Please sign in to comment.