Skip to content

Commit

Permalink
lf_create_wanpath.py: LAN-3445 - create lf_create_wanpath.py
Browse files Browse the repository at this point in the history
lf_create_wanpath.py creates a wanpath using the lanforge api
given an existing wanlink endpoint

Signed-off-by: Cameron LaPlante <[email protected]>

added help note
  • Loading branch information
claplante-candela committed Jan 14, 2025
1 parent d04401e commit 75ffc00
Showing 1 changed file with 337 additions and 0 deletions.
337 changes: 337 additions & 0 deletions py-scripts/lf_create_wanpath.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,337 @@
#!/usr/bin/env python3

'''
NAME: lf_create_wanpath.py
PURPOSE: create a wanpath using the lanforge api given an existing wanlink endpoint
EXAMPLE:
$ ./lf_create_wanpath.py --mgr 192.168.102.158 --mgr_port 8080\
--wp_name test_wp-A --wl_endp test_wl-A\
--speed 102400 --latency 25 --max_jitter 50 --jitter_freq 6 --drop_freq 12\
--log_level debug --debug
$ ./lf_create_wanpath.py --mgr 192.168.102.158 --mgr_port 8080\
--wp_name test_wp-B --wl_endp test_wl-B\
--speed 102400 --latency 25 --max_jitter 50 --jitter_freq 6 --drop_freq 12\
--log_level debug --debug
$ ./lf_create_wanpath.py --mgr 192.168.102.158 --mgr_port 8080\
--wp_name test_wp-C --wl_endp test_wl-A\
--source_ip 1.1.1.1 --source_ip_mask 2.2.2.2 --dest_ip 3.3.3.3 --dest_ip_mask 4.4.4.4\
--drop_freq 5 --dup_freq 6 --extra_buffer 7 --jitter_freq 8 --latency 9 --max_drop_amt 10\
--max_jitter 11 --max_lateness 12 --max_reorder_amt 13 --min_drop_amt 14 --min_reorder_amt 15\
--reorder_freq 16 --speed 17 --test_mgr default_tm\
--log_level debug --debug
NOTES:
-> Wanlink must already exist - can be created with lf_create_wanlink.py:
$ ./lf_create_wanlink.py --mgr 192.168.102.158 --mgr_port 8080 --port_A eth1 --port_B eth2\
--speed_A 1024000 --speed_B 2048000 --wl_name test_wl --latency_A 24 --latency_B 32\
--max_jitter_A 50 --max_jitter_B 20 --jitter_freq 6 --drop_freq 12\
--log_level debug --debug
-> lanforge api expects 'wanlink' but it is really looking for the endpoint name
ie. wanlink test_wl has endpoints test_wl-A and test_wl-B.
SCRIPT_CLASSIFICATION: Tool
SCRIPT_CATEGORIES:
STATUS: PROTOTYPE
VERIFIED_ON: Underdevelopment
INCLUDE_IN_README:
False
LICENSE: Free to distribute and modify. LANforge systems must be licensed.
Copyright 2024 Candela Technologies Inc.
'''

import sys
import importlib
import argparse
import os
import logging

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

if sys.version_info[0] != 3:
print('This script requires Python3')
exit()

lf_logger_config = importlib.import_module('py-scripts.lf_logger_config')

logger = logging.getLogger(__name__)


class lf_create_wanpath():
'''wanpath creation and maitenance class
Handles initialization, creation and updating of a wanpath in lanforge api
'''

def __init__(self,
lf_mgr=None,
lf_port=None,
lf_user=None,
lf_passwd=None,
debug=False
):

'''Initializes instance based on lanforge connection parameters
Args:
lf_mgr: the GUI to connect to
lf_port: the port to connect to
lf_user: lanforge username (default lanforge)
lf_psswd: lanforge password (default lanforge)
debug: debug flag
'''
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)

self.command: LFJsonCommand
self.command = self.session.get_command()
self.query: LFJsonQuery
self.query = self.session.get_query()

