-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapi_connection.py
341 lines (283 loc) · 11.4 KB
/
api_connection.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
import requests, json, sys
'''
This file will help you send the GET commend to the Juniper NorthStar controller
to reterive the latest node info, path info, traffic info to calculate the
weighted shortest path info.
This file will help you send the POST command to the Juniper NorthStar controller
to update the shortest path info.
'''
# Disable warnings about unverified certificates
if hasattr(requests, 'packages') and hasattr(requests.packages, 'urllib3'):
requests.packages.urllib3.disable_warnings()
# Load from your config file.....
server_ip = "1.2.3.4"
northstar_username ="********"
northstar_password = "********"
auth_header = {"Authentication":""}
# Connect to your northstar server and return a token for authorization and future api calls
def connect_to_northstar():
# Get our NS authentication token
print("Attempting to connect to Northstar: {ip}".format(ip=server_ip))
northstar_url = "https://{server_ip}:8443/".format(server_ip=server_ip)
auth_url = northstar_url + "oauth2/token"
payload = {'grant_type': 'password', 'username': northstar_username, 'password': northstar_password}
auth_tuple = (northstar_username, northstar_password)
try:
response = requests.post(auth_url, data=payload, auth=auth_tuple, verify=False)
print payload
except:
print("Failed to connect to server")
else:
if response.status_code != 200:
print("Failed to authenticate")
else:
auth_data = json.loads(response.text)
print auth_data
auth_header['Authorization'] = "{token_type} {access_token}".format(**auth_data)
# Get all of the data needed (Topology and LSP)
def gather_topology():
#def gather_topology(auth_header):
print("Attempting to collect data")
# Retrieve the topology
northstar_url = "https://{server_ip}:8443/NorthStar/API/V2/tenant/1/topology/1".format(server_ip=server_ip)
response_topology = requests.get(northstar_url, headers=auth_header, verify=False)
# Retrieve the LSPs
northstar_url = "https://{server_ip}:8443/NorthStar/API/V2/tenant/1/topology/1/te-lsps/".format(server_ip=server_ip)
response_lsp_te = requests.get(northstar_url, headers=auth_header, verify=False)
# Store our raw data in a dictionary
data = {
"topology": response_topology.json(),
"lsp_te": response_lsp_te.json()
}
return data
# Alter an existing LSP
def modify_lsp(lsp, new_path):
'''
:param name: Name of LSP
:param path: A list of IPs/Hops that the LSP needs to traverse.
:return:
'''
result = requests.get('https://{server_ip}:8443/NorthStar/API/v2/tenant/1/topology/1/te-lsps/{lsp}'.format(server_ip=server_ip, lsp=str(lsp['lspIndex'])), headers=auth_header, verify=False)
lsp = result.json()
print "??????????"
print lsp
print "??????????"
new_lsp = {}
# Clear the ERO Data
new_lsp['from'] = lsp['from']
new_lsp['to'] = lsp['to']
new_lsp['name'] = lsp['name']
new_lsp['pathType'] = lsp['pathType']
new_lsp['lspIndex'] = lsp['lspIndex']
ero = []
# Build new ERO Data
for ip_address in new_path:
hop = {
"topoObjectType": "ipv4",
"address": ip_address,
# "loose" : True,
}
ero.append(hop)
new_lsp['plannedProperties'] = {
# 'preferredEro' : ero
#'ero' : ero
'calculatedEro' : []
#'calculatedEro' : ero
}
new_lsp = json.dumps(new_lsp)
result = requests.put('https://{server_ip}:8443/NorthStar/API/v2/tenant/1/topology/1/te-lsps/817'.format(server_ip=server_ip), json=new_lsp, headers=auth_header, verify=False)
#result = requests.put('https://{server_ip}:8443/NorthStar/API/v2/tenant/1/topology/1/te-lsps/{lsp}'.format(server_ip=server_ip, lsp=str(new_lsp['lspIndex'])), json=new_lsp, headers=auth_header, verify=False)
print("@@@@@@@@@@@@@@@@@@@@@@")
print(new_lsp)
print lsp['lspIndex']
print("@@@@@@@@@@@@@@@@@@@@@@")
#result = requests.put('https://{server_ip}:8443/NorthStar/API/v2/tenant/1/topology/1/te-lsps/{lsp}'.format(server_ip=server_ip, lsp=str(lsp['lspIndex'])), json=lsp, headers=auth_header, verify=False)
return result
def send_lsp_update(lsp_name, new_path):
""" Sends the API call for updating ERO for LSPs
Input is the ero array that is to be sent.
expected format::
ero= [
{ 'topoObjectType': 'ipv4', 'address': '10.210.15.2'},
{ 'topoObjectType': 'ipv4', 'address': '10.210.13.2'},
{ 'topoObjectType': 'ipv4', 'address': '10.210.17.1'}
]
Updates the northstar controller with the new LSPs.
ERO Name/ Number mapping to Class ranking (same for both directions):
LSP1: Premium 1: The lowest Latency link.
Intended for real time applications
LSP2: Premium 2: The second lowest latency redundant link from gold One
Intended for real time and business critical applications
LSP3: Plus: The second lowest latency link that is not Gold Two
Intended for business relevant applications
LSP4: Regular: The third lowest latency link that is neither gold one, gold two or silver
Intended for scavenger class applications
"""
print("Updating ", lsp_name, "on NorthStar Controller")
requs = requests.get(
'https://' + server_ip +
':8443/NorthStar/API/v1/tenant/1/topology/1/te-lsps/',
headers=auth_header, verify=False)
dump = json.dumps(requs.json())
lsp_list = json.loads(dump)
# Find target LSP to use lspIndex
for lsp in lsp_list:
if lsp['name'] == lsp_name:
break
# Fill only the required fields
# ero = ero_input
ero = []
# Build new ERO Data
print lsp
for ip_address in new_path:
hop = {
"topoObjectType": "ipv4",
"address": ip_address,
# "loose" : True,
}
ero.append(hop)
new_lsp = {}
# "provisioningType":"SR"
for key in ('from', 'to', 'name', 'lspIndex', 'pathType', 'provisioningType'):
new_lsp[key] = lsp[key]
new_lsp['plannedProperties'] = {
"bandwidth": "100M",
'ero': ero
# 'calculatedEro' : []
#'preferredEro' : ero
}
response = requests.put(
'https://10.10.2.64:8443/NorthStar/API/v1/tenant/1/topology/1/te-lsps/' + str(new_lsp[
'lspIndex']),
json=new_lsp, headers=auth_header, verify=False)
print("LSP Updated on NorthStar Controller")
print response
def modify_lsp2(lsp, new_path):
'''
:param name: Name of LSP
:param path: A list of IPs/Hops that the LSP needs to traverse.
:return:
'''
lspIdx = lsp['lspIndex']
print lspIdx
dd = { 'op' : 'replace', "path": '/plannedProperties/ero', 'value':[] }
body = []
body.append(dd)
# Build new ERO Data
for ip_address in new_path:
hop = {
"topoObjectType": "ipv4",
"address": ip_address,
"loose" : True,
}
dd['value'].append(hop)
result = requests.get('https://{server_ip}:8443/NorthStar/API/v2/tenant/1/topology/1/te-lsps/{lsp}'.format(server_ip=server_ip, lsp=str(lspIdx)), headers=auth_header, verify=False)
print "LLLLLLL"
print result
print "LLLLLLL"
result = requests.patch('https://{server_ip}:8443/NorthStar/API/v2/tenant/1/topology/1/te-lsps/{lsp}'.format(server_ip=server_ip, lsp=str(lspIdx)), json=body, headers=auth_header, verify=False)
print("@@@@@@@@@@@@@@@@@@@@@@")
print(body)
print("@@@@@@@@@@@@@@@@@@@@@@")
#result = requests.put('https://{server_ip}:8443/NorthStar/API/v2/tenant/1/topology/1/te-lsps/{lsp}'.format(server_ip=server_ip, lsp=str(lsp['lspIndex'])), json=lsp, headers=auth_header, verify=False)
return result
# Gather what fields are available
def gather_api_fields():
# Example dictionary for getting bandwidth statistics
result = requests.post("https://{server_ip}:8443/NorthStar/API/V2/tenant/1/statistics/interfaces/fields".format(server_ip=server_ip), headers=auth_header, verify=False)
interface_fields = result.json()
print interface_fields
# Example dictionary for getting delay statistics
result = requests.post("https://{server_ip}:8443/NorthStar/API/V2/tenant/1/statistics/delay/fields".format(server_ip=server_ip), headers=auth_header, verify=False)
delay_fields = result.json()
print delay_fields
return interface_fields, delay_fields
# Gather network health statistics
def gather_statistics(type, requested_fields):
'''
EXAMPLE FORMAT FOR REQUESTING DATA
GETS "interface_stats.egress_stats.if_bps" & "interface_stats.ingress_stats.if_pps"
requested_fields = {
'endTime': 'now',
'startTime': 'now-1h',
'aggregation': 'avg',
'interval': '1m',
'counter': ['interface_stats.egress_stats.if_bps', 'interface_stats.ingress_stats.if_pps']
}
'''
result = requests.post('https://{server_ip}:8443/NorthStar/API/v2/tenant/1/statistics/{type}/bulk'.format(server_ip=server_ip, type=type),
headers=auth_header, verify=False, data=requested_fields)
print "================="
# print result.json()
print "================="
return result.json()
# Connect to Northstar
connect_to_northstar()
# Get topology information
data = gather_topology()
############ Telemetry Examples #############
# Pull all available fields for bandwidth and delay statistics
bandwidth_stats_fields, delay_stats_fields = gather_api_fields()
# Example dictionary for getting bandwidth statistics
requested_fields_bandwidth = {
'endTime': 'now',
'startTime': 'now-1h',
'aggregation': 'avg',
'interval': '1m',
'counter': ['interface_stats.egress_stats.if_bps', 'interface_stats.ingress_stats.if_pps']
}
# Retrieve bandwidth related statistics for all interfaces
bandwidth_stats = gather_statistics('interfaces', requested_fields_bandwidth)
# Example dictionary for getting delay statistics
requested_fields_delay = {
'endTime': 'now',
'startTime': 'now-1h',
'aggregation': 'avg',
'interval': '1h',
'counter': [ 'average_rtt']
#'counter': [ 'max_rtt', 'average_rtt', 'loss_percent']
}
# Retrieve delay/loss related statistics for all interfaces
delay_stats = gather_statistics('interfaces', requested_fields_delay)
# Example dictionary for getting delay statistics
requested_fields_traffic = {
'endTime': 'now',
'startTime': 'now-1h',
'aggregation': 'avg',
'interval': '1h',
# 'counter': [ 'average_rtt']
#'counter': [ 'max_rtt', 'average_rtt', 'loss_percent']
}
# Retrieve delay/loss related statistics for all interfaces
traffic_stats = gather_statistics('interfaces', requested_fields_traffic)
############ LSP Modification Example #############
# List of hops that the LSP must traverse.
# This is just a list of IPs
#new_path = ["10.147.5.2","10.148.5.1"]
new_path = ["10.147.6.2","10.210.11.1", "10.148.6.1"]
#new_path = ["10.147.6.1","10.147.6.2","10.146.6.2","10.148.6.1",]
# Find target LSP to use lspIndex
for lsp in data['lsp_te']:
print lsp
print "-------------------"
if lsp['name'] == 'SR-LSP-West-East-Three':
# Copy the LSP into a new dictionary
result = modify_lsp(lsp, new_path)
print(result)
break
send_lsp_update('SR-LSP-West-East-Three', new_path)
########### Interface Status Example #############
data = gather_topology()
print "~~~~~~~~~~~~~~~~"
print data
for link in data['topology']['links']:
#print "[][][][][][]["
#print link
print(link['operationalStatus'])
print "~~~~~~~~~~~~~~~"
print "***************"
#print delay_stats
for latency in delay_stats:
print delay_stats[latency]
print ''
print "::::::::::::::::"