Skip to content

Commit a01b9dd

Browse files
author
Rahl, Christian
committed
Cleanup
1 parent 611e6af commit a01b9dd

7 files changed

+240
-7
lines changed

.gitignore

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
##Yaml except for example
2+
!*.example.(yaml|yml)
3+
!**/*.example.(yaml|yml)
4+
**/*.(yaml|yml)
5+
*.(yaml|yml)
6+
7+
#JSON except for example
8+
**/*.JSON
9+
*.JSON
10+
!*.example.JSON
11+
!**/*.example.JSON
12+
13+
#CSV except for examples
14+
**/*.CSV
15+
*.CSV
16+
!*.example.CSV
17+
!**/*.example.CSV
18+
19+
# Python Environments
20+
.env
21+
.venv
22+
env/
23+
venv/
24+
ENV/
25+
env.bak/
26+
venv.bak/
27+
28+
# Byte-compiled / optimized / DLL files
29+
__pycache__/
30+
*.py[cod]
31+
*$py.class
32+
33+
# Distribution / packaging
34+
.Python
35+
build/
36+
develop-eggs/
37+
dist/
38+
downloads/
39+
eggs/
40+
.eggs/
41+
lib/
42+
lib64/
43+
parts/
44+
sdist/
45+
var/
46+
wheels/
47+
share/python-wheels/
48+
*.egg-info/
49+
.installed.cfg
50+
*.egg
51+
MANIFEST

Modify-PHPIPAM/README.md

Whitespace-only changes.

Modify-PHPIPAM/changes.example.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"server":{
3+
"url":"https://phpipam.example.com",
4+
"app": "app",
5+
"timeout": 30
6+
},
7+
"actions":{
8+
"delete_old_ap_ips":{
9+
"file":"delete.example.csv",
10+
"controller":"addresses",
11+
"function": "delete"
12+
},
13+
"create_aps_ips":{
14+
"file":"create.example.csv",
15+
"controller":"addresses",
16+
"function":"update"
17+
}
18+
}
19+
}

Modify-PHPIPAM/create.example.csv

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
id,ip,is_gateway,hostname,description,tag
2+
,192.168.10.1,yes,gateway,use this for routing,used
3+
,192.168.9.5,no,user1,user 1 on subnet,used
4+
,192.168.9.6,no,user2(future),future reserved ip for user,reserved

Modify-PHPIPAM/delete.example.csv

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
id,ip
2+
,192.168.10.5
3+
,192.168.8.6
4+
,192.168.2.2
5+
15000,192.168.10.10

Modify-PHPIPAM/modify-phpipam.py

