Skip to content

Commit

Permalink
Use mac field (#34)
Browse files Browse the repository at this point in the history
* Use mac field

* Add the possibility to specify a mac when adding an IP address, this
  field is optional
* Expose mac address when returning the IP addresses
* Be able to find an IP based on the mac address
  • Loading branch information
achamo authored and dclaisse committed Aug 23, 2019
1 parent adcf0b4 commit a7e9dd2
Show file tree
Hide file tree
Showing 6 changed files with 264 additions and 57 deletions.
20 changes: 18 additions & 2 deletions ipam/client/abstractipam.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ class AbstractIPAM:
__metaclass__ = ABCMeta

@abstractmethod
def add_ip(self, ipaddr, dnsname, description):
def add_ip(self, ipaddr, dnsname, description, mac=None):
raise NotImplementedError()

@abstractmethod
def add_next_ip(self, subnet, dnsname, description):
def add_next_ip(self, subnet, dnsname, description, mac=None):
raise NotImplementedError()

@abstractmethod
Expand All @@ -30,6 +30,10 @@ def add_next_subnet(self, parent_subnet, prefixlen, description):
def delete_subnet(self, subnet, empty_subnet):
raise NotImplementedError()

@abstractmethod
def get_ip(self, ip):
raise NotImplementedError()

@abstractmethod
def get_hostname_by_ip(self, ip):
raise NotImplementedError()
Expand All @@ -38,6 +42,10 @@ def get_hostname_by_ip(self, ip):
def get_description_by_ip(self, ip):
raise NotImplementedError()

@abstractmethod
def get_mac_by_ip(self, ip):
raise NotImplementedError()

@abstractmethod
def get_ip_interface_list_by_desc(self, description):
raise NotImplementedError()
Expand All @@ -62,6 +70,14 @@ def get_ip_list_by_desc(self, description):
def get_ip_by_desc(self, description):
raise NotImplementedError()

@abstractmethod
def get_ip_list_by_mac(self, mac):
raise NotImplementedError()

@abstractmethod
def get_ip_by_mac(self, mac):
raise NotImplementedError()

@abstractmethod
def get_subnet_list_by_desc(self, description):
raise NotImplementedError()
Expand Down
125 changes: 113 additions & 12 deletions ipam/client/backends/phpipam.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def find_subnet_id(self, subnet):
"for subnet {}".format(subnet)
)

def add_ip(self, ipaddress, hostname, description):
def add_ip(self, ipaddress, hostname, description, mac=None):
""" Adds an IP address in IPAM. ipaddress must be an
instance of ip_interface. Returns True """
with MySQLLock(self):
Expand All @@ -146,24 +146,26 @@ def add_ip(self, ipaddress, hostname, description):
raise ValueError("IP address %s already registered"
% (ipaddress.ip))
self.cur.execute("INSERT INTO ipaddresses \
(subnetId, ip_addr, description, %s) \
VALUES (%d, '%d', '%s', '%s')"
(subnetId, ip_addr, description, %s, mac) \
VALUES (%d, '%d', '%s', '%s', '%s')"
% (self.hostname_db_field, subnetid,
ipaddress.ip, description, hostname))
ipaddress.ip, description, hostname,
'' if mac is None else mac))
return True

