· 6 years ago · Dec 05, 2019, 09:44 PM
1import json
2import ssl
3import requests
4import sys
5import urllib3
6import ipaddress
7import f5.bigip
8from datetime import datetime
9
10# This is literally only because otherwise requests complain about the certificate.
11urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
12spacer = "\n "
13
14def validate_ip_address(address):
15 try:
16 ipaddress.ip_address(address)
17 return True
18 except ValueError as e:
19 errors.write(str(datetime.now()) + " " + str(e) + "code line 18")
20 errors.write(spacer + "This is not a valid address. Probably an incorrect value being read. code line 18\n")
21 return False
22
23def check_inventory_status(address, lb):
24 r = requests.get('http://inventory.web.com:81/searchexactip/{0}'.format(address))
25 inventory_data = r.json()
26 if str(inventory_data['data'][0]['linked_server']).upper() == lb.upper():
27 return True
28 return False
29
30def set_ip_linked_asset(address, lb):
31 link_header = {'AuthUser': apikey}
32 # Determine what type of IP this is based on first octet.
33 if "10." in address[:3]:
34 iptype = "4"
35 elif "192." in address[:4]:
36 iptype = "3"
37 elif "172." in address[:4]:
38 iptype = "3"
39 else:
40 # If it's not a private IP address, it must be public.
41 # Self IPs should never be KVM, Loopback, or MGMT.
42 iptype = "4"
43 if ".registeredsite.com" in lb:
44 lbasset = lb[:-19]
45 else:
46 lbasset = lb
47 asset = requests.get('http://inventory.web.com:81/searchassetsbyname/{0}'.format(lbasset))
48 asset_json = asset.json()
49 asset_id = asset_json['data'][0]['id']
50 asset_name = asset_json['data'][0]['name']
51 linkip = requests.get('http://inventory.web.com:81/addip/{0}/{1}/{2}'.format(asset_id, address, iptype), headers=link_header)
52 #print(linkip.content)
53 try:
54 response = linkip.json()
55 return response
56 except ValueError as e:
57 errors.write(str(datetime.now()) + " The following error occurred from the inventory api: " + str(e) + " code line 59\n")
58 errors.write(" This generally means that this failed and did not return a response code. code line 59\n")
59 pass
60
61def a10_login(username, password, lb):
62 credentials = {
63 "credentials":{
64 "username": username,
65 "password": password
66 }
67 }
68 get_header = {'Content-Type': 'application/json'}
69 r = requests.post("https://{0}/axapi/v3/auth".format(lb + ".registeredsite.com"),
70 json=credentials,
71 headers=get_header,
72 verify=False)
73 inventory_data = r.json()
74 #print(r.json())
75 try:
76 get_header.update({'Authorization': "A10 " + inventory_data['authresponse']['signature']})
77 except Exception as e:
78 errors.write(str(datetime.now()) + " " + str(e) + " code line 82")
79 errors.write(spacer + r.text + " code line 82\n")
80 return get_header
81
82
83def a10_logout(header, lb):
84 logoff = requests.post("https://{0}/axapi/v3/logoff".format(lb + ".registeredsite.com"),
85 headers=header,
86 verify=False)
87
88def a10_selfips(lb):
89 get_header = a10_login(username, password, lb)
90 #print(lb)
91 active_lb = "https://{0}/axapi/v3/".format(lb + ".registeredsite.com")
92
93 part_list = requests.get(active_lb + "partition",
94 headers=get_header,
95 verify=False)
96 parts = part_list.json()
97 self_ips = {"loadbalancer": lb, "ips": [] }
98
99 # Loop through the listed partitions
100 # TODO: Need to simplify my exception catching here. I don't think I need to nest the try - except clauses.
101 # I *DO* however like the fact that I can trace exactly the line causing issues in the error logs.
102 try:
103 for cur_parts in parts['partition-list']:
104 cur_part = cur_parts['partition-name']
105 switch_part = requests.post(active_lb + "active-partition/" + cur_part,
106 headers=get_header,
107 verify=False)
108 # Now we get the virtual ethernets so we can loop through.
109 new_part = requests.get(active_lb + "interface/ve/",
110 headers=get_header,
111 verify=False)
112 partition3 = new_part.json()
113 try:
114 # The list to loop
115 for x in partition3['ve-list']:
116 try:
117 # Now we narrow it down to the list of IP address, and specifically get the ipv4 addresses
118 for y in x['ip']['address-list']:
119 try:
120 self_ips['ips'].append(y['ipv4-address'])
121 except KeyError as e:
122 errors.write(str(datetime.now()) + ": KeyError looking for ipv4-address key in IPs" + spacer +
123 "Relevant JSON:\n" + x['ip'])
124
125 except KeyError as e:
126 errors.write(str(datetime.now()) +
127 ": Issue getting address list" + str(e) + "\n" + spacer + "Relevant JSON:\n" + json.dumps(x['ip'],
128 indent=2,
129 sort_keys=True))
130 continue
131 except KeyError as e:
132 errors.write(str(datetime.now()) + ": " + str(e) + " Unable to retrieve ve-list key from partitions")
133 errors.write(spacer + "Relevant JSON: \n" + json.dumps(partition3, indent=2, sort_keys=True))
134 continue
135 except Exception as e:
136 errors.write(str(datetime.now()) + ": " + str(e) + " Error getting partition list\n" + spacer +
137 "Relevant JSON:\n" + json.dumps(cur_parts, indent=2, sort_keys=True))
138
139 a10_logout(get_header, lb)
140 return self_ips # Then we append this to a list, and loop through to loop through wheeeee!
141
142#This connects to each a10 and produces a list: [LB name, VIP name, IP address of vip, and Partition]
143def test_vip_pull(lb):
144 get_head = a10_login(username, password, lb)
145 #print(get_head)
146 active_lb = "https://{0}/axapi/v3/".format(lb + ".registeredsite.com")
147 part_list = requests.get(active_lb + "partition",
148 headers=get_head,
149 verify=False)
150
151 parts = part_list.json()
152 inventory_updates = []
153
154 for partitions in parts['partition-list']:
155 part_name = partitions['partition-name']
156 switch_part = requests.post(active_lb + "active-partition/" + part_name,
157 headers=get_head,
158 verify=False)
159 virtual_servers = requests.get(active_lb + "slb/virtual-server/",
160 headers=get_head,
161 verify=False)
162 virtual_server_list = virtual_servers.json()
163 #print(json.dumps(virtual_ser6vers.json(), sort_keys=True, indent=4))
164 for x in virtual_server_list['virtual-server-list']:
165 try:
166 #print("VIP name: " + x['name'] + " with the IP address: " + x['ip-address'])
167 if str(x['ip-address']) == "0.0.0.0":
168 logging.write(str(datetime.now()) + ": Not real vip -- {0}\n".format(x['name']))
169
170
171 else:
172 inventory_updates.append([lb, x['name'], x['ip-address'], part_name])
173
174 except KeyError as e:
175 if 'ipv6-address' in x.keys():
176 errors.write(str(datetime.now()) +
177 ": {0} is an IPv6 vip. Inventory doesn't support IPv6 addresses yet.".format(x['name'])
178 + spacer + "VIP address: {0} \n\n".format(x['ipv6-address']))
179 else:
180 errors.write(str(datetime.now()) + " VIP name: " + x['name'] +
181 " need to check this vip for details \n this vip's json is missing key: " +
182 str(e) + "\n" + json.dumps(x, indent=2, sort_keys=True))
183 a10_logout(get_head, lb)
184 #for x in inventory_updates:
185 # print(x)
186 return inventory_updates
187
188def vip_inventory_update(inventory_updates): # A list must be passed
189 link_header = {
190 'AuthUser': apikey,
191 }
192 for m in inventory_updates:
193 r = requests.get('http://inventory.web.com:81/searchexactip/{0}'.format(m[2]))
194 r_json = r.json()
195
196 try:
197 ipid = r_json['data'][0]['ipid']
198 except KeyError as e:
199
200 errors.write(str(datetime.now()) +
201 ": Could not locate the IP address ({0}) in inventory.".format(m[2])
202 + spacer
203 + "Relevant JSON:\n {0}\n".format(str(json.dumps(r_json, indent=2, sort_keys=True))))
204
205 continue
206 if str(r_json['data'][0]['linked_server']).upper() == m[0].upper():
207 logging.write(str(datetime.now()) + ": Already linked {0} - {1}\n".format(m[1], m[2]))
208
209 else:
210 logging.write(str(datetime.now()) + ": Updating {0} - {1}\n".format(m[1], m[2]))
211 payload = {
212 "ID": r_json['data'][0]['ipid'],
213 "CLASSIFICATION": "VIP",
214 "PURPOSE": "VIP: {2}, LB: {0}, Partition: {1}".format(m[0], m[3], m[1]),
215 "HOSTNAME": m[1]
216 }
217 payload_send = {'JSON': json.dumps(payload)}
218 #print(json.dumps(payload, indent=4))
219 update_vip = requests.post('http://inventory.web.com:81/editip/', headers=link_header, data=payload_send)
220 set_ip_linked_asset(m[2], m[0])
221
222with open('/home/svc-infrastructure/a10_inventory/inventory_credentials.txt') as f:
223 credentials = [x.strip().split(':') for x in f]
224
225username = credentials[0][0]
226password = credentials[0][1]
227apikey = credentials[0][2]
228
229errors = open('/home/svc-infrastructure/a10_inventory/inventory_verify.err', "a+")
230logging = open('/home/svc-infrastructure/a10_inventory/inventory_verify.log', "a+")
231
232if __name__ == "__main__":
233 lb_lista = ["atl4prdlb03", "atl4prdlb04", "atl4prdlb05", "atl4prdlb06", "atl4prdlb07",
234 "atl4crplb01", "atl4prdlb09", "jax4crplb01", "jax4prdlb04", "jax4prdlb05", "jax4prdlb06",
235 "jax4prdlb07", "jax4prdlb08", "jax4stglb02", "jax4devqalb01"]
236
237 lb_listb = []
238 for i in lb_lista:
239 lb_listb.append(i + "a")
240 lb_listb.append(i + "b")
241
242 for lbs in lb_lista:
243 vip_inventory_update(test_vip_pull(lbs))