+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
#!/usr/bin/python
2+
3+
import phpipamapi
4+
import json
5+
import argparse
6+
import getpass
7+
8+
class PHPIpamModifier:
9+
"""
10+
Program that creates or deletes items in their respective resource
11+
"""
12+
def __init__(self, args: argparse.Namespace) -> None:
13+
self.__server_info, self.__actions = self._read_json(args.filename)
14+
15+
self.__server_api_call = self._api_call(self.__server_info, args)
16+
17+
self.__action_choices = {'addresses':{'search':self.__server_api_call.addresses.search,
18+
'create':self.__server_api_call.addresses.create,
19+
'patch':self.__server_api_call.addresses.patch,
20+
'delete':self.__server_api_call.addresses.delete}}
21+
22+
self._process_actions()
23+
24+
def _read_json(self, filename: str) -> tuple:
25+
try:
26+
with open(filename, "r", encoding="utf-8") as file:
27+
jcontents = json.load(file)
28+
29+
except OSError as e:
30+
print(f"File issue: {e}")
31+
32+
except ValueError as e:
33+
print(F"JSON processing issue: {e}")
34+
35+
return jcontents['server'], jcontents['actions']
36+
37+
def _api_call(self, server_info: dict, args: argparse.Namespace) -> phpipamapi.Caller:
38+
39+
try:
40+
if "key" in server_info and args.password is None and args.username is None:
41+
return phpipamapi.Caller(server_info['url'], server_info['app'],
42+
api_key=server_info['key'])
43+
44+
elif args.password is not None and args.username is not None:
45+
return phpipamapi.Caller(server_info['url'], server_info['app'],
46+
api_user=args.username, api_password=args.password)
47+
48+
else:
49+
username = input("API Username: ")
50+
password = getpass.getpass("API Password: ")
51+
52+
return phpipamapi.Caller(server_info['url'], server_info['app'],
53+
api_user=username, api_password=password)
54+
55+
except ExceptionGroup as e:
56+
print(f"Issue creating api caller: {e}")
57+
58+
def _read_csv(self, filename: str) -> list[dict]:
59+
items = []
60+
61+
with open(filename, "r", encoding="utf-8") as file:
62+
headers = [header.strip() for header in file.readline().split(',')]
63+
64+
for line in file:
65+
items.append({headers[i]:value.strip() for i, value in enumerate(line.split(','))})
66+
67+
return items
68+
69+
def _process_actions(self):
70+
for action in self.__actions.value():
71+
if action["function"].lower() == "update":
72+
self._update_items(action)
73+
74+
elif action["function"].lower() == "delete":
75+
self._delete_items(action)
76+
77+
else:
78+
print("whut")
79+
raise NotImplementedError(f"Operation {action["function"]} is not implemented, "\
80+
f"options are (update, create)")
81+
82+
def _update_items(self, action: dict):
83+
csv_changes = self._read_csv(action['file'])
84+
result_changes = []
85+
86+
for item in csv_changes:
87+
88+
id_exists = "id" in item and (item["id"] is not None or item["id"] != "")
89+
90+
if id_exists:
91+
try:
92+
return_result = self.__action_choices[action['controller']]['patch'](item['id'], data=item)
93+
94+
except:
95+
print(f"Item: {item}, was unable to complete update")
96+
97+
elif not id_exists:
98+
try:
99+
return_data = self.__action_choices[action['controller']]['search'](item["ip"])
100+
101+
if "id" in return_data and return_data["id"] is not None:
102+
item["id"] = return_data["id"]
103+
return_result = self.__action_choices[action['controller']]['patch'](item['id'], data=item)
104+
105+
else:
106+
if "id" in item and (item["id"] is None or item["id"] == ""):
107+
item.pop("id")
108+
return_result = self.__action_choices[action['controller']]['create'](data=item)
109+
110+
except:
111+
print(f"Item: failed to create {item}")
112+
113+
try:
114+
result_changes.append(return_result["data"])
115+
116+
except:
117+
print(f"Results missing data: {return_result}")
118+
119+
def _delete_items(self, action: dict):
120+
csv_changes = self._read_csv(action['file'])
121+
result_changes = []
122+
123+
for item in csv_changes:
124+
if "id" in item and not (item["id"] is None or item["id"] == ""):
125+
try:
126+
return_result = self.__action_choices[action['controller']]['delete'](item["id"])
127+
128+
except:
129+
print(f"Error deleting ip: {item}")
130+
131+
else:
132+
133+
try:
134+
return_data = self.__action_choices[action['controller']]['search'](item["ip"])
135+
item["id"] = return_data["id"]
136+
return_result = self.__action_choices[action['controller']]['delete'](item["id"])
137+
138+
except:
139+
print(f"Error deleting ip: {item}")
140+
141+
try:
142+
result_changes.append(return_result["data"])
143+
144+
except:
145+
print(f"Results missing data: {return_result}")
146+
147+
if __name__ == "__main__":
148+
149+
parser = argparse.ArgumentParser(prog='modify-phpipam',
150+
description='Modify phpipam based on defined json/csv config')
151+
152+
login = parser.add_argument_group("Login",
153+
description="Method to provide login information via args")
154+
login.add_argument('-u', '--user', dest='username', type=ascii)
155+
login.add_argument('-p', '--pass', dest='password', type=ascii)
156+
parser.add_argument('filename', help="Filename for Json work file")
157+
158+
args = parser.parse_args()
159+
160+
PHPIpamModifier(args)

README.md

+1-7
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,4 @@ Personal Network Scripts used by me. Will include a variety of vendor specific o
33

44
# Current Vendors or Tasks
55
Cisco
6-
- IP Phone inventory
7-
8-
Palo Alto
9-
- Panorama Duplicate and Cleanup Policy Script
10-
11-
12-
6+
- IP Phone inventory

0 commit comments

Comments
 (0)