Pushing existing code

This commit is contained in:
Dom 2023-07-01 23:48:34 +01:00
parent 57a06cee89
commit 887d2e5a8a
3 changed files with 173 additions and 0 deletions

View File

@ -1,2 +1,24 @@
# IPAMLite
## Command Line Operation
```
IP Address Manager (Lite)
Example usage:
$ cd IPAMLite
$ chmod +x ipam
$ ./ipam
$ curl -X POST -H "Content-type: application/json" -d "{\"ip\" : \"192.168.1.5\", \"subnet\" : \"24\"}" "127.0.0.1:5000/specific_lease"
$ curl -X POST -H "Content-type: application/json" -d "{\"network\" : \"192.168.1.0\", \"subnet\" : \"24\"}" "127.0.0.1:5000/sequential_lease"
$ curl -X POST -H "Content-type: application/json" -d "{\"ip\" : \"192.168.1.5\", \"subnet\" : \"24\"}" "127.0.0.1:5000/release"
$ curl 127.0.0.1:5000/database
Currently supported API calls:
- /specific_lease - HTTP POST, adds a specified IP address to the database
- Takes: ip, subnet
- /sequential_lease - HTTP POST, adds the next available IP address in the subnet to the database
- Takes: network, subnet
- /release - HTTP POST, release an IP address from the database
- Takes: ip, subnet
- /database - HTTP GET, returns the IP address database
```

130
ipam Executable file
View File

@ -0,0 +1,130 @@
#!/usr/bin/env python3
import ipaddress
import json
import os
from flask import Flask, request
class IPAMLite(object):
def __init__(self, database_file='ipam.json'):
self.database_file = database_file
self.leased = []
def database(self):
return(json.dumps(self.leased, indent=4))
def sequential_lease(self, network, subnet):
network_exists = False
host_addresses = [str(ip) for ip in ipaddress.IPv4Network(f'{network}/{subnet}').hosts()]
for network_dict in self.leased:
if f'{network}/{subnet}' in network_dict.keys():
for network_address, leased_addresses in network_dict.items():
leaseable_addresses = [ip for ip in host_addresses if ip not in leased_addresses]
if len(leaseable_addresses) >= 1:
next_available_lease = leaseable_addresses[0]
leased_addresses.append(next_available_lease)
network_exists = True
break
else:
return f'\U0001F916 No address space left in: {network}/{subnet}\n'
if not network_exists:
next_available_lease = host_addresses[0]
self.leased.append({str(f'{network}/{subnet}'): [next_available_lease]})
self.save_database()
return f'\U0001F916 Lease added: {next_available_lease}/{subnet}\n'
def specific_lease(self, ip, subnet):
network_exists = False
network_address = ipaddress.ip_interface(f'{ip}/{subnet}').network
for network_dict in self.leased:
for network, leased_addresses in network_dict.items():
if ip in leased_addresses:
return f'\U0001F916 Lease already exists: {ip}/{subnet}\n'
if str(network) == str(network_address):
leased_addresses.append(ip)
network_exists = True
if not network_exists:
self.leased.append({str(network_address): [ip]})
self.save_database()
return f'\U0001F916 Lease added: {ip}/{subnet}\n'
def release(self, ip, subnet):
for index in range(len(self.leased)):
for network, leased_addresses in self.leased[index].items():
if ip in leased_addresses and len(leased_addresses) < 2:
del self.leased[index]
self.save_database()
return f'\U0001F916 Lease removed: {ip}/{subnet}\n'
break
elif ip in leased_addresses and len(leased_addresses) > 1:
leased_addresses.remove(ip)
self.save_database()
return f'\U0001F916 Lease removed: {ip}/{subnet}\n'
break
return f'\U0001F916 Nothing to release for: {ip}/{subnet}\n'
def save_database(self):
with open(self.database_file, 'w') as ipam_file:
json.dump(self.leased, ipam_file, indent=4)
def load_database(self):
if os.path.exists(self.database_file):
with open(self.database_file, 'r') as ipam_file:
db = json.load(ipam_file)
for lease in db:
self.leased.append(lease)
print(f'\U0001F916 Database file "{self.database_file}" loaded successfully')
else:
print(f'\U0001F916 Cannot load database file "{self.database_file}"')
IPAM = IPAMLite()
IPAM.load_database()
app = Flask(__name__)
@app.route('/database', methods=['GET'])
def get_database():
return IPAM.database()
@app.route('/sequential_lease', methods=['POST'])
def handle_sequential_lease():
if request.is_json:
data = request.json
lease_response = IPAM.sequential_lease(data['network'], data['subnet'])
return f'{lease_response}'
else:
return 'Data type not supported, supported data types: JSON\n'
@app.route('/specific_lease', methods=['POST'])
def handle_specific_lease():
if request.is_json:
data = request.json
lease_response = IPAM.specific_lease(data['ip'], data['subnet'])
return f'{lease_response}'
else:
return 'Data type not supported, supported data types: JSON\n'
@app.route('/release', methods=['POST'])
def handle_release():
if request.is_json:
data = request.json
release_response = IPAM.release(data['ip'], data['subnet'])
return f'{release_response}'
else:
return 'Data type not supported, supported data types: JSON\n'
if __name__ == '__main__':
app.run(debug = True)

21
ipam.json Normal file
View File

@ -0,0 +1,21 @@
[
{
"10.0.0.0/24": [
"10.0.0.1",
"10.0.0.2",
"10.0.0.3"
]
},
{
"192.168.1.0/24": [
"192.168.1.1",
"192.168.1.4"
]
},
{
"10.0.0.0/8": [
"10.0.0.1",
"10.0.0.2"
]
}
]