From e1474f11cfffa51cc80aa461e0ed6f6fb771f40a Mon Sep 17 00:00:00 2001 From: shivamcandela Date: Mon, 21 Jun 2021 00:20:38 +0530 Subject: [PATCH] old lanforge-scripts test Signed-off-by: shivamcandela --- py-json/LANforge/lf_json_autogen.py | 9651 ----------------- py-json/station_profile.py | 54 +- py-scripts/artifacts/CenturyGothic.woff | Bin 70128 -> 0 bytes py-scripts/artifacts/custom-example.css | 11 - py-scripts/artifacts/report.css | 299 - py-scripts/create_station.py | 62 +- py-scripts/ghost_profile.py | 195 - py-scripts/grafana_profile.py | 65 +- py-scripts/lf_dataplane_config.json | 20 - py-scripts/lf_dataplane_test.py | 143 +- py-scripts/lf_report.py | 143 +- py-scripts/sandbox/lf_dataplane_json.py | 334 - py-scripts/sandbox/lf_pdf_search.py | 146 - py-scripts/sandbox/lf_read_json.py | 118 - .../test_ipv4_variable_time2.py | 0 py-scripts/scripts_deprecated/lf_check_jbr.py | 563 - py-scripts/sta_connect2.py | 1 - py-scripts/test_ip_connection.py | 292 - py-scripts/test_ip_variable_time.py | 520 - .../test_ipv4_connection.py | 3 +- .../{scripts_deprecated => }/test_ipv4_l4.py | 2 +- .../test_ipv4_l4_ftp_upload.py | 2 +- .../test_ipv4_l4_ftp_urls_per_ten.py | 2 +- .../test_ipv4_l4_ftp_wifi.py | 2 +- .../test_ipv4_l4_urls_per_ten.py | 2 +- .../test_ipv4_l4_wifi.py | 2 +- py-scripts/test_ipv4_ttls.py | 2 + .../test_ipv4_variable_time.py | 2 +- .../test_ipv6_connection.py | 3 +- .../test_ipv6_variable_time.py | 2 +- py-scripts/test_l3_longevity.py | 70 +- py-scripts/test_l3_powersave_traffic.py | 4 +- py-scripts/test_l4.py | 446 - py-scripts/tools/lf_check.json | 50 - py-scripts/tools/lf_check.py | 510 +- py-scripts/tools/lf_check_config_template.ini | 133 +- py-scripts/tools/lf_header_template.py | 21 - py-scripts/update_dependencies.py | 8 +- 38 files changed, 388 insertions(+), 13495 deletions(-) delete mode 100644 py-json/LANforge/lf_json_autogen.py delete mode 100755 py-scripts/artifacts/CenturyGothic.woff delete mode 100644 py-scripts/artifacts/custom-example.css delete mode 100644 py-scripts/artifacts/report.css delete mode 100755 py-scripts/ghost_profile.py delete mode 100755 py-scripts/lf_dataplane_config.json delete mode 100755 py-scripts/sandbox/lf_dataplane_json.py delete mode 100755 py-scripts/sandbox/lf_pdf_search.py delete mode 100644 py-scripts/sandbox/lf_read_json.py rename py-scripts/{scripts_deprecated => sandbox}/test_ipv4_variable_time2.py (100%) delete mode 100755 py-scripts/scripts_deprecated/lf_check_jbr.py delete mode 100755 py-scripts/test_ip_connection.py delete mode 100644 py-scripts/test_ip_variable_time.py rename py-scripts/{scripts_deprecated => }/test_ipv4_connection.py (98%) rename py-scripts/{scripts_deprecated => }/test_ipv4_l4.py (99%) rename py-scripts/{scripts_deprecated => }/test_ipv4_l4_ftp_upload.py (99%) rename py-scripts/{scripts_deprecated => }/test_ipv4_l4_ftp_urls_per_ten.py (99%) rename py-scripts/{scripts_deprecated => }/test_ipv4_l4_ftp_wifi.py (99%) rename py-scripts/{scripts_deprecated => }/test_ipv4_l4_urls_per_ten.py (99%) rename py-scripts/{scripts_deprecated => }/test_ipv4_l4_wifi.py (99%) rename py-scripts/{scripts_deprecated => }/test_ipv4_variable_time.py (99%) rename py-scripts/{scripts_deprecated => }/test_ipv6_connection.py (98%) rename py-scripts/{scripts_deprecated => }/test_ipv6_variable_time.py (99%) delete mode 100755 py-scripts/test_l4.py delete mode 100644 py-scripts/tools/lf_check.json delete mode 100644 py-scripts/tools/lf_header_template.py diff --git a/py-json/LANforge/lf_json_autogen.py b/py-json/LANforge/lf_json_autogen.py deleted file mode 100644 index 0cd95b6f..00000000 --- a/py-json/LANforge/lf_json_autogen.py +++ /dev/null @@ -1,9651 +0,0 @@ -#!/usr/bin/env python3 -"""----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated by LANforge JsonApiPythonGenerator, Fri Jun 18 14:04:25 PDT 2021 - This file expects to live in py-json/LANforge directory. ------ ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" -import sys -import json -import keyword -from enum import Enum -from LANforge import LFRequest -from LANforge.lfcli_base import LFCliBase -from lfcli_base import LFCliBase - -class LFJsonGet(LFCliBase): - def __init__(self, lfclient_host='localhost', - lfclient_port=8080, - debug_=False, - _exit_on_error=False, - _exit_on_fail=False, - _proxy_str=None, - _capture_signal_list=[] - ): - super().__init__(_lfjson_host=lfclient_host, - _lfjson_port=lfclient_port, - _debug=debug_, - _exit_on_error=_exit_on_error, - _exit_on_fail=_exit_on_fail, - _proxy_str=_proxy_str, - _capture_signal_list=_capture_signal_list) - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Extract fields from this response using the expected keys: - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - def extractValues(self, response=None, singular_key=None, plural_key=None): - if (singular_key is None) or (plural_key is None) or (not singular_key) or (not plural_key): - raise ValueError("extractValues wants non-empty response, singular_key and plural_key") - - if (singular_key in response) and (not response[ singular_key ]): - return [] - elif ( singular_key in response) and ( type(response[ singular_key ]) is dict): - return [ response[ singular_key ] ] - elif ( plural_key in response) and (not response[ plural_key ]): - return [] - else: - return response[ plural_key ] - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /attenuator - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - entity+id entity id - module+1 module 1 - module+2 module 2 - module+3 module 3 - module+4 module 4 - module+5 module 5 - module+6 module 6 - module+7 module 7 - module+8 module 8 - name name - script script - state state - temperature temperature - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_attenuator(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/attenuator" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="attenuator", - plural_key="attenuators") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /chamber - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - chamber chamber - chamber+connections chamber connections - chamber+resources chamber resources - chamber+type chamber type - duts duts - entity+id entity id - flags flags - hide hide - isolation isolation - marked marked - open open - reported+rotation+%28deg%29 reported rotation (deg) - reported+rpm reported rpm - reported+tilt+%28deg%29 reported tilt (deg) - resource resource - rotation+%28deg%29 rotation (deg) - rpm rpm - smas smas - tilt+%28deg%29 tilt (deg) - turntable turntable - turntable+type turntable type - virtual virtual - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_chamber(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/chamber" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="chamber", - plural_key="chambers") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cx - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - avg+rtt avg rtt - bps+rx+a bps rx a - bps+rx+b bps rx b - drop+pkts+a drop pkts a - drop+pkts+b drop pkts b - eid eid - endpoints+%28a%C2%A0%E2%86%94%C2%A0b%29 endpoints (a ↔ b) - entity+id entity id - name name - pkt+rx+a pkt rx a - pkt+rx+b pkt rx b - rpt+timer rpt timer - rx+drop+%25+a rx drop % a - rx+drop+%25+b rx drop % b - state state - type type - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_cx(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/cx" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="", - plural_key="") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /dut - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - api+version api version - bssid-1 bssid-1 - bssid-2 bssid-2 - bssid-3 bssid-3 - bssid-4 bssid-4 - bssid-5 bssid-5 - bssid-6 bssid-6 - bssid-7 bssid-7 - bssid-8 bssid-8 - dut dut - eap-id eap-id - entity+id entity id - hw+info hw info - image+file image file - lan lan - mgt+ip mgt ip - model+number model number - notes notes - num+ant+radio+1 num ant radio 1 - num+ant+radio+2 num ant radio 2 - num+ant+radio+3 num ant radio 3 - password-1 password-1 - password-2 password-2 - password-3 password-3 - password-4 password-4 - password-5 password-5 - password-6 password-6 - password-7 password-7 - password-8 password-8 - serial+number serial number - serial+port serial port - ssid-1 ssid-1 - ssid-2 ssid-2 - ssid-3 ssid-3 - ssid-4 ssid-4 - ssid-5 ssid-5 - ssid-6 ssid-6 - ssid-7 ssid-7 - ssid-8 ssid-8 - sw+info sw info - wan wan - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_dut(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/dut" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="dut", - plural_key="duts") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /endp - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - 1st+rx 1st rx - a%2Fb a/b - bursty bursty - crc+fail crc fail - cwnd cwnd - cx+active cx active - cx+estab cx estab - cx+estab%2Fs cx estab/s - cx+to cx to - delay delay - destination+addr destination addr - dropped dropped - dup+pkts dup pkts - eid eid - elapsed elapsed - entity+id entity id - jitter jitter - max+pdu max pdu - max+rate max rate - min+pdu min pdu - min+rate min rate - mng mng - name name - ooo+pkts ooo pkts - pattern pattern - pdu%2Fs+rx pdu/s rx - pdu%2Fs+tx pdu/s tx - pps+rx+ll pps rx ll - pps+tx+ll pps tx ll - rcv+buf rcv buf - replays replays - run run - rx+ber rx ber - rx+bytes rx bytes - rx+drop+%25 rx drop % - rx+dup+%25 rx dup % - rx+ooo+%25 rx ooo % - rx+pdus rx pdus - rx+pkts+ll rx pkts ll - rx+rate rx rate - rx+rate+%281%C2%A0min%29 rx rate (1 min) - rx+rate+%28last%29 rx rate (last) - rx+rate+ll rx rate ll - rx+wrong+dev rx wrong dev - script script - send+buf send buf - source+addr source addr - tcp+mss tcp mss - tcp+rtx tcp rtx - tx+bytes tx bytes - tx+pdus tx pdus - tx+pkts+ll tx pkts ll - tx+rate tx rate - tx+rate+%281%C2%A0min%29 tx rate (1 min) - tx+rate+%28last%29 tx rate (last) - tx+rate+ll tx rate ll - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_endp(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/endp" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="endpoint", - plural_key="endpoint") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /events - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - eid eid - entity+id entity id - event event - event+description event description - id id - name name - priority priority - time-stamp time-stamp - type type - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_events(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/events" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="alert", - plural_key="alerts") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /fileio - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - buf-rd buf-rd - buf-wr buf-wr - bytes-rd bytes-rd - bytes-wr bytes-wr - crc+fail crc fail - eid eid - entity+id entity id - files+%23 files # - files-read files-read - files-wr files-wr - io+fail io fail - max-file-sz max-file-sz - max-rd-bps max-rd-bps - max-rw-sz max-rw-sz - max-wr-bps max-wr-bps - min-file-sz min-file-sz - min-rd-bps min-rd-bps - min-rw-sz min-rw-sz - min-wr-bps min-wr-bps - name name - read-bps read-bps - rpt+timer rpt timer - rx-bps-20s rx-bps-20s - status status - tx-bps-20s tx-bps-20s - type type - write-bps write-bps - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_fileio(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/fileio" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="endpoint", - plural_key="endpoint") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /generic - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - bps+rx bps rx - bps+tx bps tx - command command - dropped dropped - eid eid - elapsed elapsed - entity+id entity id - last+results last results - name name - pdu%2Fs+rx pdu/s rx - pdu%2Fs+tx pdu/s tx - rpt+timer rpt timer - rpt%23 rpt# - rx+bytes rx bytes - rx+pkts rx pkts - status status - tx+bytes tx bytes - tx+pkts tx pkts - type type - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_generic(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/generic" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="endpoint", - plural_key="endpoints") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /gui-cli - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - na na - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_gui_cli(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/gui-cli" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="", - plural_key="") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /layer4 - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - %21conn !conn - acc.+denied acc. denied - bad-proto bad-proto - bad-url bad-url - bytes-rd bytes-rd - bytes-wr bytes-wr - dns-avg dns-avg - dns-max dns-max - dns-min dns-min - eid eid - elapsed elapsed - entity+id entity id - fb-avg fb-avg - fb-max fb-max - fb-min fb-min - ftp-host ftp-host - ftp-port ftp-port - ftp-stor ftp-stor - http-p http-p - http-r http-r - http-t http-t - login-denied login-denied - name name - nf+%284xx%29 nf (4xx) - other-err other-err - read read - redir redir - rpt+timer rpt timer - rslv-h rslv-h - rslv-p rslv-p - rx+rate rx rate - rx+rate+%281%C2%A0min%29 rx rate (1 min) - status status - timeout timeout - total-err total-err - total-urls total-urls - tx+rate tx rate - tx+rate+%281%C2%A0min%29 tx rate (1 min) - type type - uc-avg uc-avg - uc-max uc-max - uc-min uc-min - urls%2Fs urls/s - write write - - # hidden columns: - rpt-time rpt-time - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_layer4(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/layer4" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="endpoint", - plural_key="endpoint") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /port - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - 4way+time+%28us%29 4way time (us) - activity activity - alias alias - anqp+time+%28us%29 anqp time (us) - ap ap - beacon beacon - bps+rx bps rx - bps+rx+ll bps rx ll - bps+tx bps tx - bps+tx+ll bps tx ll - bytes+rx+ll bytes rx ll - bytes+tx+ll bytes tx ll - channel channel - collisions collisions - connections connections - crypt crypt - cx+ago cx ago - cx+time+%28us%29 cx time (us) - device device - dhcp+%28ms%29 dhcp (ms) - down down - entity+id entity id - gateway+ip gateway ip - ip ip - ipv6+address ipv6 address - ipv6+gateway ipv6 gateway - key%2Fphrase key/phrase - login-fail login-fail - login-ok login-ok - logout-fail logout-fail - logout-ok logout-ok - mac mac - mask mask - misc misc - mode mode - mtu mtu - no+cx+%28us%29 no cx (us) - noise noise - parent+dev parent dev - phantom phantom - port port - port+type port type - pps+rx pps rx - pps+tx pps tx - qlen qlen - reset reset - retry+failed retry failed - rx+bytes rx bytes - rx+crc rx crc - rx+drop rx drop - rx+errors rx errors - rx+fifo rx fifo - rx+frame rx frame - rx+length rx length - rx+miss rx miss - rx+over rx over - rx+pkts rx pkts - rx-rate rx-rate - sec sec - signal signal - ssid ssid - status status - time-stamp time-stamp - tx+abort tx abort - tx+bytes tx bytes - tx+crr tx crr - tx+errors tx errors - tx+fifo tx fifo - tx+hb tx hb - tx+pkts tx pkts - tx+wind tx wind - tx-failed+%25 tx-failed % - tx-rate tx-rate - wifi+retries wifi retries - - # hidden columns: - beacon_rx_signal beacon_rx_signal - port_cur_flags_h port_cur_flags_h - port_cur_flags_l port_cur_flags_l - port_supported_flags_h port_supported_flags_h - port_supported_flags_l port_supported_flags_l - resource resource - rx_multicast rx_multicast - tx_dropped tx_dropped - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_port(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/port" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="interface", - plural_key="interfaces") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /radiostatus - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - _links _links - antenna antenna - ap ap - capabilities capabilities - channel channel - country country - driver driver - entity+id entity id - entity+id entity id - frag frag - frequency frequency - max_sta max_sta - max_vap max_vap - max_vifs max_vifs - monitors_up monitors_up - monitors_up monitors_up - phantom phantom - port port - resource resource - rts rts - stations_down stations_down - stations_up stations_up - tx-power tx-power - vaps_down vaps_down - vaps_up vaps_up - verbose+debug verbose debug - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_radiostatus(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/radiostatus" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="radio", - plural_key="radios") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /resource - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - bps-rx-3s bps-rx-3s - bps-tx-3s bps-tx-3s - cli-port cli-port - cpu cpu - ctrl-ip ctrl-ip - ctrl-port ctrl-port - eid eid - entity+id entity id - free+mem free mem - free+swap free swap - gps gps - hostname hostname - hw+version hw version - load load - max+if-up max if-up - max+staged max staged - mem mem - phantom phantom - ports ports - rx+bytes rx bytes - shelf shelf - sta+up sta up - sw+version sw version - swap swap - tx+bytes tx bytes - - # hidden columns: - timestamp timestamp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_resource(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/resource" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="resource", - plural_key="resources") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /scan - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - na na - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_scan(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/scan" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="scan-results", - plural_key="scan-results") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /stations - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - ap ap - auth-for auth-for - capabilities capabilities - entity+id entity id - idle idle - roam-duration roam-duration - rx+bytes rx bytes - rx+pkts rx pkts - rx+rate rx rate - signal signal - station+bssid station bssid - tx+bytes tx bytes - tx+pkts tx pkts - tx+rate tx rate - tx+retries tx retries - tx-failed tx-failed - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_stations(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/stations" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="station", - plural_key="stations") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /status-msg - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - na na - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_status_msg(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/status-msg" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="sessions/messages", - plural_key="sessions/messages") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /test-group - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - cross+connects cross connects - entity+id entity id - name name - run run - script script - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_test_group(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/test-group" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="groups", - plural_key="groups") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /text - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - eid eid - name name - text text - type type - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_text(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/text" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="record", - plural_key="records") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /voip - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - bps+rx+a bps rx a - bps+rx+b bps rx b - delay+a+%E2%86%90+b delay a ← b - delay+a+%E2%86%92+b delay a → b - eid eid - endpoints+%28a%C2%A0%E2%86%94%C2%A0b%29 endpoints (a ↔ b) - entity+id entity id - jitter+a+%E2%86%90+b jitter a ← b - jitter+a+%E2%86%92+b jitter a → b - name name - pkt+tx+a%C2%A0%E2%86%90%C2%A0b pkt tx a ← b - pkt+tx+a%C2%A0%E2%86%92%C2%A0b pkt tx a → b - rpt+timer rpt timer - rx+drop+%25+a rx drop % a - rx+drop+%25+b rx drop % b - state state - type type - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_voip(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/voip" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="connection", - plural_key="connections") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /voip-endp - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - calls+answered calls answered - calls+attempted calls attempted - calls+completed calls completed - calls+failed calls failed - cf+404 cf 404 - cf+408 cf 408 - cf+busy cf busy - cf+canceled cf canceled - delay delay - destination+addr destination addr - dropped dropped - dup+pkts dup pkts - eid eid - elapsed elapsed - entity+id entity id - jb+cur jb cur - jb+over jb over - jb+silence jb silence - jb+under jb under - jitter jitter - mng mng - name name - ooo+pkts ooo pkts - pesq pesq - pesq+bklg pesq bklg - pesq%23 pesq# - reg+state reg state - rst rst - rtp+rtt rtp rtt - run run - rx+bytes rx bytes - rx+pkts rx pkts - source+addr source addr - state state - tx+bytes tx bytes - tx+pkts tx pkts - vad+pkts vad pkts - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_voip_endp(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/voip-endp" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="endpoint", - plural_key="endpoints") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /vr - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - active+ipv6+router active ipv6 router - bgp+4byte+as bgp 4byte as - bgp+damping bgp damping - bgp+peers bgp peers - cluster+id cluster id - collision+domain+id collision domain id - confederation+id confederation id - damping+half+life damping half life - damping+max+suppress damping max suppress - damping+reuse damping reuse - damping+suppress damping suppress - entity+id entity id - height height - ipv6+radv ipv6 radv - is+bgp+reflector is bgp reflector - local+as local as - multicast+routing multicast routing - name name - netsmith-state netsmith-state - notes notes - pad pad - ripv2 ripv2 - router+connections router connections - router+id router id - router+id router id - use+confederation use confederation - use+existing+cfg use existing cfg - use+ospf use ospf - use+rip+dft+route use rip dft route - using+bgp using bgp - using+olsr using olsr - width width - x x - xorp+sha xorp sha - y y - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_vr(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/vr" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="virtual-routers", - plural_key="virtual-routers") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /vrcx - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - entity+id entity id - height height - interface+cost interface cost - local-a local-a - local-b local-b - netsmith-state netsmith-state - remote-a remote-a - remote-b remote-b - resource resource - rip+metric rip metric - vrrp+id vrrp id - vrrp+interval vrrp interval - vrrp+ip vrrp ip - vrrp+ip-prefix vrrp ip-prefix - vrrp+priority vrrp priority - wan+link wan link - width width - x x - y y - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_vrcx(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/vrcx" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="router-connections", - plural_key="router-connections") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /wl - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - bps+rx+a bps rx a - bps+rx+b bps rx b - eid eid - endpoints+%28a%C2%A0%E2%86%94%C2%A0b%29 endpoints (a ↔ b) - entity+id entity id - k-m k-m - name name - pkt+tx+a%C2%A0%E2%86%90%C2%A0b pkt tx a ← b - pkt+tx+a%C2%A0%E2%86%92%C2%A0b pkt tx a → b - rpt+timer rpt timer - state state - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_wl(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/wl" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="", - plural_key="") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /wl-endp - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - buffer buffer - corrupt+1 corrupt 1 - corrupt+2 corrupt 2 - corrupt+3 corrupt 3 - corrupt+4 corrupt 4 - corrupt+5 corrupt 5 - corrupt+6 corrupt 6 - delay delay - dropfreq+%25 dropfreq % - dropped dropped - dup+pkts dup pkts - dupfreq+%25 dupfreq % - eid eid - elapsed elapsed - extrabuf extrabuf - failed-late failed-late - jitfreq+%25 jitfreq % - max+rate max rate - maxjitter maxjitter - maxlate maxlate - name name - ooo+pkts ooo pkts - qdisc qdisc - reordfrq+%25 reordfrq % - run run - rx+bytes rx bytes - rx+pkts rx pkts - script script - serdelay serdelay - tx+bytes tx bytes - tx+drop+%25 tx drop % - tx+pkts tx pkts - tx+rate tx rate - tx-failed tx-failed - wps wps - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_wl_endp(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/wl-endp" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="endpoint", - plural_key="endpoint") - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /ws-msg - - URL Encoded Column Names JSON keys - use these in a URL use these to get value - ------------------ ---------------------- - na na - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def get_ws_msg(self, - fields=[], - debug_=False): - debug_ |= self.debug - url = "/ws-msg" - if (fields is not None) and (type(fields) is not list): - raise ValueError("fields must be a None or a list") - - if (fields is not None) and (len(fields) > 0): - for field in fields: - if field.index(" ") > -1 : - raise ValueError("field should be URL encoded: [%s]" % (field)) - url += "?fields=%s" % (",".join(fields)) - response = self.json_get(url, debug_=debug_) - if response is None: - return None - return self.extractValues(response=response, - singular_key="", - plural_key="") - -"""----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - - These are POST requests - ------ ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - -class LFJsonPost(LFCliBase): - def __init__(self, lfclient_host='localhost', - lfclient_port=8080, - debug_=False, - _exit_on_error=False, - _exit_on_fail=False, - _proxy_str=None, - _capture_signal_list=[] - ): - super().__init__(_lfjson_host=lfclient_host, - _lfjson_port=lfclient_port, - _debug=debug_, - _exit_on_error=_exit_on_error, - _exit_on_fail=_exit_on_fail, - _proxy_str=_proxy_str, - _capture_signal_list=_capture_signal_list) - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_arm_endp - - https://www.candelatech.com/lfcli_ug.php#add_arm_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_arm_endp(self, - alias=None, - cpu_id=None, - mx_pkt_sz=None, - pkt_sz=None, - port=None, - pps=None, - resource=None, - shelf=None, - tos=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "cpu_id" : cpu_id, - "mx_pkt_sz" : mx_pkt_sz, - "pkt_sz" : pkt_sz, - "port" : port, - "pps" : pps, - "resource" : resource, - "shelf" : shelf, - "tos" : tos, - "type" : type, - } - response = self.json_post("/cli-json/add_arm_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_bgp_peer - - https://www.candelatech.com/lfcli_ug.php#add_bgp_peer - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_bgp_peer_flags(Enum): - ENABLE_PEER = 1 # Set this to zero if you don't want this peer enabled. - PEER_CLIENT = 2 # Sets corresponding Xorp flag in BGP Peer section. - PEER_CONFED_MEMBER = 4 # Sets corresponding Xorp flag in BGP Peer section. - PEER_UNICAST_V4 = 8 # Sets corresponding Xorp flag in BGP Peer section. - - - def post_add_bgp_peer(self, - p_as=None, - delay_open_time=None, - flags=None, - holdtime=None, - local_dev=None, - nexthop=None, - nexthop6=None, - peer_id=None, - peer_index=None, - resource=None, - shelf=None, - vr_id=None, - debug_=False): - debug_ |= self.debug - data = { - "as" : p_as, - "delay_open_time" : delay_open_time, - "flags" : flags, - "holdtime" : holdtime, - "local_dev" : local_dev, - "nexthop" : nexthop, - "nexthop6" : nexthop6, - "peer_id" : peer_id, - "peer_index" : peer_index, - "resource" : resource, - "shelf" : shelf, - "vr_id" : vr_id, - } - response = self.json_post("/cli-json/add_bgp_peer", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_bond - - https://www.candelatech.com/lfcli_ug.php#add_bond - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_bond(self, - network_devs=None, - port=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "network_devs" : network_devs, - "port" : port, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/add_bond", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_br - - https://www.candelatech.com/lfcli_ug.php#add_br - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_br_br_flags(Enum): - none = 0 # no features - stp_enabled = 1 # Enable Spanning Tree Protocol (STP) - - - def post_add_br(self, - br_aging_time=None, - br_flags=None, - br_forwarding_delay=None, - br_hello_time=None, - br_max_age=None, - br_priority=None, - network_devs=None, - port=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "br_aging_time" : br_aging_time, - "br_flags" : br_flags, - "br_forwarding_delay" : br_forwarding_delay, - "br_hello_time" : br_hello_time, - "br_max_age" : br_max_age, - "br_priority" : br_priority, - "network_devs" : network_devs, - "port" : port, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/add_br", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_cd - - https://www.candelatech.com/lfcli_ug.php#add_cd - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_cd_flags(Enum): - ERR = 2 # Set to kernel mode. - RUNNING = 1 # Set to running state. - - - def post_add_cd(self, - alias=None, - bps=None, - flags=None, - report_timer=None, - resource=None, - shelf=None, - state=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "bps" : bps, - "flags" : flags, - "report_timer" : report_timer, - "resource" : resource, - "shelf" : shelf, - "state" : state, - "type" : type, - } - response = self.json_post("/cli-json/add_cd", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_cd_endp - - https://www.candelatech.com/lfcli_ug.php#add_cd_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_cd_endp(self, - cd=None, - endp=None, - debug_=False): - debug_ |= self.debug - data = { - "cd" : cd, - "endp" : endp, - } - response = self.json_post("/cli-json/add_cd_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_cd_vr - - https://www.candelatech.com/lfcli_ug.php#add_cd_vr - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_cd_vr(self, - cd=None, - vr=None, - debug_=False): - debug_ |= self.debug - data = { - "cd" : cd, - "vr" : vr, - } - response = self.json_post("/cli-json/add_cd_vr", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_chamber - - https://www.candelatech.com/lfcli_ug.php#add_chamber - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_chamber_chamber_flags(Enum): - OPEN = 4 # (3) Door is open, no real isolation right now. - PHANTOM = 1 # (1) Chamber is not actually here right now. - VIRTUAL = 2 # (2) No real chamber, open-air grouping of equipment. - - - def post_add_chamber(self, - chamber_type=None, - dut_name1=None, - dut_name2=None, - dut_name3=None, - dut_name4=None, - flags=None, - flags_mask=None, - height=None, - isolation=None, - lanforge1=None, - lanforge2=None, - lanforge3=None, - lanforge4=None, - name=None, - resource=None, - sma_count=None, - turntable_type=None, - width=None, - x=None, - y=None, - debug_=False): - debug_ |= self.debug - data = { - "chamber_type" : chamber_type, - "dut_name1" : dut_name1, - "dut_name2" : dut_name2, - "dut_name3" : dut_name3, - "dut_name4" : dut_name4, - "flags" : flags, - "flags_mask" : flags_mask, - "height" : height, - "isolation" : isolation, - "lanforge1" : lanforge1, - "lanforge2" : lanforge2, - "lanforge3" : lanforge3, - "lanforge4" : lanforge4, - "name" : name, - "resource" : resource, - "sma_count" : sma_count, - "turntable_type" : turntable_type, - "width" : width, - "x" : x, - "y" : y, - } - response = self.json_post("/cli-json/add_chamber", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_chamber_cx - - https://www.candelatech.com/lfcli_ug.php#add_chamber_cx - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_chamber_cx_chamber_cx_flags(Enum): - CONNECTED = 1 # (1) Connected to something. If flag is not set, connection is open to the air (maybe with antenna) - TERMINATED = 2 # (2) Connection is terminated, signal shall not pass! - - - def post_add_chamber_cx(self, - a_id=None, - atten_id=None, - b_id=None, - connection_idx=None, - flags=None, - flags_mask=None, - internal=None, - min_atten=None, - name=None, - zrssi2=None, - zrssi5=None, - debug_=False): - debug_ |= self.debug - data = { - "a_id" : a_id, - "atten_id" : atten_id, - "b_id" : b_id, - "connection_idx" : connection_idx, - "flags" : flags, - "flags_mask" : flags_mask, - "internal" : internal, - "min_atten" : min_atten, - "name" : name, - "zrssi2" : zrssi2, - "zrssi5" : zrssi5, - } - response = self.json_post("/cli-json/add_chamber_cx", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_chamber_path - - https://www.candelatech.com/lfcli_ug.php#add_chamber_path - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_chamber_path(self, - chamber=None, - content=None, - path=None, - debug_=False): - debug_ |= self.debug - data = { - "chamber" : chamber, - "content" : content, - "path" : path, - } - response = self.json_post("/cli-json/add_chamber_path", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_channel_group - - https://www.candelatech.com/lfcli_ug.php#add_channel_group - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_channel_group_types(Enum): - clear = 0 # Channel(s) are bundled into a single span. No conversion or - e_m = 0 # Channel(s) are signalled using E&M signalling (specific - fcshdlc = 0 # The zapdel driver performs HDLC encoding and decoding on the - fxogs = 0 # Channel(s) are signalled using FXO Groundstart protocol. - fxoks = 0 # Channel(s) are signalled using FXO Koolstart protocol. - fxols = 0 # Channel(s) are signalled using FXO Loopstart protocol. - fxsgs = 0 # Channel(s) are signalled using FXS Groundstart protocol. - fxsks = 0 # Channel(s) are signalled using FXS Koolstart protocol. - fxsls = 0 # Channel(s) are signalled using FXS Loopstart protocol. - indclear = 0 # Like 'clear' except all channels are treated individually and - nethdlc = 0 # The zaptel driver bundles the channels together into an - rawhdlc = 0 # The zaptel driver performs HDLC encoding and decoding on the - unused = 0 # No signalling is performed, each channel in the list remains idle - - - def post_add_channel_group(self, - alias=None, - channels=None, - idle_flag=None, - mtu=None, - resource=None, - shelf=None, - span_num=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "channels" : channels, - "idle_flag" : idle_flag, - "mtu" : mtu, - "resource" : resource, - "shelf" : shelf, - "span_num" : span_num, - "type" : type, - } - response = self.json_post("/cli-json/add_channel_group", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_cx - - https://www.candelatech.com/lfcli_ug.php#add_cx - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_cx(self, - alias=None, - rx_endp=None, - test_mgr=None, - tx_endp=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "rx_endp" : rx_endp, - "test_mgr" : test_mgr, - "tx_endp" : tx_endp, - } - response = self.json_post("/cli-json/add_cx", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_dut - - https://www.candelatech.com/lfcli_ug.php#add_dut - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_dut_dut_flags(Enum): - p_11r = 512 # Use .11r connection logic on all ssids, deprecated, see add_dut_ssid. - AP_MODE = 2 # (2) DUT acts as AP. - DHCPD_LAN = 64 # Provides DHCP server on LAN port - DHCPD_WAN = 128 # Provides DHCP server on WAN port - EAP_PEAP = 2048 # Use EAP-PEAP connection logic on all ssids, deprecated, see add_dut_ssid. - EAP_TTLS = 1024 # Use EAP-TTLS connection logic on all ssids, deprecated, see add_dut_ssid. - INACTIVE = 4 # (3) Ignore this in ChamberView, etc - NOT_DHCPCD = 4096 # Station/edge device that is NOT using DHCP. - STA_MODE = 1 # (1) DUT acts as Station. - WEP = 8 # Use WEP encryption on all ssids, deprecated, see add_dut_ssid. - WPA = 16 # Use WPA encryption on all ssids, deprecated, see add_dut_ssid. - WPA2 = 32 # Use WPA2 encryption on all ssids, deprecated, see add_dut_ssid. - WPA3 = 256 # Use WPA3 encryption on all ssids, deprecated, see add_dut_extras. - - - def post_add_dut(self, - antenna_count1=None, - antenna_count2=None, - antenna_count3=None, - api_id=None, - bssid1=None, - bssid2=None, - bssid3=None, - eap_id=None, - flags=None, - flags_mask=None, - hw_version=None, - img_file=None, - lan_port=None, - mgt_ip=None, - model_num=None, - name=None, - passwd1=None, - passwd2=None, - passwd3=None, - serial_num=None, - serial_port=None, - ssid1=None, - ssid2=None, - ssid3=None, - sw_version=None, - top_left_x=None, - top_left_y=None, - wan_port=None, - debug_=False): - debug_ |= self.debug - data = { - "antenna_count1" : antenna_count1, - "antenna_count2" : antenna_count2, - "antenna_count3" : antenna_count3, - "api_id" : api_id, - "bssid1" : bssid1, - "bssid2" : bssid2, - "bssid3" : bssid3, - "eap_id" : eap_id, - "flags" : flags, - "flags_mask" : flags_mask, - "hw_version" : hw_version, - "img_file" : img_file, - "lan_port" : lan_port, - "mgt_ip" : mgt_ip, - "model_num" : model_num, - "name" : name, - "passwd1" : passwd1, - "passwd2" : passwd2, - "passwd3" : passwd3, - "serial_num" : serial_num, - "serial_port" : serial_port, - "ssid1" : ssid1, - "ssid2" : ssid2, - "ssid3" : ssid3, - "sw_version" : sw_version, - "top_left_x" : top_left_x, - "top_left_y" : top_left_y, - "wan_port" : wan_port, - } - response = self.json_post("/cli-json/add_dut", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_dut_notes - - https://www.candelatech.com/lfcli_ug.php#add_dut_notes - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_dut_notes(self, - dut=None, - text=None, - debug_=False): - debug_ |= self.debug - data = { - "dut" : dut, - "text" : text, - } - response = self.json_post("/cli-json/add_dut_notes", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_dut_ssid - - https://www.candelatech.com/lfcli_ug.php#add_dut_ssid - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_dut_ssid_dut_flags(Enum): - p_11r = 512 # Use .11r connection logic - EAP_PEAP = 2048 # Use EAP-PEAP connection logic - EAP_TTLS = 1024 # Use EAP-TTLS connection logic - WEP = 8 # Use WEP encryption - WPA = 16 # Use WPA encryption - WPA2 = 32 # Use WPA2 encryption - WPA3 = 256 # Use WPA3 encryption - - - def post_add_dut_ssid(self, - bssid=None, - name=None, - passwd=None, - ssid=None, - ssid_flags=None, - ssid_flags_mask=None, - ssid_idx=None, - debug_=False): - debug_ |= self.debug - data = { - "bssid" : bssid, - "name" : name, - "passwd" : passwd, - "ssid" : ssid, - "ssid_flags" : ssid_flags, - "ssid_flags_mask" : ssid_flags_mask, - "ssid_idx" : ssid_idx, - } - response = self.json_post("/cli-json/add_dut_ssid", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_endp - - https://www.candelatech.com/lfcli_ug.php#add_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_endp_payload_pattern(Enum): - PRBS_11_8_10 = 0 # PRBS (see above) - PRBS_15_0_14 = 0 # PRBS (see above) - PRBS_4_0_3 = 0 # Use linear feedback shift register to generate pseudo random sequence. - PRBS_7_0_6 = 0 # PRBS (see above) - custom = 0 # Enter your own payload with the set_endp_payload cmd. - decreasing = 0 # bytes start at FF and decrease, wrapping if needed - increasing = 0 # bytes start at 00 and increase, wrapping if needed - ones = 0 # payload is all ones (FF) - random = 0 # generate a new random payload each time sent - random_fixed = 0 # means generate one random payload, and send it over and over again. - zeros = 0 # payload is all zeros (00) - - class add_endp_type(Enum): - custom_ether = 0 # LF frames with custom options, use with playback - custom_mc_udp = 0 # LF Multicast UDP IPv4 - custom_tcp = 0 # LF TCP IPv4 frame with custom options - custom_udp = 0 # LF UDP IPv4 frame with custom options - lf = 0 # LF protocol - lf_sctp = 0 # SCTP IPv4 protocol - lf_sctp6 = 0 # SCTP IPv6 protocol - lf_tcp = 0 # TCP IPv4 connection - lf_tcp6 = 0 # TCP IPv6 connection - lf_udp = 0 # UDP IPv4 connection - lf_udp6 = 0 # UDP IPv6 connection - mc_udp = 0 # LF Multicast IPv4 - - - def post_add_endp(self, - alias=None, - ip_port=None, - is_pkt_sz_random=None, - is_rate_bursty=None, - max_pkt=None, - max_rate=None, - min_pkt=None, - min_rate=None, - multi_conn=None, - payload_pattern=None, - port=None, - resource=None, - send_bad_crc_per_million=None, - shelf=None, - ttl=None, - type=None, - use_checksum=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "ip_port" : ip_port, - "is_pkt_sz_random" : is_pkt_sz_random, - "is_rate_bursty" : is_rate_bursty, - "max_pkt" : max_pkt, - "max_rate" : max_rate, - "min_pkt" : min_pkt, - "min_rate" : min_rate, - "multi_conn" : multi_conn, - "payload_pattern" : payload_pattern, - "port" : port, - "resource" : resource, - "send_bad_crc_per_million" : send_bad_crc_per_million, - "shelf" : shelf, - "ttl" : ttl, - "type" : type, - "use_checksum" : use_checksum, - } - response = self.json_post("/cli-json/add_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_event - - https://www.candelatech.com/lfcli_ug.php#add_event - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_event(self, - details=None, - event_id=None, - name=None, - priority=None, - debug_=False): - debug_ |= self.debug - data = { - "details" : details, - "event_id" : event_id, - "name" : name, - "priority" : priority, - } - response = self.json_post("/cli-json/add_event", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_file_endp - - https://www.candelatech.com/lfcli_ug.php#add_file_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_file_endp_fio_flags(Enum): - AUTO_MOUNT = 2 # (2) Attempt to mount with the provided information if not already mounted. - AUTO_UNMOUNT = 4 # (4) Attempt to un-mount when stopping test. - CHECK_MOUNT = 1 # (1) Attempt to verify NFS and SMB mounts match the configured values. - O_APPEND = 512 # (512) Open files for writing with O_APPEND instead - O_DIRECT = 8 # (8) Open file with O_DIRECT flag, disables caching. Must use block-size read/write calls. - O_LARGEFILE = 32 # (32) Open files with O_LARGEFILE. This allows greater than 2GB files on 32-bit systems. - UNLINK_BW = 16 # (16) Unlink file before writing. This works around issues with CIFS for some file-servers. - UNMOUNT_FORCE = 64 # (64) Use -f flag when calling umount - UNMOUNT_LAZY = 128 # (128) Use -l flag when calling umount - USE_FSTATFS = 256 # (256) Use fstatfs system call to verify file-system type when opening files. - - class add_file_endp_payload_pattern(Enum): - PRBS_11_8_10 = 0 # PRBS (see above) - PRBS_15_0_14 = 0 # PRBS (see above) - PRBS_4_0_3 = 0 # Use linear feedback shift register to generate pseudo random sequence. - PRBS_7_0_6 = 0 # PRBS (see above) - custom = 0 # Enter your own payload with the set_endp_payload cmd. - decreasing = 0 # bytes start at FF and decrease, wrapping if needed. - increasing = 0 # bytes start at 00 and increase, wrapping if needed. - ones = 0 # Payload is all ones (FF). - random = 0 # generate a new random payload each time sent. - random_fixed = 0 # Means generate one random payload, and send it over - zeros = 0 # Payload is all zeros (00). - - - def post_add_file_endp(self, - alias=None, - directory=None, - fio_flags=None, - max_read_rate=None, - max_write_rate=None, - min_read_rate=None, - min_write_rate=None, - mount_dir=None, - mount_options=None, - payload_pattern=None, - port=None, - prefix=None, - resource=None, - retry_timer=None, - server_mount=None, - shelf=None, - type=None, - volume=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "directory" : directory, - "fio_flags" : fio_flags, - "max_read_rate" : max_read_rate, - "max_write_rate" : max_write_rate, - "min_read_rate" : min_read_rate, - "min_write_rate" : min_write_rate, - "mount_dir" : mount_dir, - "mount_options" : mount_options, - "payload_pattern" : payload_pattern, - "port" : port, - "prefix" : prefix, - "resource" : resource, - "retry_timer" : retry_timer, - "server_mount" : server_mount, - "shelf" : shelf, - "type" : type, - "volume" : volume, - } - response = self.json_post("/cli-json/add_file_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_gen_endp - - https://www.candelatech.com/lfcli_ug.php#add_gen_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_gen_endp(self, - alias=None, - port=None, - resource=None, - shelf=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "port" : port, - "resource" : resource, - "shelf" : shelf, - "type" : type, - } - response = self.json_post("/cli-json/add_gen_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_gre - - https://www.candelatech.com/lfcli_ug.php#add_gre - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_gre(self, - local_lower_ip=None, - port=None, - remote_lower_ip=None, - report_timer=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "local_lower_ip" : local_lower_ip, - "port" : port, - "remote_lower_ip" : remote_lower_ip, - "report_timer" : report_timer, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/add_gre", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_group - - https://www.candelatech.com/lfcli_ug.php#add_group - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_group_flags(Enum): - group_total_rates = 4 # Set rates as total for group. - - - def post_add_group(self, - flags=None, - flags_mask=None, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "flags" : flags, - "flags_mask" : flags_mask, - "name" : name, - } - response = self.json_post("/cli-json/add_group", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_l4_endp - - https://www.candelatech.com/lfcli_ug.php#add_l4_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_l4_endp_http_auth_type(Enum): - BASIC = 1 # Basic authentication - DIGEST = 2 # Digest (MD5) authentication - GSSNEGOTIATE = 4 # GSS authentication - NTLM = 8 # NTLM authentication - - class add_l4_endp_proxy_auth_type(Enum): - BASIC = 1 # 1 Basic authentication - BIND_DNS = 512 # 512 Make DNS requests go out endpoints Port. - DIGEST = 2 # 2 Digest (MD5) authentication - DISABLE_EPSV = 4096 # 4096 Disable FTP EPSV option - DISABLE_PASV = 2048 # 2048 Disable FTP PASV option (will use PORT command) - GSSNEGOTIATE = 4 # 4 GSS authentication - INCLUDE_HEADERS = 256 # 256 especially for IMAP - NTLM = 8 # 8 NTLM authentication - USE_DEFLATE_COMPRESSION = 128 # 128 Use deflate compression - USE_GZIP_COMPRESSION = 64 # 64 Use gzip compression - USE_IPV6 = 1024 # 1024 Resolve URL is IPv6. Will use IPv4 if not selected. - USE_PROXY_CACHE = 32 # 32 Use proxy cache - - class add_l4_endp_type(Enum): - l4_generic = 0 # Layer 4 type - - - def post_add_l4_endp(self, - alias=None, - block_size=None, - dns_cache_timeout=None, - http_auth_type=None, - ip_addr=None, - max_speed=None, - port=None, - proxy_auth_type=None, - proxy_port=None, - proxy_server=None, - proxy_userpwd=None, - quiesce_after=None, - resource=None, - shelf=None, - smtp_from=None, - ssl_cert_fname=None, - timeout=None, - type=None, - url=None, - url_rate=None, - user_agent=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "block_size" : block_size, - "dns_cache_timeout" : dns_cache_timeout, - "http_auth_type" : http_auth_type, - "ip_addr" : ip_addr, - "max_speed" : max_speed, - "port" : port, - "proxy_auth_type" : proxy_auth_type, - "proxy_port" : proxy_port, - "proxy_server" : proxy_server, - "proxy_userpwd" : proxy_userpwd, - "quiesce_after" : quiesce_after, - "resource" : resource, - "shelf" : shelf, - "smtp_from" : smtp_from, - "ssl_cert_fname" : ssl_cert_fname, - "timeout" : timeout, - "type" : type, - "url" : url, - "url_rate" : url_rate, - "user_agent" : user_agent, - } - response = self.json_post("/cli-json/add_l4_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_monitor - - https://www.candelatech.com/lfcli_ug.php#add_monitor - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_monitor_flags(Enum): - disable_ht40 = 2048 # Disable HT-40 even if hardware and AP support it. - disable_ht80 = 134217728 # Disable HT80 (for AC chipset NICs only) - ht160_enable = 4294967296 # Enable HT160 mode. - - - def post_add_monitor(self, - aid=None, - ap_name=None, - bssid=None, - flags=None, - flags_mask=None, - radio=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "aid" : aid, - "ap_name" : ap_name, - "bssid" : bssid, - "flags" : flags, - "flags_mask" : flags_mask, - "radio" : radio, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/add_monitor", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_mvlan - - https://www.candelatech.com/lfcli_ug.php#add_mvlan - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_mvlan(self, - flags=None, - index=None, - mac=None, - old_name=None, - port=None, - report_timer=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "flags" : flags, - "index" : index, - "mac" : mac, - "old_name" : old_name, - "port" : port, - "report_timer" : report_timer, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/add_mvlan", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_ppp_link - - https://www.candelatech.com/lfcli_ug.php#add_ppp_link - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_ppp_link(self, - auth=None, - channel_groups=None, - debug=None, - down_time_max_ms=None, - down_time_min_ms=None, - dst_ip=None, - extra_args=None, - holdoff=None, - lcp_echo_failure=None, - lcp_echo_interval=None, - mlppp_descriptor=None, - persist=None, - pppoe_transport_port=None, - resource=None, - run_time_max_ms=None, - run_time_min_ms=None, - shelf=None, - src_ip=None, - transport_type=None, - tty_transport_device=None, - unit=None, - debug_=False): - debug_ |= self.debug - data = { - "auth" : auth, - "channel_groups" : channel_groups, - "debug" : debug, - "down_time_max_ms" : down_time_max_ms, - "down_time_min_ms" : down_time_min_ms, - "dst_ip" : dst_ip, - "extra_args" : extra_args, - "holdoff" : holdoff, - "lcp_echo_failure" : lcp_echo_failure, - "lcp_echo_interval" : lcp_echo_interval, - "mlppp_descriptor" : mlppp_descriptor, - "persist" : persist, - "pppoe_transport_port" : pppoe_transport_port, - "resource" : resource, - "run_time_max_ms" : run_time_max_ms, - "run_time_min_ms" : run_time_min_ms, - "shelf" : shelf, - "src_ip" : src_ip, - "transport_type" : transport_type, - "tty_transport_device" : tty_transport_device, - "unit" : unit, - } - response = self.json_post("/cli-json/add_ppp_link", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_profile - - https://www.candelatech.com/lfcli_ug.php#add_profile - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_profile_profile_flags(Enum): - p_11r = 64 # Use 802.11r roaming setup. - BSS_TRANS = 1024 # Enable BSS Transition logic - DHCP_SERVER = 1 # This should provide DHCP server. - EAP_PEAP = 512 # Enable EAP-PEAP - EAP_TTLS = 128 # Use 802.1x EAP-TTLS - NAT = 256 # Enable NAT if this object is in a virtual router - SKIP_DHCP_ROAM = 16 # Ask station to not re-do DHCP on roam. - WEP = 2 # Use WEP encryption - WPA = 4 # Use WPA encryption - WPA2 = 8 # Use WPA2 encryption - WPA3 = 32 # Use WPA3 encryption - - class add_profile_wifi_mode(Enum): - p_802_11a = 1 # 802.11a - AUTO = 0 # 802.11g - abg = 4 # 802.11abg - abgn = 5 # 802.11abgn - abgnAC = 8 # 802.11abgn-AC - abgnAX = 12 # 802.11abgn-AX - an = 10 # 802.11an - anAC = 9 # 802.11an-AC - anAX = 14 # 802.11an-AX - as_is = 0 # Make no changes to current configuration - b = 2 # 802.11b - bg = 7 # 802.11bg - bgn = 6 # 802.11bgn - bgnAC = 11 # 802.11bgn-AC - bgnAX = 13 # 802.11bgn-AX - bond = 9 # Bonded pair of Ethernet ports. - bridged_ap = 2 # AP device in bridged mode. The EIDs may specify radio and bridged port. - client = 8 # Client-side non-WiFi device (Ethernet port, for instance). - g = 3 # 802.11g - mobile_sta = 6 # Mobile station device. Expects to connect to DUT AP(s) and upstream LANforge. - monitor = 5 # Monitor device/sniffer. The EIDs may specify which radios to use. - peer = 10 # Edge device, client or server (Ethernet port, for instance). - rdd = 7 # Pair of redirect devices, typically associated with VR to act as traffic endpoint - routed_ap = 3 # AP in routed mode. The EIDs may specify radio and upstream port. - sta = 1 # Station device, most likely non mobile. The EIDs may specify radio(s) to use. - uplink = 11 # Uplink towards rest of network (can go in virtual router and do NAT) - upstream = 4 # Upstream server device. The EIDs may specify which ports to use. - vlan = 12 # 802.1q VLAN. Specify VID with the 'freq' option. - - - def post_add_profile(self, - alias_prefix=None, - antenna=None, - bandwidth=None, - eap_id=None, - flags_mask=None, - freq=None, - instance_count=None, - mac_pattern=None, - name=None, - passwd=None, - profile_flags=None, - profile_type=None, - ssid=None, - vid=None, - wifi_mode=None, - debug_=False): - debug_ |= self.debug - data = { - "alias_prefix" : alias_prefix, - "antenna" : antenna, - "bandwidth" : bandwidth, - "eap_id" : eap_id, - "flags_mask" : flags_mask, - "freq" : freq, - "instance_count" : instance_count, - "mac_pattern" : mac_pattern, - "name" : name, - "passwd" : passwd, - "profile_flags" : profile_flags, - "profile_type" : profile_type, - "ssid" : ssid, - "vid" : vid, - "wifi_mode" : wifi_mode, - } - response = self.json_post("/cli-json/add_profile", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_profile_notes - - https://www.candelatech.com/lfcli_ug.php#add_profile_notes - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_profile_notes(self, - dut=None, - text=None, - debug_=False): - debug_ |= self.debug - data = { - "dut" : dut, - "text" : text, - } - response = self.json_post("/cli-json/add_profile_notes", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_rdd - - https://www.candelatech.com/lfcli_ug.php#add_rdd - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_rdd(self, - peer_ifname=None, - port=None, - report_timer=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "peer_ifname" : peer_ifname, - "port" : port, - "report_timer" : report_timer, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/add_rdd", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_sec_ip - - https://www.candelatech.com/lfcli_ug.php#add_sec_ip - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_sec_ip(self, - ip_list=None, - port=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "ip_list" : ip_list, - "port" : port, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/add_sec_ip", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_sta - - https://www.candelatech.com/lfcli_ug.php#add_sta - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_sta_flags(Enum): - p_80211r_pmska_cache = 67108864 # Enable oportunistic PMSKA caching for WPA2 (Related to 802.11r). - p_80211u_additional = 1048576 # AP requires additional step for access (802.11u Interworking) - p_80211u_auto = 262144 # Enable 802.11u (Interworking) Auto-internetworking feature. Always enabled currently. - p_80211u_e911 = 2097152 # AP claims emergency services reachable (802.11u Interworking) - p_80211u_e911_unauth = 4194304 # AP provides Unauthenticated emergency services (802.11u Interworking) - p_80211u_enable = 131072 # Enable 802.11u (Interworking) feature. - p_80211u_gw = 524288 # AP Provides access to internet (802.11u Interworking) - p_8021x_radius = 33554432 # Use 802.1x (RADIUS for AP). - create_admin_down = 68719476736 # Station should be created admin-down. - custom_conf = 32 # Use Custom wpa_supplicant config file. - disable_twt = 17592186044416 # Disable TWT mode - disable_fast_reauth = 8589934592 # Disable fast_reauth option for virtual stations. - disable_gdaf = 16777216 # AP: Disable DGAF (used by HotSpot 2.0). - disable_ht80 = 134217728 # Disable HT80 (for AC chipset NICs only) - disable_roam = 2147483648 # Disable automatic station roaming based on scan results. - disable_sgi = 16384 # Disable SGI (Short Guard Interval). - hs20_enable = 8388608 # Enable Hotspot 2.0 (HS20) feature. Requires WPA-2. - ht160_enable = 4294967296 # Enable HT160 mode. - ht40_disable = 2048 # Disable HT-40 even if hardware and AP support it. - ibss_mode = 536870912 # Station should be in IBSS mode. - lf_sta_migrate = 32768 # OK-To-Migrate (Allow station migration between LANforge radios) - mesh_mode = 17179869184 # Station should be in MESH mode. - no_supp_op_class_ie = 274877906944 # Do not include supported-oper-class-IE in assoc requests. May work around AP bugs. - osen_enable = 1073741824 # Enable OSEN protocol (OSU Server-only Authentication) - passive_scan = 8192 # Use passive scanning (don't send probe requests). - power_save_enable = 34359738368 # Station should enable power-save. May not work in all drivers/configurations. - scan_ssid = 4096 # Enable SCAN-SSID flag in wpa_supplicant. - txo_enable = 549755813888 # Enable/disable tx-offloads, typically managed by set_wifi_txo command - use_bss_transition = 8796093022208 # Enable BSS transition. - use_wpa3 = 1099511627776 # Enable WPA-3 (SAE Personal) mode. - verbose = 65536 # Verbose-Debug: Increase debug info in wpa-supplicant and hostapd logs. - wds_mode = 137438953472 # WDS station (sort of like a lame mesh), not supported on ath10k - wep_enable = 512 # Use wpa_supplicant configured for WEP encryption. - wpa2_enable = 1024 # Use wpa_supplicant configured for WPA2 encryption. - wpa_enable = 16 # Enable WPA - - class add_sta_mode(Enum): - p_802_11a = 1 # 802.11a - AUTO = 0 # 802.11g - abg = 4 # 802.11abg - abgn = 5 # 802.11abgn - abgnAC = 8 # 802.11abgn-AC - abgnAX = 12 # 802.11abgn-AX - an = 10 # 802.11an - anAC = 9 # 802.11an-AC - anAX = 14 # 802.11an-AX - b = 2 # 802.11b - bg = 7 # 802.11bg - bgn = 6 # 802.11bgn - bgnAC = 11 # 802.11bgn-AC - bgnAX = 13 # 802.11bgn-AX - g = 3 # 802.11g - - class add_sta_rate(Enum): - _a_g = 0 # 6 Mbps, 9 Mbps, 12 Mbps, 18 Mbps, 24 Mbps, 36 Mbps, 48 Mbps, 54 Mbps - _b = 0 # 1Mbps, 2Mbps, 5.5 Mbps, 11 Mbps - DEFAULT = 0 # Use maximum available speed - MCS0_76 = 0 # /n rates - _bitmap_ = 0 # '0xff 00 ...' to directly specify the MCS bitmap. - - - def post_add_sta(self, - ampdu_density=None, - ampdu_factor=None, - ap=None, - flags=None, - flags_mask=None, - ieee80211w=None, - key=None, - mac=None, - max_amsdu=None, - mode=None, - nickname=None, - radio=None, - rate=None, - resource=None, - shelf=None, - ssid=None, - sta_br_ip=None, - sta_name=None, - wpa_cfg_file=None, - x_coord=None, - y_coord=None, - z_coord=None, - debug_=False): - debug_ |= self.debug - data = { - "ampdu_density" : ampdu_density, - "ampdu_factor" : ampdu_factor, - "ap" : ap, - "flags" : flags, - "flags_mask" : flags_mask, - "ieee80211w" : ieee80211w, - "key" : key, - "mac" : mac, - "max_amsdu" : max_amsdu, - "mode" : mode, - "nickname" : nickname, - "radio" : radio, - "rate" : rate, - "resource" : resource, - "shelf" : shelf, - "ssid" : ssid, - "sta_br_ip" : sta_br_ip, - "sta_name" : sta_name, - "wpa_cfg_file" : wpa_cfg_file, - "x_coord" : x_coord, - "y_coord" : y_coord, - "z_coord" : z_coord, - } - response = self.json_post("/cli-json/add_sta", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_t1_span - - https://www.candelatech.com/lfcli_ug.php#add_t1_span - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_t1_span_buildout(Enum): - _15db = 6 # -15db (CSU) - _22_5db = 7 # -22.5db (CSU) - _7_5db = 5 # -7.5db (CSU) - p_0db = 8 # 0db (CSU) - p_133_ft = 0 # 1-133 feet - p_266_ft = 1 # 122-266 feet - p_399_ft = 2 # 266-399 feet - p_533_ft = 3 # 399-533 feet - p_655_ft = 4 # 533-655 feet - - - def post_add_t1_span(self, - buildout=None, - coding=None, - cpu_id=None, - first_channel=None, - framing=None, - mtu=None, - pci_bus=None, - pci_slot=None, - resource=None, - shelf=None, - span_num=None, - timing=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "buildout" : buildout, - "coding" : coding, - "cpu_id" : cpu_id, - "first_channel" : first_channel, - "framing" : framing, - "mtu" : mtu, - "pci_bus" : pci_bus, - "pci_slot" : pci_slot, - "resource" : resource, - "shelf" : shelf, - "span_num" : span_num, - "timing" : timing, - "type" : type, - } - response = self.json_post("/cli-json/add_t1_span", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_text_blob - - https://www.candelatech.com/lfcli_ug.php#add_text_blob - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_text_blob(self, - name=None, - text=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - "text" : text, - "type" : type, - } - response = self.json_post("/cli-json/add_text_blob", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_tgcx - - https://www.candelatech.com/lfcli_ug.php#add_tgcx - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_tgcx(self, - cxname=None, - tgname=None, - debug_=False): - debug_ |= self.debug - data = { - "cxname" : cxname, - "tgname" : tgname, - } - response = self.json_post("/cli-json/add_tgcx", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_threshold - - https://www.candelatech.com/lfcli_ug.php#add_threshold - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_threshold_thresh_id(Enum): - Delete_Marked = -3 # Delete any marked. - Mark_All = -2 # Mark all - - class add_threshold_thresh_type(Enum): - NO_RX_SINCE = 6 # Have not received any bytes/packets in specified time. - RX_BPS_RATE_OOR_1m = 5 # rx-bps over last 1 minute is out of range. - RX_BPS_RATE_OOR_30S = 3 # rx-bps over last 30 seconds is out of range. - RX_BPS_RATE_OOR_3S = 1 # rx-bps over last 3 seconds is out of range. - TT_RX_DROP_OOR = 8 # RX Drop percentage is out of range (per-million). - TT_RX_LAT_OOR = 7 # Latency running-average out of range. - TX_BPS_RATE_OOR_1m = 4 # tx-bps over last 1 minute is out of range. - TX_BPS_RATE_OOR_30S = 2 # tx-bps over last 30 seconds is out of range. - TX_BPS_RATE_OOR_3S = 0 # tx-bps over last 3 seconds is out of range. - - - def post_add_threshold(self, - endp=None, - thresh_id=None, - thresh_max=None, - thresh_min=None, - thresh_type=None, - debug_=False): - debug_ |= self.debug - data = { - "endp" : endp, - "thresh_id" : thresh_id, - "thresh_max" : thresh_max, - "thresh_min" : thresh_min, - "thresh_type" : thresh_type, - } - response = self.json_post("/cli-json/add_threshold", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_tm - - https://www.candelatech.com/lfcli_ug.php#add_tm - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_tm(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/add_tm", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_traffic_profile - - https://www.candelatech.com/lfcli_ug.php#add_traffic_profile - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_traffic_profile_traffic_profile_flags(Enum): - BI_DIRECTIONAL = 2 # Should we do bi-directional traffic? - IPERF_UDP = 4 # If Iperf, should use UDP. If not set, then will use TCP. - UP = 1 # Upload direction (this not set means download) - - class add_traffic_profile_wifi_mode(Enum): - Iperf3_Client = 6 # iperf3 client - Iperf3_Server = 5 # iperf3 server - as_is = 0 # Make no changes to current configuration - http = 3 # Not yet implemented - https = 4 # Not yet implemented - tcp = 2 - udp = 1 - - - def post_add_traffic_profile(self, - instance_count=None, - max_pdu=None, - max_speed=None, - min_pdu=None, - min_speed=None, - name=None, - tos=None, - traffic_profile_flags=None, - traffic_profile_flags_mask=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "instance_count" : instance_count, - "max_pdu" : max_pdu, - "max_speed" : max_speed, - "min_pdu" : min_pdu, - "min_speed" : min_speed, - "name" : name, - "tos" : tos, - "traffic_profile_flags" : traffic_profile_flags, - "traffic_profile_flags_mask" : traffic_profile_flags_mask, - "type" : type, - } - response = self.json_post("/cli-json/add_traffic_profile", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_traffic_profile_notes - - https://www.candelatech.com/lfcli_ug.php#add_traffic_profile_notes - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_traffic_profile_notes(self, - dut=None, - text=None, - debug_=False): - debug_ |= self.debug - data = { - "dut" : dut, - "text" : text, - } - response = self.json_post("/cli-json/add_traffic_profile_notes", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_vap - - https://www.candelatech.com/lfcli_ug.php#add_vap - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_vap_flags(Enum): - p_80211h_enable = 268435456 # Enable 802.11h (needed for running on DFS channels) Requires 802.11d. - p_80211r_pmska_cache = 67108864 # Enable oportunistic PMSKA caching for WPA2 (Related to 802.11r). - p_80211u_additional = 1048576 # AP requires additional step for access (802.11u Interworking) - p_80211u_auto = 262144 # Enable 802.11u (Interworking) Auto-internetworking feature. Always enabled currently. - p_80211u_e911 = 2097152 # AP claims emergency services reachable (802.11u Interworking) - p_80211u_e911_unauth = 4194304 # AP provides Unauthenticated emergency services (802.11u Interworking) - p_80211u_enable = 131072 # Enable 802.11u (Interworking) feature. - p_80211u_gw = 524288 # AP Provides access to internet (802.11u Interworking) - p_8021x_radius = 33554432 # Use 802.1x (RADIUS for AP). - create_admin_down = 68719476736 # Station should be created admin-down. - disable_dgaf = 16777216 # AP Disable DGAF (used by HotSpot 2.0). - disable_ht40 = 2048 # Disable HT-40 (will use HT-20 if available). - disable_ht80 = 134217728 # Disable HT80 (for AC chipset NICs only) - enable_80211d = 64 # Enable 802.11D to broadcast country-code & channels in VAPs - enable_wpa = 16 # Enable WPA - hostapd_config = 32 # Use Custom hostapd config file. - hs20_enable = 8388608 # Enable Hotspot 2.0 (HS20) feature. Requires WPA-2. - ht160_enable = 4294967296 # Enable HT160 mode. - osen_enable = 1073741824 # Enable OSEN protocol (OSU Server-only Authentication) - pri_sec_ch_enable = 256 # Enable Primary/Secondary channel switch. - short_preamble = 128 # Allow short-preamble - use_bss_load = 2199023255552 # Enable BSS Load IE in Beacons and Probe Responses (.11e). - use_bss_transition = 8796093022208 # Enable BSS transition. - use_rrm_report = 4398046511104 # Enable Radio measurements IE in beacon and probe responses. - use_wpa3 = 1099511627776 # Enable WPA-3 (SAE Personal) mode. - verbose = 65536 # Verbose-Debug: Increase debug info in wpa-supplicant and hostapd logs. - wep_enable = 512 # Enable WEP Encryption - wpa2_enable = 1024 # Enable WPA2 Encryption - - class add_vap_mode(Enum): - p_802_11a = 1 # 802.11a - AUTO = 0 # 802.11g - abg = 4 # 802.11abg - abgn = 5 # 802.11abgn - abgnAC = 8 # 802.11abgn-AC - abgnAX = 12 # 802.11abgn-AX - an = 10 # 802.11an - anAC = 9 # 802.11an-AC - anAX = 14 # 802.11an-AXAUTO | 0 # - b = 2 # 802.11b - bg = 7 # 802.11bg - bgn = 6 # 802.11bgn - bgnAC = 11 # 802.11bgn-AC - bgnAX = 13 # 802.11bgn-AX - g = 3 # 802.11g - - - def post_add_vap(self, - ap_name=None, - beacon=None, - custom_cfg=None, - dtim_period=None, - flags=None, - flags_mask=None, - frag_thresh=None, - ieee80211w=None, - key=None, - mac=None, - max_sta=None, - mode=None, - radio=None, - rate=None, - resource=None, - shelf=None, - ssid=None, - x_coord=None, - y_coord=None, - z_coord=None, - debug_=False): - debug_ |= self.debug - data = { - "ap_name" : ap_name, - "beacon" : beacon, - "custom_cfg" : custom_cfg, - "dtim_period" : dtim_period, - "flags" : flags, - "flags_mask" : flags_mask, - "frag_thresh" : frag_thresh, - "ieee80211w" : ieee80211w, - "key" : key, - "mac" : mac, - "max_sta" : max_sta, - "mode" : mode, - "radio" : radio, - "rate" : rate, - "resource" : resource, - "shelf" : shelf, - "ssid" : ssid, - "x_coord" : x_coord, - "y_coord" : y_coord, - "z_coord" : z_coord, - } - response = self.json_post("/cli-json/add_vap", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_venue - - https://www.candelatech.com/lfcli_ug.php#add_venue - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_venue_freq_24(Enum): - ALL = 65535 # ALL - Ch_1 = 1 # Channel 1 - Ch_2 = 2 # Channel 2 - Ch_3 = 4 # Channel 3 - - class add_venue_freq_5(Enum): - Ch_100 = 2048 # Channel 100 5500 - Ch_104 = 4096 # Channel 104 5520 - Ch_108 = 8192 # Channel 108 5540 - Ch_112 = 16384 # Channel 112 5560 - Ch_116 = 32768 # Channel 116 5580 - Ch_120 = 65536 # Channel 120 5600 - Ch_124 = 131072 # Channel 124 5620 - Ch_128 = 262144 # Channel 128 5640 - Ch_132 = 524288 # Channel 132 5660 - Ch_136 = 1048576 # Channel 136 5680 - Ch_140 = 2097152 # Channel 140 5700 - Ch_149 = 4194304 # Channel 149 5745 - Ch_153 = 8388608 # Channel 153 5765 - Ch_157 = 16777216 # Channel 157 5785 - Ch_161 = 33554432 # Channel 161 5805 - Ch_165 = 67108864 # Channel 165 5825 - Ch_36 = 1 # Channel 36 5180 - Ch_38 = 2 # Channel 38 5190 - Ch_40 = 4 # Channel 40 5200 - Ch_42 = 8 # Channel 42 5210 - Ch_44 = 16 # Channel 44 5220 - Ch_46 = 32 # Channel 46 5230 - Ch_48 = 64 # Channel 48 5240 - Ch_52 = 128 # Channel 52 5260 - Ch_56 = 256 # Channel 56 5280 - Ch_60 = 512 # Channel 60 5300 - Ch_64 = 1024 # Channel 64 5320 - - - def post_add_venue(self, - description=None, - freq_24=None, - freq_5=None, - resource=None, - shelf=None, - venu_id=None, - x1=None, - x2=None, - y1=None, - y2=None, - debug_=False): - debug_ |= self.debug - data = { - "description" : description, - "freq_24" : freq_24, - "freq_5" : freq_5, - "resource" : resource, - "shelf" : shelf, - "venu_id" : venu_id, - "x1" : x1, - "x2" : x2, - "y1" : y1, - "y2" : y2, - } - response = self.json_post("/cli-json/add_venue", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_vlan - - https://www.candelatech.com/lfcli_ug.php#add_vlan - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_vlan(self, - old_name=None, - port=None, - report_timer=None, - resource=None, - shelf=None, - vid=None, - debug_=False): - debug_ |= self.debug - data = { - "old_name" : old_name, - "port" : port, - "report_timer" : report_timer, - "resource" : resource, - "shelf" : shelf, - "vid" : vid, - } - response = self.json_post("/cli-json/add_vlan", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_voip_endp - - https://www.candelatech.com/lfcli_ug.php#add_voip_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_voip_endp(self, - alias=None, - auth_user_name=None, - display_name=None, - gateway_port=None, - ip_addr=None, - peer_phone_num=None, - phone_num=None, - port=None, - proxy_passwd=None, - resource=None, - rtp_port=None, - rx_sound_file=None, - shelf=None, - sip_gateway=None, - tx_sound_file=None, - vad_max_timer=None, - vad_timer=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "auth_user_name" : auth_user_name, - "display_name" : display_name, - "gateway_port" : gateway_port, - "ip_addr" : ip_addr, - "peer_phone_num" : peer_phone_num, - "phone_num" : phone_num, - "port" : port, - "proxy_passwd" : proxy_passwd, - "resource" : resource, - "rtp_port" : rtp_port, - "rx_sound_file" : rx_sound_file, - "shelf" : shelf, - "sip_gateway" : sip_gateway, - "tx_sound_file" : tx_sound_file, - "vad_max_timer" : vad_max_timer, - "vad_timer" : vad_timer, - } - response = self.json_post("/cli-json/add_voip_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_vr - - https://www.candelatech.com/lfcli_ug.php#add_vr - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_vr_flags(Enum): - p_4BYTE_AS_NUMBER = 64 # Sets corresponding Xorp flag. - BGP_CONFED = 256 # Configure BGP in a confederation. - BGP_DAMPING = 512 # Enable BGP damping section in Xorp configuration file. - ENABLE_BGP = 32 # Set this to zero if you don't want BGP on this VR. - RIP_ACCEPT_DR = 2048 # Tell RIP to accept default-routes. - ROUTE_REFLECTOR = 128 # Act as BGP Route Reflector. - USE_IPV6 = 16 # Enable IPv6 OSPF routing for this virtual router. - USE_IPV6_RADVD = 8 # Enable IPv6 RADV Daemon for interfaces in this virtual router. - USE_RIP = 1024 # Enable RIP routing protocol in Xorp. - USE_XORP_MCAST = 2 # Enable Xorp Multicast routing (requires OSPF to be enabled currently) - USE_XORP_OLSR = 4096 # Enable OLSR routing protocol in Xorp. - USE_XORP_OSPF = 1 # Enable Xorp router daemon with OSPF (IPv4) protocol - USE_XORP_SHA = 4 # Enable Telcordia's Xorp SHA option (requires OSPF to be enabled) - - - def post_add_vr(self, - alias=None, - flags=None, - height=None, - notes=None, - resource=None, - shelf=None, - vr_id=None, - width=None, - x=None, - y=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "flags" : flags, - "height" : height, - "notes" : notes, - "resource" : resource, - "shelf" : shelf, - "vr_id" : vr_id, - "width" : width, - "x" : x, - "y" : y, - } - response = self.json_post("/cli-json/add_vr", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_vr_bgp - - https://www.candelatech.com/lfcli_ug.php#add_vr_bgp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_vr_bgp_flags(Enum): - p_4BYTE_AS_NUMBER = 64 # Sets corresponding Xorp flag. - BGP_CONFED = 256 # Configure BGP in a confederation. - BGP_DAMPING = 512 # Enable BGP damping section in Xorp configuration file. - ENABLE_BGP = 32 # Set this to zero if you don't want BGP on this VR. - ROUTE_REFLECTOR = 128 # Act as BGP Route Reflector. - - - def post_add_vr_bgp(self, - bgp_id=None, - cluster_id=None, - confed_id=None, - flags=None, - half_life=None, - local_as=None, - max_suppress=None, - resource=None, - reuse=None, - shelf=None, - suppress=None, - vr_id=None, - debug_=False): - debug_ |= self.debug - data = { - "bgp_id" : bgp_id, - "cluster_id" : cluster_id, - "confed_id" : confed_id, - "flags" : flags, - "half_life" : half_life, - "local_as" : local_as, - "max_suppress" : max_suppress, - "resource" : resource, - "reuse" : reuse, - "shelf" : shelf, - "suppress" : suppress, - "vr_id" : vr_id, - } - response = self.json_post("/cli-json/add_vr_bgp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_vrcx - - https://www.candelatech.com/lfcli_ug.php#add_vrcx - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_vrcx_flags(Enum): - custom_dhcpd = 1024 # Use custom DHCP config file - dhcpd_enabled = 512 # Serve IPv4 DHCP on this interface - ipv6_enabled = 8192 # Serve IPv6 DHCP on this interface - nat_enabled = 256 # This connection will NAT outgoing packets - subnet_0 = 1 # Specify subnet 0 - subnet_1 = 2 # Specify subnet 1 - subnet_2 = 4 # Specify subnet 2 - subnet_3 = 8 # Specify subnet 3 - subnet_4 = 16 # Specify subnet 4 - subnet_5 = 32 # Specify subnet 5 - subnet_6 = 64 # Specify subnet 6 - subnet_7 = 128 # Specify subnet 7 - use_multicast = 2048 # Use this interface for multicast and-rp - use_vrrp = 4096 # Use this interface for VRRP - - - def post_add_vrcx(self, - dhcp_dns=None, - dhcp_dns6=None, - dhcp_domain=None, - dhcp_lease_time=None, - dhcp_max=None, - dhcp_max6=None, - dhcp_min=None, - dhcp_min6=None, - flags=None, - height=None, - interface_cost=None, - local_dev=None, - local_dev_b=None, - nexthop=None, - ospf_area=None, - remote_dev=None, - remote_dev_b=None, - resource=None, - rip_metric=None, - shelf=None, - subnets=None, - vr_name=None, - vrrp_id=None, - vrrp_interval=None, - vrrp_ip=None, - vrrp_ip_prefix=None, - vrrp_priority=None, - wanlink=None, - width=None, - x=None, - y=None, - debug_=False): - debug_ |= self.debug - data = { - "dhcp_dns" : dhcp_dns, - "dhcp_dns6" : dhcp_dns6, - "dhcp_domain" : dhcp_domain, - "dhcp_lease_time" : dhcp_lease_time, - "dhcp_max" : dhcp_max, - "dhcp_max6" : dhcp_max6, - "dhcp_min" : dhcp_min, - "dhcp_min6" : dhcp_min6, - "flags" : flags, - "height" : height, - "interface_cost" : interface_cost, - "local_dev" : local_dev, - "local_dev_b" : local_dev_b, - "nexthop" : nexthop, - "ospf_area" : ospf_area, - "remote_dev" : remote_dev, - "remote_dev_b" : remote_dev_b, - "resource" : resource, - "rip_metric" : rip_metric, - "shelf" : shelf, - "subnets" : subnets, - "vr_name" : vr_name, - "vrrp_id" : vrrp_id, - "vrrp_interval" : vrrp_interval, - "vrrp_ip" : vrrp_ip, - "vrrp_ip_prefix" : vrrp_ip_prefix, - "vrrp_priority" : vrrp_priority, - "wanlink" : wanlink, - "width" : width, - "x" : x, - "y" : y, - } - response = self.json_post("/cli-json/add_vrcx", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_vrcx2 - - https://www.candelatech.com/lfcli_ug.php#add_vrcx2 - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_add_vrcx2(self, - local_dev=None, - nexthop6=None, - resource=None, - shelf=None, - subnets6=None, - vr_name=None, - debug_=False): - debug_ |= self.debug - data = { - "local_dev" : local_dev, - "nexthop6" : nexthop6, - "resource" : resource, - "shelf" : shelf, - "subnets6" : subnets6, - "vr_name" : vr_name, - } - response = self.json_post("/cli-json/add_vrcx2", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_vsta - - https://www.candelatech.com/lfcli_ug.php#add_sta - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_sta_flags(Enum): - p_80211r_pmska_cache = 67108864 # Enable oportunistic PMSKA caching for WPA2 (Related to 802.11r). - p_80211u_additional = 1048576 # AP requires additional step for access (802.11u Interworking) - p_80211u_auto = 262144 # Enable 802.11u (Interworking) Auto-internetworking feature. Always enabled currently. - p_80211u_e911 = 2097152 # AP claims emergency services reachable (802.11u Interworking) - p_80211u_e911_unauth = 4194304 # AP provides Unauthenticated emergency services (802.11u Interworking) - p_80211u_enable = 131072 # Enable 802.11u (Interworking) feature. - p_80211u_gw = 524288 # AP Provides access to internet (802.11u Interworking) - p_8021x_radius = 33554432 # Use 802.1x (RADIUS for AP). - create_admin_down = 68719476736 # Station should be created admin-down. - custom_conf = 32 # Use Custom wpa_supplicant config file. - disable_twt = 17592186044416 # Disable TWT mode - disable_fast_reauth = 8589934592 # Disable fast_reauth option for virtual stations. - disable_gdaf = 16777216 # AP: Disable DGAF (used by HotSpot 2.0). - disable_ht80 = 134217728 # Disable HT80 (for AC chipset NICs only) - disable_roam = 2147483648 # Disable automatic station roaming based on scan results. - disable_sgi = 16384 # Disable SGI (Short Guard Interval). - hs20_enable = 8388608 # Enable Hotspot 2.0 (HS20) feature. Requires WPA-2. - ht160_enable = 4294967296 # Enable HT160 mode. - ht40_disable = 2048 # Disable HT-40 even if hardware and AP support it. - ibss_mode = 536870912 # Station should be in IBSS mode. - lf_sta_migrate = 32768 # OK-To-Migrate (Allow station migration between LANforge radios) - mesh_mode = 17179869184 # Station should be in MESH mode. - no_supp_op_class_ie = 274877906944 # Do not include supported-oper-class-IE in assoc requests. May work around AP bugs. - osen_enable = 1073741824 # Enable OSEN protocol (OSU Server-only Authentication) - passive_scan = 8192 # Use passive scanning (don't send probe requests). - power_save_enable = 34359738368 # Station should enable power-save. May not work in all drivers/configurations. - scan_ssid = 4096 # Enable SCAN-SSID flag in wpa_supplicant. - txo_enable = 549755813888 # Enable/disable tx-offloads, typically managed by set_wifi_txo command - use_bss_transition = 8796093022208 # Enable BSS transition. - use_wpa3 = 1099511627776 # Enable WPA-3 (SAE Personal) mode. - verbose = 65536 # Verbose-Debug: Increase debug info in wpa-supplicant and hostapd logs. - wds_mode = 137438953472 # WDS station (sort of like a lame mesh), not supported on ath10k - wep_enable = 512 # Use wpa_supplicant configured for WEP encryption. - wpa2_enable = 1024 # Use wpa_supplicant configured for WPA2 encryption. - wpa_enable = 16 # Enable WPA - - class add_sta_mode(Enum): - p_802_11a = 1 # 802.11a - AUTO = 0 # 802.11g - abg = 4 # 802.11abg - abgn = 5 # 802.11abgn - abgnAC = 8 # 802.11abgn-AC - abgnAX = 12 # 802.11abgn-AX - an = 10 # 802.11an - anAC = 9 # 802.11an-AC - anAX = 14 # 802.11an-AX - b = 2 # 802.11b - bg = 7 # 802.11bg - bgn = 6 # 802.11bgn - bgnAC = 11 # 802.11bgn-AC - bgnAX = 13 # 802.11bgn-AX - g = 3 # 802.11g - - class add_sta_rate(Enum): - _a_g = 0 # 6 Mbps, 9 Mbps, 12 Mbps, 18 Mbps, 24 Mbps, 36 Mbps, 48 Mbps, 54 Mbps - _b = 0 # 1Mbps, 2Mbps, 5.5 Mbps, 11 Mbps - DEFAULT = 0 # Use maximum available speed - MCS0_76 = 0 # /n rates - _bitmap_ = 0 # '0xff 00 ...' to directly specify the MCS bitmap. - - - def post_add_vsta(self, - ampdu_density=None, - ampdu_factor=None, - ap=None, - flags=None, - flags_mask=None, - ieee80211w=None, - key=None, - mac=None, - max_amsdu=None, - mode=None, - nickname=None, - radio=None, - rate=None, - resource=None, - shelf=None, - ssid=None, - sta_br_ip=None, - sta_name=None, - wpa_cfg_file=None, - x_coord=None, - y_coord=None, - z_coord=None, - debug_=False): - debug_ |= self.debug - data = { - "ampdu_density" : ampdu_density, - "ampdu_factor" : ampdu_factor, - "ap" : ap, - "flags" : flags, - "flags_mask" : flags_mask, - "ieee80211w" : ieee80211w, - "key" : key, - "mac" : mac, - "max_amsdu" : max_amsdu, - "mode" : mode, - "nickname" : nickname, - "radio" : radio, - "rate" : rate, - "resource" : resource, - "shelf" : shelf, - "ssid" : ssid, - "sta_br_ip" : sta_br_ip, - "sta_name" : sta_name, - "wpa_cfg_file" : wpa_cfg_file, - "x_coord" : x_coord, - "y_coord" : y_coord, - "z_coord" : z_coord, - } - response = self.json_post("/cli-json/add_vsta", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/add_wl_endp - - https://www.candelatech.com/lfcli_ug.php#add_wl_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class add_wl_endp_wle_flags(Enum): - SHOW_WP = 1 # Show WanPaths in wanlink endpoint table in GUI - - - def post_add_wl_endp(self, - alias=None, - cpu_id=None, - description=None, - dest_ip=None, - dest_ip_mask=None, - drop_every_xth_pkt=None, - drop_freq=None, - dup_every_xth_pkt=None, - dup_freq=None, - extra_buffer=None, - ignore_bandwidth=None, - ignore_dup=None, - ignore_latency=None, - ignore_loss=None, - jitter_freq=None, - latency=None, - max_drop_amt=None, - max_jitter=None, - max_lateness=None, - max_rate=None, - max_reorder_amt=None, - min_drop_amt=None, - min_reorder_amt=None, - playback_capture=None, - playback_capture_file=None, - playback_loop=None, - port=None, - reorder_every_xth_pkt=None, - reorder_freq=None, - resource=None, - shelf=None, - source_ip=None, - source_ip_mask=None, - speed=None, - test_mgr=None, - wanlink=None, - wle_flags=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "cpu_id" : cpu_id, - "description" : description, - "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, - "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_rate" : max_rate, - "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, - "port" : port, - "reorder_every_xth_pkt" : reorder_every_xth_pkt, - "reorder_freq" : reorder_freq, - "resource" : resource, - "shelf" : shelf, - "source_ip" : source_ip, - "source_ip_mask" : source_ip_mask, - "speed" : speed, - "test_mgr" : test_mgr, - "wanlink" : wanlink, - "wle_flags" : wle_flags, - } - response = self.json_post("/cli-json/add_wl_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/admin - - https://www.candelatech.com/lfcli_ug.php#admin - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_admin(self, - arg1=None, - arg2=None, - arg3=None, - arg5=None, - cmd=None, - debug_=False): - debug_ |= self.debug - data = { - "arg1" : arg1, - "arg2" : arg2, - "arg3" : arg3, - "arg5" : arg5, - "cmd" : cmd, - } - response = self.json_post("/cli-json/admin", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/apply_vr_cfg - - https://www.candelatech.com/lfcli_ug.php#apply_vr_cfg - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_apply_vr_cfg(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/apply_vr_cfg", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/blink_attenuator - - https://www.candelatech.com/lfcli_ug.php#blink_attenuator - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_blink_attenuator(self, - resource=None, - serno=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "serno" : serno, - "shelf" : shelf, - } - response = self.json_post("/cli-json/blink_attenuator", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/c_show_ports - - https://www.candelatech.com/lfcli_ug.php#c_show_ports - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class c_show_ports_probe_flags(Enum): - BRIDGE = 8 # 8 include bridges - EASY_IP_INFO = 16 # 16 Everything but gateway information, which is expensive to probe. - ETHTOOL = 4 # 4 include ethtool results - GW = 32 # 32 include gateway information - GW_FORCE_REFRESH = 64 # 64 Force GW (re)probe. Otherwise, cached values *might* be used. - MII = 2 # 2 include MII - WIFI = 1 # 1 include wifi stations - - - def post_c_show_ports(self, - port=None, - probe_flags=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "port" : port, - "probe_flags" : probe_flags, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/c_show_ports", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/cancel_vr_cfg - - https://www.candelatech.com/lfcli_ug.php#cancel_vr_cfg - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_cancel_vr_cfg(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/cancel_vr_cfg", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/clear_card_counters - - https://www.candelatech.com/lfcli_ug.php#clear_resource_counters - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_clear_card_counters(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/clear_card_counters", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/clear_cd_counters - - https://www.candelatech.com/lfcli_ug.php#clear_cd_counters - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_clear_cd_counters(self, - cd_name=None, - debug_=False): - debug_ |= self.debug - data = { - "cd_name" : cd_name, - } - response = self.json_post("/cli-json/clear_cd_counters", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/clear_cx_counters - - https://www.candelatech.com/lfcli_ug.php#clear_cx_counters - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_clear_cx_counters(self, - cx_name=None, - debug_=False): - debug_ |= self.debug - data = { - "cx_name" : cx_name, - } - response = self.json_post("/cli-json/clear_cx_counters", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/clear_endp_counters - - https://www.candelatech.com/lfcli_ug.php#clear_endp_counters - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_clear_endp_counters(self, - endp_name=None, - incr_seqno=None, - just_latency=None, - debug_=False): - debug_ |= self.debug - data = { - "endp_name" : endp_name, - "incr_seqno" : incr_seqno, - "just_latency" : just_latency, - } - response = self.json_post("/cli-json/clear_endp_counters", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/clear_group - - https://www.candelatech.com/lfcli_ug.php#clear_group - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_clear_group(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/clear_group", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/clear_port_counters - - https://www.candelatech.com/lfcli_ug.php#clear_port_counters - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class clear_port_counters_extra(Enum): - dhcp4_lease = 0 # Remove dhcp lease files for IPv4 DHCP - dhcp6_lease = 0 # Remove dhcp lease files for IPv6 DHCP - dhcp_leases = 0 # Remove dhcp lease files for IPv4 and IPv6 DHCP - - - def post_clear_port_counters(self, - extra=None, - port=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "extra" : extra, - "port" : port, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/clear_port_counters", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/clear_resource_counters - - https://www.candelatech.com/lfcli_ug.php#clear_resource_counters - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_clear_resource_counters(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/clear_resource_counters", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/clear_wp_counters - - https://www.candelatech.com/lfcli_ug.php#clear_wp_counters - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_clear_wp_counters(self, - endp_name=None, - wp_name=None, - debug_=False): - debug_ |= self.debug - data = { - "endp_name" : endp_name, - "wp_name" : wp_name, - } - response = self.json_post("/cli-json/clear_wp_counters", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/create_client - - https://www.candelatech.com/lfcli_ug.php#create_client - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_create_client(self, - name=None, - password=None, - super_user=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - "password" : password, - "super_user" : super_user, - } - response = self.json_post("/cli-json/create_client", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/diag - - https://www.candelatech.com/lfcli_ug.php#diag - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_diag(self, - arg1=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "arg1" : arg1, - "type" : type, - } - response = self.json_post("/cli-json/diag", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/discover - - https://www.candelatech.com/lfcli_ug.php#discover - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_discover(self, - disconnect=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "disconnect" : disconnect, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/discover", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/do_pesq - - https://www.candelatech.com/lfcli_ug.php#do_pesq - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_do_pesq(self, - endp_name=None, - result_file_name=None, - debug_=False): - debug_ |= self.debug - data = { - "endp_name" : endp_name, - "result_file_name" : result_file_name, - } - response = self.json_post("/cli-json/do_pesq", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/exit - - https://www.candelatech.com/lfcli_ug.php#quit - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_exit(self, - debug_=False): - debug_ |= self.debug - data = { - } - response = self.json_post("/cli-json/exit", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/file - - https://www.candelatech.com/lfcli_ug.php#file - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_file(self, - card=None, - cmd=None, - filename=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "card" : card, - "cmd" : cmd, - "filename" : filename, - "shelf" : shelf, - } - response = self.json_post("/cli-json/file", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/flash_attenuator - - https://www.candelatech.com/lfcli_ug.php#flash_attenuator - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_flash_attenuator(self, - filename=None, - resource=None, - serno=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "filename" : filename, - "resource" : resource, - "serno" : serno, - "shelf" : shelf, - } - response = self.json_post("/cli-json/flash_attenuator", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getavglatency - - https://www.candelatech.com/lfcli_ug.php#getavglatency - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getavglatency(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getavglatency", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getinrxbps - - https://www.candelatech.com/lfcli_ug.php#getinrxbps - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getinrxbps(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getinrxbps", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getinrxrate - - https://www.candelatech.com/lfcli_ug.php#getinrxrate - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getinrxrate(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getinrxrate", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getintxrate - - https://www.candelatech.com/lfcli_ug.php#getintxrate - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getintxrate(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getintxrate", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getipadd - - https://www.candelatech.com/lfcli_ug.php#getipadd - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getipadd(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getipadd", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getmac - - https://www.candelatech.com/lfcli_ug.php#getmac - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getmac(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getmac", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getmask - - https://www.candelatech.com/lfcli_ug.php#getmask - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getmask(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getmask", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getpktdrops - - https://www.candelatech.com/lfcli_ug.php#getpktdrops - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getpktdrops(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getpktdrops", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getrxendperrpkts - - https://www.candelatech.com/lfcli_ug.php#getrxendperrpkts - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getrxendperrpkts(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getrxendperrpkts", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getrxpkts - - https://www.candelatech.com/lfcli_ug.php#getrxpkts - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getrxpkts(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getrxpkts", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/getrxporterrpkts - - https://www.candelatech.com/lfcli_ug.php#getrxporterrpkts - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_getrxporterrpkts(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/getrxporterrpkts", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/gettxpkts - - https://www.candelatech.com/lfcli_ug.php#gettxpkts - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_gettxpkts(self, - aorb=None, - cx=None, - debug_=False): - debug_ |= self.debug - data = { - "aorb" : aorb, - "cx" : cx, - } - response = self.json_post("/cli-json/gettxpkts", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/gossip - - https://www.candelatech.com/lfcli_ug.php#gossip - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_gossip(self, - message=None, - debug_=False): - debug_ |= self.debug - data = { - "message" : message, - } - response = self.json_post("/cli-json/gossip", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/help - - https://www.candelatech.com/lfcli_ug.php#help - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_help(self, - command=None, - debug_=False): - debug_ |= self.debug - data = { - "command" : command, - } - response = self.json_post("/cli-json/help", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/init_wiser - - https://www.candelatech.com/lfcli_ug.php#init_wiser - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_init_wiser(self, - file_name=None, - node_count=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "file_name" : file_name, - "node_count" : node_count, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/init_wiser", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/licenses - - https://www.candelatech.com/lfcli_ug.php#licenses - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_licenses(self, - popup=None, - show_file=None, - debug_=False): - debug_ |= self.debug - data = { - "popup" : popup, - "show_file" : show_file, - } - response = self.json_post("/cli-json/licenses", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/load - - https://www.candelatech.com/lfcli_ug.php#load - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_load(self, - action=None, - clean_chambers=None, - clean_dut=None, - clean_profiles=None, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "action" : action, - "clean_chambers" : clean_chambers, - "clean_dut" : clean_dut, - "clean_profiles" : clean_profiles, - "name" : name, - } - response = self.json_post("/cli-json/load", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/log_level - - https://www.candelatech.com/lfcli_ug.php#log_level - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class log_level_level(Enum): - ALL = 4294967295 # Log everything - CUST1 = 65536 # Cust-1, latency info (65536) - DB = 128 # Database related logging (128) - DBG = 32 # debug (32) - DBG2 = 4096 # very verbose logging (4096) - DIS = 1 # disasters (1) - ERR = 2 # errors (2) - INF = 8 # info (8) - LIO = 8192 # IO logging (8192) - LL_PROF = 32768 # Profiling information (32768) - OUT1 = 16384 # Some std-out logging (16384) - PARSE = 2048 # PARSE specific (2048) - SCRIPT = 1024 # Scripting specific stuff (1024) - SEC = 64 # log security violations (64) - TRC = 16 # function trace (16) - WRN = 4 # warnings (4) - XMT = 256 # Output going to clients (256) - - - def post_log_level(self, - level=None, - target=None, - debug_=False): - debug_ |= self.debug - data = { - "level" : level, - "target" : target, - } - response = self.json_post("/cli-json/log_level", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/log_msg - - https://www.candelatech.com/lfcli_ug.php#log_msg - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_log_msg(self, - message=None, - debug_=False): - debug_ |= self.debug - data = { - "message" : message, - } - response = self.json_post("/cli-json/log_msg", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/login - - https://www.candelatech.com/lfcli_ug.php#login - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_login(self, - name=None, - password=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - "password" : password, - } - response = self.json_post("/cli-json/login", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/logout - - https://www.candelatech.com/lfcli_ug.php#quit - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_logout(self, - debug_=False): - debug_ |= self.debug - data = { - } - response = self.json_post("/cli-json/logout", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/motd - - https://www.candelatech.com/lfcli_ug.php#motd - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_motd(self, - debug_=False): - debug_ |= self.debug - data = { - } - response = self.json_post("/cli-json/motd", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/nc_show_cd - - https://www.candelatech.com/lfcli_ug.php#nc_show_cd - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_nc_show_cd(self, - collision_domain=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "collision_domain" : collision_domain, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/nc_show_cd", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/nc_show_channel_groups - - https://www.candelatech.com/lfcli_ug.php#nc_show_channel_groups - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_nc_show_channel_groups(self, - channel_name=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "channel_name" : channel_name, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/nc_show_channel_groups", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/nc_show_endpoints - - https://www.candelatech.com/lfcli_ug.php#nc_show_endpoints - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_nc_show_endpoints(self, - endpoint=None, - extra=None, - debug_=False): - debug_ |= self.debug - data = { - "endpoint" : endpoint, - "extra" : extra, - } - response = self.json_post("/cli-json/nc_show_endpoints", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/nc_show_pesq - - https://www.candelatech.com/lfcli_ug.php#nc_show_pesq - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_nc_show_pesq(self, - endpoint=None, - debug_=False): - debug_ |= self.debug - data = { - "endpoint" : endpoint, - } - response = self.json_post("/cli-json/nc_show_pesq", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/nc_show_ports - - https://www.candelatech.com/lfcli_ug.php#nc_show_ports - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class nc_show_ports_probe_flags(Enum): - BRIDGE = 8 # 8 include bridges - EASY_IP_INFO = 16 # 16 Everything but gateway information, which is expensive to probe. - ETHTOOL = 4 # 4 include ethtool results - GW = 32 # 32 include gateway information - GW_FORCE_REFRESH = 64 # 64 Force GW (re)probe. Otherwise, cached values *might* be used. - MII = 2 # 2 include MII - WIFI = 1 # 1 include wifi stations - - - def post_nc_show_ports(self, - port=None, - probe_flags=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "port" : port, - "probe_flags" : probe_flags, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/nc_show_ports", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/nc_show_ppp_links - - https://www.candelatech.com/lfcli_ug.php#nc_show_ppp_links - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_nc_show_ppp_links(self, - link_num=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "link_num" : link_num, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/nc_show_ppp_links", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/nc_show_spans - - https://www.candelatech.com/lfcli_ug.php#nc_show_spans - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_nc_show_spans(self, - resource=None, - shelf=None, - span_number=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - "span_number" : span_number, - } - response = self.json_post("/cli-json/nc_show_spans", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/nc_show_vr - - https://www.candelatech.com/lfcli_ug.php#nc_show_vr - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_nc_show_vr(self, - resource=None, - router=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "router" : router, - "shelf" : shelf, - } - response = self.json_post("/cli-json/nc_show_vr", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/nc_show_vrcx - - https://www.candelatech.com/lfcli_ug.php#nc_show_vrcx - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_nc_show_vrcx(self, - cx_name=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "cx_name" : cx_name, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/nc_show_vrcx", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/notify_dhcp - - https://www.candelatech.com/lfcli_ug.php#notify_dhcp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_notify_dhcp(self, - cmd=None, - netmask=None, - new_dns=None, - new_ip=None, - new_ip6=None, - new_mtu=None, - new_router=None, - port=None, - reason=None, - debug_=False): - debug_ |= self.debug - data = { - "cmd" : cmd, - "netmask" : netmask, - "new_dns" : new_dns, - "new_ip" : new_ip, - "new_ip6" : new_ip6, - "new_mtu" : new_mtu, - "new_router" : new_router, - "port" : port, - "reason" : reason, - } - response = self.json_post("/cli-json/notify_dhcp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/port_reset_completed - - https://www.candelatech.com/lfcli_ug.php#port_reset_completed - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_port_reset_completed(self, - extra=None, - port=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "extra" : extra, - "port" : port, - "type" : type, - } - response = self.json_post("/cli-json/port_reset_completed", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/probe_port - - https://www.candelatech.com/lfcli_ug.php#probe_port - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_probe_port(self, - key=None, - port=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "key" : key, - "port" : port, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/probe_port", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/probe_ports - - https://www.candelatech.com/lfcli_ug.php#probe_ports - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_probe_ports(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/probe_ports", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/quiesce_endp - - https://www.candelatech.com/lfcli_ug.php#quiesce_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_quiesce_endp(self, - endp_name=None, - debug_=False): - debug_ |= self.debug - data = { - "endp_name" : endp_name, - } - response = self.json_post("/cli-json/quiesce_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/quiesce_group - - https://www.candelatech.com/lfcli_ug.php#quiesce_group - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_quiesce_group(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/quiesce_group", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/quit - - https://www.candelatech.com/lfcli_ug.php#quit - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_quit(self, - debug_=False): - debug_ |= self.debug - data = { - } - response = self.json_post("/cli-json/quit", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/reboot_os - - https://www.candelatech.com/lfcli_ug.php#reboot_os - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_reboot_os(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/reboot_os", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/report - - https://www.candelatech.com/lfcli_ug.php#report - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_report(self, - reporting_on=None, - rpt_dir=None, - save_endps=None, - save_ports=None, - save_resource=None, - debug_=False): - debug_ |= self.debug - data = { - "reporting_on" : reporting_on, - "rpt_dir" : rpt_dir, - "save_endps" : save_endps, - "save_ports" : save_ports, - "save_resource" : save_resource, - } - response = self.json_post("/cli-json/report", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/reset_port - - https://www.candelatech.com/lfcli_ug.php#reset_port - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class reset_port_pre_ifdown(Enum): - P_IN = 0 # Only call the portal login (do not reset drivers/supplicant/dhcp) - P_OUT = 0 # Only call the portal logout (do not reset drivers/supplicant/dhcp) - YES = 0 # (include logout) Call portal-bot.pl ... --logout before going down. - - - def post_reset_port(self, - port=None, - pre_ifdown=None, - reset_ospf=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "port" : port, - "pre_ifdown" : pre_ifdown, - "reset_ospf" : reset_ospf, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/reset_port", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/reset_serial_span - - https://www.candelatech.com/lfcli_ug.php#reset_serial_span - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_reset_serial_span(self, - resource=None, - shelf=None, - span=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - "span" : span, - } - response = self.json_post("/cli-json/reset_serial_span", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_attenuator - - https://www.candelatech.com/lfcli_ug.php#rm_attenuator - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_attenuator(self, - resource=None, - serno=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "serno" : serno, - "shelf" : shelf, - } - response = self.json_post("/cli-json/rm_attenuator", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_cd - - https://www.candelatech.com/lfcli_ug.php#rm_cd - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_cd(self, - cd=None, - debug_=False): - debug_ |= self.debug - data = { - "cd" : cd, - } - response = self.json_post("/cli-json/rm_cd", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_cd_endp - - https://www.candelatech.com/lfcli_ug.php#rm_cd_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_cd_endp(self, - cd=None, - endp=None, - debug_=False): - debug_ |= self.debug - data = { - "cd" : cd, - "endp" : endp, - } - response = self.json_post("/cli-json/rm_cd_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_cd_vr - - https://www.candelatech.com/lfcli_ug.php#rm_cd_vr - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_cd_vr(self, - cd=None, - endp=None, - debug_=False): - debug_ |= self.debug - data = { - "cd" : cd, - "endp" : endp, - } - response = self.json_post("/cli-json/rm_cd_vr", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_chamber - - https://www.candelatech.com/lfcli_ug.php#rm_chamber - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_chamber(self, - chamber=None, - debug_=False): - debug_ |= self.debug - data = { - "chamber" : chamber, - } - response = self.json_post("/cli-json/rm_chamber", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_chamber_path - - https://www.candelatech.com/lfcli_ug.php#rm_chamber_path - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_chamber_path(self, - chamber=None, - path=None, - debug_=False): - debug_ |= self.debug - data = { - "chamber" : chamber, - "path" : path, - } - response = self.json_post("/cli-json/rm_chamber_path", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_channel_group - - https://www.candelatech.com/lfcli_ug.php#rm_channel_group - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_channel_group(self, - channel_name=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "channel_name" : channel_name, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/rm_channel_group", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_client - - https://www.candelatech.com/lfcli_ug.php#rm_client - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_client(self, - client_name=None, - client_password=None, - debug_=False): - debug_ |= self.debug - data = { - "client_name" : client_name, - "client_password" : client_password, - } - response = self.json_post("/cli-json/rm_client", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_cx - - https://www.candelatech.com/lfcli_ug.php#rm_cx - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_cx(self, - cx_name=None, - test_mgr=None, - debug_=False): - debug_ |= self.debug - data = { - "cx_name" : cx_name, - "test_mgr" : test_mgr, - } - response = self.json_post("/cli-json/rm_cx", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_db - - https://www.candelatech.com/lfcli_ug.php#rm_db - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_db(self, - db_name=None, - debug_=False): - debug_ |= self.debug - data = { - "db_name" : db_name, - } - response = self.json_post("/cli-json/rm_db", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_dut - - https://www.candelatech.com/lfcli_ug.php#rm_dut - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_dut(self, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "shelf" : shelf, - } - response = self.json_post("/cli-json/rm_dut", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_endp - - https://www.candelatech.com/lfcli_ug.php#rm_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_endp(self, - endp_name=None, - debug_=False): - debug_ |= self.debug - data = { - "endp_name" : endp_name, - } - response = self.json_post("/cli-json/rm_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_event - - https://www.candelatech.com/lfcli_ug.php#rm_event - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_event(self, - event_id=None, - debug_=False): - debug_ |= self.debug - data = { - "event_id" : event_id, - } - response = self.json_post("/cli-json/rm_event", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_group - - https://www.candelatech.com/lfcli_ug.php#rm_group - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_group(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/rm_group", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_ppp_link - - https://www.candelatech.com/lfcli_ug.php#rm_ppp_link - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_ppp_link(self, - resource=None, - shelf=None, - unit_num=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - "unit_num" : unit_num, - } - response = self.json_post("/cli-json/rm_ppp_link", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_profile - - https://www.candelatech.com/lfcli_ug.php#rm_profile - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_profile(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/rm_profile", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_resource - - https://www.candelatech.com/lfcli_ug.php#rm_resource - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_resource(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/rm_resource", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_rfgen - - https://www.candelatech.com/lfcli_ug.php#rm_rfgen - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_rfgen(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/rm_rfgen", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_sec_ip - - https://www.candelatech.com/lfcli_ug.php#rm_sec_ip - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_sec_ip(self, - ip_list=None, - port=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "ip_list" : ip_list, - "port" : port, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/rm_sec_ip", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_span - - https://www.candelatech.com/lfcli_ug.php#rm_span - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_span(self, - resource=None, - shelf=None, - span_num=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - "span_num" : span_num, - } - response = self.json_post("/cli-json/rm_span", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_test_mgr - - https://www.candelatech.com/lfcli_ug.php#rm_test_mgr - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_test_mgr(self, - test_mgr=None, - debug_=False): - debug_ |= self.debug - data = { - "test_mgr" : test_mgr, - } - response = self.json_post("/cli-json/rm_test_mgr", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_text_blob - - https://www.candelatech.com/lfcli_ug.php#rm_text_blob - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_text_blob(self, - name=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - "type" : type, - } - response = self.json_post("/cli-json/rm_text_blob", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_tgcx - - https://www.candelatech.com/lfcli_ug.php#rm_tgcx - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_tgcx(self, - cxname=None, - tgname=None, - debug_=False): - debug_ |= self.debug - data = { - "cxname" : cxname, - "tgname" : tgname, - } - response = self.json_post("/cli-json/rm_tgcx", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_threshold - - https://www.candelatech.com/lfcli_ug.php#rm_threshold - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_threshold(self, - endp=None, - thresh_id=None, - debug_=False): - debug_ |= self.debug - data = { - "endp" : endp, - "thresh_id" : thresh_id, - } - response = self.json_post("/cli-json/rm_threshold", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_traffic_profile - - https://www.candelatech.com/lfcli_ug.php#rm_traffic_profile - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_traffic_profile(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/rm_traffic_profile", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_venue - - https://www.candelatech.com/lfcli_ug.php#rm_venue - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_venue(self, - resource=None, - shelf=None, - venu_id=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - "venu_id" : venu_id, - } - response = self.json_post("/cli-json/rm_venue", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_vlan - - https://www.candelatech.com/lfcli_ug.php#rm_vlan - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_vlan(self, - port=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "port" : port, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/rm_vlan", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_vr - - https://www.candelatech.com/lfcli_ug.php#rm_vr - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_vr(self, - resource=None, - router_name=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "router_name" : router_name, - "shelf" : shelf, - } - response = self.json_post("/cli-json/rm_vr", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_vrcx - - https://www.candelatech.com/lfcli_ug.php#rm_vrcx - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_vrcx(self, - connection_name=None, - resource=None, - shelf=None, - vr_id=None, - vrcx_only=None, - debug_=False): - debug_ |= self.debug - data = { - "connection_name" : connection_name, - "resource" : resource, - "shelf" : shelf, - "vr_id" : vr_id, - "vrcx_only" : vrcx_only, - } - response = self.json_post("/cli-json/rm_vrcx", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rm_wanpath - - https://www.candelatech.com/lfcli_ug.php#rm_wanpath - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rm_wanpath(self, - endp_name=None, - wp_name=None, - debug_=False): - debug_ |= self.debug - data = { - "endp_name" : endp_name, - "wp_name" : wp_name, - } - response = self.json_post("/cli-json/rm_wanpath", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/rpt_script - - https://www.candelatech.com/lfcli_ug.php#rpt_script - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_rpt_script(self, - endp=None, - flags=None, - group_action=None, - loop_count=None, - name=None, - private=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "endp" : endp, - "flags" : flags, - "group_action" : group_action, - "loop_count" : loop_count, - "name" : name, - "private" : private, - "type" : type, - } - response = self.json_post("/cli-json/rpt_script", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/save - - https://www.candelatech.com/lfcli_ug.php#write - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_save(self, - db_name=None, - debug_=False): - debug_ |= self.debug - data = { - "db_name" : db_name, - } - response = self.json_post("/cli-json/save", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/scan_wifi - - https://www.candelatech.com/lfcli_ug.php#scan_wifi - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class scan_wifi_extra(Enum): - NA = 0 # (or left blank) the system does a full scan - dump = 0 # then only cached values are returned - trigger_freq__freq_ = 0 # scan exactly those frequencies - - - def post_scan_wifi(self, - extra=None, - key=None, - port=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "extra" : extra, - "key" : key, - "port" : port, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/scan_wifi", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_arm_info - - https://www.candelatech.com/lfcli_ug.php#set_arm_info - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_arm_info_arm_flags(Enum): - random_payload = 65536 # Use random payload sizes instead of linear increase - rel_tstamp = 1024 # Use Relative Timestamps. This will increase performance - slow_start = 8192 # Use slow-start logic. This ramps up - udp_checksum = 16384 # Use UDP Checksums. - use_gw_mac = 4096 # Use default gateway's MAC for destination MAC. - use_tcp = 32768 # Use TCP instead of UDP protocol. (Note this is NOT stateful TCP!) - - - def post_set_arm_info(self, - arm_flags=None, - burst=None, - dst_mac=None, - dst_mac_count=None, - ip_dst_max=None, - ip_dst_min=None, - ip_src_max=None, - ip_src_min=None, - max_pkt_size=None, - min_pkt_size=None, - multi_pkts=None, - name=None, - pkts_to_send=None, - src_mac=None, - src_mac_count=None, - udp_dst_max=None, - udp_dst_min=None, - udp_src_max=None, - udp_src_min=None, - debug_=False): - debug_ |= self.debug - data = { - "arm_flags" : arm_flags, - "burst" : burst, - "dst_mac" : dst_mac, - "dst_mac_count" : dst_mac_count, - "ip_dst_max" : ip_dst_max, - "ip_dst_min" : ip_dst_min, - "ip_src_max" : ip_src_max, - "ip_src_min" : ip_src_min, - "max_pkt_size" : max_pkt_size, - "min_pkt_size" : min_pkt_size, - "multi_pkts" : multi_pkts, - "name" : name, - "pkts_to_send" : pkts_to_send, - "src_mac" : src_mac, - "src_mac_count" : src_mac_count, - "udp_dst_max" : udp_dst_max, - "udp_dst_min" : udp_dst_min, - "udp_src_max" : udp_src_max, - "udp_src_min" : udp_src_min, - } - response = self.json_post("/cli-json/set_arm_info", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_attenuator - - https://www.candelatech.com/lfcli_ug.php#set_attenuator - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_attenuator(self, - atten_idx=None, - mode=None, - pulse_count=None, - pulse_interval_ms=None, - pulse_time_ms=None, - pulse_width_us5=None, - resource=None, - serno=None, - shelf=None, - val=None, - debug_=False): - debug_ |= self.debug - data = { - "atten_idx" : atten_idx, - "mode" : mode, - "pulse_count" : pulse_count, - "pulse_interval_ms" : pulse_interval_ms, - "pulse_time_ms" : pulse_time_ms, - "pulse_width_us5" : pulse_width_us5, - "resource" : resource, - "serno" : serno, - "shelf" : shelf, - "val" : val, - } - response = self.json_post("/cli-json/set_attenuator", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_chamber - - https://www.candelatech.com/lfcli_ug.php#set_chamber - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_chamber(self, - chamber=None, - cur_rotation=None, - position=None, - speed_rpm=None, - tilt=None, - turntable=None, - debug_=False): - debug_ |= self.debug - data = { - "chamber" : chamber, - "cur_rotation" : cur_rotation, - "position" : position, - "speed_rpm" : speed_rpm, - "tilt" : tilt, - "turntable" : turntable, - } - response = self.json_post("/cli-json/set_chamber", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_cx_report_timer - - https://www.candelatech.com/lfcli_ug.php#set_cx_report_timer - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_cx_report_timer(self, - cx_name=None, - cxonly=None, - milliseconds=None, - test_mgr=None, - debug_=False): - debug_ |= self.debug - data = { - "cx_name" : cx_name, - "cxonly" : cxonly, - "milliseconds" : milliseconds, - "test_mgr" : test_mgr, - } - response = self.json_post("/cli-json/set_cx_report_timer", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_cx_state - - https://www.candelatech.com/lfcli_ug.php#set_cx_state - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_cx_state_cx_state(Enum): - DELETED = 0 # Deletes the CX(s). - QUIESCE = 0 # Stop transmitting and gracefully stop cross-connect. - RUNNING = 0 # Sets the CX(s) in the running state. - STOPPED = 0 # Sets the CX(s) in the stopped state. - SWITCH = 0 # Sets the CX(s) in the running state, stopping any conflicting tests. - - - def post_set_cx_state(self, - cx_name=None, - cx_state=None, - test_mgr=None, - debug_=False): - debug_ |= self.debug - data = { - "cx_name" : cx_name, - "cx_state" : cx_state, - "test_mgr" : test_mgr, - } - response = self.json_post("/cli-json/set_cx_state", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_addr - - https://www.candelatech.com/lfcli_ug.php#set_endp_addr - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_endp_addr(self, - ip=None, - mac=None, - max_port=None, - min_port=None, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "ip" : ip, - "mac" : mac, - "max_port" : max_port, - "min_port" : min_port, - "name" : name, - } - response = self.json_post("/cli-json/set_endp_addr", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_details - - https://www.candelatech.com/lfcli_ug.php#set_endp_details - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_endp_details(self, - conn_timeout=None, - dst_mac=None, - max_conn_timer=None, - max_ip_port=None, - max_reconn_pause=None, - mcast_src_ip=None, - mcast_src_port=None, - min_conn_timer=None, - min_reconn_pause=None, - name=None, - pkts_to_send=None, - rcvbuf_size=None, - sndbuf_size=None, - tcp_delack_segs=None, - tcp_max_delack=None, - tcp_min_delack=None, - tcp_mss=None, - debug_=False): - debug_ |= self.debug - data = { - "conn_timeout" : conn_timeout, - "dst_mac" : dst_mac, - "max_conn_timer" : max_conn_timer, - "max_ip_port" : max_ip_port, - "max_reconn_pause" : max_reconn_pause, - "mcast_src_ip" : mcast_src_ip, - "mcast_src_port" : mcast_src_port, - "min_conn_timer" : min_conn_timer, - "min_reconn_pause" : min_reconn_pause, - "name" : name, - "pkts_to_send" : pkts_to_send, - "rcvbuf_size" : rcvbuf_size, - "sndbuf_size" : sndbuf_size, - "tcp_delack_segs" : tcp_delack_segs, - "tcp_max_delack" : tcp_max_delack, - "tcp_min_delack" : tcp_min_delack, - "tcp_mss" : tcp_mss, - } - response = self.json_post("/cli-json/set_endp_details", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_file - - https://www.candelatech.com/lfcli_ug.php#set_endp_file - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_endp_file(self, - file=None, - name=None, - playback=None, - debug_=False): - debug_ |= self.debug - data = { - "file" : file, - "name" : name, - "playback" : playback, - } - response = self.json_post("/cli-json/set_endp_file", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_flag - - https://www.candelatech.com/lfcli_ug.php#set_endp_flag - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_endp_flag_flag(Enum): - AutoHelper = 0 # Automatically run on helper process - ClearPortOnStart = 0 # clear stats on start - DoChecksum = 0 # Enable checksumming - EnableConcurrentSrcIP = 0 # Concurrent source IPs? - EnableLinearSrcIP = 0 # linearized source IPs - EnableLinearSrcIPPort = 0 # linearized IP ports - EnableRndSrcIP = 0 # randomize source IP - KernelMode = 0 # Enable kernel mode - QuiesceAfterDuration = 0 # quiesce after time period - QuiesceAfterRange = 0 # quiesce after range of bytes - Unmanaged = 0 # Set endpoint unmanaged - UseAutoNAT = 0 # NAT friendly behavior - - - def post_set_endp_flag(self, - flag=None, - name=None, - val=None, - debug_=False): - debug_ |= self.debug - data = { - "flag" : flag, - "name" : name, - "val" : val, - } - response = self.json_post("/cli-json/set_endp_flag", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_payload - - https://www.candelatech.com/lfcli_ug.php#set_endp_payload - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_endp_payload_payload_type(Enum): - PRBS_11_8_10 = 0 # PRBS (see above) - PRBS_15_0_14 = 0 # PRBS (see above) - PRBS_4_0_3 = 0 # Use linear feedback shift register to generate pseudo random sequence. - PRBS_7_0_6 = 0 # PRBS (see above) - custom = 0 # Enter your own payload with the set_endp_payload - decreasing = 0 # bytes start at FF and decrease, wrapping if needed. - increasing = 0 # bytes start at 00 and increase, wrapping if needed. - ones = 0 # Payload is all ones (FF). - random = 0 # generate a new random payload each time sent. - random_fixed = 0 # means generate one random payload, and send it over and over again. - zeros = 0 # Payload is all zeros (00). - - - def post_set_endp_payload(self, - name=None, - payload=None, - payload_type=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - "payload" : payload, - "payload_type" : payload_type, - } - response = self.json_post("/cli-json/set_endp_payload", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_pld_bounds - - https://www.candelatech.com/lfcli_ug.php#set_endp_pld_bounds - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_endp_pld_bounds(self, - is_random=None, - max_pld_size=None, - min_pld_size=None, - name=None, - use_checksum=None, - debug_=False): - debug_ |= self.debug - data = { - "is_random" : is_random, - "max_pld_size" : max_pld_size, - "min_pld_size" : min_pld_size, - "name" : name, - "use_checksum" : use_checksum, - } - response = self.json_post("/cli-json/set_endp_pld_bounds", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_proxy - - https://www.candelatech.com/lfcli_ug.php#set_endp_proxy - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_endp_proxy(self, - enabled=None, - endp_name=None, - proxy_ip=None, - proxy_ip_port=None, - debug_=False): - debug_ |= self.debug - data = { - "enabled" : enabled, - "endp_name" : endp_name, - "proxy_ip" : proxy_ip, - "proxy_ip_port" : proxy_ip_port, - } - response = self.json_post("/cli-json/set_endp_proxy", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_quiesce - - https://www.candelatech.com/lfcli_ug.php#set_endp_quiesce - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_endp_quiesce(self, - name=None, - quiesce=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - "quiesce" : quiesce, - } - response = self.json_post("/cli-json/set_endp_quiesce", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_report_timer - - https://www.candelatech.com/lfcli_ug.php#set_endp_report_timer - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_endp_report_timer(self, - endp_name=None, - milliseconds=None, - debug_=False): - debug_ |= self.debug - data = { - "endp_name" : endp_name, - "milliseconds" : milliseconds, - } - response = self.json_post("/cli-json/set_endp_report_timer", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_tos - - https://www.candelatech.com/lfcli_ug.php#set_endp_tos - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_endp_tos_tos(Enum): - LOWCOST = 0 - LOWDELAY = 0 - RELIABILITY = 0 - THROUGHPUT = 0 - - - def post_set_endp_tos(self, - name=None, - priority=None, - tos=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - "priority" : priority, - "tos" : tos, - } - response = self.json_post("/cli-json/set_endp_tos", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_endp_tx_bounds - - https://www.candelatech.com/lfcli_ug.php#set_endp_tx_bounds - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_endp_tx_bounds(self, - is_bursty=None, - max_tx_rate=None, - min_tx_rate=None, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "is_bursty" : is_bursty, - "max_tx_rate" : max_tx_rate, - "min_tx_rate" : min_tx_rate, - "name" : name, - } - response = self.json_post("/cli-json/set_endp_tx_bounds", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_event_interest - - https://www.candelatech.com/lfcli_ug.php#set_event_interest - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_event_interest_ei_flags(Enum): - CLEAR = 0 # will clear interest - SET = 1 # set interest flag - - class set_event_interest_events1(Enum): - BAD_TOS = 4194304 # Endpoint has bad ToS values configured. - Bad_MAC = 1048576 # Invalid MAC address configured. - Cleared = 8192 # Counters were cleared for some entity. - Connect = 256 # WiFi interface connected to AP. - Custom = 4 # Custom event (generated by USER in GUI or CLI). - DHCP_Fail = 32768 # DHCP Failed, maybe out of leases? - DHCP_Timeout = 65536 # Timed out talking to DHCP server. - DHCP4_Error = 131072 # DHCP gave out duplicated IP address. - DHCP6_Error = 262144 # DHCPv6 gave out duplicated IPv6 address. - Disconnect = 128 # WiFi interface disconnected from AP. - Endp_Started = 64 # Endpoint was started. - Endp_Stopped = 32 # Endpoint stopped for some reason. - Link_Down = 1 # Notify when Interface Link goes DOWN. - Link_Errors = 16384 # Port shows low-level link errors. - Link_Up = 2 # Notify when Interface Link goes UP. - Login = 1024 # CLI/GUI user connected to LANforge. - Logout = 512 # CLI/GUI user disconnected from LANforge. - Migrated = 2097152 # Port (station network interface) migrated. - NO_RX_SINCE = 8388608 # Endpoint threshold alert. - NO_RX_SINCE_CLEARED = 16777216 # Endpoint threshold alert cleared. - RX_BPS_OOR_1M = 536870912 # Endpoint threshold alert. - RX_BPS_OOR_1M_CLEARED = 1073741824 # Endpoint threshold alert cleared. - RX_BPS_OOR_30S = 134217728 # Endpoint threshold alert. - RX_BPS_OOR_30S_CLEARED = 268435456 # Endpoint threshold alert cleared. - RX_BPS_OOR_3S = 33554432 # Endpoint threshold alert. - RX_BPS_OOR_3S_CLEARED = 67108864 # Endpoint threshold alert cleared. - Resource_Down = 8 # Resource has crashed, rebooted, etc. - Resource_Up = 16 # Resource has connected to manager. - Start_Reports = 4096 # Start saving report data files (CSV). - Stop_Reports = 2048 # Stop saving report data files (CSV). - TX_BPS_OOR_3S = 2147483648 # Endpoint threshold alert. - WiFi_Config = 524288 # WiFi Configuration Error. - - class set_event_interest_events2(Enum): - FW_CRASH = 2048 # Firmware for entity has crashed. - FW_FAIL = 4096 # Firmware failed powerup, may require reboot. - IFDOWN_FAIL = 32768 # IFDOWN-PRE Script (ifup --logout) returned error code. - IFDOWN_OK = 65536 # IFDOWN-PRE Script (ifup --logout) completed successfully. - IFUP_FAIL = 8192 # IFUP-POST Script returned error code. - IFUP_OK = 16384 # IFUP-POST Script completed successfully. - RX_DROP_OOR_1M = 512 # Endpoint threshold alert. - RX_DROP_OOR_1M_CLEARED = 1024 # Endpoint threshold alert cleared. - RX_DROP_OOR_3S = 128 # Endpoint threshold alert. - RX_DROP_OOR_3S_CLEARED = 256 # Endpoint threshold alert cleared. - RX_LAT_OOR = 32 # Endpoint threshold alert. - RX_LAT_OOR_CLEARED = 64 # Endpoint threshold alert cleared. - TX_BPS_OOR_1M = 8 # Endpoint threshold alert. - TX_BPS_OOR_1M_CLEARED = 16 # Endpoint threshold alert cleared. - TX_BPS_OOR_30S = 2 # Endpoint threshold alert. - TX_BPS_OOR_30S_CLEARED = 4 # Endpoint threshold alert cleared. - TX_BPS_OOR_3S_CLEARED = 1 # Endpoint threshold alert cleared. - - - def post_set_event_interest(self, - ei_flags=None, - event_cnt=None, - events1=None, - events2=None, - events3=None, - events4=None, - var1=None, - debug_=False): - debug_ |= self.debug - data = { - "ei_flags" : ei_flags, - "event_cnt" : event_cnt, - "events1" : events1, - "events2" : events2, - "events3" : events3, - "events4" : events4, - "var1" : var1, - } - response = self.json_post("/cli-json/set_event_interest", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_event_priority - - https://www.candelatech.com/lfcli_ug.php#set_event_priority - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_event_priority_event(Enum): - Bad_MAC = 20 # Invalid MAC address configured. - Cleared = 13 # Counters were cleared for some entity. - Connect = 8 # WiFi interface connected to AP. - Custom = 2 # Custom event (generated by USER in GUI or CLI). - DHCP_Fail = 15 # DHCP Failed, maybe out of leases? - DHCP_Timeout = 16 # Timed out talking to DHCP server. - DHCP4_Error = 17 # DHCP gave out duplicated IP address. - DHCP6_Error = 18 # DHCPv6 gave out duplicated IPv6 address. - Disconnect = 7 # WiFi interface disconnected from AP. - Endp_Started = 6 # Endpoint was started. - Endp_Stopped = 5 # Endpoint stopped for some reason. - Link_Down = 0 # Notify when Interface Link goes UP. - Link_Errors = 14 # Port shows low-level link errors. - Link_Up = 1 # Notify when Interface Link goes DOWN. - Login = 10 # CLI/GUI user connected to LANforge. - Logout = 9 # CLI/GUI user disconnected from LANforge. - Migrated = 21 # Port (station network interface) migrated. - Resource_Down = 3 # Resource has crashed, rebooted, etc. - Resource_Up = 4 # Resource has connected to manager. - Start_Reports = 12 # Start saving report data files (CSV). - Stop_Reports = 11 # Stop saving report data files (CSV). - WiFi_Config = 19 # WiFi Configuration Error. - - class set_event_priority_priority(Enum): - AUTO = 0 # Let event creator decide the priority. - CRITICAL = 4 - DEBUG = 1 - FATAL = 5 - INFO = 2 - WARNING = 3 - - - def post_set_event_priority(self, - event=None, - priority=None, - debug_=False): - debug_ |= self.debug - data = { - "event" : event, - "priority" : priority, - } - response = self.json_post("/cli-json/set_event_priority", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_fe_info - - https://www.candelatech.com/lfcli_ug.php#set_fe_info - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_fe_info(self, - directory=None, - io_direction=None, - max_file_size=None, - max_rw_sz=None, - min_file_size=None, - min_rw_sz=None, - name=None, - num_files=None, - prefix=None, - quiesce_after_files=None, - debug_=False): - debug_ |= self.debug - data = { - "directory" : directory, - "io_direction" : io_direction, - "max_file_size" : max_file_size, - "max_rw_sz" : max_rw_sz, - "min_file_size" : min_file_size, - "min_rw_sz" : min_rw_sz, - "name" : name, - "num_files" : num_files, - "prefix" : prefix, - "quiesce_after_files" : quiesce_after_files, - } - response = self.json_post("/cli-json/set_fe_info", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_flag - - https://www.candelatech.com/lfcli_ug.php#set_flag - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_flag_flag(Enum): - brief = 0 # Request more abbreviated output to various commands. - prompt_newlines = 0 # Add a newline after every prompt. Can help with scripts - push_all_rpts = 0 # If enabled, server will send port, endpoint, and other - push_endp_rpts = 0 # If enabled, server will send endpoint reports without - request_keyed_text = 0 # Normally most keyed-text events are only sent to the GUI - stream_events = 0 # Normally the CLI will not show Events (as seen in the Event - - - def post_set_flag(self, - client=None, - flag=None, - val=None, - debug_=False): - debug_ |= self.debug - data = { - "client" : client, - "flag" : flag, - "val" : val, - } - response = self.json_post("/cli-json/set_flag", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_gen_cmd - - https://www.candelatech.com/lfcli_ug.php#set_gen_cmd - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_gen_cmd(self, - command=None, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "command" : command, - "name" : name, - } - response = self.json_post("/cli-json/set_gen_cmd", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_gps_info - - https://www.candelatech.com/lfcli_ug.php#set_gps_info - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_gps_info(self, - altitude=None, - ew=None, - lattitude=None, - longitude=None, - ns=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "altitude" : altitude, - "ew" : ew, - "lattitude" : lattitude, - "longitude" : longitude, - "ns" : ns, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/set_gps_info", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_ifup_script - - https://www.candelatech.com/lfcli_ug.php#set_ifup_script - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_ifup_script(self, - flags=None, - port=None, - post_ifup_script=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "flags" : flags, - "port" : port, - "post_ifup_script" : post_ifup_script, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/set_ifup_script", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_license - - https://www.candelatech.com/lfcli_ug.php#set_license - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_license(self, - licenses=None, - debug_=False): - debug_ |= self.debug - data = { - "licenses" : licenses, - } - response = self.json_post("/cli-json/set_license", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_mc_endp - - https://www.candelatech.com/lfcli_ug.php#set_mc_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_mc_endp(self, - mcast_dest_port=None, - mcast_group=None, - name=None, - rcv_mcast=None, - ttl=None, - debug_=False): - debug_ |= self.debug - data = { - "mcast_dest_port" : mcast_dest_port, - "mcast_group" : mcast_group, - "name" : name, - "rcv_mcast" : rcv_mcast, - "ttl" : ttl, - } - response = self.json_post("/cli-json/set_mc_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_password - - https://www.candelatech.com/lfcli_ug.php#set_password - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_password(self, - client=None, - new_password=None, - old_password=None, - debug_=False): - debug_ |= self.debug - data = { - "client" : client, - "new_password" : new_password, - "old_password" : old_password, - } - response = self.json_post("/cli-json/set_password", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_poll_mode - - https://www.candelatech.com/lfcli_ug.php#set_poll_mode - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_poll_mode(self, - mode=None, - debug_=False): - debug_ |= self.debug - data = { - "mode" : mode, - } - response = self.json_post("/cli-json/set_poll_mode", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_port - - https://www.candelatech.com/lfcli_ug.php#set_port - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_port_cmd_flags(Enum): - abort_if_scripts = 1024 # Forceably abort all ifup/down scripts on this Port. - force_MII_probe = 4 # Force MII probe - from_dhcp = 512 # Settings come from DHCP client. - from_user = 128 # from_user (Required to change Mgt Port config - new_gw_probe = 32 # Force new GW probe - new_gw_probe_dev = 64 # Force new GW probe for ONLY this interface - no_hw_probe = 8 # Don't probe hardware - probe_wifi = 16 # Probe WIFI - reset_transceiver = 1 # Reset transciever - restart_link_neg = 2 # Restart link negotiation - skip_port_bounce = 256 # skip-port-bounce (Don't ifdown/up - use_pre_ifdown = 2048 # Call pre-ifdown script before bringing interface down. - - class set_port_current_flags(Enum): - adv_100bt_fd = 8388608 # advert-100bt-FD - adv_100bt_hd = 4194304 # advert-100bt-HD - adv_10bt_fd = 2097152 # advert-10bt-FD - adv_10bt_hd = 1048576 # advert-10bt-HD - adv_10g_fd = 34359738368 # advert-10G-FD - adv_2_5g_fd = 17179869184 # advert-2.5G-FD - adv_5g_fd = 288230376151711744 # Advertise 5Gbps link speed. - adv_flow_ctl = 134217728 # advert-flow-control - auto_neg = 256 # auto-negotiate - aux_mgt = 140737488355328 # Enable Auxillary-Management flag for this port. - fixed_100bt_fd = 16 # Fixed-100bt-FD - fixed_100bt_hd = 8 # Fixed-100bt-HD - fixed_10bt_fd = 4 # Fixed-10bt-FD - fixed_10bt_hd = 2 # Fixed-10bt-HD (half duplex) - ftp_enabled = 70368744177664 # Enable FTP (vsftpd) service for this port. - gro_enabled = 274877906944 # GRO-Enabled - gso_enabled = 1099511627776 # GSO-Enabled - http_enabled = 35184372088832 # Enable HTTP (nginx) service for this port. - if_down = 1 # Interface Down - ignore_dhcp = 562949953421312 # Don't set DHCP acquired IP on interface, - ipsec_client = 18014398509481984 # Enable client IPSEC xfrm on this port. - ipsec_concentrator = 36028797018963968 # Enable concentrator (upstream) IPSEC xfrm on this port. - lro_enabled = 137438953472 # LRO-Enabled - no_dhcp_rel = 8796093022208 # No-DHCP-Release - no_dhcp_restart = 281474976710656 # Disable restart of DHCP on link connect (ie, wifi). - no_ifup_post = 1125899906842624 # Skip ifup-post script if we can detect that we - promisc = 268435456 # PROMISC - radius_enabled = 9007199254740992 # Enable RADIUS service (using hostapd as radius server) - rxfcs = 4398046511104 # RXFCS - service_dns = 72057594037927936 # Enable DNS (dnsmasq) service on this port. - staged_ifup = 17592186044416 # Staged-IFUP - tso_enabled = 68719476736 # TSO-Enabled - ufo_enabled = 549755813888 # UFO-Enabled - use_dhcp = 2147483648 # USE-DHCP - use_dhcpv6 = 2199023255552 # USE-DHCPv6 - - class set_port_dhcp_client_id(Enum): - NA = 0 # Do not change from current value. - NONE = 0 # Do not use dhcp client ID. - _string_ = 0 # Use the string for the client ID. - __DEVNAME = 0 # Use the interface's name as the client ID. - __MAC = 0 # Use interface's MAC address for the client ID. - - class set_port_dhcp_hostname(Enum): - NA = 0 # Do not change from current value. - NONE = 0 # Do not use dhcp Hostname - _string_ = 0 # Use the string for the Hostname. - __ALIAS__ = 0 # Use alias if set, or EID behaviour if alias is not set.. - __EID__ = 0 # Use hostname 'CT-[resource-id].[port-name]' - - class set_port_dhcp_vendor_id(Enum): - NA = 0 # Do not change from current value. - NONE = 0 # Do not use dhcp vendor ID - _string_ = 0 # Use the string for the vendor ID. - - class set_port_flags2(Enum): - bypass_disconnect = 512 # Logically disconnect the cable (link-down) - bypass_enabled = 16 # Enable Bypass Device - bypass_power_down = 128 # Should bypass be on when we shutdown or loose power? - bypass_power_on = 256 # Should bypass be on when we first power up? - supports_bypass = 2 # Support Bypass Devices - use_stp = 1 # Use Spanning Tree Protocol - - class set_port_interest(Enum): - alias = 4096 # Port alias - aux_mgt = 536870912 # Enable/disable Auxillary-Management for a port - bridge = 65536 # BRIDGE - bypass = 262144 # Bypass - command_flags = 1 # apply command flags - cpu_mask = 1048576 # CPU Mask, useful for pinning process to CPU core - current_flags = 2 # apply current flags - dhcp = 16384 # including client-id. - dhcp_rls = 67108864 # DHCP release - dhcpv6 = 16777216 # Use DHCPv6 - gen_offload = 524288 # Generic offload flags, everything but LRO - ifdown = 8388608 # Down interface - interal_use_1 = 2048 # (INTERNAL USE) - ip_Mask = 8 # IP mask - ip_address = 4 # IP address - ip_gateway = 16 # IP gateway - ipv6_addrs = 131072 # IPv6 Address - link_speed = 128 # Link speed - lro_offload = 2097152 # LRO (Must be disabled when used in Wanlink, - mac_address = 32 # MAC address - mtu = 256 # MTU - no_apply_dhcp = 2147483648 # Enable/disable NO-APPLY-DHCP flag for a port - no_dhcp_conn = 1073741824 # Enable/disable NO-DHCP-ON-CONNECT flag for a port - promisc_mode = 1024 # PROMISC mode - rpt_timer = 32768 # Report Timer - rx_all = 8192 # Rx-ALL - rxfcs = 33554432 # RXFCS - skip_ifup_roam = 4294967296 # Enable/disable SKIP-IFUP-ON-ROAM flag for a port - sta_br_id = 4194304 # WiFi Bridge identifier. 0 means no bridging. - supported_flags = 64 # apply supported flags - svc_ftpd = 268435456 # Enable/disable FTP Service for a port - svc_httpd = 134217728 # Enable/disable HTTP Service for a port - tx_queue_length = 512 # TX Queue Length - - - def post_set_port(self, - alias=None, - br_aging_time=None, - br_forwarding_delay=None, - br_hello_time=None, - br_max_age=None, - br_port_cost=None, - br_port_priority=None, - br_priority=None, - bypass_wdt=None, - cmd_flags=None, - cpu_mask=None, - current_flags=None, - current_flags_msk=None, - dhcp_client_id=None, - dhcp_hostname=None, - dhcp_vendor_id=None, - dns_servers=None, - flags2=None, - gateway=None, - interest=None, - ip_addr=None, - ipsec_concentrator=None, - ipsec_local_id=None, - ipsec_passwd=None, - ipsec_remote_id=None, - ipv6_addr_global=None, - ipv6_addr_link=None, - ipv6_dflt_gw=None, - mac=None, - mtu=None, - netmask=None, - port=None, - report_timer=None, - resource=None, - shelf=None, - sta_br_id=None, - tx_queue_len=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "br_aging_time" : br_aging_time, - "br_forwarding_delay" : br_forwarding_delay, - "br_hello_time" : br_hello_time, - "br_max_age" : br_max_age, - "br_port_cost" : br_port_cost, - "br_port_priority" : br_port_priority, - "br_priority" : br_priority, - "bypass_wdt" : bypass_wdt, - "cmd_flags" : cmd_flags, - "cpu_mask" : cpu_mask, - "current_flags" : current_flags, - "current_flags_msk" : current_flags_msk, - "dhcp_client_id" : dhcp_client_id, - "dhcp_hostname" : dhcp_hostname, - "dhcp_vendor_id" : dhcp_vendor_id, - "dns_servers" : dns_servers, - "flags2" : flags2, - "gateway" : gateway, - "interest" : interest, - "ip_addr" : ip_addr, - "ipsec_concentrator" : ipsec_concentrator, - "ipsec_local_id" : ipsec_local_id, - "ipsec_passwd" : ipsec_passwd, - "ipsec_remote_id" : ipsec_remote_id, - "ipv6_addr_global" : ipv6_addr_global, - "ipv6_addr_link" : ipv6_addr_link, - "ipv6_dflt_gw" : ipv6_dflt_gw, - "mac" : mac, - "mtu" : mtu, - "netmask" : netmask, - "port" : port, - "report_timer" : report_timer, - "resource" : resource, - "shelf" : shelf, - "sta_br_id" : sta_br_id, - "tx_queue_len" : tx_queue_len, - } - response = self.json_post("/cli-json/set_port", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_port_alias - - https://www.candelatech.com/lfcli_ug.php#set_port_alias - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_port_alias(self, - alias=None, - port=None, - resource=None, - shelf=None, - vport=None, - debug_=False): - debug_ |= self.debug - data = { - "alias" : alias, - "port" : port, - "resource" : resource, - "shelf" : shelf, - "vport" : vport, - } - response = self.json_post("/cli-json/set_port_alias", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_ppp_link_state - - https://www.candelatech.com/lfcli_ug.php#set_ppp_link_state - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_ppp_link_state(self, - link=None, - ppp_state=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "link" : link, - "ppp_state" : ppp_state, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/set_ppp_link_state", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_resource - - https://www.candelatech.com/lfcli_ug.php#set_resource - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_resource_resource_flags(Enum): - skip_load_db_on_start = 1 # Should we skip loading the DB on start? - - - def post_set_resource(self, - device_profiles=None, - max_helper_count=None, - max_staged_bringup=None, - max_station_bringup=None, - max_trying_ifup=None, - resource=None, - resource_flags=None, - resource_flags_mask=None, - shelf=None, - top_left_x=None, - top_left_y=None, - debug_=False): - debug_ |= self.debug - data = { - "device_profiles" : device_profiles, - "max_helper_count" : max_helper_count, - "max_staged_bringup" : max_staged_bringup, - "max_station_bringup" : max_station_bringup, - "max_trying_ifup" : max_trying_ifup, - "resource" : resource, - "resource_flags" : resource_flags, - "resource_flags_mask" : resource_flags_mask, - "shelf" : shelf, - "top_left_x" : top_left_x, - "top_left_y" : top_left_y, - } - response = self.json_post("/cli-json/set_resource", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_rfgen - - https://www.candelatech.com/lfcli_ug.php#set_rfgen - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_rfgen_rfgen_flags(Enum): - one_burst = 8 # Run for about 1 second and stop. Uses 5-sec sweep time for single pulse train. - running = 2 # Should we start the RF Generator or not? - - - def post_set_rfgen(self, - bb_gain=None, - freq_khz=None, - gain=None, - id=None, - if_gain=None, - pulse_count=None, - pulse_interval_us=None, - pulse_width_us=None, - resource=None, - rfgen_flags=None, - rfgen_flags_mask=None, - shelf=None, - sweep_time_ms=None, - debug_=False): - debug_ |= self.debug - data = { - "bb_gain" : bb_gain, - "freq_khz" : freq_khz, - "gain" : gain, - "id" : id, - "if_gain" : if_gain, - "pulse_count" : pulse_count, - "pulse_interval_us" : pulse_interval_us, - "pulse_width_us" : pulse_width_us, - "resource" : resource, - "rfgen_flags" : rfgen_flags, - "rfgen_flags_mask" : rfgen_flags_mask, - "shelf" : shelf, - "sweep_time_ms" : sweep_time_ms, - } - response = self.json_post("/cli-json/set_rfgen", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_script - - https://www.candelatech.com/lfcli_ug.php#set_script - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_script_flags(Enum): - SCR_COMPLETED = 128 # Set automatically by LANforge. - SCR_HIDE_CONSTRAINTS = 8192 # Hide constraints messages. - SCR_HIDE_CSV = 32 # Don't print the CSV data in the report. - SCR_HIDE_HUNT = 2048 # Hide the individual hunt steps..just show results. - SCR_HIDE_ITER_DETAILS = 8 # Hide iteration detail reports. - SCR_HIDE_LAT = 4096 # Hide latency distribution reports. - SCR_HIDE_LEGEND = 16 # Don't print the legend in the report. - SCR_LOOP = 256 # Loop script until manually stopped. - SCR_NO_KEYED_RPT = 2 # Script should NOT send reports to the CLI/GUI. - SCR_RUN_ON_MGR = 64 # Set automatically by LANforge. - SCR_SHOW_ATTENUATION = 16384 # Show attenuation packet stats. - SCR_SHOW_DUPS = 512 # Report duplicate packets. - SCR_SHOW_GOLDEN_3P = 131072 # Add 'golden' third-party AP graph for comparison (where available). - SCR_SHOW_GOLDEN_LF = 65536 # Add 'golden' LANforge graph for comparison (where available). - SCR_SHOW_OOO = 1024 # Report out-of-order packets. - SCR_STOPPED = 1 # Script should NOT have any affect on the endpoint. - SCR_SYMMETRIC = 4 # This script should apply settings to the peer endpoing as well. - SCR_USE_MSS = 32768 # When setting packet size, set TCP MSS instead if endpoint supports that. - - class set_script_type(Enum): - NONE = 0 # Delete any existing script. - Script2544 = 0 # For RFC 2544 type testing. - ScriptAtten = 0 # For Attenuators only. - ScriptHunt = 0 # Hunt for maximum speed with constraints. - ScriptWL = 0 # For iterating through WanLink settings - - - def post_set_script(self, - endp=None, - flags=None, - group_action=None, - loop_count=None, - name=None, - private=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "endp" : endp, - "flags" : flags, - "group_action" : group_action, - "loop_count" : loop_count, - "name" : name, - "private" : private, - "type" : type, - } - response = self.json_post("/cli-json/set_script", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_sec_ip - - https://www.candelatech.com/lfcli_ug.php#set_sec_ip - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_sec_ip(self, - ip_list=None, - port=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "ip_list" : ip_list, - "port" : port, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/set_sec_ip", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_voip_info - - https://www.candelatech.com/lfcli_ug.php#set_voip_info - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_voip_info(self, - codec=None, - first_call_delay=None, - jitter_buffer_sz=None, - local_sip_port=None, - loop_call_count=None, - loop_wavefile_count=None, - max_call_duration=None, - max_inter_call_gap=None, - messaging_protocol=None, - min_call_duration=None, - min_inter_call_gap=None, - name=None, - pesq_server_ip=None, - pesq_server_passwd=None, - pesq_server_port=None, - reg_expire_timer=None, - ringing_timer=None, - sound_dev=None, - debug_=False): - debug_ |= self.debug - data = { - "codec" : codec, - "first_call_delay" : first_call_delay, - "jitter_buffer_sz" : jitter_buffer_sz, - "local_sip_port" : local_sip_port, - "loop_call_count" : loop_call_count, - "loop_wavefile_count" : loop_wavefile_count, - "max_call_duration" : max_call_duration, - "max_inter_call_gap" : max_inter_call_gap, - "messaging_protocol" : messaging_protocol, - "min_call_duration" : min_call_duration, - "min_inter_call_gap" : min_inter_call_gap, - "name" : name, - "pesq_server_ip" : pesq_server_ip, - "pesq_server_passwd" : pesq_server_passwd, - "pesq_server_port" : pesq_server_port, - "reg_expire_timer" : reg_expire_timer, - "ringing_timer" : ringing_timer, - "sound_dev" : sound_dev, - } - response = self.json_post("/cli-json/set_voip_info", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_vrcx_cost - - https://www.candelatech.com/lfcli_ug.php#set_vrcx_cost - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_vrcx_cost(self, - interface_cost=None, - local_dev=None, - local_dev_b=None, - remote_dev=None, - remote_dev_b=None, - resource=None, - shelf=None, - vr_name=None, - wanlink=None, - debug_=False): - debug_ |= self.debug - data = { - "interface_cost" : interface_cost, - "local_dev" : local_dev, - "local_dev_b" : local_dev_b, - "remote_dev" : remote_dev, - "remote_dev_b" : remote_dev_b, - "resource" : resource, - "shelf" : shelf, - "vr_name" : vr_name, - "wanlink" : wanlink, - } - response = self.json_post("/cli-json/set_vrcx_cost", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wanlink_info - - https://www.candelatech.com/lfcli_ug.php#set_wanlink_info - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_wanlink_info(self, - drop_freq=None, - dup_freq=None, - extra_buffer=None, - jitter_freq=None, - latency=None, - max_drop_amt=None, - max_jitter=None, - max_lateness=None, - max_reorder_amt=None, - min_drop_amt=None, - min_reorder_amt=None, - name=None, - playback_capture_file=None, - reorder_freq=None, - speed=None, - debug_=False): - debug_ |= self.debug - data = { - "drop_freq" : drop_freq, - "dup_freq" : dup_freq, - "extra_buffer" : extra_buffer, - "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, - "name" : name, - "playback_capture_file" : playback_capture_file, - "reorder_freq" : reorder_freq, - "speed" : speed, - } - response = self.json_post("/cli-json/set_wanlink_info", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wanlink_pcap - - https://www.candelatech.com/lfcli_ug.php#set_wanlink_pcap - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_wanlink_pcap(self, - capture=None, - directory=None, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "capture" : capture, - "directory" : directory, - "name" : name, - } - response = self.json_post("/cli-json/set_wanlink_pcap", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wanpath_corruption - - https://www.candelatech.com/lfcli_ug.php#set_wanpath_corruption - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_wanpath_corruption_flags(Enum): - BIT_FLIP = 4 # Flip a random bit in a byte. - BIT_TRANSPOSE = 8 # Transpose two side-by-side bits in a byte. - DO_CHAIN_ON_HIT = 16 # Do next corruption if this corruption is applied. - OVERWRITE_FIXED = 2 # Write a fixed value to a byte. - OVERWRITE_RANDOM = 1 # Write a random value to a byte. - RECALC_CSUMS = 32 # Attempt to re-calculate UDP and TCP checksums. - - - def post_set_wanpath_corruption(self, - byte=None, - flags=None, - index=None, - max_offset=None, - min_offset=None, - name=None, - path=None, - rate=None, - debug_=False): - debug_ |= self.debug - data = { - "byte" : byte, - "flags" : flags, - "index" : index, - "max_offset" : max_offset, - "min_offset" : min_offset, - "name" : name, - "path" : path, - "rate" : rate, - } - response = self.json_post("/cli-json/set_wanpath_corruption", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wanpath_filter - - https://www.candelatech.com/lfcli_ug.php#set_wanpath_filter - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_wanpath_filter(self, - defer_flush=None, - dst_filter=None, - filter_type=None, - passive=None, - reverse=None, - src_filter=None, - wl_name=None, - wp_name=None, - debug_=False): - debug_ |= self.debug - data = { - "defer_flush" : defer_flush, - "dst_filter" : dst_filter, - "filter_type" : filter_type, - "passive" : passive, - "reverse" : reverse, - "src_filter" : src_filter, - "wl_name" : wl_name, - "wp_name" : wp_name, - } - response = self.json_post("/cli-json/set_wanpath_filter", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wanpath_running - - https://www.candelatech.com/lfcli_ug.php#set_wanpath_running - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_wanpath_running_running(Enum): - AS_PARENT = 0 # then it will be started and stopped as the parent WanLink is. - RUNNING = 0 # then it will be running at all times - STOPPED = 0 # then it will not be running at any time. - - - def post_set_wanpath_running(self, - running=None, - wl_name=None, - wp_name=None, - debug_=False): - debug_ |= self.debug - data = { - "running" : running, - "wl_name" : wl_name, - "wp_name" : wp_name, - } - response = self.json_post("/cli-json/set_wanpath_running", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wifi_corruptions - - https://www.candelatech.com/lfcli_ug.php#set_wifi_corruptions - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_wifi_corruptions_corrupt_flags(Enum): - MSG_TYPE_DEAUTH = 2 # de-authentication message - MSG_TYPE_EAPOL = 1 # Any EAPOL message - MSG_TYPE_EAPOL_1_OF_2 = 64 # EAPOL message 1/2 - MSG_TYPE_EAPOL_1_OF_4 = 4 # EAPOL message 1/4 - MSG_TYPE_EAPOL_2_OF_2 = 128 # EAPOL message 2/2 - MSG_TYPE_EAPOL_2_OF_4 = 8 # EAPOL message 2/4 - MSG_TYPE_EAPOL_3_OF_4 = 16 # EAPOL message 3/4 - MSG_TYPE_EAPOL_4_OF_4 = 32 # EAPOL message 4/4 - MSG_TYPE_EAPOL_ASSOC = 512 # EAP Association - MSG_TYPE_EAPOL_KEY_REQ = 256 # EAP Key Request (not sure if this works properly) - MST_TYPE_EAPOL_ID_REQ = 1024 # EAP Identity request - MST_TYPE_EAPOL_ID_RESP = 2048 # EAP Identity response - MST_TYPE_EAPOL_OTHER_REQ = 4096 # EAP Requests that do not match other things. - MST_TYPE_EAPOL_OTHER_RESP = 8192 # EAP Responses that do not match other things. - - - def post_set_wifi_corruptions(self, - corrupt_flags=None, - corrupt_per_mil=None, - delay_flags=None, - delay_max=None, - delay_min=None, - dup_flags=None, - dup_per_65535=None, - ignore_flags=None, - ignore_per_mil=None, - port=None, - req_flush=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "corrupt_flags" : corrupt_flags, - "corrupt_per_mil" : corrupt_per_mil, - "delay_flags" : delay_flags, - "delay_max" : delay_max, - "delay_min" : delay_min, - "dup_flags" : dup_flags, - "dup_per_65535" : dup_per_65535, - "ignore_flags" : ignore_flags, - "ignore_per_mil" : ignore_per_mil, - "port" : port, - "req_flush" : req_flush, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/set_wifi_corruptions", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wifi_custom - - https://www.candelatech.com/lfcli_ug.php#set_wifi_custom - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_wifi_custom(self, - port=None, - resource=None, - shelf=None, - text=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "port" : port, - "resource" : resource, - "shelf" : shelf, - "text" : text, - "type" : type, - } - response = self.json_post("/cli-json/set_wifi_custom", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wifi_extra - - https://www.candelatech.com/lfcli_ug.php#set_wifi_extra - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_wifi_extra(self, - anonymous_identity=None, - anqp_3gpp_cell_net=None, - ca_cert=None, - client_cert=None, - domain=None, - eap=None, - group=None, - hessid=None, - identity=None, - imsi=None, - ipaddr_type_avail=None, - key=None, - key_mgmt=None, - milenage=None, - network_auth_type=None, - network_type=None, - pac_file=None, - pairwise=None, - password=None, - phase1=None, - phase2=None, - pin=None, - pk_passwd=None, - port=None, - private_key=None, - psk=None, - realm=None, - resource=None, - roaming_consortium=None, - shelf=None, - venue_group=None, - venue_type=None, - debug_=False): - debug_ |= self.debug - data = { - "anonymous_identity" : anonymous_identity, - "anqp_3gpp_cell_net" : anqp_3gpp_cell_net, - "ca_cert" : ca_cert, - "client_cert" : client_cert, - "domain" : domain, - "eap" : eap, - "group" : group, - "hessid" : hessid, - "identity" : identity, - "imsi" : imsi, - "ipaddr_type_avail" : ipaddr_type_avail, - "key" : key, - "key_mgmt" : key_mgmt, - "milenage" : milenage, - "network_auth_type" : network_auth_type, - "network_type" : network_type, - "pac_file" : pac_file, - "pairwise" : pairwise, - "password" : password, - "phase1" : phase1, - "phase2" : phase2, - "pin" : pin, - "pk_passwd" : pk_passwd, - "port" : port, - "private_key" : private_key, - "psk" : psk, - "realm" : realm, - "resource" : resource, - "roaming_consortium" : roaming_consortium, - "shelf" : shelf, - "venue_group" : venue_group, - "venue_type" : venue_type, - } - response = self.json_post("/cli-json/set_wifi_extra", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wifi_extra2 - - https://www.candelatech.com/lfcli_ug.php#set_wifi_extra2 - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_wifi_extra2(self, - corrupt_gtk_rekey_mic=None, - freq_24=None, - freq_5=None, - ignore_assoc=None, - ignore_auth=None, - ignore_probe=None, - ignore_reassoc=None, - ocsp=None, - port=None, - post_ifup_script=None, - radius_ip=None, - radius_port=None, - req_flush=None, - resource=None, - shelf=None, - venue_id=None, - debug_=False): - debug_ |= self.debug - data = { - "corrupt_gtk_rekey_mic" : corrupt_gtk_rekey_mic, - "freq_24" : freq_24, - "freq_5" : freq_5, - "ignore_assoc" : ignore_assoc, - "ignore_auth" : ignore_auth, - "ignore_probe" : ignore_probe, - "ignore_reassoc" : ignore_reassoc, - "ocsp" : ocsp, - "port" : port, - "post_ifup_script" : post_ifup_script, - "radius_ip" : radius_ip, - "radius_port" : radius_port, - "req_flush" : req_flush, - "resource" : resource, - "shelf" : shelf, - "venue_id" : venue_id, - } - response = self.json_post("/cli-json/set_wifi_extra2", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wifi_radio - - https://www.candelatech.com/lfcli_ug.php#set_wifi_radio - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_wifi_radio_flags(Enum): - ct_sta_mode = 262144 # Enable CT-STA mode if radio supports it. Efficiently replaces sw-crypt in some firmware. - firmware_cfg = 524288 # Apply firmware config. - hw_sim = 1 # Create hw-sim virtual radio if radio does not already exist. - ignore_radar = 1048576 # Ignore RADAR events reported by firmware. - no_scan_share = 64 # Disable sharing scan results. - no_sw_crypt = 131072 # Disable software-crypt for this radio. Disables some virtual-station features. - use_syslog = 536870912 # Put supplicant logs in syslog instead of a file. - verbose = 65536 # Verbose-Debug: Increase debug info in wpa-supplicant and hostapd logs. - - class set_wifi_radio_mode(Enum): - p_802_11a = 1 # 802.11a - AUTO = 0 # 802.11g - abg = 4 # 802.11abg - abgn = 5 # 802.11abgn - abgnAC = 8 # 802.11abgn-AC - abgnAX = 12 # 802.11abgn-AX - an = 10 # 802.11an - anAC = 9 # 802.11an-AC - anAX = 14 # 802.11an-AX - b = 2 # 802.11b - bg = 7 # 802.11bg - bgn = 6 # 802.11bgn - bgnAC = 11 # 802.11bgn-AC - bgnAX = 13 # 802.11bgn-AX - g = 3 # 802.11g - - - def post_set_wifi_radio(self, - active_peer_count=None, - ampdu_factor=None, - antenna=None, - channel=None, - const_tx=None, - country=None, - flags=None, - flags_mask=None, - frag_thresh=None, - frequency=None, - fwname=None, - fwver=None, - mac=None, - max_amsdu=None, - mode=None, - peer_count=None, - pref_ap=None, - pulse2_interval_us=None, - pulse_interval=None, - pulse_width=None, - radio=None, - rate=None, - rate_ctrl_count=None, - resource=None, - rts=None, - shelf=None, - skid_limit=None, - stations_count=None, - tids_count=None, - tx_pulses=None, - txdesc_count=None, - txpower=None, - vdev_count=None, - debug_=False): - debug_ |= self.debug - data = { - "active_peer_count" : active_peer_count, - "ampdu_factor" : ampdu_factor, - "antenna" : antenna, - "channel" : channel, - "const_tx" : const_tx, - "country" : country, - "flags" : flags, - "flags_mask" : flags_mask, - "frag_thresh" : frag_thresh, - "frequency" : frequency, - "fwname" : fwname, - "fwver" : fwver, - "mac" : mac, - "max_amsdu" : max_amsdu, - "mode" : mode, - "peer_count" : peer_count, - "pref_ap" : pref_ap, - "pulse2_interval_us" : pulse2_interval_us, - "pulse_interval" : pulse_interval, - "pulse_width" : pulse_width, - "radio" : radio, - "rate" : rate, - "rate_ctrl_count" : rate_ctrl_count, - "resource" : resource, - "rts" : rts, - "shelf" : shelf, - "skid_limit" : skid_limit, - "stations_count" : stations_count, - "tids_count" : tids_count, - "tx_pulses" : tx_pulses, - "txdesc_count" : txdesc_count, - "txpower" : txpower, - "vdev_count" : vdev_count, - } - response = self.json_post("/cli-json/set_wifi_radio", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wifi_txo - - https://www.candelatech.com/lfcli_ug.php#set_wifi_txo - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_wifi_txo(self, - port=None, - resource=None, - shelf=None, - txo_bw=None, - txo_enable=None, - txo_mcs=None, - txo_nss=None, - txo_pream=None, - txo_retries=None, - txo_sgi=None, - txo_txpower=None, - debug_=False): - debug_ |= self.debug - data = { - "port" : port, - "resource" : resource, - "shelf" : shelf, - "txo_bw" : txo_bw, - "txo_enable" : txo_enable, - "txo_mcs" : txo_mcs, - "txo_nss" : txo_nss, - "txo_pream" : txo_pream, - "txo_retries" : txo_retries, - "txo_sgi" : txo_sgi, - "txo_txpower" : txo_txpower, - } - response = self.json_post("/cli-json/set_wifi_txo", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wl_corruption - - https://www.candelatech.com/lfcli_ug.php#set_wl_corruption - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_wl_corruption_flags(Enum): - BIT_FLIP = 4 # Flip a random bit in a byte. - BIT_TRANSPOSE = 8 # Transpose two side-by-side bits in a byte. - DO_CHAIN_ON_HIT = 16 # Do next corruption if this corruption is applied. - OVERWRITE_FIXED = 2 # Write a fixed value to a byte. - OVERWRITE_RANDOM = 1 # Write a random value to a byte. - RECALC_CSUMS = 32 # Attempt to re-calculate UDP and TCP checksums. - - - def post_set_wl_corruption(self, - byte=None, - flags=None, - index=None, - max_offset=None, - min_offset=None, - name=None, - rate=None, - debug_=False): - debug_ |= self.debug - data = { - "byte" : byte, - "flags" : flags, - "index" : index, - "max_offset" : max_offset, - "min_offset" : min_offset, - "name" : name, - "rate" : rate, - } - response = self.json_post("/cli-json/set_wl_corruption", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wl_qdisc - - https://www.candelatech.com/lfcli_ug.php#set_wl_qdisc - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_wl_qdisc_qdisc(Enum): - FIFO = 0 # is the default queuing discipline, no arguments - WRR__queue_queue_____ = 0 # Weighted Round Robbin is also available - - - def post_set_wl_qdisc(self, - name=None, - qdisc=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - "qdisc" : qdisc, - } - response = self.json_post("/cli-json/set_wl_qdisc", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wp_corruption - - https://www.candelatech.com/lfcli_ug.php#set_wanpath_corruption - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_wanpath_corruption_flags(Enum): - BIT_FLIP = 4 # Flip a random bit in a byte. - BIT_TRANSPOSE = 8 # Transpose two side-by-side bits in a byte. - DO_CHAIN_ON_HIT = 16 # Do next corruption if this corruption is applied. - OVERWRITE_FIXED = 2 # Write a fixed value to a byte. - OVERWRITE_RANDOM = 1 # Write a random value to a byte. - RECALC_CSUMS = 32 # Attempt to re-calculate UDP and TCP checksums. - - - def post_set_wp_corruption(self, - byte=None, - flags=None, - index=None, - max_offset=None, - min_offset=None, - name=None, - path=None, - rate=None, - debug_=False): - debug_ |= self.debug - data = { - "byte" : byte, - "flags" : flags, - "index" : index, - "max_offset" : max_offset, - "min_offset" : min_offset, - "name" : name, - "path" : path, - "rate" : rate, - } - response = self.json_post("/cli-json/set_wp_corruption", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wp_filter - - https://www.candelatech.com/lfcli_ug.php#set_wanpath_filter - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_set_wp_filter(self, - defer_flush=None, - dst_filter=None, - filter_type=None, - passive=None, - reverse=None, - src_filter=None, - wl_name=None, - wp_name=None, - debug_=False): - debug_ |= self.debug - data = { - "defer_flush" : defer_flush, - "dst_filter" : dst_filter, - "filter_type" : filter_type, - "passive" : passive, - "reverse" : reverse, - "src_filter" : src_filter, - "wl_name" : wl_name, - "wp_name" : wp_name, - } - response = self.json_post("/cli-json/set_wp_filter", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/set_wp_running - - https://www.candelatech.com/lfcli_ug.php#set_wanpath_running - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class set_wanpath_running_running(Enum): - AS_PARENT = 0 # then it will be started and stopped as the parent WanLink is. - RUNNING = 0 # then it will be running at all times - STOPPED = 0 # then it will not be running at any time. - - - def post_set_wp_running(self, - running=None, - wl_name=None, - wp_name=None, - debug_=False): - debug_ |= self.debug - data = { - "running" : running, - "wl_name" : wl_name, - "wp_name" : wp_name, - } - response = self.json_post("/cli-json/set_wp_running", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_alerts - - https://www.candelatech.com/lfcli_ug.php#show_alerts - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class show_alerts_type(Enum): - All = 0 - CX = 0 - Card = 0 - Channel_Group = 0 - CollisionDomain = 0 - Endp = 0 - PESQ = 0 - PPP_Link = 0 - Port = 0 - Shelf = 0 - Span = 0 - Test_Mgr = 0 - - - def post_show_alerts(self, - card=None, - endp=None, - extra=None, - port=None, - shelf=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "card" : card, - "endp" : endp, - "extra" : extra, - "port" : port, - "shelf" : shelf, - "type" : type, - } - response = self.json_post("/cli-json/show_alerts", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_attenuators - - https://www.candelatech.com/lfcli_ug.php#show_attenuators - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_attenuators(self, - resource=None, - serno=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "serno" : serno, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_attenuators", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_cards - - https://www.candelatech.com/lfcli_ug.php#show_resources - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_cards(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_cards", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_cd - - https://www.candelatech.com/lfcli_ug.php#show_cd - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_cd(self, - collision_domain=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "collision_domain" : collision_domain, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_cd", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_chamber - - https://www.candelatech.com/lfcli_ug.php#show_chamber - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_chamber(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/show_chamber", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_channel_groups - - https://www.candelatech.com/lfcli_ug.php#show_channel_groups - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_channel_groups(self, - channel_name=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "channel_name" : channel_name, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_channel_groups", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_clients - - https://www.candelatech.com/lfcli_ug.php#show_clients - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_clients(self, - debug_=False): - debug_ |= self.debug - data = { - } - response = self.json_post("/cli-json/show_clients", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_cx - - https://www.candelatech.com/lfcli_ug.php#show_cx - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_cx(self, - cross_connect=None, - test_mgr=None, - debug_=False): - debug_ |= self.debug - data = { - "cross_connect" : cross_connect, - "test_mgr" : test_mgr, - } - response = self.json_post("/cli-json/show_cx", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_cxe - - https://www.candelatech.com/lfcli_ug.php#show_cxe - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_cxe(self, - cross_connect=None, - test_mgr=None, - debug_=False): - debug_ |= self.debug - data = { - "cross_connect" : cross_connect, - "test_mgr" : test_mgr, - } - response = self.json_post("/cli-json/show_cxe", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_dbs - - https://www.candelatech.com/lfcli_ug.php#show_dbs - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_dbs(self, - debug_=False): - debug_ |= self.debug - data = { - } - response = self.json_post("/cli-json/show_dbs", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_dut - - https://www.candelatech.com/lfcli_ug.php#show_dut - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_dut(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/show_dut", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_endp_payload - - https://www.candelatech.com/lfcli_ug.php#show_endp_payload - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_endp_payload(self, - max_bytes=None, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "max_bytes" : max_bytes, - "name" : name, - } - response = self.json_post("/cli-json/show_endp_payload", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_endpoints - - https://www.candelatech.com/lfcli_ug.php#show_endpoints - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_endpoints(self, - endpoint=None, - extra=None, - debug_=False): - debug_ |= self.debug - data = { - "endpoint" : endpoint, - "extra" : extra, - } - response = self.json_post("/cli-json/show_endpoints", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_err - - https://www.candelatech.com/lfcli_ug.php#show_err - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_err(self, - message=None, - debug_=False): - debug_ |= self.debug - data = { - "message" : message, - } - response = self.json_post("/cli-json/show_err", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_event_interest - - https://www.candelatech.com/lfcli_ug.php#show_event_interest - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_event_interest(self, - debug_=False): - debug_ |= self.debug - data = { - } - response = self.json_post("/cli-json/show_event_interest", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_events - - https://www.candelatech.com/lfcli_ug.php#show_events - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class show_events_type(Enum): - All = 0 - CX = 0 - Card = 0 - Channel_Group = 0 - CollisionDomain = 0 - Endp = 0 - PESQ = 0 - PPP_Link = 0 - Port = 0 - Shelf = 0 - Span = 0 - Test_Mgr = 0 - - - def post_show_events(self, - card=None, - endp=None, - extra=None, - port=None, - shelf=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "card" : card, - "endp" : endp, - "extra" : extra, - "port" : port, - "shelf" : shelf, - "type" : type, - } - response = self.json_post("/cli-json/show_events", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_files - - https://www.candelatech.com/lfcli_ug.php#show_files - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_files(self, - dir_flags=None, - directory=None, - filter=None, - key=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "dir_flags" : dir_flags, - "directory" : directory, - "filter" : filter, - "key" : key, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_files", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_group - - https://www.candelatech.com/lfcli_ug.php#show_group - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_group(self, - group=None, - debug_=False): - debug_ |= self.debug - data = { - "group" : group, - } - response = self.json_post("/cli-json/show_group", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_pesq - - https://www.candelatech.com/lfcli_ug.php#show_pesq - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_pesq(self, - endpoint=None, - debug_=False): - debug_ |= self.debug - data = { - "endpoint" : endpoint, - } - response = self.json_post("/cli-json/show_pesq", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_ports - - https://www.candelatech.com/lfcli_ug.php#show_ports - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_ports(self, - port=None, - probe_flags=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "port" : port, - "probe_flags" : probe_flags, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_ports", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_ppp_links - - https://www.candelatech.com/lfcli_ug.php#show_ppp_links - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_ppp_links(self, - link_num=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "link_num" : link_num, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_ppp_links", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_profile - - https://www.candelatech.com/lfcli_ug.php#show_profile - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_profile(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/show_profile", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_resources - - https://www.candelatech.com/lfcli_ug.php#show_resources - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_resources(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_resources", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_rfgen - - https://www.candelatech.com/lfcli_ug.php#show_rfgen - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_rfgen(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_rfgen", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_rt - - https://www.candelatech.com/lfcli_ug.php#show_rt - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_rt(self, - key=None, - resource=None, - shelf=None, - virtual_router=None, - debug_=False): - debug_ |= self.debug - data = { - "key" : key, - "resource" : resource, - "shelf" : shelf, - "virtual_router" : virtual_router, - } - response = self.json_post("/cli-json/show_rt", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_script_results - - https://www.candelatech.com/lfcli_ug.php#show_script_results - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_script_results(self, - endpoint=None, - key=None, - debug_=False): - debug_ |= self.debug - data = { - "endpoint" : endpoint, - "key" : key, - } - response = self.json_post("/cli-json/show_script_results", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_spans - - https://www.candelatech.com/lfcli_ug.php#show_spans - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_spans(self, - resource=None, - shelf=None, - span_number=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - "span_number" : span_number, - } - response = self.json_post("/cli-json/show_spans", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_text_blob - - https://www.candelatech.com/lfcli_ug.php#show_text_blob - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_text_blob(self, - brief=None, - name=None, - type=None, - debug_=False): - debug_ |= self.debug - data = { - "brief" : brief, - "name" : name, - "type" : type, - } - response = self.json_post("/cli-json/show_text_blob", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_tm - - https://www.candelatech.com/lfcli_ug.php#show_tm - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_tm(self, - test_mgr=None, - debug_=False): - debug_ |= self.debug - data = { - "test_mgr" : test_mgr, - } - response = self.json_post("/cli-json/show_tm", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_traffic_profile - - https://www.candelatech.com/lfcli_ug.php#show_traffic_profile - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_traffic_profile(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/show_traffic_profile", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_venue - - https://www.candelatech.com/lfcli_ug.php#show_venue - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_venue(self, - resource=None, - shelf=None, - venu_id=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - "venu_id" : venu_id, - } - response = self.json_post("/cli-json/show_venue", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_vr - - https://www.candelatech.com/lfcli_ug.php#show_vr - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_vr(self, - resource=None, - router=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "router" : router, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_vr", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_vrcx - - https://www.candelatech.com/lfcli_ug.php#show_vrcx - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_vrcx(self, - cx_name=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "cx_name" : cx_name, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/show_vrcx", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_wanpaths - - https://www.candelatech.com/lfcli_ug.php#show_wanpaths - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_wanpaths(self, - endpoint=None, - wanpath=None, - debug_=False): - debug_ |= self.debug - data = { - "endpoint" : endpoint, - "wanpath" : wanpath, - } - response = self.json_post("/cli-json/show_wanpaths", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/show_wps - - https://www.candelatech.com/lfcli_ug.php#show_wanpaths - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_show_wps(self, - endpoint=None, - wanpath=None, - debug_=False): - debug_ |= self.debug - data = { - "endpoint" : endpoint, - "wanpath" : wanpath, - } - response = self.json_post("/cli-json/show_wps", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/shutdown - - https://www.candelatech.com/lfcli_ug.php#shutdown - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_shutdown(self, - chdir=None, - really=None, - serverctl=None, - debug_=False): - debug_ |= self.debug - data = { - "chdir" : chdir, - "really" : really, - "serverctl" : serverctl, - } - response = self.json_post("/cli-json/shutdown", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/shutdown_card - - https://www.candelatech.com/lfcli_ug.php#shutdown_resource - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_shutdown_card(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/shutdown_card", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/shutdown_os - - https://www.candelatech.com/lfcli_ug.php#shutdown_os - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_shutdown_os(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/shutdown_os", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/shutdown_resource - - https://www.candelatech.com/lfcli_ug.php#shutdown_resource - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_shutdown_resource(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/shutdown_resource", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/sniff_port - - https://www.candelatech.com/lfcli_ug.php#sniff_port - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - class sniff_port_flags(Enum): - DUMPCAP = 2 # Use command-line dumpcap, more efficient than tshark - MATE_TERMINAL = 4 # Launch tshark/dumpcap in mate-terminal - MATE_XTERM = 8 # Launch tshark/dumpcap in xterm - TSHARK = 1 # Use command-line tshark instead of wireshark - - - def post_sniff_port(self, - display=None, - duration=None, - flags=None, - outfile=None, - port=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "display" : display, - "duration" : duration, - "flags" : flags, - "outfile" : outfile, - "port" : port, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/sniff_port", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/start_endp - - https://www.candelatech.com/lfcli_ug.php#start_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_start_endp(self, - endp_name=None, - debug_=False): - debug_ |= self.debug - data = { - "endp_name" : endp_name, - } - response = self.json_post("/cli-json/start_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/start_group - - https://www.candelatech.com/lfcli_ug.php#start_group - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_start_group(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/start_group", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/start_ppp_link - - https://www.candelatech.com/lfcli_ug.php#start_ppp_link - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_start_ppp_link(self, - resource=None, - shelf=None, - unit_num=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - "unit_num" : unit_num, - } - response = self.json_post("/cli-json/start_ppp_link", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/stop_endp - - https://www.candelatech.com/lfcli_ug.php#stop_endp - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_stop_endp(self, - endp_name=None, - debug_=False): - debug_ |= self.debug - data = { - "endp_name" : endp_name, - } - response = self.json_post("/cli-json/stop_endp", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/stop_group - - https://www.candelatech.com/lfcli_ug.php#stop_group - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_stop_group(self, - name=None, - debug_=False): - debug_ |= self.debug - data = { - "name" : name, - } - response = self.json_post("/cli-json/stop_group", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/stop_ppp_link - - https://www.candelatech.com/lfcli_ug.php#stop_ppp_link - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_stop_ppp_link(self, - resource=None, - shelf=None, - unit_num=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - "unit_num" : unit_num, - } - response = self.json_post("/cli-json/stop_ppp_link", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/tail - - https://www.candelatech.com/lfcli_ug.php#tail - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_tail(self, - cmd=None, - key=None, - message=None, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "cmd" : cmd, - "key" : key, - "message" : message, - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/tail", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/tm_register - - https://www.candelatech.com/lfcli_ug.php#tm_register - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_tm_register(self, - client_name=None, - test_mgr=None, - debug_=False): - debug_ |= self.debug - data = { - "client_name" : client_name, - "test_mgr" : test_mgr, - } - response = self.json_post("/cli-json/tm_register", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/tm_unregister - - https://www.candelatech.com/lfcli_ug.php#tm_unregister - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_tm_unregister(self, - client_name=None, - test_mgr=None, - debug_=False): - debug_ |= self.debug - data = { - "client_name" : client_name, - "test_mgr" : test_mgr, - } - response = self.json_post("/cli-json/tm_unregister", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/version - - https://www.candelatech.com/lfcli_ug.php#version - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_version(self, - debug_=False): - debug_ |= self.debug - data = { - } - response = self.json_post("/cli-json/version", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/who - - https://www.candelatech.com/lfcli_ug.php#who - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_who(self, - debug_=False): - debug_ |= self.debug - data = { - } - response = self.json_post("/cli-json/who", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/wifi_cli_cmd - - https://www.candelatech.com/lfcli_ug.php#wifi_cli_cmd - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_wifi_cli_cmd(self, - port=None, - resource=None, - shelf=None, - wpa_cli_cmd=None, - debug_=False): - debug_ |= self.debug - data = { - "port" : port, - "resource" : resource, - "shelf" : shelf, - "wpa_cli_cmd" : wpa_cli_cmd, - } - response = self.json_post("/cli-json/wifi_cli_cmd", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/wifi_event - - https://www.candelatech.com/lfcli_ug.php#wifi_event - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_wifi_event(self, - device=None, - event=None, - msg=None, - status=None, - debug_=False): - debug_ |= self.debug - data = { - "device" : device, - "event" : event, - "msg" : msg, - "status" : status, - } - response = self.json_post("/cli-json/wifi_event", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/wiser_reset - - https://www.candelatech.com/lfcli_ug.php#wiser_reset - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_wiser_reset(self, - resource=None, - shelf=None, - debug_=False): - debug_ |= self.debug - data = { - "resource" : resource, - "shelf" : shelf, - } - response = self.json_post("/cli-json/wiser_reset", - data, - debug_=debug_) - return response - # - - - - """----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- - Generated method for /cli-json/write - - https://www.candelatech.com/lfcli_ug.php#write - ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----""" - - def post_write(self, - db_name=None, - debug_=False): - debug_ |= self.debug - data = { - "db_name" : db_name, - } - response = self.json_post("/cli-json/write", - data, - debug_=debug_) - return response - # diff --git a/py-json/station_profile.py b/py-json/station_profile.py index 69241d89..6561e10f 100644 --- a/py-json/station_profile.py +++ b/py-json/station_profile.py @@ -1,5 +1,5 @@ -# !/usr/bin/env python3 +#!/usr/bin/env python3 from LANforge.lfcli_base import LFCliBase from LANforge import LFRequest from LANforge import LFUtils @@ -32,10 +32,7 @@ class StationProfile: shelf=1, dhcp=True, debug_=False, - use_ht160=False, - COMMANDS=["add_sta", "set_port"], - desired_add_sta_flags = ["wpa2_enable", "80211u_enable", "create_admin_down"], - desired_add_sta_flags_mask = ["wpa2_enable", "80211u_enable", "create_admin_down"]): + use_ht160=False): self.debug = debug_ self.lfclient_url = lfclient_url self.ssid = ssid @@ -48,9 +45,9 @@ class StationProfile: self.security = security self.local_realm = local_realm self.use_ht160 = use_ht160 - self.COMMANDS = COMMANDS - self.desired_add_sta_flags = desired_add_sta_flags - self.desired_add_sta_flags_mask = desired_add_sta_flags_mask + self.COMMANDS = ["add_sta", "set_port"] + self.desired_add_sta_flags = ["wpa2_enable", "80211u_enable", "create_admin_down"] + self.desired_add_sta_flags_mask = ["wpa2_enable", "80211u_enable", "create_admin_down"] self.number_template = number_template_ self.station_names = [] # eids, these are created station names self.add_sta_data = { @@ -91,21 +88,6 @@ class StationProfile: "realm": None, "domain": None } - self.wifi_txo_data_modified = False - self.wifi_txo_data = { - "shelf": 1, - "resource": 1, - "port": None, - "txo_enable": None, - "txo_txpower": None, - "txo_pream": None, - "txo_mcs": None, - "txo_nss": None, - "txo_bw": None, - "txo_retries": None, - "txo_sgi": None - - } self.reset_port_extra_data = { "shelf": 1, @@ -120,24 +102,6 @@ class StationProfile: "seconds_till_reset": 0 } - def set_wifi_txo(self, txo_ena=1, - tx_power=255, - pream=0, - mcs=0, - nss=0, - bw=0, - retries=1, - sgi=0): - self.wifi_txo_data_modified = True - self.wifi_txo_data["txo_enable"] = txo_ena - self.wifi_txo_data["txo_txpower"] = tx_power - self.wifi_txo_data["txo_pream"] = pream - self.wifi_txo_data["txo_mcs"] = mcs - self.wifi_txo_data["txo_nss"] = nss - self.wifi_txo_data["txo_bw"] = bw - self.wifi_txo_data["txo_retries"] = retries - self.wifi_txo_data["txo_sgi"] = sgi - def set_wifi_extra(self, key_mgmt="WPA-EAP", pairwise="CCMP TKIP", group="CCMP TKIP", @@ -415,8 +379,6 @@ class StationProfile: set_port.set_port_interest_flags) self.wifi_extra_data["resource"] = radio_resource self.wifi_extra_data["shelf"] = radio_shelf - self.wifi_txo_data["resource"] = radio_resource - self.wifi_txo_data["shelf"] = radio_shelf self.reset_port_extra_data["resource"] = radio_resource self.reset_port_extra_data["shelf"] = radio_shelf @@ -425,7 +387,6 @@ class StationProfile: add_sta_r = LFRequest.LFRequest(self.lfclient_url + "/cli-json/add_sta", debug_=debug) set_port_r = LFRequest.LFRequest(self.lfclient_url + "/cli-json/set_port", debug_=debug) wifi_extra_r = LFRequest.LFRequest(self.lfclient_url + "/cli-json/set_wifi_extra", debug_=debug) - wifi_txo_r = LFRequest.LFRequest(self.lfclient_url + "/cli-json/set_wifi_txo", debug_=debug) my_sta_names = [] # add radio here if (num_stations > 0) and (len(sta_names_) < 1): @@ -501,14 +462,9 @@ class StationProfile: self.wifi_extra_data["resource"] = radio_resource self.wifi_extra_data["port"] = name - self.wifi_txo_data["resource"] = radio_resource - self.wifi_txo_data["port"] = name if self.wifi_extra_data_modified: wifi_extra_r.addPostData(self.wifi_extra_data) json_response = wifi_extra_r.jsonPost(debug) - if self.wifi_txo_data_modified: - wifi_txo_r.addPostData(self.wifi_txo_data) - json_response = wifi_txo_r.jsonPost(debug) # append created stations to self.station_names self.station_names.append("%s.%s.%s" % (radio_shelf, radio_resource, name)) diff --git a/py-scripts/artifacts/CenturyGothic.woff b/py-scripts/artifacts/CenturyGothic.woff deleted file mode 100755 index 877ec4a278c206d5d76dc9a380c875c622b2b6a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 70128 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 diff --git a/py-scripts/artifacts/custom-example.css b/py-scripts/artifacts/custom-example.css deleted file mode 100644 index 26e93750..00000000 --- a/py-scripts/artifacts/custom-example.css +++ /dev/null @@ -1,11 +0,0 @@ -/* file reserved for customer styling of reports */ -/* rename to custom.css to take effect */ - -.TitleFont {} -.HeaderFont {} -.TableFont {} -.TableBorder {} -.ImgStyle {} -.HeaderStyle {} -.FooterStyle {} -/* eof */ diff --git a/py-scripts/artifacts/report.css b/py-scripts/artifacts/report.css deleted file mode 100644 index 734a0423..00000000 --- a/py-scripts/artifacts/report.css +++ /dev/null @@ -1,299 +0,0 @@ -html, body,div { - margin: 0; - padding:0; - font-size: 14px; -} -h1,h2,h3,h4 { - padding: 0em; - line-height: 1.5; - text-align: left; - color: rgb(42,91,41); -} -@font-face { - font-family: CenturyGothic; - src: url("CenturyGothic.woff"), - url("images/CenturyGothic.woff"), - url("/images/CenturyGothic.woff"), - url("http://www.candelatech.com/images/CenturyGothic.woff"); -} -body,h1,h2,h3,h4 { - font-family: CenturyGothic, "Century Gothic", Arial, Helvetica, sans-serif; -} -h1 { font-size: 30px;} -h2 { font-size: 24px;} -h3 { font-size: 18px;} -h4 { font-size: 14px;} -li,pre,tt { - text-align: left; -} -pre { - font-size: 10px; -} -table { - border-collapse: collapse; - background: #e0e0e0; -} -table, td, th { - border: 1px solid gray; - padding 4px; -} -table.noborder, table.noborder td, table.noborder th { - border: 0 none; -} -td { - background: white; -} -td.ar { - text-align: right; -} -th { - color: rgb(42,91,41); - text-align: center; -} -#lf_title { - text-align: center; - background-image: url(candela_swirl_small-72h.png); - background-position: right; - background-repeat: no-repeat; - height: 90px; -} -#new_chart { - display: block; - height: 250px; - min-width: 200px; - width: 80%; - border: 1px solid black; - margin: 14px auto; - padding: 14px; - vertical-align: bottom; - text-align: center; -} -.lf_chart { - margin: 1em; - padding: 5px; -} -#error_types ul { - background: #f0f0f0; - font-size: 12px; - line-height: 1.5; - margin: 1em; - padding: 0.25em inherit 0.25em inherit; - max-height: 8em; - overflow: auto; -} -li { - line-height: 1.5; -} -.contentDiv { - min-width: 800px; - max-width: 8in; - margin: 1em auto; - padding: 0; -} -.ct-point { - stroke-width: 6px;} - -.o_el { - display: inline-block; - width: 100px; - height: 230px; - border: none; - margin: 1px 1px 16px 1px; - padding: 10px 10px 0 10px; - background: #eee; - text-align: center; - vertical-align: bottom; -} -.bar_el { - display: block; - background: green; - border: none; - min-height: 1px; - - margin: 0 0 5px 0; - padding: 0; - text-align: center; -} -.label_el { - color: black; - display: block; - font-size: 14px; - font-family: Arial,Helvetica,sans-serif,mono; - margin: 1px; - text-align: center; - vertical-align: bottom; - width: inherit; -} -.value_el { - font-family: Arial,Helvetica,sans-serif,mono; - color: black; - display: block; - font-size: 14px; - margin: 0 auto; - padding: none; - border: none; - background: white; - text-align: center; - vertical-align: bottom; - width: auto; -} -.value_el>span { - background: #f0f0f0a0; - border: 1px solid #f0f0f0a0; - border-radius: 5px; - padding: 1px; - min-width: 2em; -} -.error { - color: red; -} - -@media only screen { -.hideFromPrint { } -.hideFromScreen { display:none; } -} -@media only print { -.hideFromScreen { } -.hideFromPrint { display:none; } -} - -/* these styles will get overridden by custom.css */ -#BannerBack { - background-color: #e68b15; - height: 205px; - max-height: 205px; - border: 0 none; - margin: 0; - padding: 0; - top: 0; - left: 0; - width: 100%; -} -#Banner { - background-image:url("banner.png"); - background-repeat:no-repeat; - padding: 0; - margin: 0 auto; - min-width: 1000px; - min-height: 205px; - width: 1000px; - height: 205px; - max-width: 1000px; - max-height: 205px; -} -#BannerLogo { - text-align: right; - padding: 25px; - margin: 5px; - width: 200px; - border: none; -} -.TitleFontScreen { - margin-left: auto; - margin-right: auto; - margin-top: 1em; - margin-bottom: 0.2em; - font-size: 50px; - padding-top: 1em; -} - -.TitleFontPrint { - line-height: 1; - margin-left: 0px; - margin-right: auto; - margin-top: 0.5em; - margin-bottom: 0.2em; - padding-top: 20px; - padding-left: 20px; - color: darkgreen; -} - -.TitleFontPrintSub { - line-height: 1; - margin-left: 0px; - margin-right: auto; - margin-top: 0; - margin-bottom: 0; - /*font-size: 20px; Let 'h3', etc control this */ - padding-top: 0px; - padding-left: 20px; -} - -.HeaderFont {} -.TableFont {} -.TableBorder {} -.ImgStyle {} -div.Section h1, div.Section h2 { - margin: 0 0 0 0em; -} -div.HeaderStyle h1, div.HeaderStyle h2 { - text-align: left; - margin: 0 0 0 0; - max-width: 8in; - min-width: 800px; -} -div.Section { - padding 5px; - position: relative; -} -div.Section img { - margin: 0; - padding: 0; - position: relative; - top: 50%; - transform: translateY(-50%); -} -div.FooterStyle { - width: 100%; - vertical-align: middle; - border: 0 none; - border-top: 2px solid #2A5B29; - color: #2A5B29; - font-size: 12px; - margin-top: 2em; -} -div.FooterStyle img { - width: auto; - height: auto; - text-align: right; -} -div.FooterStyle span.Gradient { - background: white; - color: #2A5B29; - display: inline-block; - height: 30px; - line-height: 1; - padding-top: 22px; - padding-bottom: 20px; - padding-left: 2em; - vertical-align: middle; - max-width:80%; - float:left; - width:50%; -} -.FooterStyle a, .FooterStyle a:visited { - color: #2A5B29; - font-size: 12px; - line-height: 1; - height: 30px; - margin: 0; - padding: 0; - vertical-align: middle; -} -div.FooterStyle a.LogoImgLink { - display: inline-block; - text-align: right; - float: right; -} -a .LogoImgLink { -} -a.LogoImgLink img { -} - -table.dataframe { - margin: 1em; - padding: 0; -} -table.dataframe tr th { - padding: 0.5em; -} \ No newline at end of file diff --git a/py-scripts/create_station.py b/py-scripts/create_station.py index 62e4973e..df685f58 100755 --- a/py-scripts/create_station.py +++ b/py-scripts/create_station.py @@ -33,7 +33,6 @@ class CreateStation(Realm): _proxy_str=None, _debug_on=False, _up=True, - _set_txo_data=None, _exit_on_error=False, _exit_on_fail=False): super().__init__(_host, @@ -49,7 +48,6 @@ class CreateStation(Realm): self.number_template = _number_template self.debug = _debug_on self.up = _up - self.set_txo_data = _set_txo_data self.station_profile = self.new_station_profile() self.station_profile.lfclient_url = self.lfclient_url self.station_profile.ssid = self.ssid @@ -62,6 +60,7 @@ class CreateStation(Realm): pprint.pprint(self.sta_list) print("---- ~Station List ----- ----- ----- ----- ----- ----- \n") + def build(self): # Build stations self.station_profile.use_security(self.security, self.ssid, self.password) @@ -71,15 +70,6 @@ class CreateStation(Realm): self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) self.station_profile.set_command_param("set_port", "report_timer", 1500) self.station_profile.set_command_flag("set_port", "rpt_timer", 1) - if self.set_txo_data is not None: - self.station_profile.set_wifi_txo(txo_ena=self.set_txo_data["txo_enable"], - tx_power=self.set_txo_data["txpower"], - pream=self.set_txo_data["pream"], - mcs=self.set_txo_data["mcs"], - nss=self.set_txo_data["nss"], - bw=self.set_txo_data["bw"], - retries=self.set_txo_data["retries"], - sgi=self.set_txo_data["sgi"], ) self.station_profile.create(radio=self.radio, sta_names_=self.sta_list, debug=self.debug) if self.up: self.station_profile.admin_up() @@ -88,7 +78,7 @@ class CreateStation(Realm): def main(): - parser = LFCliBase.create_basic_argparse( # see create_basic_argparse in ../py-json/LANforge/lfcli_base.py + parser = LFCliBase.create_basic_argparse( prog='create_station.py', formatter_class=argparse.RawTextHelpFormatter, epilog='''\ @@ -101,7 +91,6 @@ def main(): Command example: ./create_station.py --radio wiphy0 - --start_id 2 --num_stations 3 --security open --ssid netgear @@ -109,18 +98,14 @@ Command example: --debug ''') required = parser.add_argument_group('required arguments') - required.add_argument('--start_id', help='--start_id default 0', default=0) + #required.add_argument('--security', help='WiFi Security protocol: < open | wep | wpa | wpa2 | wpa3 >', required=True) args = parser.parse_args() - # if args.debug: + #if args.debug: # pprint.pprint(args) # time.sleep(5) if (args.radio is None): - raise ValueError("--radio required") - - start_id = 0 - if (args.start_id != 0): - start_id = int(args.start_id) + raise ValueError("--radio required") num_sta = 2 if (args.num_stations is not None) and (int(args.num_stations) > 0): @@ -128,33 +113,20 @@ Command example: num_sta = num_stations_converted station_list = LFUtils.port_name_series(prefix="sta", - start_id=start_id, - end_id=start_id + num_sta - 1, - padding_number=10000, - radio=args.radio) - - print("station_list {}".format(station_list)) - set_txo_data={ - "txo_enable": 1, - "txpower": 255, - "pream": 0, - "mcs": 0, - "nss": 0, - "bw": 3, - "retries": 1, - "sgi": 0 - } + start_id=0, + end_id=num_sta-1, + padding_number=10000, + radio=args.radio) create_station = CreateStation(_host=args.mgr, - _port=args.mgr_port, - _ssid=args.ssid, - _password=args.passwd, - _security=args.security, - _sta_list=station_list, - _radio=args.radio, - _set_txo_data=None, - _proxy_str=args.proxy, - _debug_on=args.debug) + _port=args.mgr_port, + _ssid=args.ssid, + _password=args.passwd, + _security=args.security, + _sta_list=station_list, + _radio=args.radio, + _proxy_str=args.proxy, + _debug_on=args.debug) create_station.build() print('Created %s stations' % num_sta) diff --git a/py-scripts/ghost_profile.py b/py-scripts/ghost_profile.py deleted file mode 100755 index 2b20b377..00000000 --- a/py-scripts/ghost_profile.py +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env python3 - -""" -NAME: ghost_profile.py -PURPOSE: modify ghost database from the command line. -SETUP: A Ghost installation which the user has admin access to. -EXAMPLE: ./ghost_profile.py --article_text_file text.txt --title Test --authors Matthew --ghost_token SECRET_KEY --host 192.168.1.1 - -There is a specific class for uploading wifi capacity graphs called wifi_capacity. - -EXAMPLE: ./ghost_profile.py --ghost_token TOKEN --ghost_host 192.168.100.147 ---folders /home/lanforge/html-reports/wifi-capacity-2021-06-04-02-51-07 ---wifi_capacity appl --authors Matthew --title 'wifi capacity 2021 06 04 02 51 07' --server 192.168.93.51 ---user_pull lanforge --password_pull lanforge --customer candela --testbed heather --test_run test-run-6 ---user_push matt --password_push PASSWORD - - Matthew Stidham - Copyright 2021 Candela Technologies Inc - License: Free to distribute and modify. LANforge systems must be licensed. -""" -import sys -import os -import argparse - -if sys.version_info[0] != 3: - print("This script requires Python 3") - exit(1) - -if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) - sys.path.append(os.path.join(os.path.abspath('..'), 'py-dashboard')) - -from GhostRequest import GhostRequest - - -class UseGhost: - def __init__(self, - _ghost_token=None, - host="localhost", - port=8080, - _debug_on=False, - _exit_on_fail=False, - _ghost_host="localhost", - _ghost_port=2368, ): - self.ghost_host = _ghost_host - self.ghost_port = _ghost_port - self.ghost_token = _ghost_token - self.GP = GhostRequest(self.ghost_host, - str(self.ghost_port), - _api_token=self.ghost_token, - debug_=_debug_on) - - def create_post(self, title, text, tags, authors): - return self.GP.create_post(title=title, text=text, tags=tags, authors=authors) - - def create_post_from_file(self, title, file, tags, authors): - text = open(file).read() - return self.GP.create_post(title=title, text=text, tags=tags, authors=authors) - - def upload_image(self, image): - return self.GP.upload_image(image) - - def upload_images(self, folder): - return self.GP.upload_images(folder) - - def custom_post(self, folder, authors): - return self.GP.custom_post(folder, authors) - - def wifi_capacity(self, - authors, - folders, - title, - server_pull, - ghost_host, - port, - user_pull, - password_pull, - user_push, - password_push, - customer, - testbed, - test_run, - grafana_dashboard, - grafana_token, - grafana_host, - grafana_port): - target_folders = list() - return self.GP.wifi_capacity_to_ghost(authors, - folders, - title, - server_pull, - ghost_host, - port, - user_pull, - password_pull, - user_push, - password_push, - customer, - testbed, - test_run, - target_folders, - grafana_dashboard, - grafana_token, - grafana_host, - grafana_port) - - -def main(): - parser = argparse.ArgumentParser( - prog='ghost_profile.py', - formatter_class=argparse.RawTextHelpFormatter, - epilog='''Manage Ghost Website''', - description=''' - ghost_profile.py - ---------------- - Command example: - ./ghost_profile.py - --ghost_token''' - ) - optional = parser.add_argument_group('optional arguments') - optional.add_argument('--ghost_token', default=None) - optional.add_argument('--create_post', default=None) - optional.add_argument('--article_text_file', default=None) - - optional.add_argument('--ghost_port', help='Ghost port if different from 2368', default=2368) - optional.add_argument('--ghost_host', help='Ghost host if different from localhost', default='localhost') - optional.add_argument('--article_text') - optional.add_argument('--article_tags', action='append') - optional.add_argument('--authors', action='append') - optional.add_argument('--title', default=None) - optional.add_argument('--image', default=None) - optional.add_argument('--folder', default=None) - optional.add_argument('--custom_post', default=None) - optional.add_argument('--wifi_capacity', default=None) - optional.add_argument('--folders', action='append', default=None) - optional.add_argument('--server_pull') - optional.add_argument('--port', default=22) - optional.add_argument('--user_pull', default='lanforge') - optional.add_argument('--password_pull', default='lanforge') - optional.add_argument('--user_push') - optional.add_argument('--password_push') - optional.add_argument('--customer') - optional.add_argument('--testbed') - optional.add_argument('--test_run', default=None) - optional.add_argument('--grafana_dashboard') - optional.add_argument('--grafana_token', default=None) - optional.add_argument('--grafana_host', default=None) - optional.add_argument('--grafana_port', default=3000) - optional.add_argument('--debug') - args = parser.parse_args() - - Ghost = UseGhost(_ghost_token=args.ghost_token, - _ghost_port=args.ghost_port, - _ghost_host=args.ghost_host, - _debug_on=args.debug) - - if args.create_post is not None: - Ghost.create_post(args.title, args.article_text, args.article_tags, args.authors) - if args.article_text_file is not None: - Ghost.create_post_from_file(args.title, args.article_text_file, args.article_tags, args.authors) - - if args.image is not None: - Ghost.upload_image(args.image) - - if args.custom_post is not None: - if args.folders is not None: - Ghost.custom_post(args.folders, args.authors) - else: - Ghost.custom_post(args.folder, args.authors) - else: - if args.folder is not None: - Ghost.upload_images(args.folder) - - if args.wifi_capacity is not None: - Ghost.wifi_capacity(args.authors, - args.folders, - args.title, - args.server_pull, - args.ghost_host, - args.port, - args.user_pull, - args.password_pull, - args.user_push, - args.password_push, - args.customer, - args.testbed, - args.test_run, - args.grafana_dashboard, - args.grafana_token, - args.grafana_host, - args.grafana_port) - - -if __name__ == "__main__": - main() diff --git a/py-scripts/grafana_profile.py b/py-scripts/grafana_profile.py index a78bb987..06c15a07 100755 --- a/py-scripts/grafana_profile.py +++ b/py-scripts/grafana_profile.py @@ -24,37 +24,36 @@ import string import random -#!/usr/bin/env python3 +class UseGrafana(LFCliBase): + def __init__(self, + _grafana_token, + host="localhost", + _grafana_host="localhost", + port=8080, + _debug_on=False, + _exit_on_fail=False, + _grafana_port=3000): + super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail) + self.grafana_token = _grafana_token + self.grafana_port = _grafana_port + self.grafana_host = _grafana_host + self.GR = GrafanaRequest(self.grafana_host, str(self.grafana_port), _folderID=0, _api_token=self.grafana_token) -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Class holds default settings for json requests to Grafana - -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -import sys + def create_dashboard(self, + dashboard_name): + return self.GR.create_dashboard(dashboard_name) -if sys.version_info[0] != 3: - print("This script requires Python 3") - exit() + def delete_dashboard(self, + dashboard_uid): + return self.GR.delete_dashboard(dashboard_uid) -import requests + def list_dashboards(self): + return self.GR.list_dashboards() -import json + def create_dashboard_from_data(self, + json_file): + return self.GR.create_dashboard_from_data(json_file=json_file) -#!/usr/bin/env python3 - -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# Class holds default settings for json requests to Grafana - -# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -import sys - -if sys.version_info[0] != 3: - print("This script requires Python 3") - exit() - -import requests - -import json - -class UseGrafana(GrafanaRequest): def groupby(self, params, grouptype): dic = dict() dic['params'] = list() @@ -302,6 +301,7 @@ class UseGrafana(GrafanaRequest): return dict(zip(graph_group, units)) + def main(): parser = LFCliBase.create_basic_argparse( prog='grafana_profile.py', @@ -353,13 +353,11 @@ def main(): optional.add_argument('--from_date', help='Date you want to start your Grafana dashboard from', default='now-1y') optional.add_argument('--graph_height', help='Custom height for the graph on grafana dashboard', default=8) optional.add_argument('--graph_width', help='Custom width for the graph on grafana dashboard', default=12) - optional.add_argument('--create_snapshot', action='store_true') - optional.add_argument('--list_snapshots', action='store_true') args = parser.parse_args() Grafana = UseGrafana(args.grafana_token, - args.grafana_host, - grafanajson_port=args.grafana_port + args.grafana_port, + args.grafana_host ) if args.dashboard_name is not None: Grafana.create_dashboard(args.dashboard_name) @@ -388,13 +386,6 @@ def main(): graph_height=args.graph_height, graph__width=args.graph_width) - if args.create_snapshot: - Grafana.create_snapshot(args.title) - - if args.list_snapshots: - Grafana.list_snapshots() - - if __name__ == "__main__": main() diff --git a/py-scripts/lf_dataplane_config.json b/py-scripts/lf_dataplane_config.json deleted file mode 100755 index 088a829d..00000000 --- a/py-scripts/lf_dataplane_config.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "mgr":"192.168.0.101", - "port":"8080", - "lf_user":"lanforge", - "lf_password":"lanforge", - "instance_name":"dataplane-instance", - "config_name":"test_con", - "upstream":"1.1.eth1", - "dut":"asus_5g", - "duration":"15s", - "station":"1.1.eth2", - "download_speed":"85%", - "upload_speed":"0", - "pull_report": true, - "raw_line": ["pkts: Custom;60;MTU", "cust_pkt_sz: 88 1200", "directions: DUT Transmit", "traffic_types: UDP", "bandw_options: 20", "spatial_streams: 1"] -} - - - - \ No newline at end of file diff --git a/py-scripts/lf_dataplane_test.py b/py-scripts/lf_dataplane_test.py index 30292022..17939f5b 100755 --- a/py-scripts/lf_dataplane_test.py +++ b/py-scripts/lf_dataplane_test.py @@ -10,7 +10,7 @@ Note: To Run this script gui should be opened with This script is used to automate running Dataplane tests. You may need to view a Dataplane test configured through the GUI to understand the options and how best to input data. - + ./lf_dataplane_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \ --instance_name dataplane-instance --config_name test_con --upstream 1.1.eth2 \ --dut linksys-8450 --duration 15s --station 1.1.sta01500 \ @@ -40,7 +40,7 @@ port_sorting: 0 kpi_id: Dataplane Pkt-Size notes0: ec5211 in bridge mode, wpa2 auth. bg: 0xE0ECF8 -test_rig: +test_rig: show_scan: 1 auto_helper: 0 skip_2: 0 @@ -88,7 +88,7 @@ show_1m: 1 pause_iter: 0 outer_loop_atten: 0 show_realtime: 1 -operator: +operator: mconn: 1 mpkt: 1000 tos: 0 @@ -215,16 +215,11 @@ class DataplaneTest(cv_test): def main(): - parser = argparse.ArgumentParser(description=""" - - IMPORTANT: Start lanforge with socket 3990 : ./lfclient.bash -cli-socket 3990 - lfclient.bash is located in the LANforgeGUI_X.X.X directory - - On local or remote system: ./lfclient.bash -cli-socket 3990 -s LF_MGR - On local system the -s LF_MGR will be local_host if not provided - + parser = argparse.ArgumentParser(""" Open this file in an editor and read the top notes for more details. + Example: + ./lf_dataplane_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \ --instance_name dataplane-instance --config_name test_con --upstream 1.1.eth2 \ --dut linksys-8450 --duration 15s --station 1.1.sta01500 \ @@ -238,53 +233,12 @@ def main(): --influx_token=-u_Wd-L8o992701QF0c5UmqEp7w7Z7YOMaWLxOMgmHfATJGnQbbmYyNxHBR9PgD6taM_tcxqJl6U8DjU1xINFQ== \ --influx_bucket ben \ --influx_tag testbed Ferndale-01 - - - Example 2: - ./lf_dataplane_test.py --json .json - - see sample json file: lf_dataplane_config.json - - Sample .json between using eth1 and eth2 - { - "mgr":"192.168.0.101", - "port":"8080", - "lf_user":"lanforge", - "lf_password":"lanforge", - "instance_name":"dataplane-instance", - "config_name":"test_con", - "upstream":"1.1.eth1", - "dut":"asus_5g", - "duration":"15s", - "station":"1.1.eth2", - "download_speed":"85%", - "upload_speed":"0", - "raw_line": ["pkts: Custom;60;MTU", "cust_pkt_sz: 88 1200", "directions: DUT Transmit", "traffic_types: UDP", "bandw_options: 20", "spatial_streams: 1"] - } - - Sample .json between using eth1 and station 1.1.sta0002 - { - "mgr":"192.168.0.101", - "port":"8080", - "lf_user":"lanforge", - "lf_password":"lanforge", - "instance_name":"dataplane-instance", - "config_name":"test_con", - "upstream":"1.1.eth1", - "dut":"asus_5g", - "duration":"15s", - "station":"1.1.sta0002", - "download_speed":"85%", - "upload_speed":"0", - "raw_line": ["pkts: Custom;60;MTU", "cust_pkt_sz: 88 1200", "directions: DUT Transmit", "traffic_types: UDP", "bandw_options: 20", "spatial_streams: 1"] - } - + """ ) cv_add_base_parser(parser) # see cv_test_manager.py - parser.add_argument('--json', help="--json json input file", default="") parser.add_argument("-u", "--upstream", type=str, default="", help="Upstream port for wifi capacity test ex. 1.1.eth2") parser.add_argument("--station", type=str, default="", @@ -293,7 +247,7 @@ def main(): parser.add_argument("--dut", default="", help="Specify DUT used by this test, example: linksys-8450") parser.add_argument("--download_speed", default="", - help="Specify requested download speed. Percentage of theoretical is also supported. Default: 85%%.") + help="Specify requested download speed. Percentage of theoretical is also supported. Default: 85%") parser.add_argument("--upload_speed", default="", help="Specify requested upload speed. Percentage of theoretical is also supported. Default: 0") parser.add_argument("--duration", default="", @@ -303,69 +257,28 @@ def main(): args = parser.parse_args() - # use json config file - if args.json != "": - try: - with open(args.json, 'r') as json_config: - json_data = json.load(json_config) - except: - print("Error reading {}".format(args.json)) - # json configuation takes presidence to command line - # TODO see if there is easier way to search presence, look at parser args - if "mgr" in json_data: - args.mgr = json_data["mgr"] - if "port" in json_data: - args.port = json_data["port"] - if "lf_user" in json_data: - args.lf_user = json_data["lf_user"] - if "lf_password" in json_data: - args.lf_password = json_data["lf_password"] - if "instance_name" in json_data: - args.instance_name = json_data["instance_name"] - if "config_name" in json_data: - args.config_name = json_data["config_name"] - if "upstream" in json_data: - args.upstream = json_data["upstream"] - if "dut" in json_data: - args.dut = json_data["dut"] - if "duration" in json_data: - args.duration = json_data["duration"] - if "station" in json_data: - args.station = json_data["station"] - if "download_speed" in json_data: - args.download_speed = json_data["download_speed"] - if "upload_speed" in json_data: - args.upload_speed = json_data["upload_speed"] - if "pull_report" in json_data: - args.pull_report = json_data["pull_report"] - if "raw_line" in json_data: - # the json_data is a list , need to make into a list of lists, to match command line raw_line paramaters - # https://www.tutorialspoint.com/convert-list-into-list-of-lists-in-python - json_data_tmp = [[x] for x in json_data["raw_line"]] - args.raw_line = json_data_tmp - cv_base_adjust_parser(args) - CV_Test = DataplaneTest(lf_host=args.mgr, - lf_port=args.port, - lf_user=args.lf_user, - lf_password=args.lf_password, - instance_name=args.instance_name, - config_name=args.config_name, - upstream=args.upstream, - pull_report=args.pull_report, - load_old_cfg=args.load_old_cfg, - download_speed=args.download_speed, - upload_speed=args.upload_speed, - duration=args.duration, - dut=args.dut, - station=args.station, - enables=args.enable, - disables=args.disable, - raw_lines=args.raw_line, - raw_lines_file=args.raw_lines_file, - sets=args.set, - graph_groups=args.graph_groups + CV_Test = DataplaneTest(lf_host = args.mgr, + lf_port = args.port, + lf_user = args.lf_user, + lf_password = args.lf_password, + instance_name = args.instance_name, + config_name = args.config_name, + upstream = args.upstream, + pull_report = args.pull_report, + load_old_cfg = args.load_old_cfg, + download_speed = args.download_speed, + upload_speed = args.upload_speed, + duration = args.duration, + dut = args.dut, + station = args.station, + enables = args.enable, + disables = args.disable, + raw_lines = args.raw_line, + raw_lines_file = args.raw_lines_file, + sets = args.set, + graph_groups = args.graph_groups ) CV_Test.setup() CV_Test.run() diff --git a/py-scripts/lf_report.py b/py-scripts/lf_report.py index e23bc70b..a9d76de1 100755 --- a/py-scripts/lf_report.py +++ b/py-scripts/lf_report.py @@ -25,10 +25,9 @@ LICENSE: INCLUDE_IN_README ''' -import datetime import os import shutil - +import datetime import pandas as pd import pdfkit @@ -51,8 +50,7 @@ class lf_report(): _results_dir_name = "LANforge_Test_Results", _output_format = 'html', # pass in on the write functionality, current not used _dataframe="", - _path_date_time="", - _custom_css='custom-example.css'): # this is where the final report is placed. + _path_date_time=""): # this is where the final report is placed. #other report paths, # _path is where the directory with the data time will be created @@ -91,15 +89,13 @@ class lf_report(): self.logo_directory = "artifacts" self.logo_file_name = "CandelaLogo2-90dpi-200x90-trans.png" # does this need to be configurable. self.current_path = os.path.dirname(os.path.abspath(__file__)) - self.custom_css = _custom_css + # pass in _date to allow to change after construction self.set_date_time_directory(_date,_results_dir_name) self.build_date_time_directory() - self.font_file = "CenturyGothic.woff" # move the banners and candela images to report path self.copy_banner() - self.copy_css() self.copy_logo() def copy_banner(self): @@ -107,35 +103,21 @@ class lf_report(): banner_dst_file = str(self.path_date_time)+'/'+ str(self.banner_file_name) #print("banner src_file: {}".format(banner_src_file)) #print("dst_file: {}".format(banner_dst_file)) - shutil.copy(banner_src_file, banner_dst_file) - - def copy_css(self): - reportcss_src_file = str(self.current_path)+'/'+str(self.banner_directory)+'/report.css' - reportcss_dest_file = str(self.path_date_time)+'/report.css' - - customcss_src_file = str(self.current_path)+'/'+str(self.banner_directory)+'/'+str(self.custom_css) - customcss_dest_file = str(self.path_date_time)+'/custom.css' - - font_src_file = str(self.current_path)+'/'+str(self.banner_directory)+'/'+str(self.font_file) - font_dest_file = str(self.path_date_time)+'/'+str(self.font_file) - - shutil.copy(reportcss_src_file, reportcss_dest_file) - shutil.copy(customcss_src_file, customcss_dest_file) - shutil.copy(font_src_file, font_dest_file) + shutil.copy(banner_src_file,banner_dst_file) def copy_logo(self): logo_src_file = str(self.current_path)+'/'+str(self.logo_directory)+'/'+str(self.logo_file_name) logo_dst_file = str(self.path_date_time)+'/'+ str(self.logo_file_name) #print("logo_src_file: {}".format(logo_src_file)) #print("logo_dst_file: {}".format(logo_dst_file)) - shutil.copy(logo_src_file, logo_dst_file) + shutil.copy(logo_src_file,logo_dst_file) def move_graph_image(self,): graph_src_file = str(self.graph_image) graph_dst_file = str(self.path_date_time)+'/'+ str(self.graph_image) print("graph_src_file: {}".format(graph_src_file)) print("graph_dst_file: {}".format(graph_dst_file)) - shutil.move(graph_src_file, graph_dst_file) + shutil.move(graph_src_file,graph_dst_file) def set_path(self,_path): self.path = _path @@ -175,7 +157,6 @@ class lf_report(): def set_graph_title(self,_graph_title): self.graph_title = _graph_title - # The _date is set when class is enstanciated / created so this set_date should be used with caution, used to synchronize results def set_date(self,_date): self.date = _date @@ -195,12 +176,9 @@ class lf_report(): def set_graph_image(self,_graph_image): self.graph_image = _graph_image - def get_date(self): - return self.date - def get_path(self): return self.path - # get_path_date_time, get_report_path and need to be the same + # get_path_date_time, get_report_path and need to be the same () def get_path_date_time(self): return self.path_date_time @@ -270,57 +248,61 @@ class lf_report(): def build_all(self): self.build_banner() - self.start_content_div() self.build_table_title() self.build_table() - self.end_content_div() def build_banner(self): - # NOTE: {{ }} are the ESCAPED curly braces - self.banner_html = """ - - - - - - - - {title} - - -

- -
-""".format( - title=self.title, - date=self.date, - ) + self.banner_html = """ + + + + + +
+ + + BANNER + +
+
+ + +
+
+

""" + str(self.title) + """

+

""" + str(self.date) + """

+
+
+
+
+
+
+ """ self.html += self.banner_html def build_table_title(self): - self.table_title_html = "

{title}

".format(title=self.table_title) + self.table_title_html = """ + + + + +
+

""" + str(self.table_title) + """

+ """ self.html += self.table_title_html - def start_content_div(self): - self.html += "\n
\n" - def build_text(self): - # please do not use 'style=' tags unless you cannot override a class self.text_html = """ -
-

{text}

\n -
""".format(text=self.text) + + + + +
+

""" + str(self.text) + """

+ """ self.html += self.text_html + def build_date_time(self): self.date_time = str(datetime.datetime.now().strftime("%Y-%m-%d-%H-h-%m-m-%S-s")).replace(':','-') return self.date_time @@ -343,29 +325,30 @@ class lf_report(): def build_objective(self): self.obj_html = """ - -

{title}

-

{objective}

- """.format(title=self.obj_title, - objective=self.objective) + +

""" + str(self.obj_title) + """

+

""" + str(self.objective) + """

+ """ self.html += self.obj_html def build_graph_title(self): self.table_graph_html = """ -
-

{title}

- """.format(title=self.graph_title) + + + + +
+

""" + str(self.graph_title) + """

+ """ self.html += self.table_graph_html def build_graph(self): self.graph_html_obj = """ - - """.format(image=self.graph_image) + +

+ """ self.html +=self.graph_html_obj - def end_content_div(self): - self.html += "\n
\n" - # Unit Test if __name__ == "__main__": diff --git a/py-scripts/sandbox/lf_dataplane_json.py b/py-scripts/sandbox/lf_dataplane_json.py deleted file mode 100755 index 5bb7c80b..00000000 --- a/py-scripts/sandbox/lf_dataplane_json.py +++ /dev/null @@ -1,334 +0,0 @@ -#!/usr/bin/env python3 - -""" -Note: To Run this script gui should be opened with - - path: cd LANforgeGUI_5.4.3 (5.4.3 can be changed with GUI version) - pwd (Output : /home/lanforge/LANforgeGUI_5.4.3) - ./lfclient.bash -cli-socket 3990 - -This script is used to automate running Dataplane tests. You -may need to view a Dataplane test configured through the GUI to understand -the options and how best to input data. - - ./lf_dataplane_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \ - --instance_name dataplane-instance --config_name test_con --upstream 1.1.eth2 \ - --dut linksys-8450 --duration 15s --station 1.1.sta01500 \ - --download_speed 85% --upload_speed 0 \ - --raw_line 'pkts: Custom;60;142;256;512;1024;MTU' \ - --raw_line 'cust_pkt_sz: 88 1200' \ - --raw_line 'directions: DUT Transmit;DUT Receive' \ - --raw_line 'traffic_types: UDP;TCP' \ - --test_rig Testbed-01 --pull_report \ - --influx_host c7-graphana --influx_port 8086 --influx_org Candela \ - --influx_token=-u_Wd-L8o992701QF0c5UmqEp7w7Z7YOMaWLxOMgmHfATJGnQbbmYyNxHBR9PgD6taM_tcxqJl6U8DjU1xINFQ== \ - --influx_bucket ben \ - --influx_tag testbed Ferndale-01 - -Note: - --raw_line 'line contents' will add any setting to the test config. This is - useful way to support any options not specifically enabled by the - command options. - --set modifications will be applied after the other config has happened, - so it can be used to override any other config. - -Example of raw text config for Dataplane, to show other possible options: - -show_events: 1 -show_log: 0 -port_sorting: 0 -kpi_id: Dataplane Pkt-Size -notes0: ec5211 in bridge mode, wpa2 auth. -bg: 0xE0ECF8 -test_rig: -show_scan: 1 -auto_helper: 0 -skip_2: 0 -skip_5: 0 -skip_5b: 1 -skip_dual: 0 -skip_tri: 1 -selected_dut: ea8300 -duration: 15000 -traffic_port: 1.1.157 sta01500 -upstream_port: 1.1.2 eth2 -path_loss: 10 -speed: 85% -speed2: 0Kbps -min_rssi_bound: -150 -max_rssi_bound: 0 -channels: AUTO -modes: Auto -pkts: Custom;60;142;256;512;1024;MTU -spatial_streams: AUTO -security_options: AUTO -bandw_options: AUTO -traffic_types: UDP;TCP -directions: DUT Transmit;DUT Receive -txo_preamble: OFDM -txo_mcs: 0 CCK, OFDM, HT, VHT -txo_retries: No Retry -txo_sgi: OFF -txo_txpower: 15 -attenuator: 0 -attenuator2: 0 -attenuator_mod: 255 -attenuator_mod2: 255 -attenuations: 0..+50..950 -attenuations2: 0..+50..950 -chamber: 0 -tt_deg: 0..+45..359 -cust_pkt_sz: 88 1200 -show_bar_labels: 1 -show_prcnt_tput: 0 -show_3s: 0 -show_ll_graphs: 0 -show_gp_graphs: 1 -show_1m: 1 -pause_iter: 0 -outer_loop_atten: 0 -show_realtime: 1 -operator: -mconn: 1 -mpkt: 1000 -tos: 0 -loop_iterations: 1 - -""" - -import sys -import os -import argparse -import time -import json -from os import path - -if sys.version_info[0] != 3: - print("This script requires Python 3") - exit(1) - -if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) - -from cv_test_manager import cv_test -from cv_test_manager import * - - -class DataplaneTest(cv_test): - def __init__(self, - lf_host="localhost", - lf_port=8080, - lf_user="lanforge", - lf_password="lanforge", - ssh_port=22, - local_path="", - instance_name="dpt_instance", - config_name="dpt_config", - upstream="1.1.eth2", - pull_report=False, - load_old_cfg=False, - upload_speed="0", - download_speed="85%", - duration="15s", - station="1.1.sta01500", - dut="NA", - enables=[], - disables=[], - raw_lines=[], - raw_lines_file="", - sets=[], - graph_groups=None, - report_dir="" - ): - super().__init__(lfclient_host=lf_host, lfclient_port=lf_port) - - self.lf_host = lf_host - self.lf_port = lf_port - self.lf_user = lf_user - self.lf_password = lf_password - self.instance_name = instance_name - self.config_name = config_name - self.dut = dut - self.duration = duration - self.upstream = upstream - self.station = station - self.pull_report = pull_report - self.load_old_cfg = load_old_cfg - self.test_name = "Dataplane" - self.upload_speed = upload_speed - self.download_speed = download_speed - self.enables = enables - self.disables = disables - self.raw_lines = raw_lines - self.raw_lines_file = raw_lines_file - self.sets = sets - self.graph_groups = graph_groups - self.report_dir = report_dir - self.ssh_port = ssh_port - self.local_path = local_path - - def setup(self): - # Nothing to do at this time. - return - - def run(self): - self.sync_cv() - time.sleep(2) - self.sync_cv() - - blob_test = "dataplane-test-latest-" - - self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name - self.show_text_blob(None, None, False) - - # Test related settings - cfg_options = [] - - ### HERE### - self.apply_cfg_options(cfg_options, self.enables, self.disables, self.raw_lines, self.raw_lines_file) - - # cmd line args take precedence and so come last in the cfg array. - if self.upstream != "": - cfg_options.append("upstream_port: " + self.upstream) - if self.station != "": - cfg_options.append("traffic_port: " + self.station) - if self.download_speed != "": - cfg_options.append("speed: " + self.download_speed) - if self.upload_speed != "": - cfg_options.append("speed2: " + self.upload_speed) - if self.duration != "": - cfg_options.append("duration: " + self.duration) - if self.dut != "": - cfg_options.append("selected_dut: " + self.dut) - - # We deleted the scenario earlier, now re-build new one line at a time. - - self.build_cfg(self.config_name, blob_test, cfg_options) - - cv_cmds = [] - self.create_and_run_test(self.load_old_cfg, self.test_name, self.instance_name, - self.config_name, self.sets, - self.pull_report, self.lf_host, self.lf_user, self.lf_password, - cv_cmds, ssh_port=self.ssh_port, local_path=self.local_path, - graph_groups_file=self.graph_groups) - self.rm_text_blob(self.config_name, blob_test) # To delete old config with same name - - -def main(): - parser = argparse.ArgumentParser(""" - Open this file in an editor and read the top notes for more details. - - Example: - - ./lf_dataplane_test.py --mgr localhost --port 8080 --lf_user lanforge --lf_password lanforge \ - --instance_name dataplane-instance --config_name test_con --upstream 1.1.eth2 \ - --dut linksys-8450 --duration 15s --station 1.1.sta01500 \ - --download_speed 85% --upload_speed 0 \ - --raw_line 'pkts: Custom;60;142;256;512;1024;MTU' \ - --raw_line 'cust_pkt_sz: 88 1200' \ - --raw_line 'directions: DUT Transmit;DUT Receive' \ - --raw_line 'traffic_types: UDP;TCP' \ - --test_rig Testbed-01 --pull_report \ - --influx_host c7-graphana --influx_port 8086 --influx_org Candela \ - --influx_token=-u_Wd-L8o992701QF0c5UmqEp7w7Z7YOMaWLxOMgmHfATJGnQbbmYyNxHBR9PgD6taM_tcxqJl6U8DjU1xINFQ== \ - --influx_bucket ben \ - --influx_tag testbed Ferndale-01 - - """ - ) - - cv_add_base_parser(parser) # see cv_test_manager.py - - parser.add_argument('--json', help="--json json input file", default="") - parser.add_argument("-u", "--upstream", type=str, default="", - help="Upstream port for wifi capacity test ex. 1.1.eth2") - parser.add_argument("--station", type=str, default="", - help="Station to be used in this test, example: 1.1.sta01500") - - parser.add_argument("--dut", default="", - help="Specify DUT used by this test, example: linksys-8450") - parser.add_argument("--download_speed", default="", - help="Specify requested download speed. Percentage of theoretical is also supported. Default: 85%") - parser.add_argument("--upload_speed", default="", - help="Specify requested upload speed. Percentage of theoretical is also supported. Default: 0") - parser.add_argument("--duration", default="", - help="Specify duration of each traffic run") - parser.add_argument("--graph_groups", help="File to save graph_groups to", default=None) - parser.add_argument("--report_dir", default="") - - args = parser.parse_args() - - # TODO - if args.json != "": - try: - with open(args.json, 'r') as json_config: - json_data = json.load(json_config) - except: - print("Error reading {}".format(args.json)) - # json configuation takes presidence to command line - # TODO see if there is easier way to search presence, look at parser args - if "mgr" in json_data: - args.mgr = json_data["mgr"] - if "port" in json_data: - args.port = json_data["port"] - if "lf_user" in json_data: - args.lf_user = json_data["lf_user"] - if "lf_password" in json_data: - args.lf_password = json_data["lf_password"] - if "instance_name" in json_data: - args.instance_name = json_data["instance_name"] - if "config_name" in json_data: - args.config_name = json_data["config_name"] - if "upstream" in json_data: - args.upstream = json_data["upstream"] - if "dut" in json_data: - args.dut = json_data["dut"] - if "duration" in json_data: - args.duration = json_data["duration"] - if "station" in json_data: - args.station = json_data["station"] - if "download_speed" in json_data: - args.download_speed = json_data["download_speed"] - if "upload_speed" in json_data: - args.upload_speed = json_data["upload_speed"] - if "raw_line" in json_data: - # the json_data is a list , need to make into a list of lists, to match command line raw_line paramaters - # https://www.tutorialspoint.com/convert-list-into-list-of-lists-in-python - json_data_tmp = [[x] for x in json_data["raw_line"]] - args.raw_line = json_data_tmp - - cv_base_adjust_parser(args) - print(args) - #exit(1) - - # if json present use json config will override - - CV_Test = DataplaneTest(lf_host = args.mgr, - lf_port = args.port, - lf_user = args.lf_user, - lf_password = args.lf_password, - instance_name = args.instance_name, - config_name = args.config_name, - upstream = args.upstream, - pull_report = args.pull_report, - load_old_cfg = args.load_old_cfg, - download_speed = args.download_speed, - upload_speed = args.upload_speed, - duration = args.duration, - dut = args.dut, - station = args.station, - enables = args.enable, - disables = args.disable, - raw_lines = args.raw_line, # this is interesting. - raw_lines_file = args.raw_lines_file, - sets = args.set, - graph_groups = args.graph_groups - ) - CV_Test.setup() - CV_Test.run() - - CV_Test.check_influx_kpi(args) - - -if __name__ == "__main__": - main() diff --git a/py-scripts/sandbox/lf_pdf_search.py b/py-scripts/sandbox/lf_pdf_search.py deleted file mode 100755 index 1c5cb42c..00000000 --- a/py-scripts/sandbox/lf_pdf_search.py +++ /dev/null @@ -1,146 +0,0 @@ -#!/usr/bin/python3 - -''' -NAME: -lf_pdf_search.py - -PURPOSE: -lf_pdf_search.py will run a pdf grep looking for specific information in pdf files -"pdfgrep -r --include 'ASA*.pdf' 'ASA End Date'" - -EXAMPLE: -lf_pdf_search.py - -NOTES: -1. copy lf_pdf_search.py to a directory that has the pdf information - -TO DO NOTES: - - -''' -import datetime -import pprint -import sys -if sys.version_info[0] != 3: - print("This script requires Python3") - exit() - - -import os -import socket -import logging -import time -from time import sleep -import argparse -import json -import configparser -import subprocess -import csv -import shutil -import os.path -import xlsxwriter -import re -import pandas as pd - - -class lf_pdf_search(): - def __init__(self): - - self.renewal_info = "" - self.timeout = 10 - self.outfile = "pdf_search" - self.result = "" - self.stdout_log_txt = "" - self.stdout_log = "" - self.stderr_log_txt = "" - self.stderr_log = "" - self.processed_log_txt = "" - self.dataframe = "" - self.pdf_search_csv = "" - - def get_data(self): - - # o.k. a little over kill here , just save data to file to help debug if something goes wrong - if self.outfile is not None: - self.stdout_log_txt = self.outfile - self.stdout_log_txt = self.stdout_log_txt + "-{}-stdout.txt".format("test") - self.stdout_log = open(self.stdout_log_txt, 'w+') - self.stderr_log_txt = self.outfile - self.stderr_log_txt = self.stderr_log_txt + "-{}-stderr.txt".format("test") - #self.logger.info("stderr_log_txt: {}".format(stderr_log_txt)) - self.stderr_log = open(self.stderr_log_txt, 'w+') - - print("Names {} {}".format(self.stdout_log.name, self.stderr_log.name)) - - # have ability to pass in a specific command - command = "pdfgrep -r --include 'ASA*.pdf' 'ASA End Date'" - print("running {}".format(command)) - - process = subprocess.Popen(['pdfgrep','-r','--include','ASA*.pdf','ASA End Date'], shell=False, stdout=self.stdout_log, stderr=self.stderr_log, universal_newlines=True) - try: - process.wait(timeout=int(self.timeout)) - self.result = "SUCCESS" - except subprocess.TimeoutExpired: - process.terminate() - self.result = "TIMEOUT" - - self.stdout_log.close() - self.stderr_log.close() - - return self.stdout_log_txt - - def preprocess_data(self): - pass - - # this method uses pandas dataframe - will use for data manipulation, - # the data mainupulation may be done in other manners - def datafile_to_dataframe(self): - # note the error_bad_lines=False will miss one of the lines - delimiter_list = [':'] - try: - self.dataframe = pd.read_csv(self.stdout_log_txt, delimiter = [':']) - #self.dataframe = pd.read_csv(self.stdout_log_txt, sep = ':') - except: - print("one of the files may have a SN: in it need to correct ") - self.dataframe = pd.read_csv(self.stdout_log_txt, delimiter = ':', error_bad_lines=False) - #print(self.dataframe) - print("saving data to .csv") - # this removes the extention of .txt - self.pdf_search_csv= self.stdout_log_txt[:-4] - self.pdf_search_csv = self.pdf_search_csv + ".csv" - self.pdf_search_csv = self.dataframe.to_csv(self.pdf_search_csv,mode='w',index=False) - - -def main(): - # arguments - parser = argparse.ArgumentParser( - prog='lf_pdf_search.py', - formatter_class=argparse.RawTextHelpFormatter, - epilog='''\ - lf_pdf_search.py : for running scripts listed in lf_check_config.ini file - ''', - description='''\ -lf_pdf_search.py ------------ - -Summary : ---------- -show renewas - ''') - - parser.add_argument('--outfile', help="--outfile used as base name for all files generated", default="") - parser.add_argument('--logfile', help="--logfile logging for output of lf_pdf_search script", default="lf_pdf_search.log") - - args = parser.parse_args() - - pdf_search = lf_pdf_search() - output_file = pdf_search.get_data() - - pdf_search.datafile_to_dataframe() - - print("output file: {}".format(str(output_file))) - print("END lf_pdf_search.py") - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/py-scripts/sandbox/lf_read_json.py b/py-scripts/sandbox/lf_read_json.py deleted file mode 100644 index 721b294e..00000000 --- a/py-scripts/sandbox/lf_read_json.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/python3 - -''' -NAME: -lf_read_json.py - -PURPOSE: -Test out reading configuration data from a .json style config file - -EXAMPLE: -./lf_read_json.py --file .json - -NOTES: - - -TO DO NOTES: - - -''' -import sys -if sys.version_info[0] != 3: - print("This script requires Python3") - exit() - - -from time import sleep -import argparse -import json - -class lf_read_json(): - def __init__(self): - - self.timeout = 10 - - - def preprocess_data(self): - pass - - - -def main(): - # arguments - parser = argparse.ArgumentParser( - prog='lf_read_json.py', - formatter_class=argparse.RawTextHelpFormatter, - epilog='''\ - lf_read_json.py : read json - ''', - description='''\ -lf_read_json.py ------------ - -Summary : ---------- - -./lf_dataplane_json.py --mgr 192.168.0.101 --port 8080 --lf_user lanforge --lf_password lanforge --instance_name dataplane-instance --config_name test_con --upstream 1.1.eth1 --dut asus_5g --duration 15s --station 1.1.13.sta0002 --download_speed 85% --upload_speed 0 --raw_line 'pkts: Custom;60;MTU' --raw_line 'cust_pkt_sz: 88 1200' --raw_line 'directions: DUT Transmit' --raw_line 'traffic_types: UDP' --raw_line 'bandw_options: 20' --raw_line 'spatial_streams: 1 - - ''') - - parser.add_argument('--json', help="--json json input file", default="config.json") - - args = parser.parse_args() - - config_json = args.json - print("config_json {}".format(config_json)) - - with open(config_json, 'r') as config_file: - config_data = json.load(config_file) - - print(config_data) - print("mgr: {}".format(config_data["mgr"])) - #print("raw_line: {}".format(config_data["raw_line"])) - raw = [] - raw = config_data["raw_line"] - print(raw) - # raw is a list - raw2 = [[x] for x in raw] - print(raw2) - - ''' - for r in raw_lines: - cfg_options.append(r[0]) - ''' - - '''./lf_dataplane_json.py --mgr 192.168.0.101 --port 8080 --lf_user lanforge --lf_password lanforge --instance_name dataplane-instance --config_name test_con --upstream 1.1.eth1 --dut asus_5g --duration 15s --station 1.1.13.sta0002 --download_speed 85% --upload_speed 0 --raw_line 'pkts: Custom;60;MTU' --raw_line 'cust_pkt_sz: 88 1200' --raw_line 'directions: DUT Transmit' --raw_line 'traffic_types: UDP' --raw_line 'bandw_options: 20' --raw_line 'spatial_streams: 1' -Namespace(config_name='test_con', disable=[], download_speed='85%', duration='15s', dut='asus_5g', enable=[], graph_groups=None, influx_bucket=None, influx_host=None, influx_org=None, influx_port=8086, influx_tag=[], influx_token=None, instance_name='dataplane-instance', json='', lf_password='lanforge', lf_user='lanforge', load_old_cfg=False, mgr='192.168.0.101', port=8080, pull_report=False, - correct version: - raw_line=[['pkts: Custom;60;MTU'], ['cust_pkt_sz: 88 1200'], ['directions: DUT Transmit'], ['traffic_types: UDP'], ['bandw_options: 20'], ['spatial_streams: 1']], raw_lines_file='', report_dir='', set=[], station='1.1.13.sta0002', test_rig='', upload_speed='0', upstream='1.1.eth1') - ''' - - ''' Incorrect version - raw_line={'pkts': ['Custom', '60', 'MTU'], 'cust_pkt_sz': ['88', '1200'], 'directions': 'DUT Transmit', 'traffic_types': 'UDP', 'bandw_options': '20', 'stpatial_streams': '1'} - ''' - '''cfg_options = [] - for r in raw: - print(r) - test = '{}:{}'.format(r,raw[r]) - cfg_options.append(test) - print(cfg_options) - ''' - - - - - - #dave = [] - #for key,val in raw.items(): dave.append(raw.items()) - - #print(dave) - - if "mgr" in config_data: - print("mgr present") - - print("END lf_read_json.py") - - -if __name__ == "__main__": - main() \ No newline at end of file diff --git a/py-scripts/scripts_deprecated/test_ipv4_variable_time2.py b/py-scripts/sandbox/test_ipv4_variable_time2.py similarity index 100% rename from py-scripts/scripts_deprecated/test_ipv4_variable_time2.py rename to py-scripts/sandbox/test_ipv4_variable_time2.py diff --git a/py-scripts/scripts_deprecated/lf_check_jbr.py b/py-scripts/scripts_deprecated/lf_check_jbr.py deleted file mode 100755 index 56c4894c..00000000 --- a/py-scripts/scripts_deprecated/lf_check_jbr.py +++ /dev/null @@ -1,563 +0,0 @@ -#!/usr/bin/python3 - -''' -NAME: -lf_check.py - -PURPOSE: -lf_check.py will run a series of tests based on the test TEST_DICTIONARY listed in lf_check_config.ini. -The lf_check_config.ini file is copied from lf_check_config_template.ini and local configuration is made -to the lf_check_config.ini. - -EXAMPLE: -lf_check.py - -NOTES: -Before using lf_check.py -1. copy lf_check_config_template.ini to the lf_check_config.ini -2. update lf_check_config.ini to enable (TRUE) tests to be run in the TEST_DICTIONARY , the TEST_DICTIONARY needs to be passed in - -''' -import datetime -import pprint -import sys -if sys.version_info[0] != 3: - print("This script requires Python3") - exit() - - -import os -import socket -import logging -import time -from time import sleep -import argparse -import json -import configparser -import subprocess -import csv -import shutil -import os.path - -# lf_report is from the parent of the current file -dir_path = os.path.dirname(os.path.realpath(__file__)) -parent_dir_path = os.path.abspath(os.path.join(dir_path,os.pardir)) -sys.path.insert(0, parent_dir_path) - -#sys.path.append('../') -from lf_report import lf_report -sys.path.append('/') - -CONFIG_FILE = os.getcwd() + '/lf_check_config.ini' -RUN_CONDITION = 'ENABLE' - -# setup logging FORMAT -FORMAT = '%(asctime)s %(name)s %(levelname)s: %(message)s' - -# lf_check class contains verificaiton configuration and ocastrates the testing. -class lf_check(): - def __init__(self, - _csv_results, - _outfile): - self.lf_mgr_ip = "" - self.lf_mgr_port = "" - self.radio_dict = {} - self.test_dict = {} - path_parent = os.path.dirname(os.getcwd()) - os.chdir(path_parent) - self.scripts_wd = os.getcwd() - self.results = "" - self.outfile = _outfile - self.test_result = "Failure" - self.results_col_titles = ["Test","Command","Result","STDOUT","STDERR"] - self.html_results = "" - self.background_green = "background-color:green" - self.background_red = "background-color:red" - self.background_purple = "background-color:purple" - - self.http_test_ip = "" - self.ftp_test_ip = "" - self.test_ip = "" - - # section TEST_GENERIC - self.radio_lf = "" - self.ssdi = "" - self.ssid_pw = "" - self.security = "" - self.num_sta = "" - self.col_names = "" - self.upstream_port = "" - - self.csv_results = _csv_results - self.csv_results_file = "" - self.csv_results_writer = "" - self.csv_results_column_headers = "" - self.logger = logging.getLogger(__name__) - self.test_timeout = 120 - self.use_blank_db = "FALSE" - self.use_factory_default_db = "FALSE" - self.use_custom_db = "FALSE" - self.production_run = "FALSE" - self.email_list_production = "" - self.host_ip_production = None - self.email_list_test = "" - self.host_ip_test = None - - # NOT complete : will send the email results - def send_results_email(self, report_file=None): - if (report_file is None): - print( "No report file, not sending email.") - return - report_url=report_file.replace('/home/lanforge/', '') - if report_url.startswith('/'): - report_url = report_url[1:] - # Following recommendation - # NOTE: https://stackoverflow.com/questions/24196932/how-can-i-get-the-ip-address-from-nic-in-python - #command = 'echo "$HOSTNAME mail system works!" | mail -s "Test: $HOSTNAME $(date)" chuck.rekiere@candelatech.com' - hostname = socket.gethostname() - ip = socket.gethostbyname(hostname) - message_txt = """Results from {hostname}:\\n -http://{ip}/{report}\\n -NOTE: for now to see stdout and stderr remove /home/lanforge from path.\\n -""".format(hostname=hostname, ip=ip, report=report_url) - - - mail_subject = "Regression Test [{hostname}] {date}".format(hostname=hostname, - date=datetime.datetime.now()) - try: - if self.production_run == "TRUE": - msg = message_txt.format(ip=self.host_ip_production) - command = "echo \"{message}\" | mail -s \"{subject}\" {address}".format( - message=msg, - subject=mail_subject, - ip=self.host_ip_production, - address=self.email_list_production) - else: - msg = message_txt.format(ip=ip) - command = "echo \"{message}\" | mail -s \"{subject}\" {address}".format( - message=msg, - subject=mail_subject, - ip=ip, #self.host_ip_test, - address=self.email_list_test) - - print("running:[{}]".format(command)) - process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) - # have email on separate timeout - process.wait(timeout=int(self.test_timeout)) - except subprocess.TimeoutExpired: - print("send email timed out") - process.terminate() - - def get_csv_results(self): - return self.csv_file.name - - def start_csv_results(self): - print("self.csv_results") - self.csv_results_file = open(self.csv_results, "w") - self.csv_results_writer = csv.writer(self.csv_results_file, delimiter=",") - self.csv_results_column_headers = ['Test','Command','Result','STDOUT','STDERR'] - self.csv_results_writer.writerow(self.csv_results_column_headers) - self.csv_results_file.flush() - - def get_html_results(self): - return self.html_results - - def start_html_results(self): - self.html_results += """ - - - - - - - - - - - - """ - - def finish_html_results(self): - self.html_results += """ - -
TestCommandResultSTDOUTSTDERR
-
-
-
- """ - - # Functions in this section are/can be overridden by descendants - # This code reads the lf_check_config.ini file to populate the test variables - def read_config_contents(self): - self.logger.info("read_config_contents {}".format(CONFIG_FILE)) - config_file = configparser.ConfigParser() - success = True - success = config_file.read(CONFIG_FILE) - self.logger.info("logger worked") - - if 'LF_MGR' in config_file.sections(): - section = config_file['LF_MGR'] - self.lf_mgr_ip = section['LF_MGR_IP'] - self.lf_mgr_port = section['LF_MGR_PORT'] - self.logger.info("lf_mgr_ip {}".format(self.lf_mgr_ip)) - self.logger.info("lf_mgr_port {}".format(self.lf_mgr_port)) - - if 'TEST_NETWORK' in config_file.sections(): - section = config_file['TEST_NETWORK'] - self.http_test_ip = section['HTTP_TEST_IP'] - self.logger.info("http_test_ip {}".format(self.http_test_ip)) - self.ftp_test_ip = section['FTP_TEST_IP'] - self.logger.info("ftp_test_ip {}".format(self.ftp_test_ip)) - self.test_ip = section['TEST_IP'] - self.logger.info("test_ip {}".format(self.test_ip)) - - if 'TEST_GENERIC' in config_file.sections(): - section = config_file['TEST_GENERIC'] - self.radio_lf = section['RADIO_USED'] - self.logger.info("radio_lf {}".format(self.radio_lf)) - self.ssid = section['SSID_USED'] - self.logger.info("ssid {}".format(self.ssid)) - self.ssid_pw = section['SSID_PW_USED'] - self.logger.info("ssid_pw {}".format(self.ssid_pw)) - self.security = section['SECURITY_USED'] - self.logger.info("secruity {}".format(self.security)) - self.num_sta = section['NUM_STA'] - self.logger.info("num_sta {}".format(self.num_sta)) - self.col_names = section['COL_NAMES'] - self.logger.info("col_names {}".format(self.col_names)) - self.upstream_port = section['UPSTREAM_PORT'] - self.logger.info("upstream_port {}".format(self.upstream_port)) - - if 'TEST_PARAMETERS' in config_file.sections(): - section = config_file['TEST_PARAMETERS'] - self.test_timeout = section['TEST_TIMEOUT'] - self.use_blank_db = section['LOAD_BLANK_DB'] - self.use_factory_default_db = section['LOAD_FACTORY_DEFAULT_DB'] - self.use_custom_db = section['LOAD_CUSTOM_DB'] - self.custom_db = section['CUSTOM_DB'] - self.production_run = section['PRODUCTION_RUN'] - self.email_list_production = section['EMAIL_LIST_PRODUCTION'] - self.host_ip_production = section['HOST_IP_PRODUCTION'] - self.email_list_test = section['EMAIL_LIST_TEST'] - self.host_ip_test = section['HOST_IP_TEST'] - - if 'RADIO_DICTIONARY' in config_file.sections(): - section = config_file['RADIO_DICTIONARY'] - self.radio_dict = json.loads(section.get('RADIO_DICT', self.radio_dict)) - self.logger.info("self.radio_dict {}".format(self.radio_dict)) - - if 'TEST_DICTIONARY' in config_file.sections(): - section = config_file['TEST_DICTIONARY'] - # for json replace the \n and \r they are invalid json characters, allows for multiple line args - try: - self.test_dict = json.loads(section.get('TEST_DICT', self.test_dict).replace('\n',' ').replace('\r',' ')) - self.logger.info("TEST_DICTIONARY: {}".format(self.test_dict)) - except: - self.logger.info("Excpetion loading TEST_DICTIONARY, is there comma after the last entry? Check syntax") - - def load_factory_default_db(self): - #self.logger.info("file_wd {}".format(self.scripts_wd)) - try: - os.chdir(self.scripts_wd) - #self.logger.info("Current Working Directory {}".format(os.getcwd())) - except: - self.logger.info("failed to change to {}".format(self.scripts_wd)) - - # no spaces after FACTORY_DFLT - command = "./{} {}".format("scenario.py", "--load FACTORY_DFLT") - process = subprocess.Popen((command).split(' '), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) - # wait for the process to terminate - out, err = process.communicate() - errcode = process.returncode - - # Not currently used - def load_blank_db(self): - #self.logger.info("file_wd {}".format(self.scripts_wd)) - try: - os.chdir(self.scripts_wd) - #self.logger.info("Current Working Directory {}".format(os.getcwd())) - except: - self.logger.info("failed to change to {}".format(self.scripts_wd)) - - # no spaces after FACTORY_DFLT - command = "./{} {}".format("scenario.py", "--load BLANK") - process = subprocess.Popen((command).split(' '), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) - - def load_custom_db(self,custom_db): - #self.logger.info("file_wd {}".format(self.scripts_wd)) - try: - os.chdir(self.scripts_wd) - #self.logger.info("Current Working Directory {}".format(os.getcwd())) - except: - self.logger.info("failed to change to {}".format(self.scripts_wd)) - - # no spaces after FACTORY_DFLT - command = "./{} {}".format("scenario.py", "--load {}".format(custom_db)) - process = subprocess.Popen((command).split(' '), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) - # wait for the process to terminate - out, err = process.communicate() - errcode = process.returncode - - def run_script_test(self): - self.start_html_results() - self.start_csv_results() - - for test in self.test_dict: - if self.test_dict[test]['enabled'] == "FALSE": - self.logger.info("test: {} skipped".format(test)) - # load the default database - elif self.test_dict[test]['enabled'] == "TRUE": - # Make the command replace ment a separate method call. - # loop through radios - for radio in self.radio_dict: - # Replace RADIO, SSID, PASSWD, SECURITY with actual config values (e.g. RADIO_0_CFG to values) - # not "KEY" is just a word to refer to the RADIO define (e.g. RADIO_0_CFG) to get the vlaues - # --num_stations needs to be int not string (no double quotes) - if self.radio_dict[radio]["KEY"] in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace(self.radio_dict[radio]["KEY"],'--radio {} --ssid {} --passwd {} --security {} --num_stations {}' - .format(self.radio_dict[radio]['RADIO'],self.radio_dict[radio]['SSID'],self.radio_dict[radio]['PASSWD'],self.radio_dict[radio]['SECURITY'],self.radio_dict[radio]['STATIONS'])) - - if 'HTTP_TEST_IP' in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('HTTP_TEST_IP',self.http_test_ip) - if 'FTP_TEST_IP' in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('FTP_TEST_IP',self.ftp_test_ip) - if 'TEST_IP' in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('TEST_IP',self.test_ip) - - if 'RADIO_USED' in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('RADIO_USED',self.radio_lf) - if 'SSID_USED' in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('SSID_USED',self.ssid) - if 'SSID_PW_USED' in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('SSID_PW_USED',self.ssid_pw) - if 'SECURITY_USED' in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('SECURITY_USED',self.security) - if 'NUM_STA' in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('NUM_STA',self.num_sta) - if 'COL_NAMES' in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('COL_NAMES',self.col_names) - if 'UPSTREAM_PORT' in self.test_dict[test]['args']: - self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('UPSTREAM_PORT',self.col_names) - if self.use_factory_default_db == "TRUE": - self.load_factory_default_db() - sleep(3) - self.logger.info("FACTORY_DFLT loaded between tests with scenario.py --load FACTORY_DFLT") - if self.use_blank_db == "TRUE": - self.load_blank_db() - sleep(1) - self.logger.info("BLANK loaded between tests with scenario.py --load BLANK") - if self.use_custom_db == "TRUE": - try: - self.load_custom_db(self.custom_db) - sleep(1) - self.logger.info("{} loaded between tests with scenario.py --load {}".format(self.custom_db,self.custom_db)) - except: - self.logger.info("custom database failed to load check existance and location") - else: - self.logger.info("no db loaded between tests: {}".format(self.use_custom_db)) - - sleep(1) # the sleep is to allow for the database to stablize - - try: - os.chdir(self.scripts_wd) - #self.logger.info("Current Working Directory {}".format(os.getcwd())) - except: - self.logger.info("failed to change to {}".format(self.scripts_wd)) - cmd_args = "{}".format(self.test_dict[test]['args']) - command = "./{} {}".format(self.test_dict[test]['command'], cmd_args) - self.logger.info("command: {}".format(command)) - self.logger.info("cmd_args {}".format(cmd_args)) - - if self.outfile is not None: - stdout_log_txt = self.outfile - stdout_log_txt = stdout_log_txt + "-{}-stdout.txt".format(test) - #self.logger.info("stdout_log_txt: {}".format(stdout_log_txt)) - stdout_log = open(stdout_log_txt, 'a') - stderr_log_txt = self.outfile - stderr_log_txt = stderr_log_txt + "-{}-stderr.txt".format(test) - #self.logger.info("stderr_log_txt: {}".format(stderr_log_txt)) - stderr_log = open(stderr_log_txt, 'a') - - - print("running {}".format(command)) - process = subprocess.Popen((command).split(' '), shell=False, stdout=stdout_log, stderr=stderr_log, universal_newlines=True) - - try: - #out, err = process.communicate() - process.wait(timeout=int(self.test_timeout)) - except subprocess.TimeoutExpired: - process.terminate() - self.test_result = "TIMEOUT" - - #if err: - # self.logger.info("command Test timed out: {}".format(command)) - - #self.logger.info(stderr_log_txt) - if(self.test_result != "TIMEOUT"): - stderr_log_size = os.path.getsize(stderr_log_txt) - if stderr_log_size > 0 : - self.logger.info("File: {} is not empty: {}".format(stderr_log_txt,str(stderr_log_size))) - - self.test_result = "Failure" - background = self.background_red - else: - self.logger.info("File: {} is empty: {}".format(stderr_log_txt,str(stderr_log_size))) - self.test_result = "Success" - background = self.background_green - else: - self.logger.info("TIMEOUT FAILURE, Check LANforge Radios") - self.test_result = "Time Out" - background = self.background_purple - - self.html_results += """ - """ + str(test) + """""" + str(command) + """ - """ + str(self.test_result) + """ - STDOUT""" - if self.test_result == "Failure": - self.html_results += """STDERR""" - elif self.test_result == "Time Out": - self.html_results += """STDERR""" - #self.html_results += """""" - else: - self.html_results += """""" - self.html_results += """""" - - row = [test,command,self.test_result,stdout_log_txt,stderr_log_txt] - self.csv_results_writer.writerow(row) - self.csv_results_file.flush() - #self.logger.info("row: {}".format(row)) - self.logger.info("test: {} executed".format(test)) - - else: - self.logger.info("enable value {} invalid for test: {}, test skipped".format(self.test_dict[test]['enabled'],test)) - - self.finish_html_results() - -def main(): - # arguments - parser = argparse.ArgumentParser( - prog='lf_check.py', - formatter_class=argparse.RawTextHelpFormatter, - epilog='''\ - lf_check.py : for running scripts listed in lf_check_config.ini file - ''', - description='''\ -lf_check.py ------------ - -Summary : ---------- -for running scripts listed in lf_check_config.ini - ''') - - parser.add_argument('--outfile', help="--outfile used as base name for all files generated", default="") - parser.add_argument('--logfile', help="--logfile logging for output of lf_check.py script", default="lf_check.log") - - args = parser.parse_args() - - # output report. - report = lf_report(_results_dir_name="lf_check", - _output_html="lf_check.html", - _output_pdf="lf-check.pdf") - - current_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) - csv_results = "lf_check{}-{}.csv".format(args.outfile,current_time) - csv_results = report.file_add_path(csv_results) - outfile = "lf_check-{}-{}".format(args.outfile,current_time) - outfile_path = report.file_add_path(outfile) - - # lf_check() class created - check = lf_check(_csv_results = csv_results, - _outfile = outfile_path) - - # get the git sha - process = subprocess.Popen(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE) - (commit_hash, err) = process.communicate() - exit_code = process.wait() - git_sha = commit_hash.decode('utf-8','ignore') - - # set up logging - logfile = args.logfile[:-4] - print("logfile: {}".format(logfile)) - logfile = "{}-{}.log".format(logfile,current_time) - logfile = report.file_add_path(logfile) - print("logfile {}".format(logfile)) - formatter = logging.Formatter(FORMAT) - logger = logging.getLogger(__name__) - logger.setLevel(logging.INFO) - file_handler = logging.FileHandler(logfile, "w") - file_handler.setFormatter(formatter) - logger.addHandler(file_handler) - logger.addHandler(logging.StreamHandler(sys.stdout)) # allows to logging to file and stdout - - logger.info("commit_hash: {}".format(commit_hash)) - logger.info("commit_hash2: {}".format(commit_hash.decode('utf-8','ignore'))) - - check.read_config_contents() # CMR need mode to just print out the test config and not run - check.run_script_test() - - # Generate Ouptput reports - report.set_title("LF Check: lf_check.py") - report.build_banner() - report.start_content_div() - report.set_table_title("LF Check Test Results") - report.build_table_title() - report.set_text("git sha: {}".format(git_sha)) - report.build_text() - html_results = check.get_html_results() - report.set_custom_html(html_results) - report.build_custom() - html_report = report.write_html_with_timestamp() - print("html report: {}".format(html_report)) - report.write_pdf_with_timestamp() - - - report_path = os.path.dirname(html_report) - parent_report_dir = os.path.dirname(report_path) - - # copy results to lastest so someone may see the latest. - lf_check_latest_html = parent_report_dir + "/lf_check_latest.html" - # duplicates html_report file up one directory - lf_check_html_report = parent_report_dir + "/{}.html".format(outfile) - - # - banner_src_png = report_path + "/banner.png" - banner_dest_png = parent_report_dir + "/banner.png" - CandelaLogo_src_png = report_path + "/CandelaLogo2-90dpi-200x90-trans.png" - CandelaLogo_dest_png = parent_report_dir + "/CandelaLogo2-90dpi-200x90-trans.png" - report_src_css = report_path + "/report.css" - report_dest_css = parent_report_dir + "/report.css" - custom_src_css = report_path + "/custom.css" - custom_dest_css = parent_report_dir + "/custom.css" - font_src_woff = report_path + "/CenturyGothic.woff" - font_dest_woff = parent_report_dir + "/CenturyGothic.woff" - - #pprint.pprint([ - # ('banner_src', banner_src_png), - # ('banner_dest', banner_dest_png), - # ('CandelaLogo_src_png', CandelaLogo_src_png), - # ('CandelaLogo_dest_png', CandelaLogo_dest_png), - # ('report_src_css', report_src_css), - # ('custom_src_css', custom_src_css) - #]) - - # copy one directory above - shutil.copyfile(html_report, lf_check_latest_html) - shutil.copyfile(html_report, lf_check_html_report) - - # copy banner and logo - shutil.copyfile(banner_src_png, banner_dest_png) - shutil.copyfile(CandelaLogo_src_png, CandelaLogo_dest_png) - shutil.copyfile(report_src_css, report_dest_css) - shutil.copyfile(custom_src_css, custom_dest_css) - shutil.copyfile(font_src_woff, font_dest_woff) - - print("lf_check_latest.html: "+lf_check_latest_html) - print("lf_check_html_report: "+lf_check_html_report) - - check.send_results_email(report_file=lf_check_html_report) - -if __name__ == '__main__': - main() - - diff --git a/py-scripts/sta_connect2.py b/py-scripts/sta_connect2.py index 0210243a..bb82dd15 100755 --- a/py-scripts/sta_connect2.py +++ b/py-scripts/sta_connect2.py @@ -143,7 +143,6 @@ class StaConnect2(LFCliBase): pprint.pprint(upstream_json) self._fail("Warning: %s lacks ip address" % self.get_upstream_url(), print_=True) return False - # remove old stations if self.clean_all_sta: print("Removing all stations on resource.") diff --git a/py-scripts/test_ip_connection.py b/py-scripts/test_ip_connection.py deleted file mode 100755 index db41b1fe..00000000 --- a/py-scripts/test_ip_connection.py +++ /dev/null @@ -1,292 +0,0 @@ -#!/usr/bin/env python3 - -""" -NAME: test_ip_connection.py -This script combines functionality of test_ipv4_connection.py and test_ipv6_connection.py. -test_ipv4_connection.py and test_ipv6_connection.py are located in py-scripts/scripts_deprecated - -PURPOSE: -test_ip_connection.py will create stations and attempt to connect to an SSID. WPA, WPA2, WPA3, WEP, and Open connection types are supported - -Script for creating a variable number of stations and attempting to connect them to an SSID. -A test will run to verify stations are associated and get an IP, if these conditions are both true, the test will -pass, otherwise, the test will fail. - -EXAMPLE: -./test_ip_connection.py --upstream_port eth1 --radio wiphy0 --num_stations 3 --security open --ssid netgear --passwd BLANK --debug - ./test_ip_connection.py --upstream_port eth1 --ipv6 --radio wiphy0 --num_stations 3 --proxy --security {open|wep|wpa|wpa2|wpa3} - --ssid netgear --passwd admin123 --mode 1 --ap "00:0e:8e:78:e1:76" --test_id --timeout 120 --debug - -Use './test_ip_connection.py' --help to see command line usage and options -Copyright 2021 Candela Technologies Inc -License: Free to distribute and modify. LANforge systems must be licensed. -""" - -import sys -import os -import argparse - -if sys.version_info[0] != 3: - print("This script requires Python 3") - exit(1) - -if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) -import LANforge -from LANforge.lfcli_base import LFCliBase -from LANforge import LFUtils -import realm -import time -import pprint - -class ConnectTest(LFCliBase): - def __init__(self, - _ssid=None, - _security=None, - _password=None, - _host=None, - _port=None, - _sta_list=None, - _number_template="00000", - _radio="wiphy0", - _proxy_str=None, - _debug_on=False, - _exit_on_error=False, - _exit_on_fail=False, - _ap=None, - _ipv6=False, - _mode=0, - _num_stations=0, - _timeout=120): - super().__init__(_host, - _port, - _proxy_str=_proxy_str, - _local_realm=realm.Realm(lfclient_host=_host, - lfclient_port=_port, - _exit_on_error=_exit_on_error, - _exit_on_fail=_exit_on_fail, - _proxy_str=_proxy_str, - debug_=_debug_on), - _debug=_debug_on, - _exit_on_fail=_exit_on_fail) - self.host = _host - self.port = _port - self.ssid = _ssid - self.security = _security - self.password = _password - self.sta_list = _sta_list - self.radio = _radio - self.timeout = 120 - self.number_template = _number_template - self.debug = _debug_on - self.ap = _ap - self.mode = _mode - self.ipv6 = _ipv6 - self.num_stations = _num_stations - - self.station_profile = self.local_realm.new_station_profile() - self.station_profile.lfclient_url = self.lfclient_url - self.station_profile.ssid = self.ssid - self.station_profile.ssid_pass = self.password - self.station_profile.security = self.security - self.station_profile.number_template_ = self.number_template - self.station_profile.mode = 0 - if self.debug: - print("----- Station List ----- ----- ----- ----- ----- ----- \n") - pprint.pprint(self.sta_list) - print("---- ~Station List ----- ----- ----- ----- ----- ----- \n") - - - def build(self): - # Build stations - self.station_profile.use_security(self.security, self.ssid, self.password) - self.station_profile.set_number_template(self.number_template) - - print("Creating stations") - self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) - self.station_profile.set_command_param("set_port", "report_timer", 1500) - self.station_profile.set_command_flag("set_port", "rpt_timer", 1) - self.station_profile.create(radio=self.radio, sta_names_=self.sta_list, debug=self.debug) - self._pass("PASS: Station build finished") - - def start(self, sta_list, print_pass, print_fail): - self.station_profile.admin_up() - associated_map = {} - ip_map = {} - print("Starting test...") - for sec in range(self.timeout): - for sta_name in sta_list: - shelf = self.local_realm.name_to_eid(sta_name)[0] - resource = self.local_realm.name_to_eid(sta_name)[1] - name = self.local_realm.name_to_eid(sta_name)[2] - if self.ipv6: - url = "port/%s/%s/%s?fields=port,alias,ipv6+address,ap" % (shelf, resource, name) - else: - url = "port/%s/%s/%s?fields=port,alias,ip,ap" % (shelf, resource, name) - sta_status = self.json_get(url, debug_=self.debug) - if self.debug: - print(sta_status) - if sta_status is None or sta_status['interface'] is None or sta_status['interface']['ap'] is None: - continue - - if (len(sta_status['interface']['ap']) == 17) and (sta_status['interface']['ap'][-3] == ':'): - associated_map[sta_name] = 1 - if self.debug: - if self.ipv6: - print("Associated", sta_name, sta_status['interface']['ap'], sta_status['interface']['ipv6 address']) - else: - print("Associated", sta_name, sta_status['interface']['ap'], sta_status['interface']['ip']) - - if self.ipv6: - if sta_status['interface']['ipv6 address'] != 'DELETED' and \ - not sta_status['interface']['ipv6 address'].startswith('fe80') \ - and sta_status['interface']['ipv6 address'] != 'AUTO': - ip_map[sta_name] = 1 - if self.debug: - print("IPv6 address:", sta_name, sta_status['interface']['ap'], - sta_status['interface']['ipv6 address']) - else: - if sta_status['interface']['ip'] != '0.0.0.0': - ip_map[sta_name] = 1 - if self.debug: - print("IP", sta_name, sta_status['interface']['ap'], sta_status['interface']['ip']) - - if (len(sta_list) == len(ip_map)) and (len(sta_list) == len(associated_map)): - break - else: - time.sleep(1) - - if self.debug: - print("sta_list", len(sta_list), sta_list) - print("ip_map", len(ip_map), ip_map) - print("associated_map", len(associated_map), associated_map) - if (len(sta_list) == len(ip_map)) and (len(sta_list) == len(associated_map)): - self._pass("PASS: All stations associated with IP", print_pass) - else: - self._fail("FAIL: Not all stations able to associate/get IP", print_fail) - print("sta_list", sta_list) - print("ip_map", ip_map) - print("associated_map", associated_map) - - return self.passes() - - def stop(self): - # Bring stations down - self.station_profile.admin_down() - - def cleanup(self, sta_list): - self.station_profile.cleanup(sta_list, debug_=self.debug) - LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, - port_list=sta_list, - debug=self.debug) - time.sleep(1) - - -def main(): - parser = LFCliBase.create_basic_argparse( - prog='test_ip_connection.py', - formatter_class=argparse.RawTextHelpFormatter, - epilog='''\ - Create stations that attempt to authenticate, associate, and receive IP addresses on the - chosen SSID - ''', - - description='''\ - test_ip_connection.py --------------------------------------- -Generic ipv6 command example: -python3 ./test_ip_connection.py - --upstream_port eth1 - --radio wiphy0 - --num_stations 3 - --ipv6 - --proxy - --security {open|wep|wpa|wpa2|wpa3} - --ssid netgear - --passwd admin123 - --mode 1 - --ap "00:0e:8e:78:e1:76" - --test_id - --timeout 120 - --debug - -Generic ipv4 command example: -./test_ip_connection.py - --upstream_port eth1 - --radio wiphy0 - --num_stations 3 - --security open - --ssid netgear - --passwd BLANK - --debug''') - - required = None - for agroup in parser._action_groups: - if agroup.title == "required arguments": - required = agroup - # if required is not None: - - optional = None - for agroup in parser._action_groups: - if agroup.title == "optional arguments": - optional = agroup - - if optional is not None: - optional.add_argument("--ipv6", help="Use ipv6 connections instead of ipv4", action="store_true", default=False) - optional.add_argument("--ap", help="Add BSSID of access point to connect to") - optional.add_argument('--mode', help=LFCliBase.Help_Mode) - optional.add_argument('--timeout', - help='--timeout sets the length of time to wait until a connection is successful', - default=30) - - args = parser.parse_args() - - if (args.radio is None): - raise ValueError("--radio required") - - num_sta = 2 - if (args.num_stations is not None) and (int(args.num_stations) > 0): - num_stations_converted = int(args.num_stations) - num_sta = num_stations_converted - - station_list = LFUtils.port_name_series(prefix="sta", - start_id=0, - end_id=num_sta - 1, - padding_number=10000, - radio=args.radio) - if args.debug: - print("args.proxy: %s" % args.proxy) - ip_test = ConnectTest(_host=args.mgr, - _port=args.mgr_port, - _ssid=args.ssid, - _password=args.passwd, - _security=args.security, - _sta_list=station_list, - _radio=args.radio, - _proxy_str=args.proxy, - _debug_on=args.debug, - _ipv6=args.ipv6, - _ap=args.ap, - _mode=args.mode, - _timeout=args.timeout) - - ip_test.cleanup(station_list) - ip_test.build() - if not ip_test.passes(): - print(ip_test.get_fail_message()) - ip_test.add_event(name="test_ip_connection.py", message=ip_test.get_fail_message()) - ip_test.exit_fail() - ip_test.start(station_list, False, False) - ip_test.stop() - if not ip_test.passes(): - print(ip_test.get_fail_message()) - ip_test.add_event(name="test_ip_connection.py", message=ip_test.get_fail_message()) - ip_test.exit_fail() - time.sleep(30) - ip_test.cleanup(station_list) - if ip_test.passes(): - ip_test.add_event(name="test_ip_connection.py", message="Full test passed, all stations associated and got IP") - ip_test.exit_success() - -if __name__ == "__main__": - main() diff --git a/py-scripts/test_ip_variable_time.py b/py-scripts/test_ip_variable_time.py deleted file mode 100644 index 179cf74b..00000000 --- a/py-scripts/test_ip_variable_time.py +++ /dev/null @@ -1,520 +0,0 @@ -#!/usr/bin/env python3 - -""" -NAME: test_ip_variable_time.py - -PURPOSE: -test_ip_variable_time.py will create stations and endpoints to generate and verify layer-3 traffic over ipv4 or ipv6. -This script replaces the functionality of test_ipv4_variable_time.py and test_ipv6_variable_time.py -This Script has two working modes: - Mode 1: - When station is not available, - - This script will create a variable number of stations each with their own set of cross-connects and endpoints. - It will then create layer 3 traffic over a specified amount of time, testing for increased traffic at regular intervals. - This test will pass if all stations increase traffic over the full test duration. - - Mode 2: - - When station is already available This script will create layer3 cross-connects and endpoints It will then - create layer 3 traffic over a specified amount of time, testing for increased traffic at regular intervals. - This test will pass if all stations increase traffic over the full test duration. - -Use './test_ip_variable_time.py --help' to see command line usage and options -Copyright 2021 Candela Technologies Inc -License: Free to distribute and modify. LANforge systems must be licensed. -""" - -import sys -import os - -if sys.version_info[0] != 3: - print("This script requires Python 3") - exit(1) - -if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) - -import argparse -from LANforge import LFUtils -from realm import Realm -import time -import datetime - - -class IPVariableTime(Realm): - def __init__(self, - ssid=None, - security=None, - password=None, - sta_list=[], - create_sta=True, - name_prefix=None, - upstream=None, - radio=None, - host="localhost", - port=8080, - mode=0, - ap=None, - traffic_type=None, - side_a_min_rate=56, side_a_max_rate=0, - side_b_min_rate=56, side_b_max_rate=0, - number_template="00000", - test_duration="5m", - use_ht160=False, - ipv6=False, - _debug_on=False, - _exit_on_error=False, - _exit_on_fail=False): - super().__init__(lfclient_host=host, - lfclient_port=port), - self.upstream = upstream - self.host = host - self.port = port - self.ssid = ssid - self.sta_list = sta_list - self.create_sta = create_sta - self.security = security - self.password = password - self.radio = radio - self.mode = mode - self.ap = ap - self.traffic_type = traffic_type - self.number_template = number_template - self.debug = _debug_on - # self.json_post("/cli-json/set_resource", { - # "shelf":1, - # "resource":all, - # "max_staged_bringup": 30, - # "max_trying_ifup": 15, - # "max_station_bringup": 6 - # }) - self.name_prefix = name_prefix - self.test_duration = test_duration - self.station_profile = self.new_station_profile() - self.cx_profile = self.new_l3_cx_profile() - self.station_profile.lfclient_url = self.lfclient_url - self.station_profile.ssid = self.ssid - self.station_profile.ssid_pass = self.password - self.station_profile.security = self.security - self.station_profile.number_template_ = self.number_template - self.station_profile.debug = self.debug - - self.station_profile.use_ht160 = use_ht160 - if self.station_profile.use_ht160: - self.station_profile.mode = 9 - self.station_profile.mode = mode - if self.ap is not None: - self.station_profile.set_command_param("add_sta", "ap", self.ap) - - self.cx_profile.host = self.host - self.cx_profile.port = self.port - self.ipv6 = ipv6 - self.cx_profile.name_prefix = self.name_prefix - self.cx_profile.side_a_min_bps = side_a_min_rate - self.cx_profile.side_a_max_bps = side_a_max_rate - self.cx_profile.side_b_min_bps = side_b_min_rate - self.cx_profile.side_b_max_bps = side_b_max_rate - - def start(self, print_pass=False, print_fail=False): - if self.create_sta: - self.station_profile.admin_up() - # to-do- check here if upstream port got IP - temp_stas = self.station_profile.station_names.copy() - - if self.wait_for_ip(temp_stas, ipv4=not self.ipv6, ipv6=self.ipv6): - self._pass("All stations got IPs") - else: - self._fail("Stations failed to get IPs") - self.exit_fail() - self.cx_profile.start_cx() - - def stop(self): - self.cx_profile.stop_cx() - if self.create_sta: - self.station_profile.admin_down() - - def pre_cleanup(self): - self.cx_profile.cleanup_prefix() - if self.create_sta: - for sta in self.sta_list: - self.rm_port(sta, check_exists=True) - - def cleanup(self): - self.cx_profile.cleanup() - if self.create_sta: - self.station_profile.cleanup() - LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=self.station_profile.station_names, - debug=self.debug) - - def build(self): - if self.create_sta: - self.station_profile.use_security(self.security, self.ssid, self.password) - self.station_profile.set_number_template(self.number_template) - print("Creating stations") - self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) - self.station_profile.set_command_param("set_port", "report_timer", 1500) - self.station_profile.set_command_flag("set_port", "rpt_timer", 1) - self.station_profile.create(radio=self.radio, sta_names_=self.sta_list, debug=self.debug) - self._pass("PASS: Station build finished") - - self.cx_profile.create(endp_type=self.traffic_type, side_a=self.sta_list, - side_b=self.upstream, - sleep_time=0) - - -def main(): - parser = Realm.create_basic_argparse( - prog='test_ip_variable_time.py', - formatter_class=argparse.RawTextHelpFormatter, - epilog='''\ - Create stations to test connection and traffic on VAPs of varying security types (WEP, WPA, WPA2, WPA3, Open) - over ipv4 or ipv6 - ''', - description='''\ -test_ip_variable_time.py: --------------------- -Generic command layout: - -python3 ./test_ip_variable_time.py - --upstream_port eth1 - --radio wiphy0 - --num_stations 32 - --security {open|wep|wpa|wpa2|wpa3} - --mode 1 - {"auto" : "0", - "a" : "1", - "b" : "2", - "g" : "3", - "abg" : "4", - "abgn" : "5", - "bgn" : "6", - "bg" : "7", - "abgnAC" : "8", - "anAC" : "9", - "an" : "10", - "bgnAC" : "11", - "abgnAX" : "12", - "bgnAX" : "13"} - --ssid netgear - --password admin123 - --test_duration 2m (default) - --monitor_interval_ms - --a_min 3000 - --b_min 1000 - --ap "00:0e:8e:78:e1:76" - --output_format csv - --traffic_type lf_udp - --report_file ~/Documents/results.csv (Example of csv file output - please use another extension for other file formats) - --compared_report ~/Documents/results_prev.csv (Example of csv file retrieval - please use another extension for other file formats) - UNDER CONSTRUCTION - --layer3_cols 'name','tx bytes','rx bytes','dropped' (column names from the GUI to print on report - please read below to know what to put here according to preferences) - --port_mgr_cols 'ap','ip' (column names from the GUI to print on report - please read below to know what to put here according to preferences) - --debug - - python3 ./test_ip_variable_time.py - --upstream_port eth1 (upstream Port) - --traffic_type lf_udp (traffic type, lf_udp | lf_tcp) - --test_duration 5m (duration to run traffic 5m --> 5 Minutes) - --create_sta False (False, means it will not create stations and use the sta_names specified below) - --sta_names sta000,sta001,sta002 (used if --create_sta False, comma separated names of stations) - - -=============================================================================== - ** FURTHER INFORMATION ** - Using the layer3_cols flag: - - Currently the output function does not support inputting the columns in layer3_cols the way they are displayed in the GUI. This quirk is under construction. To output - certain columns in the GUI in your final report, please match the according GUI column display to it's counterpart to have the columns correctly displayed in - your report. - - GUI Column Display Layer3_cols argument to type in (to print in report) - - Name | 'name' - EID | 'eid' - Run | 'run' - Mng | 'mng' - Script | 'script' - Tx Rate | 'tx rate' - Tx Rate (1 min) | 'tx rate (1 min)' - Tx Rate (last) | 'tx rate (last)' - Tx Rate LL | 'tx rate ll' - Rx Rate | 'rx rate' - Rx Rate (1 min) | 'rx rate (1 min)' - Rx Rate (last) | 'rx rate (last)' - Rx Rate LL | 'rx rate ll' - Rx Drop % | 'rx drop %' - Tx PDUs | 'tx pdus' - Tx Pkts LL | 'tx pkts ll' - PDU/s TX | 'pdu/s tx' - Pps TX LL | 'pps tx ll' - Rx PDUs | 'rx pdus' - Rx Pkts LL | 'pps rx ll' - PDU/s RX | 'pdu/s tx' - Pps RX LL | 'pps rx ll' - Delay | 'delay' - Dropped | 'dropped' - Jitter | 'jitter' - Tx Bytes | 'tx bytes' - Rx Bytes | 'rx bytes' - Replays | 'replays' - TCP Rtx | 'tcp rtx' - Dup Pkts | 'dup pkts' - Rx Dup % | 'rx dup %' - OOO Pkts | 'ooo pkts' - Rx OOO % | 'rx ooo %' - RX Wrong Dev | 'rx wrong dev' - CRC Fail | 'crc fail' - RX BER | 'rx ber' - CX Active | 'cx active' - CX Estab/s | 'cx estab/s' - 1st RX | '1st rx' - CX TO | 'cx to' - Pattern | 'pattern' - Min PDU | 'min pdu' - Max PDU | 'max pdu' - Min Rate | 'min rate' - Max Rate | 'max rate' - Send Buf | 'send buf' - Rcv Buf | 'rcv buf' - CWND | 'cwnd' - TCP MSS | 'tcp mss' - Bursty | 'bursty' - A/B | 'a/b' - Elapsed | 'elapsed' - Destination Addr | 'destination addr' - Source Addr | 'source addr' - ''') - - parser.add_argument('--mode', help='Used to force mode of stations') - parser.add_argument('--ap', help='Used to force a connection to a particular AP') - parser.add_argument('--traffic_type', help='Select the Traffic Type [lf_udp, lf_tcp, udp, tcp], type will be ' - 'adjusted automatically between ipv4 and ipv6 based on use of --ipv6 flag' - , required=True) - parser.add_argument('--output_format', help='choose either csv or xlsx') - parser.add_argument('--report_file', help='where you want to store results', default=None) - parser.add_argument('--a_min', help='--a_min bps rate minimum for side_a', default=256000) - parser.add_argument('--b_min', help='--b_min bps rate minimum for side_b', default=256000) - parser.add_argument('--test_duration', help='--test_duration sets the duration of the test', default="2m") - parser.add_argument('--layer3_cols', help='Columns wished to be monitored from layer 3 endpoint tab', - default=['name', 'tx bytes', 'rx bytes', 'tx rate', 'rx rate']) - parser.add_argument('--port_mgr_cols', help='Columns wished to be monitored from port manager tab', - default=['ap', 'ip', 'parent dev']) - parser.add_argument('--compared_report', help='report path and file which is wished to be compared with new report', - default=None) - parser.add_argument('--monitor_interval', - help='how frequently do you want your monitor function to take measurements; \, 35s, 2h', - default='10s') - parser.add_argument('--ipv6', help='Sets the test to use IPv6 traffic instead of IPv4', action='store_true') - parser.add_argument('--influx_token', help='Username for your Influx database') - parser.add_argument('--influx_bucket', help='Password for your Influx database') - parser.add_argument('--influx_org', help='Name of your Influx database') - parser.add_argument('--influx_port', help='Port where your influx database is located', default=8086) - parser.add_argument('--influx_tag', action='append', nargs=2, - help='--influx_tag Can add more than one of these.') - parser.add_argument('--influx_mgr', - help='IP address of the server your Influx database is hosted if different from your LANforge Manager', - default=None) - parser.add_argument('--create_sta', help='Used to force a connection to a particular AP', default=True) - parser.add_argument('--sta_names', help='Used to force a connection to a particular AP', default="sta0000") - args = parser.parse_args() - create_sta = True - if args.create_sta == "False": - create_sta = False - - num_sta = 2 - if (args.num_stations is not None) and (int(args.num_stations) > 0): - num_sta = int(args.num_stations) - - # Create directory - - # if file path with output file extension is not given... - # check if home/lanforge/report-data exists. if not, save - # in new folder based in current file's directory - - if args.report_file is None: - new_file_path = str(datetime.datetime.now().strftime("%Y-%m-%d-%H-h-%M-m-%S-s")).replace(':', - '-') + '_test_ip_variable_time' # create path name - try: - path = os.path.join('/home/lanforge/report-data/', new_file_path) - os.mkdir(path) - except: - curr_dir_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - path = os.path.join(curr_dir_path, new_file_path) - os.mkdir(path) - systeminfopath = str(path) + '/systeminfo.txt' - - if args.output_format in ['csv', 'json', 'html', 'hdf', 'stata', 'pickle', 'pdf', 'png', 'parquet', - 'xlsx']: - report_f = str(path) + '/data.' + args.output_format - output = args.output_format - else: - print( - 'Not supporting this report format or cannot find report format provided. Defaulting to csv data file ' - 'output type, naming it data.csv.') - report_f = str(path) + '/data.csv' - output = 'csv' - - else: - systeminfopath = str(args.report_file).split('/')[-1] - report_f = args.report_file - if args.output_format is None: - output = str(args.report_file).split('.')[-1] - else: - output = args.output_format - print("IP Test Report Data: {}".format(report_f)) - - # Retrieve last data file - compared_rept = None - if args.compared_report: - compared_report_format = args.compared_report.split('.')[-1] - # if compared_report_format not in ['csv', 'json', 'dta', 'pkl','html','xlsx','parquet','h5']: - if compared_report_format != 'csv': - print(ValueError("Cannot process this file type. Please select a different file and re-run script.")) - exit(1) - else: - compared_rept = args.compared_report - - if create_sta: - station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta - 1, padding_number_=10000, - radio=args.radio) - else: - station_list = args.sta_names.split(",") - - CX_TYPES = ("tcp", "udp", "lf_tcp", "lf_udp") - - if (args.traffic_type is None) or (args.traffic_type not in CX_TYPES): - print("cx_type needs to be lf_tcp, lf_udp, tcp, or udp, bye") - exit(1) - - if args.ipv6: - if args.traffic_type == "tcp" or args.traffic_type == "lf_tcp": - args.traffic_type = "lf_tcp6" - if args.traffic_type == "udp" or args.traffic_type == "lf_udp": - args.traffic_type = "lf_udp6" - else: - if args.traffic_type == "tcp": - args.traffic_type = "lf_tcp" - if args.traffic_type == "udp": - args.traffic_type = "lf_udp" - - ip_var_test = IPVariableTime(host=args.mgr, - port=args.mgr_port, - number_template="0000", - sta_list=station_list, - create_sta=create_sta, - name_prefix="VT", - upstream=args.upstream_port, - ssid=args.ssid, - password=args.passwd, - radio=args.radio, - security=args.security, - test_duration=args.test_duration, - use_ht160=False, - side_a_min_rate=args.a_min, - side_b_min_rate=args.b_min, - mode=args.mode, - ap=args.ap, - ipv6=args.ipv6, - traffic_type=args.traffic_type, - _debug_on=args.debug) - - ip_var_test.pre_cleanup() - - ip_var_test.build() - # exit() - if create_sta: - if not ip_var_test.passes(): - print(ip_var_test.get_fail_message()) - ip_var_test.exit_fail() - - try: - layer3connections = ','.join([[*x.keys()][0] for x in ip_var_test.json_get('endp')['endpoint']]) - except: - raise ValueError('Try setting the upstream port flag if your device does not have an eth1 port') - - if type(args.layer3_cols) is not list: - layer3_cols = list(args.layer3_cols.split(",")) - # send col names here to file to reformat - else: - layer3_cols = args.layer3_cols - # send col names here to file to reformat - if type(args.port_mgr_cols) is not list: - port_mgr_cols = list(args.port_mgr_cols.split(",")) - # send col names here to file to reformat - else: - port_mgr_cols = args.port_mgr_cols - # send col names here to file to reformat - if args.debug: - print("Layer 3 Endp column names are...") - print(layer3_cols) - print("Port Manager column names are...") - print(port_mgr_cols) - - print("Layer 3 Endp column names are...") - print(layer3_cols) - print("Port Manager column names are...") - print(port_mgr_cols) - - try: - monitor_interval = Realm.parse_time(args.monitor_interval).total_seconds() - except ValueError as error: - print(str(error)) - print(ValueError( - "The time string provided for monitor_interval argument is invalid. Please see supported time stamp increments and inputs for monitor_interval in --help. ")) - exit(1) - ip_var_test.start(False, False) - - # if args.influx_mgr is None: - # manager = args.mgr - # else: - # manager = args.influx_mgr - - if args.influx_org is not None: - from influx2 import RecordInflux - grapher = RecordInflux( # _influx_host=manager, - _influx_port=args.influx_port, - _influx_org=args.influx_org, - _influx_token=args.influx_token, - _influx_bucket=args.influx_bucket) - devices = [station.split('.')[-1] for station in station_list] - tags = dict() - tags['script'] = 'test_ip_variable_time' - try: - for k in args.influx_tag: - tags[k[0]] = k[1] - except: - pass - grapher.monitor_port_data(longevity=Realm.parse_time(args.test_duration).total_seconds(), - devices=devices, - monitor_interval=Realm.parse_time(args.monitor_interval).total_seconds(), - tags=tags) - - ip_var_test.cx_profile.monitor(layer3_cols=layer3_cols, - sta_list=station_list, - # port_mgr_cols=port_mgr_cols, - report_file=report_f, - systeminfopath=systeminfopath, - duration_sec=Realm.parse_time(args.test_duration).total_seconds(), - monitor_interval_ms=monitor_interval, - created_cx=layer3connections, - output_format=output, - compared_report=compared_rept, - script_name='test_ip_variable_time', - arguments=args, - debug=args.debug) - - ip_var_test.stop() - if create_sta: - if not ip_var_test.passes(): - print(ip_var_test.get_fail_message()) - ip_var_test.exit_fail() - LFUtils.wait_until_ports_admin_up(port_list=station_list) - - if ip_var_test.passes(): - ip_var_test.success() - ip_var_test.cleanup() - print("IP Variable Time Test Report Data: {}".format(report_f)) - - -if __name__ == "__main__": - main() diff --git a/py-scripts/scripts_deprecated/test_ipv4_connection.py b/py-scripts/test_ipv4_connection.py similarity index 98% rename from py-scripts/scripts_deprecated/test_ipv4_connection.py rename to py-scripts/test_ipv4_connection.py index bd16f197..733044e6 100755 --- a/py-scripts/scripts_deprecated/test_ipv4_connection.py +++ b/py-scripts/test_ipv4_connection.py @@ -4,7 +4,6 @@ NAME: test_ipv4_connection.py PURPOSE: -This scripts functionality has been replaced by test_ip_connection.py, consider this script deprecated test_ipv4_connection.py will create stations and attempt to connect to an SSID. WPA, WPA2, WPA3, WEP, and Open connection types are supported Script for creating a variable number of stations and attempting to connect them to an SSID. @@ -28,7 +27,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('../..'), 'py-json')) + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import LANforge from LANforge.lfcli_base import LFCliBase from LANforge import LFUtils diff --git a/py-scripts/scripts_deprecated/test_ipv4_l4.py b/py-scripts/test_ipv4_l4.py similarity index 99% rename from py-scripts/scripts_deprecated/test_ipv4_l4.py rename to py-scripts/test_ipv4_l4.py index 252e1aec..5cea2831 100755 --- a/py-scripts/scripts_deprecated/test_ipv4_l4.py +++ b/py-scripts/test_ipv4_l4.py @@ -26,7 +26,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append('../../py-json') + sys.path.append('../py-json') import argparse from LANforge.lfcli_base import LFCliBase diff --git a/py-scripts/scripts_deprecated/test_ipv4_l4_ftp_upload.py b/py-scripts/test_ipv4_l4_ftp_upload.py similarity index 99% rename from py-scripts/scripts_deprecated/test_ipv4_l4_ftp_upload.py rename to py-scripts/test_ipv4_l4_ftp_upload.py index ef231f8a..d437007b 100755 --- a/py-scripts/scripts_deprecated/test_ipv4_l4_ftp_upload.py +++ b/py-scripts/test_ipv4_l4_ftp_upload.py @@ -25,7 +25,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append('../../py-json') + sys.path.append('../py-json') import argparse from LANforge.lfcli_base import LFCliBase diff --git a/py-scripts/scripts_deprecated/test_ipv4_l4_ftp_urls_per_ten.py b/py-scripts/test_ipv4_l4_ftp_urls_per_ten.py similarity index 99% rename from py-scripts/scripts_deprecated/test_ipv4_l4_ftp_urls_per_ten.py rename to py-scripts/test_ipv4_l4_ftp_urls_per_ten.py index ee557f1d..893cf00a 100755 --- a/py-scripts/scripts_deprecated/test_ipv4_l4_ftp_urls_per_ten.py +++ b/py-scripts/test_ipv4_l4_ftp_urls_per_ten.py @@ -25,7 +25,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('../..'), 'py-json')) + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import argparse from LANforge.lfcli_base import LFCliBase diff --git a/py-scripts/scripts_deprecated/test_ipv4_l4_ftp_wifi.py b/py-scripts/test_ipv4_l4_ftp_wifi.py similarity index 99% rename from py-scripts/scripts_deprecated/test_ipv4_l4_ftp_wifi.py rename to py-scripts/test_ipv4_l4_ftp_wifi.py index b8d7b0fb..bb94ac0c 100755 --- a/py-scripts/scripts_deprecated/test_ipv4_l4_ftp_wifi.py +++ b/py-scripts/test_ipv4_l4_ftp_wifi.py @@ -26,7 +26,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append('../../py-json') + sys.path.append('../py-json') import argparse from LANforge.lfcli_base import LFCliBase diff --git a/py-scripts/scripts_deprecated/test_ipv4_l4_urls_per_ten.py b/py-scripts/test_ipv4_l4_urls_per_ten.py similarity index 99% rename from py-scripts/scripts_deprecated/test_ipv4_l4_urls_per_ten.py rename to py-scripts/test_ipv4_l4_urls_per_ten.py index 7ca7343e..8c2bc089 100755 --- a/py-scripts/scripts_deprecated/test_ipv4_l4_urls_per_ten.py +++ b/py-scripts/test_ipv4_l4_urls_per_ten.py @@ -27,7 +27,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('../..'), 'py-json')) + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import argparse from LANforge.lfcli_base import LFCliBase diff --git a/py-scripts/scripts_deprecated/test_ipv4_l4_wifi.py b/py-scripts/test_ipv4_l4_wifi.py similarity index 99% rename from py-scripts/scripts_deprecated/test_ipv4_l4_wifi.py rename to py-scripts/test_ipv4_l4_wifi.py index 67714e7e..b4e342f0 100755 --- a/py-scripts/scripts_deprecated/test_ipv4_l4_wifi.py +++ b/py-scripts/test_ipv4_l4_wifi.py @@ -25,7 +25,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append('../../py-json') + sys.path.append('../py-json') import argparse from LANforge.lfcli_base import LFCliBase diff --git a/py-scripts/test_ipv4_ttls.py b/py-scripts/test_ipv4_ttls.py index 12071cb4..aa352362 100755 --- a/py-scripts/test_ipv4_ttls.py +++ b/py-scripts/test_ipv4_ttls.py @@ -267,6 +267,8 @@ class TTLSTest(LFCliBase): self.collect_endp_stats(self.l3_cx_obj_udp.cx_profile.created_cx, traffic_type="UDP") def cleanup(self, sta_list): + self.l3_cx_obj_udp.cleanup() + self.l3_cx_obj_tcp.cleanup() self.station_profile.cleanup(sta_list) if self.vap: self.vap_profile.cleanup(1) diff --git a/py-scripts/scripts_deprecated/test_ipv4_variable_time.py b/py-scripts/test_ipv4_variable_time.py similarity index 99% rename from py-scripts/scripts_deprecated/test_ipv4_variable_time.py rename to py-scripts/test_ipv4_variable_time.py index 74282ba1..cb8b122b 100755 --- a/py-scripts/scripts_deprecated/test_ipv4_variable_time.py +++ b/py-scripts/test_ipv4_variable_time.py @@ -32,7 +32,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('../..'), 'py-json')) + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import argparse from LANforge import LFUtils diff --git a/py-scripts/scripts_deprecated/test_ipv6_connection.py b/py-scripts/test_ipv6_connection.py similarity index 98% rename from py-scripts/scripts_deprecated/test_ipv6_connection.py rename to py-scripts/test_ipv6_connection.py index 209a42e7..f8856b23 100755 --- a/py-scripts/scripts_deprecated/test_ipv6_connection.py +++ b/py-scripts/test_ipv6_connection.py @@ -4,7 +4,6 @@ NAME: test_ipv6_connection.py PURPOSE: -This scripts functionality has been replaced by test_ip_connection.py, consider this script deprecated test_ipv6_connection.py will create stations and attempt to connect to an SSID using IPv6. WPA, WPA2, WPA3, WEP, and Open connection types are supported Script for creating a variable number of stations and attempting to connect them to an SSID using IPv6. @@ -27,7 +26,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('../..'), 'py-json')) + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import LANforge from LANforge.lfcli_base import LFCliBase from LANforge import LFUtils diff --git a/py-scripts/scripts_deprecated/test_ipv6_variable_time.py b/py-scripts/test_ipv6_variable_time.py similarity index 99% rename from py-scripts/scripts_deprecated/test_ipv6_variable_time.py rename to py-scripts/test_ipv6_variable_time.py index 6f7ff285..6812c46a 100755 --- a/py-scripts/scripts_deprecated/test_ipv6_variable_time.py +++ b/py-scripts/test_ipv6_variable_time.py @@ -28,7 +28,7 @@ if sys.version_info[0] != 3: exit(1) if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('../..'), 'py-json')) + sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) import argparse from LANforge.lfcli_base import LFCliBase diff --git a/py-scripts/test_l3_longevity.py b/py-scripts/test_l3_longevity.py index 46ab2f1d..1de92dac 100755 --- a/py-scripts/test_l3_longevity.py +++ b/py-scripts/test_l3_longevity.py @@ -28,7 +28,7 @@ --radio 'radio==wiphy2,stations==1,ssid==TCH-XB7,ssid_pw==comcast123,security==wpa2' \ --radio 'radio==wiphy3,stations==1,ssid==TCH-XB7,ssid_pw==comcast123,security==wpa2' \ --radio 'radio==wiphy4,stations==1,ssid==TCH-XB7,ssid_pw==comcast123,security==wpa2' \ - --endp_type lf_udp --ap_read --ap_stats --side_a_min_bps=20000 --side_b_min_bps=400000000 \ + --endp_type lf_udp --ap_read --side_a_min_bps=20000 --side_b_min_bps=400000000 \ --attenuators 1.1..1 \ --atten_vals 20,21,40,41 @@ -104,7 +104,6 @@ class L3VariableTime(Realm): lfclient_port=8080, debug=False, influxdb=None, - ap_scheduler_stats=False, ap_read=False, ap_port='/dev/ttyUSB0', ap_baud='115200', @@ -185,14 +184,11 @@ class L3VariableTime(Realm): self.cx_profile.side_b_min_bps = side_b_min_rate[0] self.cx_profile.side_b_max_bps = side_b_max_rate[0] - self.ap_scheduler_stats = ap_scheduler_stats self.ap_read = ap_read self.ap_port = ap_port self.ap_baud = ap_baud self.ap_cmd = ap_cmd self.ap_test_mode = ap_test_mode - self.ap_umsched = "" - self.ap_msched = "" # Lookup key is port-eid name self.port_csv_files = {} @@ -241,12 +237,6 @@ class L3VariableTime(Realm): self.cx_profile.port = self.lfclient_port self.cx_profile.name_prefix = self.name_prefix - def get_ap_umsched(self): - return self.ap_umsched - - def get_ap_msched(self): - return self.ap_msched - def get_kpi_csv(self): #print("self.csv_kpi_file {}".format(self.csv_kpi_file.name)) return self.csv_kpi_file.name @@ -433,21 +423,6 @@ class L3VariableTime(Realm): else: self._pass("PASS: Stations & CX build finished: created/updated: %s stations and %s connections."%(self.station_count, self.cx_count)) - def ap_custom_cmd(self,ap_custom_cmd): - ap_results = "" - try: - # configure the serial interface - ser = serial.Serial(self.ap_port, int(self.ap_baud), timeout=5) - ss = SerialSpawn(ser) - ss.sendline(str(ap_custom_cmd)) - ss.expect([pexpect.TIMEOUT], timeout=1) # do not detete line, waits for output - ap_results = ss.before.decode('utf-8','ignore') - print("ap_custom_cmd: {} ap_results {}".format(ap_custom_cmd, ap_results)) - except: - print("ap_custom_cmd: {} WARNING unable to read AP ".format(ap_custom_cmd)) - - return ap_results - def read_ap_stats(self): # 5ghz: wl -i wl1 bs_data 2.4ghz# wl -i wl0 bs_data ap_stats = "" @@ -536,9 +511,6 @@ class L3VariableTime(Realm): # Update connections with the new rate and pdu size config. self.build(rebuild=True) - if self.ap_scheduler_stats: - self.ap_custom_cmd('wl -i wl1 dump_clear') - for atten_val in self.atten_vals: if atten_val != -1: for atten_idx in self.attenuators: @@ -568,6 +540,8 @@ class L3VariableTime(Realm): ap_row = [] ap_stats_col_titles = [] + + while cur_time < end_time: #interval_time = cur_time + datetime.timedelta(seconds=5) interval_time = cur_time + datetime.timedelta(seconds=self.polling_interval_seconds) @@ -663,14 +637,6 @@ class L3VariableTime(Realm): # At end of test step, record KPI information. self.record_kpi(len(temp_stations_list), ul, dl, ul_pdu_str, dl_pdu_str, atten_val, total_dl_bps, total_ul_bps) - # At end of test if requested store upload and download stats - if self.ap_scheduler_stats: - # get the (UL) Upload scheduler statistics - self.ap_umsched += self.ap_custom_cmd('wl -i wl1 dump umsched') - # get the (DL) Download schduler staticstics - self.ap_msched += self.ap_custom_cmd('wl -i wl1 dump msched') - - # Stop connections. self.cx_profile.stop_cx(); self.multicast_profile.stop_mc(); @@ -934,7 +900,7 @@ python3 .\\test_l3_longevity.py --test_duration 4m --endp_type \"lf_tcp lf_udp m parser.add_argument('-t', '--endp_type', help='--endp_type example --endp_type \"lf_udp lf_tcp mc_udp\" Default: lf_udp , options: lf_udp, lf_udp6, lf_tcp, lf_tcp6, mc_udp, mc_udp6', default='lf_udp', type=valid_endp_types) parser.add_argument('-u', '--upstream_port', help='--upstream_port example: --upstream_port eth1',default='eth1') - parser.add_argument('--downstream_port', help='--downstream_port example: --downstream_port eth2') + parser.add_argument('--downstream_port', help='--downstream_port example: --downstream_port eth2',default='eth2') parser.add_argument('-o','--csv_outfile', help="--csv_outfile ", default="") parser.add_argument('--polling_interval', help="--polling_interval ", default='60s') @@ -945,8 +911,6 @@ python3 .\\test_l3_longevity.py --test_duration 4m --endp_type \"lf_tcp lf_udp m parser.add_argument('--ap_port', help='--ap_port \'/dev/ttyUSB0\'',default='/dev/ttyUSB0') parser.add_argument('--ap_baud', help='--ap_baud \'115200\'',default='115200') parser.add_argument('--ap_cmd', help='ap_cmd \'wl -i wl1 bs_data\'', default="wl -i wl1 bs_data") - parser.add_argument('--ap_scheduler_stats', help='--ap_scheduler_stats flag to clear stats run test then dump ul and dl stats to file on ap', action='store_true') - parser.add_argument('--ap_test_mode', help='ap_test_mode flag present use ap canned data', action='store_true') @@ -985,12 +949,6 @@ python3 .\\test_l3_longevity.py --test_duration 4m --endp_type \"lf_tcp lf_udp m else: ap_read = False - if args.ap_scheduler_stats: - ap_scheduler_stats = args.ap_scheduler_stats - else: - ap_scheduler_stats = False - - if args.ap_test_mode: ap_test_mode = args.ap_test_mode else: @@ -1168,7 +1126,6 @@ python3 .\\test_l3_longevity.py --test_duration 4m --endp_type \"lf_tcp lf_udp m lfclient_port=lfjson_port, debug=debug, influxdb=influxdb, - ap_scheduler_stats=ap_scheduler_stats, ap_read=ap_read, ap_port=ap_port, ap_baud=ap_baud, @@ -1206,25 +1163,6 @@ python3 .\\test_l3_longevity.py --test_duration 4m --endp_type \"lf_tcp lf_udp m #report.write_pdf(_page_size = 'A3', _orientation='Landscape') report.write_pdf_with_timestamp(_page_size = 'A4', _orientation='Portrait') - # ap scheduler results and write to a file - if ap_scheduler_stats: - print("getting umsched and msched ap data and writing to a file") - file_date = report.get_date() - - ap_umsched_data = ip_var_test.get_ap_umsched() - ap_umsched = "{}-{}".format(file_date,"ap_umsched.txt") - ap_umsched = report.file_add_path(ap_umsched) - ap_umsched_file = open(ap_umsched, "w") - ap_umsched_file.write(str(ap_umsched_data)) - ap_umsched_file.close() - - ap_msched_data = ip_var_test.get_ap_msched() - ap_msched = "{}-{}".format(file_date,"ap_msched.txt") - ap_msched = report.file_add_path(ap_msched) - ap_msched_file = open(ap_msched, "w") - ap_msched_file.write(str(ap_msched_data)) - ap_msched_file.close() - #for csv_file in csv_list: # print("Ouptput reports CSV list value: {}".format(str(csv_file))) diff --git a/py-scripts/test_l3_powersave_traffic.py b/py-scripts/test_l3_powersave_traffic.py index 77cb8592..630e3408 100755 --- a/py-scripts/test_l3_powersave_traffic.py +++ b/py-scripts/test_l3_powersave_traffic.py @@ -156,8 +156,8 @@ def main(): lfjson_host = "localhost" lfjson_port = 8080 # station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=4, padding_number_=10000) - station_list = ["sta0000", "sta0001", "sta0002", "sta0003"] - ip_powersave_test = L3PowersaveTraffic(lfjson_host, lfjson_port, ssid="j-open-36", security="open", + station_list = ["sta0000", "sta0001"] + ip_powersave_test = L3PowersaveTraffic(lfjson_host, lfjson_port, ssid="jedway-open-149", security="open", password="[BLANK]", station_list=station_list, side_a_min_rate=2000, side_b_min_rate=2000, side_a_max_rate=0, side_b_max_rate=0, prefix="00000", test_duration="30s", diff --git a/py-scripts/test_l4.py b/py-scripts/test_l4.py deleted file mode 100755 index 42e3019b..00000000 --- a/py-scripts/test_l4.py +++ /dev/null @@ -1,446 +0,0 @@ -#!/usr/bin/env python3 - -""" -NAME: test_l4.py - -PURPOSE: -test_l4.py will create stations and endpoints to generate and verify layer-4 traffic - -This script will monitor the urls/s, bytes-rd, or bytes-wr attribute of the endpoints. -These attributes can be tested over FTP using a --ftp flag. -If the the monitored value does not continually increase, this test will not pass. - -This script replaces the functionality of test_ipv4_l4.py, test_ipv4_l4_ftp_upload.py, test_ipv4_l4_ftp_urls_per_ten.py, -test_ipv4_l4_ftp_wifi.py, test_ipv4_l4_urls_per_ten.py, test_ipv4_l4_urls_per_ten.py, test_ipv4_l4_wifi.py - -EXAMPLE (urls/s): - ./test_l4.py --upstream_port eth1 --radio wiphy0 --num_stations 3 --security {open|wep|wpa|wpa2|wpa3} - --ssid netgear --passwd admin123 --requests_per_ten 600 --mode 1 --num_tests 1 --test_type 'urls/s' - --url "dl http://10.40.0.1 /dev/null" --ap "00:0e:8e:78:e1:76" --target_per_ten 600 --output_format csv - --report_file ~/Documents/results.csv --test_duration 2m --debug - -EXAMPLE (bytes-wr): - ./test_l4.py --upstream_port eth1 --radio wiphy0 --num_stations 3 --security {open|wep|wpa|wpa2|wpa3} - --ssid netgear --passwd admin123 --test_duration 2m --url "ul http://10.40.0.1 /dev/null" - --requests_per_ten 600 --test_type bytes-wr --debug - -EXAMPLE (bytes-rd): - ./test_l4.py --upstream_port eth1 (optional) --radio wiphy0 (required) --num_stations 3 (optional) - --security {open|wep|wpa|wpa2|wpa3} (required) --ssid netgear (required) - --url "dl http://10.40.0.1 /dev/null" (required) --password admin123 (required) - --test_duration 2m (optional) --test_type bytes-rd --debug (optional) - -EXAMPLE (ftp urls/s): - ./test_l4.py --upstream_port eth1 --radio wiphy0 --num_stations 3 --security {open|wep|wpa|wpa2|wpa3} - --ssid netgear --passwd admin123 --test_duration 2m --interval 1s --mode 1 --ap "00:0e:8e:78:e1:76" - --requests_per_ten 600 --num_tests 1 --ftp --test_type 'urls/s' - --url "ul ftp://lanforge:lanforge@10.40.0.1/example.txt /home/lanforge/example.txt" --debug - -EXAMPLE (ftp bytes-wr): - ./test_l4.py --upstream_port eth1 --radio wiphy0 --num_stations 3 --security {open|wep|wpa|wpa2|wpa3} - --ssid netgear --passwd admin123 --test_duration 2m --url "ul ftp://10.40.0.1 /dev/null" - --requests_per_ten 600 --ftp --test_type bytes-wr --debug - -EXAMPLE (ftp bytes-rd): - ./test_l4.py --upstream_port eth1 (optional) --radio wiphy0 (required) --num_stations 3 (optional) - --security {open|wep|wpa|wpa2|wpa3} (required) --ssid netgear (required) - --url "dl ftp://10.40.0.1 /dev/null" (required) --password admin123 (required) - --test_duration 2m (optional) --ftp --test_type bytes-rd --debug (optional) - -Use './test_l4.py --help' to see command line usage and options -Copyright 2021 Candela Technologies Inc -License: Free to distribute and modify. LANforge systems must be licensed. -""" - -import sys -import os - -if sys.version_info[0] != 3: - print("This script requires Python 3") - exit(1) - -if 'py-json' not in sys.path: - sys.path.append(os.path.join(os.path.abspath('..'), 'py-json')) - -import argparse -from LANforge.lfcli_base import LFCliBase -from LANforge import LFUtils -import realm -import time -import datetime -from realm import TestGroupProfile - - -class IPV4L4(LFCliBase): - def __init__(self, - host="localhost", - port=8080, - ssid=None, - security=None, - password=None, - url=None, - ftp_user=None, - ftp_passwd=None, - requests_per_ten=None, - station_list=None, - test_duration="2m", - ap=None, - mode=0, - target_requests_per_ten=60, - number_template="00000", - num_tests=1, - radio="wiphy0", - _debug_on=False, - upstream_port="eth1", - ftp=False, - test_type=None, - _exit_on_error=False, - _exit_on_fail=False): - super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail) - - self.host = host - self.port = port - self.radio = radio - self.upstream_port = upstream_port - self.ssid = ssid - self.security = security - self.password = password - self.url = url - self.mode = mode - self.ap = ap - self.debug = _debug_on - self.requests_per_ten = int(requests_per_ten) - self.number_template = number_template - self.test_duration = test_duration - self.sta_list = station_list - self.num_tests = int(num_tests) - self.target_requests_per_ten = int(target_requests_per_ten) - - self.local_realm = realm.Realm(lfclient_host=self.host, lfclient_port=self.port) - self.l4cxprofile = realm.L4CXProfile(lfclient_host=host, - lfclient_port=port, local_realm=self.local_realm) - self.station_profile = self.local_realm.new_station_profile() - self.cx_profile = self.local_realm.new_l4_cx_profile() - - self.station_profile.lfclient_url = self.lfclient_url - self.station_profile.ssid = self.ssid - self.station_profile.ssid_pass = self.password - self.station_profile.security = self.security - self.station_profile.number_template_ = self.number_template - self.station_profile.mode = self.mode - self.test_type = test_type - self.ftp_user = ftp_user - self.ftp_passwd = ftp_passwd - if self.ap is not None: - self.station_profile.set_command_param("add_sta", "ap", self.ap) - - self.cx_profile.url = self.url - self.cx_profile.requests_per_ten = self.requests_per_ten - - self.ftp = ftp - if self.ftp and 'ftp://' not in self.url: - print("WARNING! FTP test chosen, but ftp:// not present in url!") - - if self.test_type != 'urls/s' and self.test_type != 'bytes-wr' and self.test_type != 'bytes-rd': - raise ValueError("Unknown test type: %s\nValid test types are urls/s, bytes-rd, or bytes-wr" % self.test_type) - - def build(self): - # Build stations - self.station_profile.use_security(self.security, self.ssid, self.password) - print("Creating stations") - self.station_profile.set_command_flag("add_sta", "create_admin_down", 1) - self.station_profile.set_command_param("set_port", "report_timer", 1500) - self.station_profile.set_command_flag("set_port", "rpt_timer", 1) - self.station_profile.create(radio=self.radio, sta_names_=self.sta_list, debug=self.debug) - self._pass("PASS: Station build finished") - - if self.ftp: - self.cx_profile.create(ports=self.station_profile.station_names, sleep_time=.5, debug_=self.debug, - suppress_related_commands_=True, ftp=self.ftp, - user=self.ftp_user, passwd=self.ftp_passwd, - source=self.source) - else: - self.cx_profile.create(ports=self.station_profile.station_names, sleep_time=.5, debug_=self.debug, - suppress_related_commands_=None) - - def __check_request_rate(self): - endp_list = self.json_get("layer4/list?fields=urls/s") - expected_passes = 0 - passes = 0 - if endp_list is not None and endp_list['endpoint'] is not None: - endp_list = endp_list['endpoint'] - for item in endp_list: - for name, info in item.items(): - if name in self.cx_profile.created_cx.keys(): - expected_passes += 1 - if info['urls/s'] * self.requests_per_ten >= self.target_requests_per_ten * .9: - passes += 1 - return passes == expected_passes - - def __compare_vals(self, old_list, new_list): - passes = 0 - expected_passes = 0 - if len(old_list) == len(new_list): - for item, value in old_list.items(): - expected_passes += 1 - if new_list[item] > old_list[item]: - passes += 1 - if passes == expected_passes: - return True - else: - return False - else: - return False - - def __get_bytes(self): - time.sleep(1) - cx_list = self.json_get("layer4/list?fields=name,%s" % self.test_type, debug_=self.debug) - # print("==============\n", cx_list, "\n==============") - cx_map = {} - for cx_name in cx_list['endpoint']: - if cx_name != 'uri' and cx_name != 'handler': - for item, value in cx_name.items(): - for value_name, value_rx in value.items(): - if item in self.cx_profile.created_cx.keys() and value_name == self.test_type: - cx_map[item] = value_rx - return cx_map - - def start(self, print_pass=False, print_fail=False): - if self.ftp: - self.port_util.set_ftp(port_name=self.local_realm.name_to_eid(self.upstream_port)[2], resource=1, on=True) - temp_stas = self.sta_list.copy() - - self.station_profile.admin_up() - if self.local_realm.wait_for_ip(temp_stas): - self._pass("All stations got IPs", print_pass) - else: - self._fail("Stations failed to get IPs", print_fail) - exit(1) - self.cx_profile.start_cx() - print("Starting test") - curr_time = datetime.datetime.now() - if self.test_type != 'urls/s': - old_rx_values = self.__get_bytes() - end_time = self.local_realm.parse_time(self.test_duration) + curr_time - sleep_interval = self.local_realm.parse_time(self.test_duration) // 5 - passes = 0 - expected_passes = 0 - - for test in range(self.num_tests): - expected_passes += 1 - while curr_time < end_time: - time.sleep(sleep_interval.total_seconds()) - curr_time = datetime.datetime.now() - - if self.test_type == 'urls/s': - if self.cx_profile.check_errors(self.debug): - if self.__check_request_rate(): - passes += 1 - else: - self._fail("FAIL: Request rate did not exceed target rate", print_fail) - break - else: - self._fail("FAIL: Errors found getting to %s " % self.url, print_fail) - break - - else: - new_rx_values = self.__get_bytes() - expected_passes += 1 - if self.__compare_vals(old_rx_values, new_rx_values): - passes += 1 - else: - self._fail("FAIL: Not all stations increased traffic", print_fail) - break - old_rx_values = new_rx_values - cur_time = datetime.datetime.now() - if passes == expected_passes: - self._pass("PASS: All tests passes", print_pass) - - def stop(self): - self.cx_profile.stop_cx() - if self.ftp: - self.port_util.set_ftp(port_name=self.local_realm.name_to_eid(self.upstream_port)[2], resource=1, on=False) - self.station_profile.admin_down() - - def cleanup(self, sta_list): - self.cx_profile.cleanup() - self.station_profile.cleanup(sta_list) - LFUtils.wait_until_ports_disappear(base_url=self.lfclient_url, port_list=sta_list, - debug=self.debug) -def main(): - parser = LFCliBase.create_basic_argparse( - prog='test_l4', - formatter_class=argparse.RawTextHelpFormatter, - epilog='''\ - This script will monitor the urls/s, bytes-rd, or bytes-wr attribute of the endpoints. - ''', - description='''\ - test_l4.py: --------------------- -Generic command example: -python3 ./test_l4.py - --upstream_port eth1 \\ - --radio wiphy0 \\ - --num_stations 3 \\ - --security {open|wep|wpa|wpa2|wpa3} \\ - --ssid netgear \\ - --passwd admin123 \\ - --requests_per_ten 600 \\ - --mode 1 - {"auto" : "0", - "a" : "1", - "b" : "2", - "g" : "3", - "abg" : "4", - "abgn" : "5", - "bgn" : "6", - "bg" : "7", - "abgnAC" : "8", - "anAC" : "9", - "an" : "10", - "bgnAC" : "11", - "abgnAX" : "12", - "bgnAX" : "13"} \\ - --num_tests 1 \\ - --url "dl http://10.40.0.1 /dev/null" \\ - --ap "00:0e:8e:78:e1:76" - --target_per_ten 600 \\ - --output_format csv \\ - --report_file ~/Documents/results.csv \\ - --test_duration 2m \\ - --debug - ''') - required = None - for agroup in parser._action_groups: - if agroup.title == "required arguments": - required = agroup - # if required is not None: - - optional = None - for agroup in parser._action_groups: - if agroup.title == "optional arguments": - optional = agroup - - if optional is not None: - optional.add_argument('--requests_per_ten', help='--requests_per_ten number of request per ten minutes', - default=600) - optional.add_argument('--num_tests', help='--num_tests number of tests to run. Each test runs 10 minutes', - default=1) - optional.add_argument('--url', help='--url specifies upload/download, address, and dest', - default="dl http://10.40.0.1 /dev/null") - optional.add_argument('--test_duration', help='duration of test', default="2m") - optional.add_argument('--target_per_ten', - help='--target_per_ten target number of request per ten minutes. test will check for 90 percent this value', - default=600) - optional.add_argument('--mode', help='Used to force mode of stations') - optional.add_argument('--ap', help='Used to force a connection to a particular AP') - optional.add_argument('--report_file', help='where you want to store results') - optional.add_argument('--output_format', help='choose csv or xlsx') # update once other forms are completed - optional.add_argument('--ftp', help='Use ftp for the test', action='store_true') - optional.add_argument('--test_type', help='Choose type of test to run {url/s, bytes-rd, bytes-wr}', default='bytes-rd') - optional.add_argument('--ftp_user', help='--ftp_user sets the username to be used for ftp', default="lanforge") - optional.add_argument('--ftp_passwd', help='--ftp_user sets the password to be used for ftp', default="lanforge") - - args = parser.parse_args() - - num_sta = 2 - if (args.num_stations is not None) and (int(args.num_stations) > 0): - num_stations_converted = int(args.num_stations) - num_sta = num_stations_converted - if args.report_file is None: - if args.output_format in ['csv', 'json', 'html', 'hdf', 'stata', 'pickle', 'pdf', 'parquet', 'png', 'df', - 'xlsx']: - output_form = args.output_format.lower() - print("Defaulting file output placement to /home/lanforge.") - rpt_file = '/home/data.' + output_form - else: - print("Defaulting data file output type to Excel") - rpt_file = '/home/lanforge/data.xlsx' - output_form = 'xlsx' - - else: - rpt_file = args.report_file - if args.output_format is None: - output_form = str(args.report_file).split('.')[-1] - else: - output_form = args.output_format - - # Create directory - if args.report_file is None: - try: - homedir = str(datetime.datetime.now().strftime("%Y-%m-%d-%H-%M")).replace(':', - '-') + 'test_l4' - path = os.path.join('/home/lanforge/report-data/', homedir) - os.mkdir(path) - except: - path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - print('Saving file to local directory') - else: - pass - - if args.report_file is None: - if args.output_format in ['csv', 'json', 'html', 'hdf', 'stata', 'pickle', 'pdf', 'png', 'df', 'parquet', - 'xlsx']: - rpt_file = path + '/data.' + args.output_format - output = args.output_format - else: - print('Defaulting data file output type to Excel') - rpt_file = path + '/data.xlsx' - output = 'xlsx' - else: - rpt_file = args.report_file - if args.output_format is None: - output = str(args.report_file).split('.')[-1] - else: - output = args.output_format - - station_list = LFUtils.portNameSeries(prefix_="sta", start_id_=0, end_id_=num_sta - 1, padding_number_=10000, - radio=args.radio) - - ip_test = IPV4L4(host=args.mgr, port=args.mgr_port, - ssid=args.ssid, - password=args.passwd, - radio=args.radio, - upstream_port=args.upstream_port, - security=args.security, - station_list=station_list, - url=args.url, - mode=args.mode, - ap=args.ap, - ftp=args.ftp, - ftp_user=args.ftp_user, - ftp_passwd=args.ftp_passwd, - test_type=args.test_type, - _debug_on=args.debug, - test_duration=args.test_duration, - num_tests=args.num_tests, - target_requests_per_ten=args.target_per_ten, - requests_per_ten=args.requests_per_ten) - ip_test.cleanup(station_list) - ip_test.build() - ip_test.start() - - try: - layer4traffic = ','.join([[*x.keys()][0] for x in ip_test.local_realm.json_get('layer4')['endpoint']]) - except: - pass - ip_test.l4cxprofile.monitor(col_names=['bytes-rd', 'urls/s', 'bytes-wr'], - report_file=rpt_file, - duration_sec=ip_test.local_realm.parse_time(args.test_duration).total_seconds(), - created_cx=layer4traffic, - output_format=output_form, - script_name='test_l4', - arguments=args, - debug=args.debug) - ip_test.stop() - if not ip_test.passes(): - print(ip_test.get_fail_message()) - exit(1) - time.sleep(30) - ip_test.cleanup(station_list) - if ip_test.passes(): - print("Full test passed, all endpoints met or exceeded 90 percent of the target rate") - - -if __name__ == "__main__": - main() diff --git a/py-scripts/tools/lf_check.json b/py-scripts/tools/lf_check.json deleted file mode 100644 index 3fb614bb..00000000 --- a/py-scripts/tools/lf_check.json +++ /dev/null @@ -1,50 +0,0 @@ -{ - "test_parameters":{ - "test_timeout": 200, - "load_blank_db": false, - "load_factory_default_db": true, - "load_custom_db": false, - "custom_db": "DFLT_ETH1_GEN", - "email_list_production": "chuck.rekiere@candelatech.com", - "host_ip_production": "192.168.95.6", - "email_list_test": "chuck.rekiere@candelatech.com", - "host_ip_test": "192.168.95.6" - }, - "test_network":{ - "http_test_ip": "10.40.0.10", - "ftp_test_ip": "10.40.0.10", - "test_ip": "192.168.0.104" - }, - "test_generic":{ - "radio_used": "wiphy1", - "ssid_used": "ct523c-vap", - "ssid_pw_used": "ct523c-vap", - "security_used": "wpa2", - "num_sta": 4, - "col_names": "name,tx_byptes,rx_bytes,dropped", - "upstream_port": "eth1" - }, - "radio_dict":{ - "RADIO_0_CFG":{"KEY":"RADIO_0_CFG","RADIO":"wiphy0","STATIONS":"4","SSID":"ct523c-vap","PASSWD":"ct523c-vap","SECURITY":"wpa2"}, - "RADIO_1_CFG":{"KEY":"RADIO_1_CFG","RADIO":"wiphy1","STATIONS":"4","SSID":"ct523c-vap","PASSWD":"ct523c-vap","SECURITY":"wpa2"} - }, - "test_suites":{ - "suite_one":{ - "create_l3":{"enabled":"TRUE","command":"create_l4.py","args":"--radio RADIO_USED --ssid SSID_USED --passwd SSID_PW_USED --security SECURITY_USED --debug"}, - "create_l4":{"enabled":"TRUE","command":"create_l4.py","args":"RADIO_1_CFG --debug"}, - "create_l4_2":{"enabled":"TRUE","command":"create_l4.py","args":"--radio wiphy1 --ssid ct523c-vap --passwd ct523c-vap --security wpa2 --debug"} - }, - "suite_two":{ - "test_l3_longevity":{"enabled":"TRUE","command":"test_l3_longevity.py","args":"--test_duration 15s --polling_interval 5s --upstream_port eth1 --radio 'radio==wiphy1,stations==4,ssid==ct523c-vap,ssid_pw==ct523c-vap,security==wpa2' --endp_type lf_udp --rates_are_totals --side_a_min_bps=20000 --side_b_min_bps=300000000"} - }, - - "TEST_DICTONARY":{ - "create_l3":{"enabled":"TRUE","command":"create_l4.py","args":"--radio RADIO_USED --ssid SSID_USED --passwd SSID_PW_USED --security SECURITY_USED --debug"}, - "test_l3_longevity":{"enabled":"TRUE","command":"test_l3_longevity.py","args":"--test_duration 15s --polling_interval 5s --upstream_port eth1 --radio 'radio==wiphy1,stations==4,ssid==ct523c-vap,ssid_pw==ct523c-vap,security==wpa2' --endp_type lf_udp --rates_are_totals --side_a_min_bps=20000 --side_b_min_bps=300000000"} - } - } -} - - - - \ No newline at end of file diff --git a/py-scripts/tools/lf_check.py b/py-scripts/tools/lf_check.py index f80b7a38..0445395f 100755 --- a/py-scripts/tools/lf_check.py +++ b/py-scripts/tools/lf_check.py @@ -5,84 +5,61 @@ NAME: lf_check.py PURPOSE: -lf_check.py will tests based on .ini file or .json file. -The config file may be copied from lf_check_config_template.ini, or can be generated. -The config file name can be passed in as a configuraiton parameter. -The json file may be copied from lf_check.json and updated. Currently all the parameters are needed to be set to a value - -The --production flag determine the email list for results +lf_check.py will run a series of tests based on the test TEST_DICTIONARY listed in lf_check_config.ini. +The lf_check_config.ini file is copied from lf_check_config_template.ini and local configuration is made +to the lf_check_config.ini. EXAMPLE: -lf_check.py # this will use the defaults -lf_check.py --ini --test_suite -lf_check.py --ini --test_suite --production - -lf_check.py --use_json --json --test_suite -lf_check.py --use_json --json --production +lf_check.py NOTES: Before using lf_check.py -Using .ini: -1. copy lf_check_config_template.ini to .ini , this will avoid .ini being overwritten on git pull -2. update .ini to enable (TRUE) tests to be run in the test suite, the default suite is the TEST_DICTIONARY -3. update other configuration to specific test bed for example radios - -Using .json: -1. copy lf_check.json to .json this will avoide .json being overwritten on git pull -2. update lf_check.json to enable (TRUE) tests to be run in the test suite, the default TEST_DICTIONARY - -TO DO NOTES: -6/14/2021 : -1. add server (telnet localhost 4001) build info, GUI build sha, and Kernel version to the output. -2. add unique database prior to each run +1. copy lf_check_config_template.ini to the lf_check_config.ini +2. update lf_check_config.ini to enable (TRUE) tests to be run in the TEST_DICTIONARY , the TEST_DICTIONARY needs to be passed in ''' -import datetime -import pprint + import sys if sys.version_info[0] != 3: print("This script requires Python3") exit() + import os -import socket +import pexpect import logging import time from time import sleep import argparse import json +from json import load import configparser +from pprint import * import subprocess +import re import csv import shutil -from os import path +import os.path # lf_report is from the parent of the current file dir_path = os.path.dirname(os.path.realpath(__file__)) parent_dir_path = os.path.abspath(os.path.join(dir_path,os.pardir)) sys.path.insert(0, parent_dir_path) +#sys.path.append('../') from lf_report import lf_report sys.path.append('/') +CONFIG_FILE = os.getcwd() + '/lf_check_config.ini' +RUN_CONDITION = 'ENABLE' + # setup logging FORMAT FORMAT = '%(asctime)s %(name)s %(levelname)s: %(message)s' -# lf_check class contains verificaiton configuration and ocastrates the testing. class lf_check(): def __init__(self, - _use_json, - _config_ini, - _json_data, - _test_suite, - _production, _csv_results, _outfile): - self.use_json = _use_json - self.json_data = _json_data - self.config_ini = _config_ini - self.test_suite = _test_suite - self.production_run = _production self.lf_mgr_ip = "" self.lf_mgr_port = "" self.radio_dict = {} @@ -121,53 +98,18 @@ class lf_check(): self.use_blank_db = "FALSE" self.use_factory_default_db = "FALSE" self.use_custom_db = "FALSE" + self.production_run = "FALSE" self.email_list_production = "" self.host_ip_production = None self.email_list_test = "" self.host_ip_test = None - # NOT complete : will send the email results - def send_results_email(self, report_file=None): - if (report_file is None): - print( "No report file, not sending email.") - return - report_url=report_file.replace('/home/lanforge/', '') - if report_url.startswith('/'): - report_url = report_url[1:] - # following recommendation + + + def send_results_email(self): + # Following recommendation # NOTE: https://stackoverflow.com/questions/24196932/how-can-i-get-the-ip-address-from-nic-in-python - #command = 'echo "$HOSTNAME mail system works!" | mail -s "Test: $HOSTNAME $(date)" chuck.rekiere@candelatech.com' - hostname = socket.gethostname() - ip = socket.gethostbyname(hostname) - message_txt = """Results from {hostname}: -http://{ip}/{report} -NOTE: for now to see stdout and stderr remove /home/lanforge from path. -""".format(hostname=hostname, ip=ip, report=report_url) - - mail_subject = "Regression Test [{hostname}] {date}".format(hostname=hostname, date=datetime.datetime.now()) - try: - if self.production_run == True: - msg = message_txt.format(ip=self.host_ip_production) - command = "echo \"{message}\" | mail -s \"{subject}\" {address}".format( - message=msg, - subject=mail_subject, - ip=self.host_ip_production, - address=self.email_list_production) - else: - msg = message_txt.format(ip=ip) - command = "echo \"{message}\" | mail -s \"{subject}\" {address}".format( - message=msg, - subject=mail_subject, - ip=ip, #self.host_ip_test, - address=self.email_list_test) - - print("running:[{}]".format(command)) - process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) - # have email on separate timeout - process.wait(timeout=int(self.test_timeout)) - except subprocess.TimeoutExpired: - print("send email timed out") - process.terminate() + pass def get_csv_results(self): return self.csv_file.name @@ -207,173 +149,15 @@ NOTE: for now to see stdout and stderr remove /home/lanforge from path.
""" - def read_config(self): - if self.use_json: - self.read_config_json() - else: - self.read_config_ini() - - # there is probably a more efficient way to do this in python - # Keeping it obvious for now, may be refactored later - def read_config_json(self): - #self.logger.info("read_config_json_contents {}".format(self.json_data)) - if "test_parameters" in self.json_data: - self.logger.info("json: read test_parameters") - #self.logger.info("test_parameters {}".format(self.json_data["test_parameters"])) - self.read_test_parameters() - else: - self.logger.info("EXITING test_parameters not in json {}".format(self.json_data)) - exit(1) - - if "test_network" in self.json_data: - self.logger.info("json: read test_network") - #self.logger.info("test_network {}".format(self.json_data["test_network"])) - self.read_test_network() - else: - self.logger.info("EXITING test_network not in json {}".format(self.json_data)) - exit(1) - - if "test_generic" in self.json_data: - self.logger.info("json: read test_generic") - #self.logger.info("test_generic {}".format(self.json_data["test_generic"])) - self.read_test_generic() - else: - self.logger.info("EXITING test_generic not in json {}".format(self.json_data)) - exit(1) - - if "radio_dict" in self.json_data: - self.logger.info("json: read radio_dict") - #self.logger.info("radio_dict {}".format(self.json_data["radio_dict"])) - self.radio_dict = self.json_data["radio_dict"] - self.logger.info("self.radio_dict {}".format(self.radio_dict)) - else: - self.logger.info("EXITING radio_dict not in json {}".format(self.json_data)) - exit(1) - - if "test_suites" in self.json_data: - self.logger.info("json: read test_suites looking for: {}".format(self.test_suite)) - #self.logger.info("test_suites {}".format(self.json_data["test_suites"])) - if self.test_suite in self.json_data["test_suites"]: - self.test_dict = self.json_data["test_suites"][self.test_suite] - #self.logger.info("self.test_dict {}".format(self.test_dict)) - else: - self.logger.info("EXITING test_suite {} Not Present in json test_suites: {}".format(self.test_suite, self.json_data["test_suites"])) - exit(1) - else: - self.logger.info("EXITING test_suites not in json {}".format(self.json_data)) - exit(1) - - def read_test_parameters(self): - if "test_timeout" in self.json_data["test_parameters"]: - self.test_timeout = self.json_data["test_parameters"]["test_timeout"] - else: - self.logger.info("test_timeout not in test_parameters json") - exit(1) - if "load_blank_db" in self.json_data["test_parameters"]: - self.load_blank_db = self.json_data["test_parameters"]["load_blank_db"] - else: - self.logger.info("load_blank_db not in test_parameters json") - exit(1) - if "load_factory_default_db" in self.json_data["test_parameters"]: - self.load_factory_default_db = self.json_data["test_parameters"]["load_factory_default_db"] - else: - self.logger.info("load_factory_default_db not in test_parameters json") - exit(1) - if "load_custom_db" in self.json_data["test_parameters"]: - self.load_custom_db = self.json_data["test_parameters"]["load_custom_db"] - else: - self.logger.info("load_custom_db not in test_parameters json") - exit(1) - if "custom_db" in self.json_data["test_parameters"]: - self.custom_db = self.json_data["test_parameters"]["custom_db"] - else: - self.logger.info("custom_db not in test_parameters json, if not using custom_db just put in a name") - exit(1) - if "email_list_production" in self.json_data["test_parameters"]: - self.email_list_production = self.json_data["test_parameters"]["email_list_production"] - else: - self.logger.info("email_list_production not in test_parameters json") - exit(1) - if "host_ip_production" in self.json_data["test_parameters"]: - self.host_ip_production = self.json_data["test_parameters"]["host_ip_production"] - else: - self.logger.info("host_ip_production not in test_parameters json") - exit(1) - if "email_list_test" in self.json_data["test_parameters"]: - self.email_list_test = self.json_data["test_parameters"]["email_list_test"] - else: - self.logger.info("email_list_test not in test_parameters json") - exit(1) - if "host_ip_test" in self.json_data["test_parameters"]: - self.email_list_test = self.json_data["test_parameters"]["host_ip_test"] - else: - self.logger.info("host_ip_test not in test_parameters json") - exit(1) - - def read_test_network(self): - if "http_test_ip" in self.json_data["test_network"]: - self.http_test_ip = self.json_data["test_network"]["http_test_ip"] - else: - self.logger.info("http_test_ip not in test_network json") - exit(1) - if "ftp_test_ip" in self.json_data["test_network"]: - self.ftp_test_ip = self.json_data["test_network"]["ftp_test_ip"] - else: - self.logger.info("ftp_test_ip not in test_network json") - exit(1) - if "test_ip" in self.json_data["test_network"]: - self.ftp_test_ip = self.json_data["test_network"]["test_ip"] - else: - self.logger.info("test_ip not in test_network json") - exit(1) - - def read_test_generic(self): - if "radio_used" in self.json_data["test_generic"]: - self.radio_lf = self.json_data["test_generic"]["radio_used"] - else: - self.logger.info("radio_used not in test_generic json") - exit(1) - if "ssid_used" in self.json_data["test_generic"]: - self.ssid = self.json_data["test_generic"]["ssid_used"] - else: - self.logger.info("ssid_used not in test_generic json") - exit(1) - if "ssid_pw_used" in self.json_data["test_generic"]: - self.ssid_pw = self.json_data["test_generic"]["ssid_pw_used"] - else: - self.logger.info("ssid_pw_used not in test_generic json") - exit(1) - if "security_used" in self.json_data["test_generic"]: - self.security = self.json_data["test_generic"]["security_used"] - else: - self.logger.info("security_used not in test_generic json") - exit(1) - if "num_sta" in self.json_data["test_generic"]: - self.num_sta = self.json_data["test_generic"]["num_sta"] - else: - self.logger.info("num_sta not in test_generic json") - exit(1) - if "col_names" in self.json_data["test_generic"]: - self.num_sta = self.json_data["test_generic"]["col_names"] - else: - self.logger.info("col_names not in test_generic json") - exit(1) - if "upstream_port" in self.json_data["test_generic"]: - self.num_sta = self.json_data["test_generic"]["upstream_port"] - else: - self.logger.info("upstream_port not in test_generic json") - exit(1) - - # functions in this section are/can be overridden by descendants - # this code reads the lf_check_config.ini file to populate the test variables - def read_config_ini(self): - #self.logger.info("read_config_ini_contents {}".format(self.config_ini)) + # Functions in this section are/can be overridden by descendants + # This code reads the lf_check_config.ini file to populate the test variables + def read_config_contents(self): + self.logger.info("read_config_contents {}".format(CONFIG_FILE)) config_file = configparser.ConfigParser() success = True - success = config_file.read(self.config_ini) - self.logger.info("config_file.read result {}".format(success)) + success = config_file.read(CONFIG_FILE) + self.logger.info("logger worked") - # LF_MGR parameters not used yet if 'LF_MGR' in config_file.sections(): section = config_file['LF_MGR'] self.lf_mgr_ip = section['LF_MGR_IP'] @@ -381,18 +165,6 @@ NOTE: for now to see stdout and stderr remove /home/lanforge from path. self.logger.info("lf_mgr_ip {}".format(self.lf_mgr_ip)) self.logger.info("lf_mgr_port {}".format(self.lf_mgr_port)) - if 'TEST_PARAMETERS' in config_file.sections(): - section = config_file['TEST_PARAMETERS'] - self.test_timeout = section['TEST_TIMEOUT'] - self.use_blank_db = section['LOAD_BLANK_DB'] - self.use_factory_default_db = section['LOAD_FACTORY_DEFAULT_DB'] - self.use_custom_db = section['LOAD_CUSTOM_DB'] - self.custom_db = section['CUSTOM_DB'] - self.email_list_production = section['EMAIL_LIST_PRODUCTION'] - self.host_ip_production = section['HOST_IP_PRODUCTION'] - self.email_list_test = section['EMAIL_LIST_TEST'] - self.host_ip_test = section['HOST_IP_TEST'] - if 'TEST_NETWORK' in config_file.sections(): section = config_file['TEST_NETWORK'] self.http_test_ip = section['HTTP_TEST_IP'] @@ -419,22 +191,29 @@ NOTE: for now to see stdout and stderr remove /home/lanforge from path. self.upstream_port = section['UPSTREAM_PORT'] self.logger.info("upstream_port {}".format(self.upstream_port)) + if 'TEST_PARAMETERS' in config_file.sections(): + section = config_file['TEST_PARAMETERS'] + self.test_timeout = section['TEST_TIMEOUT'] + self.use_blank_db = section['LOAD_BLANK_DB'] + self.use_factory_default_db = section['LOAD_FACTORY_DEFAULT_DB'] + self.use_custom_db = section['LOAD_CUSTOM_DB'] + self.custom_db = section['CUSTOM_DB'] + self.production_run = section['PRODUCTION_RUN'] + self.email_list_production = section['EMAIL_LIST_PRODUCTION'] + self.host_ip_production = section['HOST_IP_PRODUCTION'] + self.email_list_test = section['EMAIL_LIST_TEST'] + self.host_ip_test = section['HOST_IP_TEST'] + if 'RADIO_DICTIONARY' in config_file.sections(): section = config_file['RADIO_DICTIONARY'] self.radio_dict = json.loads(section.get('RADIO_DICT', self.radio_dict)) self.logger.info("self.radio_dict {}".format(self.radio_dict)) - if self.test_suite in config_file.sections(): - section = config_file[self.test_suite] + if 'TEST_DICTIONARY' in config_file.sections(): + section = config_file['TEST_DICTIONARY'] # for json replace the \n and \r they are invalid json characters, allows for multiple line args - try: - self.test_dict = json.loads(section.get('TEST_DICT', self.test_dict).replace('\n',' ').replace('\r',' ')) - self.logger.info("{}: {}".format(self.test_suite,self.test_dict)) - except: - self.logger.info("Excpetion loading {}, is there comma after the last entry? Check syntax".format(self.test_suite)) - else: - self.logger.info("EXITING... NOT FOUND Test Suite with name : {}".format(self.test_suite)) - exit(1) + self.test_dict = json.loads(section.get('TEST_DICT', self.test_dict).replace('\n',' ').replace('\r',' ')) + #self.logger.info("test_dict {}".format(self.test_dict)) def load_factory_default_db(self): #self.logger.info("file_wd {}".format(self.scripts_wd)) @@ -451,10 +230,12 @@ NOTE: for now to see stdout and stderr remove /home/lanforge from path. out, err = process.communicate() errcode = process.returncode - # not currently used + # Not currently used def load_blank_db(self): + #self.logger.info("file_wd {}".format(self.scripts_wd)) try: os.chdir(self.scripts_wd) + #self.logger.info("Current Working Directory {}".format(os.getcwd())) except: self.logger.info("failed to change to {}".format(self.scripts_wd)) @@ -463,8 +244,10 @@ NOTE: for now to see stdout and stderr remove /home/lanforge from path. process = subprocess.Popen((command).split(' '), shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) def load_custom_db(self,custom_db): + #self.logger.info("file_wd {}".format(self.scripts_wd)) try: os.chdir(self.scripts_wd) + #self.logger.info("Current Working Directory {}".format(os.getcwd())) except: self.logger.info("failed to change to {}".format(self.scripts_wd)) @@ -484,10 +267,10 @@ NOTE: for now to see stdout and stderr remove /home/lanforge from path. self.logger.info("test: {} skipped".format(test)) # load the default database elif self.test_dict[test]['enabled'] == "TRUE": - # make the command replace ment a separate method call. + # Make the command replace ment a separate method call. # loop through radios for radio in self.radio_dict: - # replace RADIO, SSID, PASSWD, SECURITY with actual config values (e.g. RADIO_0_CFG to values) + # Replace RADIO, SSID, PASSWD, SECURITY with actual config values (e.g. RADIO_0_CFG to values) # not "KEY" is just a word to refer to the RADIO define (e.g. RADIO_0_CFG) to get the vlaues # --num_stations needs to be int not string (no double quotes) if self.radio_dict[radio]["KEY"] in self.test_dict[test]['args']: @@ -515,35 +298,26 @@ NOTE: for now to see stdout and stderr remove /home/lanforge from path. self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('COL_NAMES',self.col_names) if 'UPSTREAM_PORT' in self.test_dict[test]['args']: self.test_dict[test]['args'] = self.test_dict[test]['args'].replace('UPSTREAM_PORT',self.col_names) - - if 'load_db' in self.test_dict[test]: - self.logger.info("load_db : {}".format(self.test_dict[test]['load_db'])) - if str(self.test_dict[test]['load_db']).lower() != "none" and str(self.test_dict[test]['load_db']).lower() != "skip": - try: - self.load_custom_db(self.test_dict[test]['load_db']) - except: - self.logger.info("custom database failed to load check existance and location: {}".format(self.test_dict[test]['load_db'])) - else: - self.logger.info("no load_db present in dictionary, load db normally") - if self.use_factory_default_db == "TRUE": - self.load_factory_default_db() - sleep(3) - self.logger.info("FACTORY_DFLT loaded between tests with scenario.py --load FACTORY_DFLT") - if self.use_blank_db == "TRUE": - self.load_blank_db() + if self.use_factory_default_db == "TRUE": + self.load_factory_default_db() + sleep(3) + self.logger.info("FACTORY_DFLT loaded between tests with scenario.py --load FACTORY_DFLT") + if self.use_blank_db == "TRUE": + self.load_blank_db() + sleep(1) + self.logger.info("BLANK loaded between tests with scenario.py --load BLANK") + if self.use_custom_db == "TRUE": + try: + self.load_custom_db(self.custom_db) sleep(1) - self.logger.info("BLANK loaded between tests with scenario.py --load BLANK") - if self.use_custom_db == "TRUE": - try: - self.load_custom_db(self.custom_db) - sleep(1) - self.logger.info("{} loaded between tests with scenario.py --load {}".format(self.custom_db,self.custom_db)) - except: - self.logger.info("custom database failed to load check existance and location: {}".format(self.custom_db)) - else: - self.logger.info("no db loaded between tests: {}".format(self.use_custom_db)) + self.logger.info("{} loaded between tests with scenario.py --load {}".format(self.custom_db,self.custom_db)) + except: + self.logger.info("custom database failed to load check existance and location") + else: + self.logger.info("no db loaded between tests: {}".format(self.use_custom_db)) + + sleep(1) # the sleep is to allow for the database to stablize - sleep(1) # DO NOT REMOVE the sleep is to allow for the database to stablize try: os.chdir(self.scripts_wd) #self.logger.info("Current Working Directory {}".format(os.getcwd())) @@ -564,22 +338,21 @@ NOTE: for now to see stdout and stderr remove /home/lanforge from path. #self.logger.info("stderr_log_txt: {}".format(stderr_log_txt)) stderr_log = open(stderr_log_txt, 'a') - # HERE is thwere the test is run + print("running {}".format(command)) + process = subprocess.Popen((command).split(' '), shell=False, stdout=stdout_log, stderr=stderr_log, universal_newlines=True) + try: - process = subprocess.Popen((command).split(' '), shell=False, stdout=stdout_log, stderr=stderr_log, universal_newlines=True) - # if there is a better solution please propose, the TIMEOUT Result is different then FAIL - try: - #out, err = process.communicate() - process.wait(timeout=int(self.test_timeout)) - except subprocess.TimeoutExpired: - process.terminate() - self.test_result = "TIMEOUT" + #out, err = process.communicate() + process.wait(timeout=int(self.test_timeout)) + except subprocess.TimeoutExpired: + process.terminate() + self.test_result = "TIMEOUT" - except: - print("No such file or directory with command: {}".format(command)) - self.logger.info("No such file or directory with command: {}".format(command)) + #if err: + # self.logger.info("command Test timed out: {}".format(command)) + #self.logger.info(stderr_log_txt) if(self.test_result != "TIMEOUT"): stderr_log_size = os.path.getsize(stderr_log_txt) if stderr_log_size > 0 : @@ -617,6 +390,7 @@ NOTE: for now to see stdout and stderr remove /home/lanforge from path. else: self.logger.info("enable value {} invalid for test: {}, test skipped".format(self.test_dict[test]['enabled'],test)) + self.finish_html_results() def main(): @@ -625,7 +399,7 @@ def main(): prog='lf_check.py', formatter_class=argparse.RawTextHelpFormatter, epilog='''\ - lf_check.py : running scripts listed in .ini or .json + lf_check.py : for running scripts listed in lf_check_config.ini file ''', description='''\ lf_check.py @@ -633,57 +407,16 @@ lf_check.py Summary : --------- -running scripts listed in .ini or .json - -Example : -./lf_check.py --ini lf_check_test.ini --suite suite_one -./lf_check.py --use_json --json lf_check_test.json --suite suite_two ---------- +for running scripts listed in lf_check_config.ini ''') - parser.add_argument('--ini', help="--ini default lf_check_config.ini", default="lf_check_config.ini") - parser.add_argument('--json', help="--json ", default="lf_check_config.json") - parser.add_argument('--use_json', help="--use_json ", action='store_true') - parser.add_argument('--suite', help="--suite default TEST_DICTIONARY", default="TEST_DICTIONARY") - parser.add_argument('--production', help="--production stores true, sends email results to production email list", action='store_true') parser.add_argument('--outfile', help="--outfile used as base name for all files generated", default="") parser.add_argument('--logfile', help="--logfile logging for output of lf_check.py script", default="lf_check.log") - args = parser.parse_args() + args = parser.parse_args() - # load test config file information either .json or .ini - use_json = False - json_data = "" - config_ini = "" - if args.use_json: - use_json = True - try: - print("args.json {}".format(args.json)) - with open(args.json, 'r') as json_config: - json_data = json.load(json_config) - except: - print("Error reading {}".format(args.json)) - else: - config_ini = os.getcwd() + '/' + args.ini - if os.path.exists(config_ini): - print("TEST CONFIG : {}".format(config_ini)) - else: - print("EXITING: NOTFOUND TEST CONFIG : {} ".format(config_ini)) - exit(1) - # select test suite - test_suite = args.suite - - if args.production: - production = True - print("Email to production list") - else: - production = False - print("Email to email list") - - # create report class for reporting - report = lf_report(_results_dir_name="lf_check", - _output_html="lf_check.html", - _output_pdf="lf-check.pdf") + # output report. + report = lf_report(_results_dir_name = "lf_check",_output_html="lf_check.html",_output_pdf="lf-check.pdf") current_time = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) csv_results = "lf_check{}-{}.csv".format(args.outfile,current_time) @@ -692,21 +425,16 @@ Example : outfile_path = report.file_add_path(outfile) # lf_check() class created - check = lf_check(_use_json = use_json, - _config_ini = config_ini, - _json_data = json_data, - _test_suite = test_suite, - _production = production, - _csv_results = csv_results, + check = lf_check(_csv_results = csv_results, _outfile = outfile_path) - # get git sha + # get the git sha process = subprocess.Popen(["git", "rev-parse", "HEAD"], stdout=subprocess.PIPE) (commit_hash, err) = process.communicate() exit_code = process.wait() git_sha = commit_hash.decode('utf-8','ignore') - # set up logging + # set up logging logfile = args.logfile[:-4] print("logfile: {}".format(logfile)) logfile = "{}-{}.log".format(logfile,current_time) @@ -720,18 +448,15 @@ Example : logger.addHandler(file_handler) logger.addHandler(logging.StreamHandler(sys.stdout)) # allows to logging to file and stdout - # logger setup print out sha logger.info("commit_hash: {}".format(commit_hash)) logger.info("commit_hash2: {}".format(commit_hash.decode('utf-8','ignore'))) - # read config and run tests - check.read_config() + check.read_config_contents() # CMR need mode to just print out the test config and not run check.run_script_test() - # generate output reports + # Generate Ouptput reports report.set_title("LF Check: lf_check.py") report.build_banner() - report.start_content_div() report.set_table_title("LF Check Test Results") report.build_table_title() report.set_text("git sha: {}".format(git_sha)) @@ -743,50 +468,27 @@ Example : print("html report: {}".format(html_report)) report.write_pdf_with_timestamp() - report_path = os.path.dirname(html_report) - parent_report_dir = os.path.dirname(report_path) - # copy results to lastest so someone may see the latest. - lf_check_latest_html = parent_report_dir + "/lf_check_latest.html" + lf_check_latest_html = os.path.dirname(os.path.dirname(html_report)) + "/lf_check_latest.html" # duplicates html_report file up one directory - lf_check_html_report = parent_report_dir + "/{}.html".format(outfile) + lf_check_html_report = os.path.dirname(os.path.dirname(html_report)) + "/{}.html".format(outfile) - banner_src_png = report_path + "/banner.png" - banner_dest_png = parent_report_dir + "/banner.png" - CandelaLogo_src_png = report_path + "/CandelaLogo2-90dpi-200x90-trans.png" - CandelaLogo_dest_png = parent_report_dir + "/CandelaLogo2-90dpi-200x90-trans.png" - report_src_css = report_path + "/report.css" - report_dest_css = parent_report_dir + "/report.css" - custom_src_css = report_path + "/custom.css" - custom_dest_css = parent_report_dir + "/custom.css" - font_src_woff = report_path + "/CenturyGothic.woff" - font_dest_woff = parent_report_dir + "/CenturyGothic.woff" - - #pprint.pprint([ - # ('banner_src', banner_src_png), - # ('banner_dest', banner_dest_png), - # ('CandelaLogo_src_png', CandelaLogo_src_png), - # ('CandelaLogo_dest_png', CandelaLogo_dest_png), - # ('report_src_css', report_src_css), - # ('custom_src_css', custom_src_css) - #]) + # + banner_src_png = os.path.dirname(html_report)+ "/banner.png" + banner_dest_png = os.path.dirname(os.path.dirname(html_report))+ "/banner.png" + CandelaLogo_src_png = os.path.dirname(html_report) + "/CandelaLogo2-90dpi-200x90-trans.png" + CandelaLogo_dest_png = os.path.dirname(os.path.dirname(html_report)) + "/CandelaLogo2-90dpi-200x90-trans.png" # copy one directory above - shutil.copyfile(html_report, lf_check_latest_html) - shutil.copyfile(html_report, lf_check_html_report) + shutil.copyfile(html_report,lf_check_latest_html) + shutil.copyfile(html_report,lf_check_html_report) # copy banner and logo - shutil.copyfile(banner_src_png, banner_dest_png) - shutil.copyfile(CandelaLogo_src_png, CandelaLogo_dest_png) - shutil.copyfile(report_src_css, report_dest_css) - shutil.copyfile(custom_src_css, custom_dest_css) - shutil.copyfile(font_src_woff, font_dest_woff) + shutil.copyfile(banner_src_png, banner_dest_png) + shutil.copyfile(CandelaLogo_src_png,CandelaLogo_dest_png) + print("lf_check_latest.html: {}".format(lf_check_latest_html)) + print("lf_check_html_report: {}".format(lf_check_html_report)) - # print out locations of results - print("lf_check_latest.html: "+lf_check_latest_html) - print("lf_check_html_report: "+lf_check_html_report) - - check.send_results_email(report_file=lf_check_html_report) if __name__ == '__main__': main() diff --git a/py-scripts/tools/lf_check_config_template.ini b/py-scripts/tools/lf_check_config_template.ini index 0e4da4d5..4c773332 100755 --- a/py-scripts/tools/lf_check_config_template.ini +++ b/py-scripts/tools/lf_check_config_template.ini @@ -23,6 +23,7 @@ LOAD_BLANK_DB = FALSE LOAD_FACTORY_DEFAULT_DB = TRUE LOAD_CUSTOM_DB = FALSE CUSTOM_DB = DFLT_ETH1_GEN +PRODUCTION_RUN = FALSE # determine whom to send emails to EMAIL_LIST_PRODUCTION = chuck.rekiere@candelatech.com HOST_IP_PRODUCTION = 192.168.95.6 EMAIL_LIST_TEST = chuck.rekiere@candelatech.com @@ -50,8 +51,11 @@ UPSTREAM_PORT = eth1 # NOTE: KEY must match ELEMENT of the DICTIONARY (RADIO_1_CFG == "KEY":"RADIO_1_CFG") [RADIO_DICTIONARY] RADIO_DICT: { - "RADIO_0_CFG":{"KEY":"RADIO_0_CFG","RADIO":"wiphy0","STATIONS":"4","SSID":"ct523c-vap","PASSWD":"ct523c-vap","SECURITY":"wpa2"}, - "RADIO_1_CFG":{"KEY":"RADIO_1_CFG","RADIO":"wiphy1","STATIONS":"4","SSID":"ct523c-vap","PASSWD":"ct523c-vap","SECURITY":"wpa2"} + "RADIO_0_CFG":{"KEY":"RADIO_0_CFG","RADIO":"wiphy0","STATIONS":"4","SSID":"ssid-wpa2","PASSWD":"ssidpw-wpa2","SECURITY":"wpa2"}, + "RADIO_1_CFG":{"KEY":"RADIO_1_CFG","RADIO":"wiphy1","STATIONS":"4","SSID":"ct523c-vap","PASSWD":"ct523c-vap","SECURITY":"wpa2"}, + "RADIO_2_CFG":{"KEY":"RADIO_2_CFG","RADIO":"wiphy1","STATIONS":"4","SSID":"ssid-wpa","PASSWD":"ssidpw-wpa","SECURITY":"wpa"}, + "RADIO_3_CFG":{"KEY":"RADIO_3_CFG","RADIO":"wiphy1","STATIONS":"4","SSID":"ssid-wep","PASSWD":"ssidpw-wep","SECURITY":"wep"}, + "RADIO_4_CFG":{"KEY":"RADIO_4_CFG","RADIO":"wiphy1","STATIONS":"4","SSID":"ssid-wpa3","PASSWD":"ssidpw-wpa3","SECURITY":"wpa3"} } # Not used @@ -61,20 +65,123 @@ LF_MGR_PORT=8080 # REPORTS are in /home/lanforge/html-reports # if /home/lanforge/html-reports not present then reports stored in local directory +#[REPORTS] +#REPORT_DIR="/home/lanforge/html-reports" -[TEST_DICTIONARY] +# TEST_DICTIONARY used by lf_check, Other section names will be ignored so can save other test lists +# TEST_DICTIONARY_ENABLE_1 is an example, it will not run unless the name is changed to TEST_DICTIONARY +[TEST_DICTIONARY_EXAMPLE_1] +#[TEST_DICTIONARY] TEST_DICT: { - "create_l3":{"enabled":"TRUE","command":"create_l4.py","args":"--radio RADIO_USED --ssid SSID_USED --passwd SSID_PW_USED --security SECURITY_USED --debug"}, - "create_l4":{"enabled":"TRUE","command":"create_l4.py","args":"RADIO_1_CFG --debug"}, - # the name needs to be unique for the dictionary - "create_l4_2":{"enabled":"TRUE","command":"create_l4.py","args":"--radio wiphy1 --ssid ct523c-vap --passwd ct523c-vap --security wpa2 --debug"} + "test_ipv4_l4":{"enabled":"FALSE","command":"test_ipv4_l4.py","args":"--radio wiphy1 --ssid ct523c-vap --passwd ct523c-vap --security wpa2 --num_stations 4 --test_duration 15s --debug"}, + "test_ipv4_variable_time2":{"enabled":"TRUE","command":"test_ipv4_variable_time.py","args":"--radio wiphy1 --ssid ct523c-vap --passwd ct523c-vap --security wpa2 --test_duration 15s --output_format excel --layer3_cols name,tx_bytes,rx_bytes,dropped --traffic_type lf_udp --debug"} } -[SUITE] +# TEST_DICTIONARY used by lf_check, Other section names will be ignored so can save other test lists +[TEST_DICTIONARY_EXAMPLE_2] +#[TEST_DICTIONARY] TEST_DICT: { - "create_l3":{"enabled":"TRUE","load_db":"none","command":"create_l4.py","args":"--radio RADIO_USED --ssid SSID_USED --passwd SSID_PW_USED --security SECURITY_USED --debug"}, - "create_l4":{"enabled":"TRUE","command":"create_l4.py","args":"RADIO_1_CFG --debug"}, - # the name needs to be unique for the dictionary - "create_l4_2":{"enabled":"TRUE","command":"create_l4.py","args":"--radio wiphy1 --ssid ct523c-vap --passwd ct523c-vap --security wpa2 --debug"} - } + "create_l3":{"enabled":"TRUE","command":"create_l3.py","args":"RADIO_1_CFG --debug"}, + "create_l4":{"enabled":"TRUE","command":"create_l4.py","args":"RADIO_1_CFG --debug"} + } +# This is an EXAMPLE dictionary of tests that can be run, copy to TEST_DICTIONARY to test. +# Feature update pass in the DICTIONARY name to be run +[TEST_DICTIONARY_EXAMPLE_3] +#[TEST_DICTIONARY] +TEST_DICT: { + "example_security_connection0":{"enabled":"TRUE","command":"example_security_connection.py","args":"RADIO_1_CFG --debug"}, + "example_security_connection1":{"enabled":"TRUE","command":"example_security_connection.py","args":"RADIO_2_CFG --debug"}, + "example_security_connection2":{"enabled":"TRUE","command":"example_security_connection.py","args":"RADIO_3_CFG --debug"}, + "example_security_connection3":{"enabled":"TRUE","command":"example_security_connection.py","args":"RADIO_4_CFG --debug"}, + "sta_connect2":{"enabled":"TRUE","command":"sta_connect2.py","args":"--dut_ssid ssid-wpa2 --dut_passwd ssidpw-wpa2 --dut_security wpa2"}, + "sta_connect_example":{"enabled":"TRUE","command":"sta_connect_example.py"}, + "test_generic0":{"enabled":"TRUE","command":"test_generic.py","args":"RADIO_1_CFG --type lfping --dest TEST_IP --debug"}, + "test_generic1":{"enabled":"TRUE","command":"test_generic.py","args":"RADIO_1_CFG --type lfping --dest TEST_IP --debug"}, + "test_generic2":{"enabled":"TRUE","command":"test_generic.py","args":"RADIO_1_CFG --type lfping --dest TEST_IP --debug"}, + "testgroup":{"enabled":"TRUE","command":"testgroup.py","args":"--group_name group1 --add_group --list_groups --debug"}, + "test_ipv4_connection":{"enabled":"TRUE","command":"test_ipv4_connection.py","args":"RADIO_1_CFG --debug"}, + "test_ipv4_l4_urls_per_ten":{"enabled":"TRUE","command":"test_ipv4_l4_urls_per_ten.py","args":"RADIO_1_CFG --num_tests 1 --requests_per_ten 600 --target_per_ten 600 --debug"}, + "test_ipv4_l4_wifi":{"enabled":"TRUE","command":"test_ipv4_l4_wifi.py","args":"RADIO_1_CFG --test_duration 15s --debug"}, + "test_ipv4_l4":{"enabled":"TRUE","command":"test_ipv4_l4.py","args":"--radio wiphy1 --ssid ct523c-vap --passwd ct523c-vap --security wpa2 --num_stations 4 --test_duration 15s --debug"}, + "test_ipv4_variable_time0":{"enabled":"TRUE","command":"test_ipv4_variable_time.py","args":"RADIO_1_CFG --test_duration 15s --output_format excel --layer3_cols COL_NAMES --traffic_type lf_udp --debug"}, + "test_ipv4_variable_time1":{"enabled":"TRUE","command":"test_ipv4_variable_time.py","args":"RADIO_1_CFG --test_duration 15s --output_format csv --layer3_cols COL_NAMES --traffic_type lf_udp --debug"}, + "test_ipv4_variable_time2":{"enabled":"TRUE","command":"test_ipv4_variable_time.py","args":"--radio wiphy1 --ssid ct523c-vap --passwd ct523c-vap --security wpa2 --test_duration 15s --output_format excel --layer3_cols name,tx_bytes,rx_bytes,dropped --traffic_type lf_udp --debug"}, + "test_ipv4_variable_time3":{"enabled":"TRUE","command":"test_ipv4_variable_time.py","args":"RADIO_1_CFG --test_duration 15s --output_format csv --layer3_cols COL_NAMES --traffic_type lf_udp --debug"}, + "create_bridge":{"enabled":"TRUE","command":"create_bridge.py","args":"--radio RADIO_USED --upstream_port UPSTREAM_PORT --target_device sta0000 --debug"}, + "create_l3":{"enabled":"TRUE","command":"create_l3.py","args":"RADIO_1_CFG --debug"}, + "create_l4":{"enabled":"TRUE","command":"create_l4.py","args":"RADIO_1_CFG --debug"}, + "create_station":{"enabled":"TRUE","command":"create_station.py","args":"--radio RADIO_USED --ssid SSID_USED --passwd SSID_PW_USED --security SECURITY_USED --debug"}, + "test_fileio":{"enabled":"TRUE","command":"test_fileio.py","args":"--macvlan_parent eth2 --num_ports 3 --use_macvlans --first_mvlan_ip 192.168.92.13 --netmask 255.255.255.0 --gateway 192.168.92.1 --test_duration 30s"}, + "test_l3_longevity":{"enabled":"TRUE","command":"test_l3_longevity.py","args":"--test_duration 20s --polling_interval 5s --upstream_port eth1 + --radio 'radio==wiphy1,stations==4,ssid==ct523c-vap,ssid_pw==ct523c-vap,security==wpa2' + --radio 'radio==wiphy2,stations==4,ssid==ct523c-vap,ssid_pw==ct523c-vap,security==wpa2' + --radio 'radio==wiphy3,stations==4,ssid==ct523c-vap,ssid_pw==ct523c-vap,security==wpa2' + --endp_type lf_udp --ap_read --ap_test_mode --rates_are_totals --side_a_min_bps=20000 --side_b_min_bps=300000000"}, + "test_status_msg":{"enabled":"TRUE","command":"test_status_msg.py","args":"--action run_test"}, + "test_wanlink":{"enabled":"TRUE","command":"test_wanlink.py","args":"--debug"}, + "sta_connect_example":{"enabled":"TRUE","command":"sta_connect_example.py","args":"RADIO_1_CFG --upstream_port UPSTREAM_PORT"}, + "wlan_capacity_calculator1":{"enabled":"TRUE","command":"./wlan_capacity_calculator.py","args":"-sta 11abg -t Voice -p 48 -m 106 -e WEP -q Yes -b 1 2 5.5 11 -pre Long -s N/A -co G.711 -r Yes -c Yes"}, + "wlan_capacity_calculator2":{"enabled":"TRUE","command":"./wlan_capacity_calculator.py","args":"-sta 11n -t Voice -d 17 -ch 40 -gu 800 -high 9 -e WEP -q Yes -ip 5 -mc 42 -b 6 9 12 24 -m 1538 -co G.729 -pl Greenfield -cw 15 -r Yes -c Yes"}, + "wlan_capacity_calculator3":{"enabled":"TRUE","command":"./wlan_capacity_calculator.py","args":"-sta 11ac -t Voice -d 9 -spa 3 -ch 20 -gu 800 -high 1 -e TKIP -q Yes -ip 3 -mc 0 -b 6 12 24 54 -m 1518 -co Greenfield -cw 15 -rc Yes"} + } + + +# This LISA is used currelty for facilitating getting testing on LISA +[TEST_DICTIONARY_LISA_SHORT] +#[TEST_DICTIONARY] +TEST_DICT: { + "create_l3":{"enabled":"TRUE","command":"create_l3.py","args":"--radio RADIO_USED --ssid SSID_USED --passwd SSID_PW_USED --security SECURITY_USED --debug"}, + "create_l4":{"enabled":"TRUE","command":"create_l4.py","args":"RADIO_1_CFG --debug"}, + "create_l4":{"enabled":"TRUE","command":"create_l4.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --debug"} + } + +#[TEST_DICTIONARY] +[TEST_DICTIONARY_LISA] +TEST_DICT: { + "example_security_connection0":{"enabled":"FALSE","command":"example_security_connection.py","args":"--num_stations 4 --ssid jedway-wpa-1 --passwd jedway-wpa-1 --radio wiphy1 --security wpa --debug"}, + "example_security_connection1":{"enabled":"FALSE","command":"example_security_connection.py","args":"--num_stations 4 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --radio wiphy1 --security wpa2 --debug"}, + "example_security_connection2":{"enabled":"FALSE","command":"example_security_connection.py","args":"--num_stations 4 --ssid jedway-wep-48 --passwd 0123456789 --radio wiphy1 --security wep --debug"}, + "example_security_connection2":{"enabled":"FALSE","command":"example_security_connection.py","args":"--num_stations 4 --ssid jedway-wpa3-1 --passwd jedway-wpa3-1 --radio wiphy1 --security wpa3 --debug"}, + "sta_connect2":{"enabled":"FALSE","command":"sta_connect2.py","args":"--dut_ssid ssid-wpa2 --dut_passwd ssidpw-wpa2 --dut_security wpa2"}, + "sta_connect_example":{"enabled":"FALSE","command":"sta_connect_example.py","args":""}, + "test_fileio":{"enabled":"FALSE","command":"test_fileio.py","args":"--macvlan_parent eth2 --num_ports 3 --use_macvlans --first_mvlan_ip 192.168.92.13 --netmask 255.255.255.0 --test_duration 30s --gateway 192.168.92.1"}, + "test_generic0":{"enabled":"FALSE","command":"test_generic.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --num_stations 4 --type lfping --dest 10.40.0.1 --debug"}, + "test_generic1":{"enabled":"FALSE","command":"test_generic.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --num_stations 4 --type speedtest --speedtest_min_up 20 --speedtest_min_dl 20 --speedtest_max_ping 150 --security wpa2 --debug"}, + "test_generic2":{"enabled":"FALSE","command":"test_generic.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --num_stations 4 --type iperf3 --debug"}, + "test_generic3":{"enabled":"FALSE","command":"test_generic.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --num_stations 4 --type lfcurl --dest 10.40.0.1 --file_output /home/lanforge/Documents/lfcurl_output.txt --debug"}, + "testgroup":{"enabled":"FALSE","command":"testgroup.py","args":"--group_name group1 --add_group --list_groups --debug"}, +# testgroup_list_groups +# testgroup_list_connections +# testgroup_delete_group + "testgroup5":{"enabled":"TRUE","command":"testgroup.py","args":"--num_stations 4 --ssid lanforge --passwd password --security wpa2 --radio wiphy0 --group_name group0 --add_group"}, + "test_ipv4_connection":{"enabled":"TRUE","command":"test_ipv4_connection.py","args":"--radio wiphy1 --num_stations 4 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --debug"}, + "test_ipv4_l4_urls_per_ten":{"enabled":"TRUE","command":"test_ipv4_l4_urls_per_ten.py","args":"--radio wiphy1 --num_stations 4 --security wpa2 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --num_tests 1 --requests_per_ten 600 --target_per_ten 600 --debug"}, + "test_ipv4_l4_wifi":{"enabled":"TRUE","command":"test_ipv4_l4_wifi.py","args":"--radio wiphy1 --num_stations 4 --security wpa2 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --test_duration 15s --debug"}, + "test_ipv4_l4":{"enabled":"TRUE","command":"test_ipv4_l4.py","args":"--radio wiphy1 --num_stations 4 --security wpa2 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --test_duration 15s --debug"}, + "test_ipv4_variable_time0":{"enabled":"TRUE","command":"test_ipv4_variable_time.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --test_duration 15s --output_format excel --layer3_cols name,tx_bytes,rx_bytes,dropped --traffic_type lf_udp --debug"}, + "test_ipv4_variable_time1":{"enabled":"TRUE","command":"test_ipv4_variable_time.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --test_duration 15s --output_format csv --layer3_cols name,tx_bytes,rx_bytes,dropped --traffic_type lf_udp --debug"}, + "test_ipv4_l4_ftp_upload":{"enabled":"TRUE","command":"test_ipv4_l4_ftp_upload.py","args":"--upstream_port eth1 --radio wiphy1 --num_stations 4 --security wpa2 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --test_duration 15s --debug"}, + "test_ipv6_connection":{"enabled":"TRUE","command":"test_ipv6_connection.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --debug"}, + "test_ipv6_variable_time":{"enabled":"TRUE","command":"test_ipv6_variable_time.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --test_duration 15s --cx_type tcp6 --debug"}, + "test_ipv6_variable_time":{"enabled":"TRUE","command":"test_ipv6_variable_time.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --debug"}, + "test_l3_longevity":{"enabled":"TRUE","command":"test_l3_longevity.py","args":"--test_duration 15s --polling_interval 5s --upstream_port eth1 + --radio 'radio==wiphy0,stations==4,ssid==jedway-wpa2-x2048-5-3,ssid_pw==jedway-wpa2-x2048-5-3,security==wpa2' + --radio 'radio==wiphy2,stations==4,ssid==jedway-wpa2-x2048-5-3,ssid_pw==jedway-wpa2-x2048-5-3,security==wpa2' + --radio 'radio==wiphy3,stations==4,ssid==ct523c-vap,ssid_pw==ct523c-vap,security==wpa2' + --endp_type lf_udp --rates_are_totals --side_a_min_bps=20000 --side_b_min_bps=300000000"}, + "test_l3_powersave_traffic":{"enabled":"TRUE","command":"test_l3_powersave_traffic.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --debug"}, + "test_status_msg":{"enabled":"TRUE","command":"test_status_msg.py","args":"--action run_test"}, + "test_wanlink":{"enabled":"TRUE","command":"test_wanlink.py","args":"--debug"}, + "create_bridge":{"enabled":"TRUE","command":"create_bridge.py","args":"--radio wiphy1 --upstream_port eth1 --target_device sta0000 --debug"}, + "create_l3":{"enabled":"TRUE","command":"create_l3.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --debug"}, + "create_l4":{"enabled":"TRUE","command":"create_l4.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --debug"}, + "create_macvlan":{"enabled":"TRUE","command":"create_macvlan.py","args":"--radio wiphy1 --macvlan_parent eth1 --debug"}, + "create_station":{"enabled":"TRUE","command":"create_station.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --debug"}, + "create_vap":{"enabled":"TRUE","command":"create_vap.py","args":"--radio wiphy1 --ssid jedway-wpa2-x2048-5-3 --passwd jedway-wpa2-x2048-5-3 --security wpa2 --debug"}, + "create_vr":{"enabled":"TRUE","command":"create_vr.py","args":"--vr_name 2.vr0 --ports 2.br0,2.vap2 --services"}, + "create_qvlan":{"enabled":"TRUE","command":"create_qvlan.py","args":"--radio wiphy1 --qvlan_parent eth1"}, + "wlan_capacity_calculator1":{"enabled":"TRUE","command":"./wlan_capacity_calculator.py","args":"-sta 11abg -t Voice -p 48 -m 106 -e WEP -q Yes -b 1 2 5.5 11 -pre Long -s N/A -co G.711 -r Yes -c Yes"}, + "wlan_capacity_calculator2":{"enabled":"TRUE","command":"./wlan_capacity_calculator.py","args":"-sta 11n -t Voice -d 17 -ch 40 -gu 800 -high 9 -e WEP -q Yes -ip 5 -mc 42 -b 6 9 12 24 -m 1538 -co G.729 -pl Greenfield -cw 15 -r Yes -c Yes"}, + "wlan_capacity_calculator3":{"enabled":"TRUE","command":"./wlan_capacity_calculator.py","args":"-sta 11ac -t Voice -d 9 -spa 3 -ch 20 -gu 800 -high 1 -e TKIP -q Yes -ip 3 -mc 0 -b 6 12 24 54 -m 1518 -co Greenfield -cw 15 -rc Yes"} + } \ No newline at end of file diff --git a/py-scripts/tools/lf_header_template.py b/py-scripts/tools/lf_header_template.py deleted file mode 100644 index 4aeda4bd..00000000 --- a/py-scripts/tools/lf_header_template.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python3 -''' -NAME: - -PURPOSE: - - -EXAMPLE: - - -SETUP: - - -NOTES: - - -COPYRIGHT: -Copyright 2021 Candela Technologies Inc - -INCLUDE_IN_README -''' \ No newline at end of file diff --git a/py-scripts/update_dependencies.py b/py-scripts/update_dependencies.py index 63d2865c..38e299d2 100755 --- a/py-scripts/update_dependencies.py +++ b/py-scripts/update_dependencies.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # INCLUDE_IN_README ''' -NAME: update_dependencies.py +NAME: update_dependencies.py PURPOSE: Installs python3 script package dependencies @@ -18,10 +18,10 @@ def main(): packages_installed = [] packages_failed =[] for package in packages: - command = "pip3 install {} >/tmp/pip3-stdout 2>/tmp/pip3-stderr".format(package) + command = "pip3 install {} ".format(package) res = subprocess.call(command, shell = True) if res == 0: - #print("Package {} install SUCCESS Returned Value: {} ".format(package, res)) + print("Package {} install SUCCESS Returned Value: {} ".format(package, res)) packages_installed.append(package) else: print("Package {} install FAILED Returned Value: {} ".format(package, res)) @@ -30,8 +30,6 @@ def main(): print("Install Complete") print("Packages Installed Success: {}\n".format(packages_installed)) - if not packages_failed: - return print("Packages Failed (Some scripts may not need these packages): {}".format(packages_failed)) if __name__ == "__main__":