def add_wanpath(self,
_alias: str = None,
_dest_ip: str = None,
_dest_ip_mask: str = None,
_drop_every_xth_pkt: str = None,
_drop_freq: str = None,
_dup_every_xth_pkt: str = None,
_dup_freq: str = None,
_extra_buffer: str = None,
_follow_binomial: str = None,
_ignore_bandwidth: str = None,
_ignore_dup: str = None,
_ignore_latency: str = None,
_ignore_loss: str = None,
_jitter_freq: str = None,
_latency: str = None,
_max_drop_amt: str = None,
_max_jitter: str = None,
_max_lateness: str = None,
_max_reorder_amt: str = None,
_min_drop_amt: str = None,
_min_reorder_amt: str = None,
_playback_capture: str = None,
_playback_capture_file: str = None,
_playback_loop: str = None,
_reorder_every_xth_pkt: str = None,
_reorder_freq: str = None,
_source_ip: str = None,
_source_ip_mask: str = None,
_speed: str = None,
_test_mgr: str = None,
_wanlink: str = None):

'''adds wanpath to specified wanlink
Args:
_alias: Name of WanPath [R]
_dest_ip: Selection filter: Destination IP
_dest_ip_mask: Selection filter: Destination IP MASK
_drop_every_xth_pkt: YES to periodically drop every Xth pkt, NO to drop packets randomly
_drop_freq: How often, out of 1,000,000 packets, should we purposefully drop a packet
_dup_every_xth_pkt: YES to periodically duplicate every Xth pkt, NO to duplicate packets randomly
_dup_freq: How often, out of 1,000,000 packets, should we purposefully duplicate a packet
_extra_buffer: Extra amount of bytes to buffer before dropping pkts (units of 1024)
_follow_binomial: YES to have ok/drop burst lengths follow a binomial distribution
_ignore_bandwidth: Should we ignore the bandwidth settings from the playback file? YES, NO, or NA
_ignore_dup: Should we ignore the Duplicate Packet settings from the playback file? YES, NO, or NA
_ignore_latency: Should we ignore the latency settings from the playback file? YES, NO, or NA
_ignore_loss: Should we ignore the packet-loss settings from the playback file? YES, NO, or NA
_jitter_freq: How often, out of 1,000,000 packets, should we apply random jitter
_latency: The base latency added to all packets (ms)
_max_drop_amt: Maximum amount of packets to drop in a row. Default is 1. [D:1]
_max_jitter: Maximum jitter (ms)
_max_lateness: Maximum amount of un-intentional delay before pkt is dropped. Default is AUTO
_max_reorder_amt: Maximum amount of packets by which to reorder, Default is 10. [D:10]
_min_drop_amt: Minimum amount of packets to drop in a row. Default is 1. [D:1]
_min_reorder_amt: Minimum amount of packets by which to reorder, Default is 1. [D:1]
_playback_capture: ON or OFF, should we play back a WAN capture file?
_playback_capture_file: Name of the WAN capture file to play back
_playback_loop: Should we loop the playback file, YES or NO or NA
_reorder_every_xth_pk: YES to periodically reorder every Xth pkt, NO to reorder packets randomly
_reorder_freq: How often, out of 1,000,000 packets, should we make a packet out of order
_source_ip: Selection filter: Source IP
_source_ip_mask: Selection filter: Source IP MASK
_speed: Maximum speed this WanLink will accept (bps)
_test_mgr: The name of the Test-Manager this WanPath is to use. Leave blank for no restrictions
_wanlink: Name of WanLink endpoint [R]
'''

# check for required arguments
if _wanlink is None:
logger.error('wanlink is None. wanlink must be set to a valid existing wanlink. Exiting')
exit(1)
elif _alias is None:
logger.error('alias is None. alias must be set to the desired name of the wanpath. Exiting')
exit(1)

