-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathlf_add_profile.py
More file actions
executable file
·414 lines (368 loc) · 21.6 KB
/
lf_add_profile.py
File metadata and controls
executable file
·414 lines (368 loc) · 21.6 KB
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
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
#!/usr/bin/env python3
"""
NAME: lf_add_profile.py
PURPOSE: Create and configure a template LANforge device profile for use in
Chamber View Scenario automation.
NOTES: The profile is not made active on the system until it is configured into
a Chamber View Scenario (e.g. via 'create_chamberview.py') and the
Chamber View Scenario is built.
EXAMPLE: # Add routed vAP with following configuration:
# - DHCP server
# - NAT enabled (when configured in virtual router)
# - Admin up on creation (active)
# - WPA2 security
#
# Note that the '--profile_flags' are specified in hexadecimal format
# See http://www.candelatech.com/lfcli_ug.php#add_profile for profile flags
./lf_add_profile.py \
--instance_count 1 \
--profile_flags 4109 \
--name "routed-AP-custom" \
--profile_type routed_ap \
--freq 2412 \
--ssid LF-routed-AP \
--passwd lanforge
# Same example but using VSCode launch.json to specify CLI
# As this will likely be run from a secondary system, you'll
# need to add the "--mgr" argument and IP in that case
"args": [
"instance_count", "1",
"profile_flags" "4109",
"name", "routed-AP-custom",
"profile_type", "routed_ap",
"freq", "2412",
"ssid", "LF-routed-AP",
"passwd", "lanforge",
]
# This configuration can be made active in a Chamber View Scenario as follows
# This example uses 'wiphy0' on LANforge resource 1
./create_chamberview.py \
--create_scenario "LF-routed-AP-scenario" \
--raw_line 'profile_link 1.1 LF-routed-AP 1 NA NA wiphy1,AUTO -1 NA' \
--raw_line 'resource 1.1.0 0'
LICENSE: Free to distribute and modify. LANforge systems must be licensed.
Copyright (C) 2020-2026 Candela Technologies Inc
"""
import argparse
import importlib
import logging
import os
import sys
if sys.version_info[0] != 3:
print("This script requires Python3")
exit()
sys.path.append(os.path.join(os.path.abspath(__file__ + "../../../")))
lanforge_api = importlib.import_module("lanforge_client.lanforge_api")
LFUtils = importlib.import_module("py-json.LANforge.LFUtils")
from lanforge_client.lanforge_api import LFSession # noqa: E402
from lanforge_client.lanforge_api import LFJsonCommand # noqa: E402
from lanforge_client.lanforge_api import LFJsonQuery # noqa: E402
lf_logger_config = importlib.import_module("py-scripts.lf_logger_config")
logger = logging.getLogger(__name__)
class lf_add_profile():
def __init__(self,
lf_mgr=None,
lf_port=None,
lf_user=None,
lf_passwd=None,
debug=False,
):
self.lf_mgr = lf_mgr
self.lf_port = lf_port
self.lf_user = lf_user
self.lf_passwd = lf_passwd
self.debug = debug
self.session = LFSession(lfclient_url="http://%s:8080" % self.lf_mgr,
debug=debug,
connection_timeout_sec=4.0,
stream_errors=True,
stream_warnings=True,
require_session=True,
exit_on_error=True)
# type hinting
self.command: LFJsonCommand
self.command = self.session.get_command()
self.query: LFJsonQuery
self.query = self.session.get_query()
# http://www.candelatech.com/lfcli_ug.php#add_profile
# add_profile Routed-AP-QA Routed-AP 0 4 0 0 vap hello123 4105
def add_profile(self,
_alias_prefix: str = None, # Port alias prefix, aka hostname prefix.
_antenna: str = None, # Antenna count for this profile.
_bandwidth: str = None, # 0 (auto), 20, 40, 80 or 160
_eap_id: str = None, # EAP Identifier
_flags_mask: str = None, # Specify what flags to set.
_freq: str = None, # WiFi frequency to be used, 0 means default.
_instance_count: str = None, # Number of devices (stations, vdevs, etc)
_mac_pattern: str = None, # Optional MAC-Address pattern, for instance: xx:xx:xx:*:*:xx
_name: str = None, # Profile Name. [R]
_passwd: str = None, # WiFi Password to be used (AP Mode), [BLANK] means no password.
_profile_flags: str = None, # Flags for this profile, see above.
_profile_flags_list: list = None, # Flags for the profile passed as list
_profile_type: str = None, # Profile type: See above. [W]
_ssid: str = None, # WiFi SSID to be used, [BLANK] means any.
_vid: str = None, # Vlan-ID (only valid for vlan profiles).
_wifi_mode: str = None, # WiFi Mode for this profile.
_response_json_list: list = None,
_errors_warnings: list = None,
_suppress_related_commands: bool = False):
if not _profile_flags_list:
_profile_flags_list = []
flag_val = 0
if _profile_flags is not None:
if '0x' in _profile_flags:
_profile_flags = str(int(_profile_flags.replace('0x', ''), 16))
flag_val = _profile_flags
logger.debug("profile_flags used flag_val = {flag_val}".format(flag_val=flag_val))
elif len(_profile_flags_list) != 0:
flag_val = self.command.set_flags(self.command.AddProfileProfileFlags, 0, flag_names=_profile_flags_list)
logger.debug("profile_flags_list used flag_val = {flag_val}".format(flag_val=flag_val))
else:
logger.error("_profile_flags is None and _profile_flags_list is empty")
# flag_val = self.command.set_flags(self.command.AddProfileProfileFlags,0, flag_names=_profile_flags)
self.command.post_add_profile(
alias_prefix=_alias_prefix, # Port alias prefix, aka hostname prefix.
antenna=_antenna, # Antenna count for this profile.
bandwidth=_bandwidth, # 0 (auto), 20, 40, 80 or 160
eap_id=_eap_id, # EAP Identifier
flags_mask=flag_val, # Specify what flags to set.
freq=_freq, # WiFi frequency to be used, 0 means default.
instance_count=_instance_count, # Number of devices (stations, vdevs, etc)
mac_pattern=_mac_pattern, # Optional MAC-Address pattern, for instance: xx:xx:xx:*:*:xx
name=_name, # Profile Name. [R]
passwd=_passwd, # WiFi Password to be used (AP Mode), [BLANK] means no password.
profile_flags=flag_val, # Flags for this profile, see above.
profile_type=_profile_type, # Profile type: See lanforge_api [W]
ssid=_ssid, # WiFi SSID to be used, [BLANK] means any.
vid=_vid, # Vlan-ID (only valid for vlan profiles).
wifi_mode=_wifi_mode, # WiFi Mode for this profile.
response_json_list=_response_json_list,
debug=self.debug,
errors_warnings=_errors_warnings,
suppress_related_commands=_suppress_related_commands)
# This text will be added to the end of the notes field for Profiles.
# The text must be entered one line at a time, primarily due to CLI parsing limitations.
# http://www.candelatech.com/lfcli_ug.php#add_profile_notes
def add_profile_notes(self,
_dut: str = None, # Profile Name. [R]
_text: str = None, # [BLANK] will erase all, any other text will be appended to existing text.
_response_json_list: list = None,
_errors_warnings: list = None,
_suppress_related_commands: bool = False):
self.command.post_add_profile_notes(
dut=_dut, # Profile Name. [R]
text=_text, # [BLANK] will erase all, any other text will be appended to existing text.
response_json_list=_response_json_list,
debug=self.debug,
errors_warnings=_errors_warnings,
suppress_related_commands=_suppress_related_commands)
def main():
help_summary = "This script is helpful to create profiles on the lanforge device"
parser = argparse.ArgumentParser(
prog=__file__,
formatter_class=argparse.RawTextHelpFormatter,
description=r'''\
NAME: lf_add_profile.py
PURPOSE: Create and configure a template LANforge device profile for use in
Chamber View Scenario automation.
NOTES: The profile is not made active on the system until it is configured into
a Chamber View Scenario (e.g. via 'create_chamberview.py') and the
Chamber View Scenario is built.
EXAMPLE: # Add routed vAP with following configuration:
# - DHCP server
# - NAT enabled (when configured in virtual router)
# - Admin up on creation (active)
# - WPA2 security
#
# Note that the '--profile_flags' are specified in hexadecimal format
# See http://www.candelatech.com/lfcli_ug.php#add_profile for profile flags
./lf_add_profile.py \
--instance_count 1 \
--profile_flags 4109 \
--name "routed-AP-custom" \
--profile_type routed_ap \
--freq 2412 \
--ssid LF-routed-AP \
--passwd lanforge
# Same example but using VSCode launch.json to specify CLI
# As this will likely be run from a secondary system, you'll
# need to add the "--mgr" argument and IP in that case
"args": [
"instance_count", "1",
"profile_flags" "4109",
"name", "routed-AP-custom",
"profile_type", "routed_ap",
"freq", "2412",
"ssid", "LF-routed-AP",
"passwd", "lanforge",
]
# This configuration can be made active in a Chamber View Scenario as follows
# This example uses 'wiphy0' on LANforge resource 1
./create_chamberview.py \
--create_scenario "LF-routed-AP-scenario" \
--raw_line 'profile_link 1.1 LF-routed-AP 1 NA NA wiphy1,AUTO -1 NA' \
--raw_line 'resource 1.1.0 0'
LICENSE: Free to distribute and modify. LANforge systems must be licensed.
Copyright (C) 2020-2026 Candela Technologies Inc
''')
# http://www.candelatech.com/lfcli_ug.php#add_profile
parser.add_argument("--host", "--mgr", dest='mgr', help='specify the GUI to connect to')
parser.add_argument("--mgr_port", help="specify the GUI to connect to, default 8080", default="8080")
parser.add_argument("--lf_user", help="lanforge user name", default="lanforge")
parser.add_argument("--lf_passwd", help="lanforge password", default="lanforge")
# http://www.candelatech.com/lfcli_ug.php#add_profile
parser.add_argument('--alias_prefix', help='(add profile) alias_prefix Port alias prefix, aka hostname prefix. ')
parser.add_argument('--antenna', help="(add profile) Antenna count for this profile.")
parser.add_argument('--bandwidth', help="(add profile) 0 (auto), 20, 40, 80 or 160")
parser.add_argument("--eap_id", help="(add profile) EAP Identifier")
parser.add_argument("--flags_mask", help="(add profile) Specify what flags to set.")
parser.add_argument("--freq", help="(add profile)WiFi frequency to be used, -1 means AUTO.")
parser.add_argument("--instance_count", help="(add profile) Number of devices (stations, vdevs, etc)")
parser.add_argument("--mac_pattern", help="(add profile) Optional MAC-Address pattern, for instance: xx:xx:xx:*:*:xx")
parser.add_argument("--name", help="(add profile) Profile Name. [R] ")
parser.add_argument('--passwd', help='(add profile) WiFi SSID to be used, [BLANK] means any.')
parser.add_argument('--profile_flags', help='pass in flags as a decimal value takes presidence over hex and --pf []')
parser.add_argument('--profile_flags_hex', help='pass in flags as a hex value')
parser.add_argument('--pf',
# nargs='+', # trying to pass in a list
action='append',
help='''
(add profile)
Profile flags entered as a list
Flags for this profilelanforge_api AddProfileProfileFlags'
enter the flags as a list 0x1009 is:
DHCP_SERVER = 0x1 # This should provide DHCP server.
SKIP_DHCP_ROAM = 0x10 # Ask station to not re-do DHCP on roam.
NAT = 0x100 # Enable NAT if this object is in a virtual router
ENABLE_POWERSAVE = 0x1000 # Enable power-save when creating stations.
pass in --profile_flags 'DHCP_SERVER,SKIP_DHCP_ROAM,NAT,ENABLE_POWERSAVE'
flags:
p_11r = 0x40 # Use 802.11r roaming setup.
ALLOW_11W = 0x800 # Set 11w (MFP/PMF) to optional.
BSS_TRANS = 0x400 # Enable BSS Transition logic
DHCP_SERVER = 0x1 # This should provide DHCP server.
EAP_PEAP = 0x200 # Enable EAP-PEAP
EAP_TTLS = 0x80 # Use 802.1x EAP-TTLS
ENABLE_POWERSAVE = 0x1000 # Enable power-save when creating stations.
NAT = 0x100 # Enable NAT if this object is in a virtual router
SKIP_DHCP_ROAM = 0x10 # Ask station to not re-do DHCP on roam.
WEP = 0x2 # Use WEP encryption
WPA = 0x4 # Use WPA encryption
WPA2 = 0x8 # Use WPA2 encryption
WPA3 = 0x20 # Use WPA3 encryption
''')
parser.add_argument("--profile_type", help='''
(add profile)
Profile type: [W]
Bridged_AP: briged-AP
Monitor: monitor
Peer: peer
RDD: rdd
Routed_AP: routed-AP
STA: STA-AC
STA: STA-AUTO
STA: STA-AX
STA: STA-abg
STA: STA-n
Uplink: uplink-nat
Upstream: upstrream
Upstream: upstream-dhcp
as_is: as-is
NA
''')
parser.add_argument("--ssid", help='(add profile) WiFi SSID to be used, [BLANK] means any.')
parser.add_argument("--vid", help='(add profile) Vlan-ID (only valid for vlan profiles).')
parser.add_argument("--wifi_mode", help='''(add profile) WiFi Mode for this profile.
p_802_11a = "802.11a" # 802.11a
AUTO = "AUTO" # 802.11g
aAX = "aAX" # 802.11a-AX (6E disables /n and /ac)
abg = "abg" # 802.11abg
abgn = "abgn" # 802.11abgn
abgnAC = "abgnAC" # 802.11abgn-AC
abgnAX = "abgnAX" # 802.11abgn-AX
an = "an" # 802.11an
anAC = "anAC" # 802.11an-AC
anAX = "anAX" # 802.11an-AX
as_is = "as_is" # Make no changes to current configuration
b = "b" # 802.11b
bg = "bg" # 802.11bg
bgn = "bgn" # 802.11bgn
bgnAC = "bgnAC" # 802.11bgn-AC
bgnAX = "bgnAX" # 802.11bgn-AX
bond = "bond" # Bonded pair of Ethernet ports.
bridged_ap = "bridged_ap" # AP device in bridged mode. The EIDs may specify radio and bridged port.
client = "client" # Client-side non-WiFi device (Ethernet port, for instance).
g = "g" # 802.11g
mobile_sta = "mobile_sta" # Mobile station device. Expects to connect to DUT AP(s) and upstream LANforge.
monitor = "monitor" # Monitor device/sniffer. The EIDs may specify which radios to use.
peer = "peer" # Edge device, client or server (Ethernet port, for instance).
rdd = "rdd" # Pair of redirect devices, typically associated with VR to act as traffic endpoint
routed_ap = "routed_ap" # AP in routed mode. The EIDs may specify radio and upstream port.
sta = "sta" # Station device, most likely non mobile. The EIDs may specify radio(s) to use
uplink = "uplink" # Uplink towards rest of network (can go in virtual router and do NAT)
upstream = "upstream" # Upstream server device. The EIDs may specify which ports to use.
vlan = "vlan" # 802.1q VLAN. Specify VID with the 'freq' option.
''')
# http://www.candelatech.com/lfcli_ug.php#add_profile_notes
parser.add_argument('--dut', help='(add profile notes) Profile Name. [R]')
parser.add_argument('--text', action='append',
nargs=1,
help='''(add profile notes) list of lines of text
[BLANK] will erase all,
any other text will be appended to existing text.
must be entered line by line
''')
# Logging Configuration
parser.add_argument('--log_level', default=None, help='Set logging level: debug | info | warning | error | critical')
parser.add_argument("--lf_logger_config_json", help="--lf_logger_config_json <json file> , json configuration of logger")
parser.add_argument('--debug', help='Legacy debug flag', action='store_true')
parser.add_argument('--help_summary', help='shows summary of the script', action='store_true')
args = parser.parse_args()
if args.help_summary:
print(help_summary)
exit(0)
# Configure logging
logger_config = lf_logger_config.lf_logger_config()
if args.log_level:
logger_config.set_level(level=args.log_level)
# Logger JSON config takes precedence over command line
if args.lf_logger_config_json:
logger_config.lf_logger_config_json = args.lf_logger_config_json
logger_config.load_lf_logger_config()
profile = lf_add_profile(lf_mgr=args.mgr,
lf_port=args.mgr_port,
lf_user=args.lf_user,
lf_passwd=args.lf_passwd,
debug=args.debug)
logger.debug("profile_flags_list {pf}".format(pf=args.pf))
if args.pf:
profile_flags_list = args.pf.copy()
else:
profile_flags_list = []
logger.info(f"Adding profile '{args.name}' to LANforge manager '{args.mgr}'")
logger.debug("args.alias_prefix {}".format(args.alias_prefix))
profile.add_profile(
_alias_prefix=args.alias_prefix, # Port alias prefix, aka hostname prefix.
_antenna=args.antenna, # Antenna count for this profile.
_bandwidth=args.bandwidth, # 0 (auto), 20, 40, 80 or 160
_eap_id=args.eap_id, # EAP Identifier
_flags_mask=args.flags_mask, # Specify what flags to set.
_freq=args.freq, # WiFi frequency to be used, 0 means default.
_instance_count=args.instance_count, # Number of devices (stations, vdevs, etc)
_mac_pattern=args.mac_pattern, # Optional MAC-Address pattern, for instance: xx:xx:xx:*:*:xx
_name=args.name, # Profile Name. [R]
_passwd=args.passwd, # WiFi Password to be used (AP Mode), [BLANK] means no password.
_profile_flags_list=profile_flags_list, # Flags for the profile passed as list
_profile_flags=args.profile_flags, # Flags for this profile, see above.
_profile_type=args.profile_type, # Profile type: See above. [W]
_ssid=args.ssid, # WiFi SSID to be used, [BLANK] means any.
_vid=args.vid, # Vlan-ID (only valid for vlan profiles).
_wifi_mode=args.wifi_mode # WiFi Mode for this profile.
)
if args.text is not None:
for text in args.text:
profile.add_profile_notes(_dut=args.name,
_text=text)
logger.info(f"Added profile '{args.name}'")
if __name__ == "__main__":
main()