def add_next_ip(self, subnet, hostname, description):
def add_next_ip(self, subnet, hostname, description, mac=None):
""" Finds next free ip in subnet, and adds it in IPAM.
Returns IP address as ip_interface """
try:
with MySQLLock(self):
ipaddress = self.get_next_free_ip(subnet)
subnetid = self.find_subnet_id(ipaddress)
self.cur.execute("INSERT INTO ipaddresses \
(subnetId, ip_addr, description, %s) \
VALUES (%d, '%d', '%s', '%s')"
(subnetId, ip_addr, description, %s, mac) \
VALUES (%d, '%d', '%s', '%s', '%s')"
% (self.hostname_db_field, subnetid,
ipaddress.ip, description, hostname))
ipaddress.ip, description, hostname,
'' if mac is None else mac))
return ipaddress
except ValueError as e:
raise ValueError("Unable to add next IP in %s: %s" % (
Expand Down Expand Up @@ -379,6 +381,45 @@ def edit_ip_description(self, ipaddress, description):
% (description, ipaddress.ip, subnetid))
return True

def edit_ip_hostname(self, ipaddress, hostname):
"""Edit an IP address hostname in IPAM. ipaddress must be an
instance of ip_interface with correct prefix length.
"""
with MySQLLock(self):
subnetid = self.find_subnet_id(ipaddress)
self.cur.execute("SELECT ip_addr FROM ipaddresses \
WHERE ip_addr='%d' AND subnetId=%d"
% (ipaddress.ip, subnetid))
row = self.cur.fetchone()
if row is None:
raise ValueError("IP address %s not present"
% (ipaddress.ip))
self.cur.execute("UPDATE ipaddresses \
SET %s='%s' \
WHERE ip_addr='%d' AND subnetId=%d"
% (self.hostname_db_field, hostname,
ipaddress.ip, subnetid))
return True

def edit_ip_mac(self, ipaddress, mac):
"""Edit an IP address MAC in IPAM. ipaddress must be an
instance of ip_interface with correct prefix length.
"""
with MySQLLock(self):
subnetid = self.find_subnet_id(ipaddress)
self.cur.execute("SELECT ip_addr FROM ipaddresses \
WHERE ip_addr='%d' AND subnetId=%d"
% (ipaddress.ip, subnetid))
row = self.cur.fetchone()
if row is None:
raise ValueError("IP address %s not present"
% (ipaddress.ip))
self.cur.execute("UPDATE ipaddresses \
SET mac='%s' \
WHERE ip_addr='%d' AND subnetId=%d"
% (mac, ipaddress.ip, subnetid))
return True

def edit_subnet_description(self, subnet, description):
"""Edit a subnet description in IPAM. subnet must be an
instance of ip_network and the description must not be
Expand Down Expand Up @@ -445,6 +486,30 @@ def delete_subnet(self, subnet, empty_subnet=False):
% subnet_id)
return True

def get_ip(self, ip):
self.cur.execute("SELECT ip.ip_addr,ip.description,ip.%s,\
s.mask,s.description,v.number,ip.mac\
FROM ipaddresses ip\
LEFT JOIN subnets s ON\
ip.subnetId = s.id\
LEFT JOIN vlans v ON\
s.vlanId = v.vlanId\
WHERE ip.ip_addr = '%d'\
AND ip.state = 1"
% (self.hostname_db_field, ip))
row = self.cur.fetchone()
if row is not None:
item = {}
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]
item['vlan_id'] = row[5]
item['mac'] = row[6]
return item
return None

def get_hostname_by_ip(self, ip):
self.cur.execute("SELECT %s FROM ipaddresses \
WHERE ip_addr='%d'"
Expand All @@ -463,6 +528,15 @@ def get_description_by_ip(self, ip):
return row[0]
return None

def get_mac_by_ip(self, ip):
self.cur.execute("SELECT mac FROM ipaddresses \
WHERE ip_addr='%d'"
% ip)
row = self.cur.fetchone()
if row is not None:
return row[0]
return None

def get_ipnetwork_list_by_desc(self, description):
"""
Wrapper for backward compatibility
Expand All @@ -471,7 +545,7 @@ def get_ipnetwork_list_by_desc(self, description):

def get_ip_interface_list_by_desc(self, description):
self.cur.execute("SELECT ip.ip_addr,ip.description,ip.%s,\
s.mask,s.description,v.number\
s.mask,s.description,v.number,ip.mac\
FROM ipaddresses ip\
LEFT JOIN subnets s ON\
ip.subnetId = s.id\
Expand All @@ -489,6 +563,7 @@ def get_ip_interface_list_by_desc(self, description):
item['dnsname'] = row[2]
item['subnet_name'] = row[4]
item['vlan_id'] = row[5]
item['mac'] = row[6]
iplist.append(item)
return iplist

Expand All @@ -500,7 +575,7 @@ def get_subnet_with_ips(self, subnet):
ipam_subnet = {}

self.cur.execute('SELECT ip.ip_addr,ip.description,ip.{},ip.state,'
's.description,s.vlanId '
's.description,s.vlanId,ip.mac '
'FROM ipaddresses ip LEFT JOIN subnets s '
'ON ip.subnetId = s.id '
"WHERE s.subnet='{}' AND s.mask='{}'"
Expand All @@ -518,6 +593,7 @@ def get_subnet_with_ips(self, subnet):
item['description'] = row[1]
item['dnsname'] = row[2]
item['state'] = row[3]
item['mac'] = row[6]
iplist.append(item)
ipam_subnet['ips'] = iplist
return ipam_subnet
Expand All @@ -543,7 +619,7 @@ def get_ipnetwork_list_by_subnet_name(self, subnet_name):

def get_ip_interface_list_by_subnet_name(self, subnet_name):
self.cur.execute("SELECT ip.ip_addr,ip.description,ip.%s,\
s.mask,s.description\
s.mask,s.description,ip.mac\
FROM ipaddresses ip\
LEFT JOIN subnets s ON\
ip.subnetId = s.id\
Expand All @@ -558,6 +634,7 @@ def get_ip_interface_list_by_subnet_name(self, subnet_name):
item['description'] = row[1]
item['dnsname'] = row[2]
item['subnet_name'] = row[4]
item['mac'] = row[5]
iplist.append(item)
return iplist

Expand All @@ -575,7 +652,7 @@ def get_ip_interface_by_subnet_name(self, subnet_name):
return iplist[0]

def get_ip_list_by_desc(self, description):
self.cur.execute("SELECT ip_addr,description,%s,state \
self.cur.execute("SELECT ip_addr,description,%s,state,mac \
FROM ipaddresses \
WHERE description LIKE '%s'"
% (self.hostname_db_field, description))
Expand All @@ -586,6 +663,7 @@ def get_ip_list_by_desc(self, description):
item['description'] = row[1]
item['dnsname'] = row[2]
item['state'] = int(row[3])
item['mac'] = row[4]
iplist.append(item)
return iplist

Expand All @@ -596,6 +674,29 @@ def get_ip_by_desc(self, description):
else:
return iplist[0]

def get_ip_list_by_mac(self, mac):
self.cur.execute("SELECT ip_addr,description,%s,state,mac \
FROM ipaddresses \
WHERE mac LIKE '%s'"
% (self.hostname_db_field, mac))
iplist = list()
for row in self.cur:
item = {}
item['ip'] = ip_address(int(row[0]))
item['description'] = row[1]
item['dnsname'] = row[2]
item['state'] = int(row[3])
item['mac'] = row[4]
iplist.append(item)
return iplist

def get_ip_by_mac(self, mac):
iplist = self.get_ip_list_by_mac(mac)
if iplist == []:
return None
else:
return iplist[0]

def get_children_subnet_list(self, parent_subnet):
netlist = list()
parent_subnet_id = self.find_subnet_id(parent_subnet)
Expand Down
3 changes: 1 addition & 2 deletions ipam/client/tests/data/db-no-settings.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
PRAGMA synchronous = OFF;
PRAGMA journal_mode = MEMORY;
BEGIN TRANSACTION;
CREATE TABLE "settings" (
"id" INTEGER PRIMARY KEY,
Expand Down Expand Up @@ -74,4 +72,5 @@ CREATE INDEX "ipaddresses_dns_name" ON "ipaddresses" ("dns_name");
CREATE INDEX "ipaddresses_ip_addr" ON "ipaddresses" ("ip_addr");
CREATE INDEX "ipaddresses_description" ON "ipaddresses" ("description");
CREATE INDEX "ipaddresses_subnetid" ON "ipaddresses" ("subnetId");
CREATE INDEX "ipaddresses_mac" ON "ipaddresses" ("mac");
END TRANSACTION;
5 changes: 2 additions & 3 deletions ipam/client/tests/data/db-old-version.sql
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
PRAGMA synchronous = OFF;
PRAGMA journal_mode = MEMORY;
BEGIN TRANSACTION;
CREATE TABLE "settings" (
"id" INTEGER PRIMARY KEY,
Expand Down Expand Up @@ -36,7 +34,7 @@ INSERT INTO "ipaddresses" VALUES (11,2,'167903236','test ip #11','test-ip-11',''
INSERT INTO "ipaddresses" VALUES (12,2,'167903237','test ip #12','test-ip-12','','','1',0,'','','NULL','0','NULL');
INSERT INTO "ipaddresses" VALUES (13,2,'167903238','test ip #13','test-ip-13','','','1',0,'','','NULL','0','NULL');
INSERT INTO "ipaddresses" VALUES (14,3,'167968770','test ip #14','test-ip-14','','','1',0,'','','NULL','0','NULL');
INSERT INTO "ipaddresses" VALUES (15,5,'168099840','test ip #15','test-ip-15','','','1',0,'','','NULL','0','NULL');
INSERT INTO "ipaddresses" VALUES (15,5,'168099840','test ip #15','test-ip-15','52:24:10:00:00:02','','1',0,'','','NULL','0','NULL');
CREATE TABLE "sections" (
"id" int(11) NOT NULL ,
"name" varchar(128) NOT NULL DEFAULT '',
Expand Down Expand Up @@ -97,4 +95,5 @@ CREATE INDEX "ipaddresses_dns_name" ON "ipaddresses" ("dns_name");
CREATE INDEX "ipaddresses_ip_addr" ON "ipaddresses" ("ip_addr");
CREATE INDEX "ipaddresses_description" ON "ipaddresses" ("description");
CREATE INDEX "ipaddresses_subnetid" ON "ipaddresses" ("subnetId");
CREATE INDEX "ipaddresses_mac" ON "ipaddresses" ("mac");
END TRANSACTION;
3 changes: 2 additions & 1 deletion ipam/client/tests/data/db-recent-version.sql
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ INSERT INTO "ipaddresses" VALUES (11,2,'167903236','test ip #11','test-ip-11',''
INSERT INTO "ipaddresses" VALUES (12,2,'167903237','test ip #12','test-ip-12','','','1',0,'','','NULL','0','NULL');
INSERT INTO "ipaddresses" VALUES (13,2,'167903238','test ip #13','test-ip-13','','','1',0,'','','NULL','0','NULL');
INSERT INTO "ipaddresses" VALUES (14,3,'167968770','test ip #14','test-ip-14','','','1',0,'','','NULL','0','NULL');
INSERT INTO "ipaddresses" VALUES (15,5,'168099840','test ip #15','test-ip-15','','','1',0,'','','NULL','0','NULL');
INSERT INTO "ipaddresses" VALUES (15,5,'168099840','test ip #15','test-ip-15','52:24:10:00:00:02','','1',0,'','','NULL','0','NULL');
CREATE TABLE "sections" (
"id" int(11) NOT NULL ,
"name" varchar(128) NOT NULL DEFAULT '',
Expand Down Expand Up @@ -97,4 +97,5 @@ CREATE INDEX "ipaddresses_hostname" ON "ipaddresses" ("hostname");
CREATE INDEX "ipaddresses_ip_addr" ON "ipaddresses" ("ip_addr");
CREATE INDEX "ipaddresses_description" ON "ipaddresses" ("description");
CREATE INDEX "ipaddresses_subnetid" ON "ipaddresses" ("subnetId");
CREATE INDEX "ipaddresses_mac" ON "ipaddresses" ("mac");
END TRANSACTION;
Loading

0 comments on commit a7e9dd2

Please sign in to comment.