# add wanpath via cli command post_add_wanpath
self.command.post_add_wanpath(alias=_alias,
dest_ip=_dest_ip,
dest_ip_mask=_dest_ip_mask,
drop_every_xth_pkt=_drop_every_xth_pkt,
drop_freq=_drop_freq,
dup_every_xth_pkt=_dup_every_xth_pkt,
dup_freq=_dup_freq,
extra_buffer=_extra_buffer,
follow_binomial=_follow_binomial,
ignore_bandwidth=_ignore_bandwidth,
ignore_dup=_ignore_dup,
ignore_latency=_ignore_latency,
ignore_loss=_ignore_loss,
jitter_freq=_jitter_freq,
latency=_latency,
max_drop_amt=_max_drop_amt,
max_jitter=_max_jitter,
max_lateness=_max_lateness,
max_reorder_amt=_max_reorder_amt,
min_drop_amt=_min_drop_amt,
min_reorder_amt=_min_reorder_amt,
playback_capture=_playback_capture,
playback_capture_file=_playback_capture_file,
playback_loop=_playback_loop,
reorder_every_xth_pkt=_reorder_every_xth_pkt,
reorder_freq=_reorder_freq,
source_ip=_source_ip,
source_ip_mask=_source_ip_mask,
speed=_speed,
test_mgr=_test_mgr,
wanlink=_wanlink
)


def main():
'''Main'''

parser = argparse.ArgumentParser(
prog=__file__,
formatter_class=argparse.RawTextHelpFormatter,
epilog="Note: endp_A is associated with _tx_endp and endp_B is associated with _rx_endp"
)

# http://www.candelatech.com/lfcli_ug.php#add_wanpath
# connection args
parser.add_argument('--host', '--mgr', dest='mgr', help='specify the GUI to connect to')
parser.add_argument('--lf_user', help='lanforge user name default lanforge', default='lanforge')
parser.add_argument('--lf_passwd', help='lanforge password defualt lanforge', default='lanforge')
parser.add_argument('--mgr_port', help='specify the GUI to connect to, default 8080', default='8080')

# creating wanpath args
parser.add_argument('--dest_ip', help='(add wanpath)Selection filter: Destination IP', default='0.0.0.0')
parser.add_argument('--dest_ip_mask', help='(add wanpath) Selection filter: Destination IP MASK', default='0.0.0.0')
parser.add_argument('--drop_freq', help='(add wanpath) How often, out of 1,000,000 packets, should we purposefully drop a packet.', default='0')
parser.add_argument('--dup_freq', help='(add wanpath) How often, out of 1,000,000 packets, should we purposefully duplicate a packet.', default='0')
parser.add_argument('--extra_buffer', help='(add wanpath) The extra amount of bytes to buffer before dropping pkts, in units of 1024, use -1 for AUTO. Default: -1', default='-1')
parser.add_argument('--jitter_freq', help='(add wanpath) How often, out of 1,000,000 packets, should we apply random jitter.', default='0')
parser.add_argument('--latency', help='(add wanpath) The base latency added to all packets, in milliseconds (or add "us" suffix for microseconds) Default: 20', default='20')
parser.add_argument('--max_drop_amt', help='(add wanpath) Maximum mount of packets to drop in a row. Default: 1', default='1')
parser.add_argument('--max_jitter', help='(add wanpath) The maximum jitter, in milliseconds (or ad "us" suffix for microseconds) Default: 10', default='10')
parser.add_argument('--max_lateness', help='(add wanpath) Maximum amount of un-intentional delay before pkt is dropped. Default: AUTO', default='AUTO')
parser.add_argument('--max_reorder_amt', help='(add wanpath) Maximum amount of packets by which to reorder, Default is 1.', default='1')
parser.add_argument('--min_drop_amt', help='(add wanpath) Minimum amount of packets to drop in a row. Default: 1', default='1')
parser.add_argument('--min_reorder_amt', help='(add wanpath) Minimum amount of packets by which to reorder, Default is 1.', default='1')
parser.add_argument('--playback_capture', help='(add wanpath) ON or OFF, should we play back a WAN capture file?', default=None)
parser.add_argument('--playback_capture_file', help='(add wanpath) Name of the WAN capture file to play back. Deafault = None', default=None)
parser.add_argument('--reorder_freq', help='(add wanpath) How often, out of 1,000,000 packets, should we make a packet out of order.', default=None)
parser.add_argument('--source_ip', help='(add wanpath) Selection filter: Source IP', default='0.0.0.0')
parser.add_argument('--source_ip_mask', help='(add wanpath) Selection filter: Source IP MASK', default='0.0.0.0')
parser.add_argument('--speed', help='(add wanpath The maximum speed this WanLink will accept (bps).', default=1000000)
parser.add_argument('--test_mgr', help='(add wanpath) The name of the Test-Manager this WanPath is to use. Leave blank for no restrictions.', default=None)
parser.add_argument('--wanlink', '--wl_endp', dest='wanlink', help='(add wanpath) The name of the wanlink endpoint to which we are adding this WanPath.', required=True)
parser.add_argument('--wp_name', '--alias', dest='wp_name', help='(add wanpath) Name of the WanPath', required=True)

