-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathixvision_ztp_port_group.py
143 lines (125 loc) · 7.26 KB
/
ixvision_ztp_port_group.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
###############################################################################
#
# Zero-Touch Automation utility for Ixia Vision Network Packet Brokers
#
# File: ixvision_ztp_port_group.py
# Author: Alex Bortok (https://github.com/bortok)
#
# Description: Form a port group based on keywords the ports are tagged with
# 1. Starting point is an Ixia Vision NPB with ports tagged by certain keywords that indicate what is connected to them
# 2. Each run of this script would configure a single port group using the supplied name and group type:
# - Search for an existing port group with the same name. If found with the matching type, continue by referencing that group. If the type doesn't match, stop.
# - If not found, create a new group
# 4. Search for enabled ports with matching keywords that are not yet members of any group and don't have any connections to/from them. Add all such ports to the group, change port mode if nessesary
# 5. For all exising port group members, check keywords and if any have no match, remove them from the port group and set to a default configuration (Network Port, no connections)
#
# COPYRIGHT 2018 - 2019 Keysight Technologies.
#
# This code is provided under the MIT license.
# You can find the complete terms in LICENSE.txt
#
###############################################################################
from ksvisionlib import *
# DEFINE VARs HERE
pg_modes_supported = {'net': 'INTERCONNECT', 'lb': 'LOAD_BALANCE'}
# DEFINE FUNCTIONS HERE
# Input
# - Connection to an NPB
# - Keywords to use for matching ports
# - Port group name
# - Port group type: "net" for network (interconnect), "lb" for load balanced tool group
# Model to operate
# NPB
# |_Connection
# |_Type
# |_Keywords[Names]
def form_port_groups(host_ip, port, username, password, tags, pg_name, pg_mode_key):
nto = VisionWebApi(host=host_ip, username=username, password=password, port=port, debug=True, logFile="ixvision_ztp_port_group_debug.log")
# Check s/w version to use proper API syntax (ixia_nto.py doesn't support API versioning)
nto_system_properties = nto.getSystem()
nto_major_version = int(nto_system_properties['software_version'][0])
if nto_major_version == 4:
pg_type_key = 'port_group_type'
else:
pg_type_key = 'type'
if pg_mode_key == 'lb' or pg_mode_key == 'LB':
pg_params = {'mode': 'TOOL', pg_type_key: 'LOAD_BALANCE'}
else: # Inside this function we will default to Network Port Group mode
pg_params = {'mode': 'NETWORK', pg_type_key: 'INTERCONNECT'}
port_group_list = nto.searchPortGroups({'name': pg_name})
ztp_port_group = None
ztp_port_group_port_list = []
if len(port_group_list) == 0:
# No existing group with such name, create new one
pg_params.update({'name': pg_name, 'keywords': ['ZTP'] + tags})
new_port_group = nto.createPortGroup(pg_params)
if new_port_group is not None and len(new_port_group) > 0:
print("No group found, created a new one with id %s" % (str(new_port_group['id'])))
ztp_port_group = new_port_group
else:
print("No group found, failed to created a new one!")
return
elif len(port_group_list) == 1:
# An existing port group found
port_group = port_group_list[0]
port_group_details = nto.getPortGroup(str(port_group['id']))
if port_group_details is not None:
# WARNING! All NTO API versions returns 'type' attribute key on GET, but not on CREATE/UPDATE
print("Found existing port group %s of %s type and %s mode" % (port_group_details['default_name'], port_group_details['type'], port_group_details['mode'])),
if port_group_details['type'] == pg_params[pg_type_key] and port_group_details['mode'] == pg_params['mode']:
# PG types match, will update the existing group
print("-- type and mode match, will update")
ztp_port_group = port_group
ztp_port_group_port_list = port_group_details['port_list']
# Update keywords
updated_keywords = []
updated_keywords.extend(port_group_details['keywords'])
for keyword in tags:
if keyword not in updated_keywords:
updated_keywords.append(keyword)
if len(updated_keywords) > len(port_group_details['keywords']):
nto.modifyPortGroup(str(port_group['id']),{'keywords': updated_keywords})
else:
# Mismatch, return
print("-- type or mode mismatch with requested %s, %s, skipping..." % (pg_params[pg_type_key], pg_params['mode']))
return
else:
print("Failed to retrieve details for port %s, skipping..." % (port_group['name']))
else:
# This should never happen, but just in case, provide details to look into
print("Found more than one port group named %s, can't continue:" % (pg_name)),
for port_group in port_group_list:
port_group_details = nto.getPortGroup(str(port_group['id']))
if port_group_details is not None:
print (" %s," % (port_group_details['default_name'])),
print("")
return
# Now search for ports to be added to the port group
port_list = nto.searchPorts({'enabled': True, 'port_group_id': None, 'dest_filter_list': [], 'source_filter_list': []})
matching_port_id_list = []
for port in port_list:
port_details = nto.getPortProperties(str(port['id']), 'id,keywords,mode')
if port_details is not None:
for keyword in tags:
if keyword in port_details['keywords'] and port['id'] not in matching_port_id_list:
print("Found port %s with matching keyword %s" % (port['name'], keyword))
# Check and update port mode, if needed
if port_details['mode'] == pg_params['mode']:
matching_port_id_list.append(port['id'])
else:
print("Convering port %s into %s mode" % (port['name'], pg_params['mode']))
nto.modifyPort(str(port['id']), {'mode': pg_params['mode']})
# Check if the modification was successful and only add the port to the list of matching ports if yes
port_details = nto.getPortProperties(str(port['id']), 'id,keywords,mode')
if port_details is not None and port_details['mode'] == pg_params['mode']:
matching_port_id_list.append(port['id'])
else:
# Note, if the same port has several keywords that match, there will be several attempts to change the mode
print("Changing port mode failed, skipping...")
if len(matching_port_id_list) == 0:
print("No matching ports found")
return
else:
print("Found %d matching ports" % (len(matching_port_id_list)))
nto.modifyPortGroup(str(ztp_port_group['id']), {'port_list': matching_port_id_list + ztp_port_group_port_list})
print("Added %d ports to port group %s" % (len(matching_port_id_list), pg_name))