# wanpath flag args
parser.add_argument('--drop_every_xth_pkt', help='(set wanpath flag) Periodically drop every Xth pkt, Default: drop packets randomly.', action='store_true')
parser.add_argument('--dup_every_xth_pkt', help='(set wanpath flag) Periodically duplicate every Xth pkt, Default: duplicate packets randomly.', action='store_true')
parser.add_argument('--follow_binomial', help='(set wanpath flag) Have ok/drop burst lengths follow a binomial distribution.', action='store_true')
parser.add_argument('--ignore_bandwidth', help='(set wanpath flag) Should we ignore the bandwidth wsettings from the playback file? Default = "False" action="store_true"', action='store_true')
parser.add_argument('--ignore_dup', help='(set wanpath flag) Should we ignore the Duplicate Packet settings from the playback file? Default = "False" action="store_true"', action='store_true')
parser.add_argument('--ignore_latency', help='(set wanpath flag) Should we ignore the packet-loss settings from the playback file? Default = "False" action="store_true"', action='store_true')
parser.add_argument('-ignore_loss', help='Should we ignore the packet-loss settings from the playback file? YES, NO, or NA.', default=None)
parser.add_argument('--playback_loop', help='(set wanpath flag) Should we loop the playback file', action='store_true')
parser.add_argument('--reorder_every_xth_pkt', help='(set wanpath flag) Periodically reorder every Xth pkt, Default: reorder packets randomly.', action='store_true')

# Logging Configuration
parser.add_argument('--debug', help='Legacy debug flag', action='store_true')
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')

args = parser.parse_args()

logger_config = lf_logger_config.lf_logger_config()
if args.log_level:
logger_config.set_level(level=args.log_level)

# lf_logger_config_json will take presidence to changing debug levels
if args.lf_logger_config_json:
logger_config.lf_logger_config_json = args.lf_logger_config_json
logger_config.load_lf_logger_config()

# initialize wanlink
wanpath = lf_create_wanpath(lf_mgr=args.mgr,
lf_port=8080,
lf_user=args.lf_user,
lf_passwd=args.lf_passwd,
debug=True
)

# create wanpath
wanpath.add_wanpath(_alias=args.wp_name,
_dest_ip=args.dest_ip,
_dest_ip_mask=args.dest_ip_mask,
_drop_every_xth_pkt=args.drop_every_xth_pkt,
_drop_freq=args.drop_freq,
_dup_every_xth_pkt=args.dup_every_xth_pkt,
_dup_freq=args.dup_freq,
_extra_buffer=args.extra_buffer,
_follow_binomial=args.follow_binomial,
_ignore_bandwidth=args.ignore_bandwidth,
_ignore_dup=args.ignore_dup,
_ignore_latency=args.ignore_latency,
_ignore_loss=args.ignore_loss,
_jitter_freq=args.jitter_freq,
_latency=args.latency,
_max_drop_amt=args.max_drop_amt,
_max_jitter=args.max_jitter,
_max_lateness=args.max_lateness,
_max_reorder_amt=args.max_reorder_amt,
_min_drop_amt=args.min_drop_amt,
_min_reorder_amt=args.min_reorder_amt,
_playback_capture=args.playback_capture,
_playback_capture_file=args.playback_capture_file,
_playback_loop=args.playback_loop,
_reorder_every_xth_pkt=args.reorder_every_xth_pkt,
_reorder_freq=args.reorder_freq,
_source_ip=args.source_ip,
_source_ip_mask=args.source_ip_mask,
_speed=args.speed,
_test_mgr=args.test_mgr,
_wanlink=args.wanlink)


if __name__ == "__main__":
main()

0 comments on commit 75ffc00

Please sign in to comment.