From ec4873be68f6c890014af88feaf4b603a0806b5e Mon Sep 17 00:00:00 2001 From: Dipendu Ghosh <37326319+dipendughosh@users.noreply.github.com> Date: Wed, 14 Aug 2024 17:54:36 +0530 Subject: [PATCH] Cyperf l47 support code to main (#1) * connect to Cyperf and fetch session_id working * port assignment done * Ethernet, IP and Vlan add working * Vlan working. REASTasV3 set ethernet, ip and vlan apis merged to one. * network_segment and ip_range maintained internally * TCP working * code cleanup * http added objective added tcp debug added * TCP actions/properties/parameters support aded * in sync with changed done in model "added headers, webpages and properties in http client and server. methods are modified as well" in model branch L47_model_support_cyperf * remove some attributes not supported at the moment * support multiple Eth range, multiple ip range * commit files used to publish * remove publish for now * add __init__.py * update author * update readme * bug fixes * fix issues * update publishing steps --- .github/ISSUE_TEMPLATE/bug_report.md | 23 + .github/ISSUE_TEMPLATE/feature_request.md | 20 + .github/workflows/publish.yml | 51 + .gitignore | 18 + CODE_OF_CONDUCT.md | 134 + do.py | 276 ++ readme.md | 131 +- requirements.txt | 17 + setup.py | 46 + snappi/snappi-1.6.2-py2.py3-none-any.whl | Bin 0 -> 396823 bytes snappi_cyperf/RESTasV3.py | 3074 +++++++++++++++++++++ snappi_cyperf/Test_l47.py | 149 + snappi_cyperf/__init__.py | 1 + snappi_cyperf/common.py | 41 + snappi_cyperf/cyperfapi.py | 397 +++ snappi_cyperf/exceptions.py | 70 + snappi_cyperf/hero.py | 161 ++ snappi_cyperf/hero_1.py | 161 ++ snappi_cyperf/hero_2.py | 165 ++ snappi_cyperf/http_config.py | 363 +++ snappi_cyperf/interface.py | 139 + snappi_cyperf/ixrestutils.py | 296 ++ snappi_cyperf/l47server.py | 108 + snappi_cyperf/logger.py | 30 + snappi_cyperf/objectiveandtimeline.py | 138 + snappi_cyperf/ports.py | 45 + snappi_cyperf/tcp.py | 74 + snappi_cyperf/timer.py | 16 + tests/Test_l47.py | 122 + 29 files changed, 6262 insertions(+), 4 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/workflows/publish.yml create mode 100644 .gitignore create mode 100644 CODE_OF_CONDUCT.md create mode 100644 do.py create mode 100644 requirements.txt create mode 100644 setup.py create mode 100644 snappi/snappi-1.6.2-py2.py3-none-any.whl create mode 100644 snappi_cyperf/RESTasV3.py create mode 100644 snappi_cyperf/Test_l47.py create mode 100644 snappi_cyperf/__init__.py create mode 100644 snappi_cyperf/common.py create mode 100644 snappi_cyperf/cyperfapi.py create mode 100644 snappi_cyperf/exceptions.py create mode 100644 snappi_cyperf/hero.py create mode 100644 snappi_cyperf/hero_1.py create mode 100644 snappi_cyperf/hero_2.py create mode 100644 snappi_cyperf/http_config.py create mode 100644 snappi_cyperf/interface.py create mode 100644 snappi_cyperf/ixrestutils.py create mode 100644 snappi_cyperf/l47server.py create mode 100644 snappi_cyperf/logger.py create mode 100644 snappi_cyperf/objectiveandtimeline.py create mode 100644 snappi_cyperf/ports.py create mode 100644 snappi_cyperf/tcp.py create mode 100644 snappi_cyperf/timer.py create mode 100644 tests/Test_l47.py diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..075c2c1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,23 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Version information** +The pypi version or branch of snappi-cyperf + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior. Prefer code snippets, pytest test cases. + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..cb561cf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a use case? Please describe.** +A clear and concise description of what the use case is. + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..f02ef7d --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,51 @@ +name: cicd + +on: [push] + +jobs: + build: + runs-on: ubuntu-20.04 + strategy: + max-parallel: 1 + matrix: + python-version: [3.9] + + steps: + - name: Checkout source + uses: actions/checkout@v2 + with: + ref: ${{ github.head_ref }} + submodules: recursive + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + rm -rf .env + python do.py setup + python do.py init + - name: Build distribution + run: | + python do.py dist + - name: Install package on clean env + run: | + rm -rf .env + python do.py setup + python do.py install + python do.py init + - name: Get package version + id: get_version + run: | + echo "::set-output name=version::v$(python do.py version)" + - name: Check tag for current version + uses: mukunku/tag-exists-action@v1.0.0 + id: check_tag + with: + tag: ${{ steps.get_version.outputs.version }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Publish package + if: github.ref == 'refs/heads/main' && steps.check_tag.outputs.exists == 'false' + run: | + PYPI_USERNAME=__token__ PYPI_PASSWORD=${{ secrets.PYPI_API_TOKEN }} python do.py release \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..260daa8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +__pycache__/ +.pytest_cache/ +.pytype/ +*.pyc + +.env/ +env/ +build/ +dist/ +*.egg-info/ + +*.log +*.pcap +*.cap +logs/ +scratch/ +.coverage +cov_report \ No newline at end of file diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..62c2974 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,134 @@ + +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +open-traffic-generator@googlegroups.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations + diff --git a/do.py b/do.py new file mode 100644 index 0000000..a4ca2b8 --- /dev/null +++ b/do.py @@ -0,0 +1,276 @@ +import fnmatch +import os +import re +import sys +import shutil +import subprocess + + +def setup(): + run( + [ + py() + " -m pip install --upgrade pip", + py() + " -m pip install --upgrade virtualenv", + py() + " -m virtualenv .env", + ] + ) + + +def init(): + run( + [ + py() + " -m pip install -r requirements.txt", + ] + ) + + +def lint(): + paths = [pkg()[0], "tests", "setup.py", "do.py"] + + run( + [ + py() + " -m black " + " ".join(paths), + py() + " -m flake8 " + " ".join(paths), + ] + ) + + +def test(): + coverage_threshold = 67 + # args = [ + # '--location="https://10.39.71.97:443"', + # ( + # '--ports="10.39.65.230;6;1 10.39.65.230;6;2 10.39.65.230;6;3' + # ' 10.39.65.230;6;4"' + # ), + # '--media="fiber"', + # "tests", + # '-m "not e2e and not l1_manual"', + # '--cov=./snappi_cyperf --cov-report term' + # ' --cov-report html:cov_report', + # ] + args = [ + "tests", + '-m "not e2e and not l1_manual and not uhd"', + "--cov=./snappi_cyperf --cov-report term" " --cov-report html:cov_report", + ] + run( + [ + py() + " -m pip install pytest-cov", + py() + " -m pytest -sv {}".format(" ".join(args)), + ] + ) + import re + + with open("./cov_report/index.html") as fp: + out = fp.read() + result = re.findall(r"data-ratio.*?[>](\d+)\b", out)[0] + if int(result) < coverage_threshold: + raise Exception( + "Coverage thresold[{0}] is NOT achieved[{1}]".format( + coverage_threshold, result + ) + ) + else: + print( + "Coverage thresold[{0}] is achieved[{1}]".format( + coverage_threshold, result + ) + ) + + +def dist(): + clean() + run( + [ + py() + " setup.py sdist bdist_wheel --universal", + ] + ) + print(os.listdir("dist")) + + +def install(): + wheel = "{}-{}-py2.py3-none-any.whl".format(*pkg()) + run(["{} -m pip install snappi/snappi-1.6.2-py2.py3-none-any.whl".format(py())]) + # run( + # [ + # "{} -m pip install --upgrade --force-reinstall {}[testing]".format( + # py(), os.path.join("dist", wheel) + # ), + # ] + # ) + + +def generate_checksum(file): + hash_sha256 = hashlib.sha256() + with open(file, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + hash_sha256.update(chunk) + return hash_sha256.hexdigest() + + +def generate_distribution_checksum(): + tar_name = "{}-{}.tar.gz".format(*pkg()) + tar_file = os.path.join("dist", tar_name) + tar_sha = os.path.join("dist", tar_name + ".sha.txt") + with open(tar_sha, "w") as f: + f.write(generate_checksum(tar_file)) + wheel_name = "{}-{}-py2.py3-none-any.whl".format(*pkg()) + wheel_file = os.path.join("dist", wheel_name) + wheel_sha = os.path.join("dist", wheel_name + ".sha.txt") + with open(wheel_sha, "w") as f: + f.write(generate_checksum(wheel_file)) + + +# addimg release + + +def release(): + run( + [ + py() + " -m pip install --upgrade twine", + "{} -m twine upload -u {} -p {} dist/*.whl dist/*.tar.gz".format( + py(), + os.environ["PYPI_USERNAME"], + os.environ["PYPI_PASSWORD"], + ), + ] + ) + + +def clean(): + """ + Removes filenames or dirnames matching provided patterns. + """ + pwd_patterns = [ + ".pytype", + "dist", + "build", + "*.egg-info", + ] + recursive_patterns = [ + ".pytest_cache", + ".coverage", + "__pycache__", + "*.pyc", + "*.log", + ] + + for pattern in pwd_patterns: + for path in pattern_find(".", pattern, recursive=False): + rm_path(path) + + for pattern in recursive_patterns: + for path in pattern_find(".", pattern, recursive=True): + rm_path(path) + + +def version(): + print(pkg()[-1]) + + +def pkg(): + """ + Returns name of python package in current directory and its version. + """ + try: + return pkg.pkg + except AttributeError: + with open("setup.py") as f: + out = f.read() + name = re.findall(r"pkg_name = \"(.+)\"", out)[0] + version = re.findall(r"version = \"(.+)\"", out)[0] + + pkg.pkg = (name, version) + return pkg.pkg + + +def rm_path(path): + """ + Removes a path if it exists. + """ + if os.path.exists(path): + if os.path.isdir(path): + shutil.rmtree(path) + else: + os.remove(path) + + +def pattern_find(src, pattern, recursive=True): + """ + Recursively searches for a dirname or filename matching given pattern and + returns all the matches. + """ + matches = [] + + if not recursive: + for name in os.listdir(src): + if fnmatch.fnmatch(name, pattern): + matches.append(os.path.join(src, name)) + return matches + + for dirpath, dirnames, filenames in os.walk(src): + for names in [dirnames, filenames]: + for name in names: + if fnmatch.fnmatch(name, pattern): + matches.append(os.path.join(dirpath, name)) + + return matches + + +def py(): + """ + Returns path to python executable to be used. + """ + try: + return py.path + except AttributeError: + py.path = os.path.join(".env", "bin", "python") + if not os.path.exists(py.path): + py.path = sys.executable + + # since some paths may contain spaces + py.path = '"' + py.path + '"' + return py.path + + +def run(commands): + """ + Executes a list of commands in a native shell and raises exception upon + failure. + """ + try: + for cmd in commands: + print(cmd) + if sys.platform != "win32": + cmd = cmd.encode("utf-8", errors="ignore") + subprocess.check_call(cmd, shell=True) + except Exception: + sys.exit(1) + + +def get_workflow_id(): + import requests + + cmd = ( + "https://api.github.com/repos/open-traffic-generator/snappi-cyperf/actions/runs" + ) + res = requests.get(cmd) + workflow_id = res.json()["workflow_runs"][0]["workflow_id"] + return workflow_id + + +def install_requests(path): + cmd = "{} -m pip install requests".format(path) + subprocess.check_call(cmd, shell=True) + + +def main(): + if len(sys.argv) >= 2: + globals()[sys.argv[1]](*sys.argv[2:]) + else: + print("usage: python do.py [args]") + + +if __name__ == "__main__": + main() diff --git a/readme.md b/readme.md index 1367c76..3a3c374 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,14 @@ # snappi extension for Cyperf +[![license](https://img.shields.io/badge/license-MIT-green.svg)](https://en.wikipedia.org/wiki/MIT_License) +[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active) +[![Build](https://github.com/open-traffic-generator/snappi-cyperf/workflows/Build/badge.svg)](https://github.com/open-traffic-generator/snappi-cyperf/actions) +[![pypi](https://img.shields.io/pypi/v/snappi_cyperf.svg)](https://pypi.org/project/snappi_cyperf) +[![python](https://img.shields.io/pypi/pyversions/snappi_cyperf.svg)](https://pypi.python.org/pypi/snappi_cyperf) +[![Total alerts](https://img.shields.io/lgtm/alerts/g/open-traffic-generator/snappi-cyperf.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/open-traffic-generator/snappi-cyperf/alerts/) +[![Language grade: Python](https://img.shields.io/lgtm/grade/python/g/open-traffic-generator/snappi-cyperf.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/open-traffic-generator/snappi-cyperf/context:python) +[![downloads](https://pepy.tech/badge/snappi-cyperf)](https://pepy.tech/project/snappi-cyperf) + This extension allows executing tests written using [snappi](https://github.com/open-traffic-generator/snappi) against Cyperf, (one of) Keysight's implementation of [Open Traffic Generator](https://github.com/open-traffic-generator/models/releases). @@ -14,12 +23,126 @@ python -m pip install --upgrade "snappi[cyperf]" ## Start scripting ```python -# TODO: add complete description and snippet +import sys + +""" +Configure a raw TCP flow with, +- tx port as source to rx port as destination +- frame count 10000, each of size 128 bytes +- transmit rate of 1000 packets per second +Validate, +- frames transmitted and received for configured flow is as expected +""" import snappi + # host is Cyperf API Server -api = snappi.api(location='https://localhost:8444', ext='cyperf') -# new config +api = snappi.api(location="https://localhost:443", ext="cyperf") config = api.config() -``` +# port location is agent-ip +tx = config.ports.port(name="tx", location="10.39.44.147")[-1] +rx = config.ports.port(name="rx", location="10.39.44.190")[-1] +# configure layer 1 properties +(d1, d2) = config.devices.device(name="d1").device(name="d2") +(e1,) = d1.ethernets.ethernet(name="d1.e1") +e1.connection.port_name = "tx" +e1.mac = "01:02:03:04:05:06" +e1.step = "00:00:00:00:00:01" +e1.count = 1 +e1.mtu = 1488 + +(e2,) = d2.ethernets.ethernet(name="d2.e2") +e2.connection.port_name = "rx" +e2.mac = "01:02:03:04:06:06" +e2.step = "00:00:00:00:00:01" +e2.count = 2 +e2.mtu = 1488 + +(vlan1,) = e1.vlans.vlan(name="vlan1") +vlan1.id = 1 +vlan1.priority = 1 +vlan1.tpid = "x8100" +vlan1.count = 1 +vlan1.step = 1 +vlan1.per_count = 1 + +(vlan2,) = e2.vlans.vlan(name="vlan2") +vlan2.id = 1 +vlan2.priority = 1 +vlan2.tpid = "x8100" +vlan2.count = 1 +vlan2.step = 1 +vlan2.per_count = 1 + +(ip1,) = e1.ipv4_addresses.ipv4(name="e1.ipv4") +ip1.address = "10.0.0.10" +ip1.gateway = "10.0.0.1" +ip1.step = "0.0.0.1" +ip1.count = 1 +ip1.prefix = 16 + +(ip2,) = e2.ipv4_addresses.ipv4(name="e2.ipv4") +ip2.address = "10.0.0.20" +ip2.gateway = "10.0.0.1" +ip2.step = "0.0.0.1" +ip2.count = 1 +ip2.prefix = 16 + +# TCP/UDP configs + +(t1,) = d1.tcps.tcp(name="Tcp1") +t1.ip_interface_name = ip1.name +t1.receive_buffer_size = 1111 +t1.transmit_buffer_size = 1112 +t1.retransmission_minimum_timeout = 100 +t1.retransmission_maximum_timeout = 1001 +t1.minimum_source_port = 100 +t1.maximum_source_port = 101 + +(t2,) = d2.tcps.tcp(name="Tcp2") +t2.ip_interface_name = ip2.name +t2.receive_buffer_size = 2222 +t2.transmit_buffer_size = 2221 +t2.retransmission_minimum_timeout = 200 +t2.retransmission_maximum_timeout = 2002 +t2.minimum_source_port = 200 +t2.maximum_source_port = 202 + +(http_1,) = d1.https.http(name="HTTP1") +http_1.profile = "Chrome" +http_1.version = "HTTP11" +http_1.connection_persistence = "ConnectionPersistenceStandard" +(http_client,) = http_1.clients.client() +http_client.cookie_reject_probability = False +http_client.max_persistent_requests = 1 + +(http_2,) = d2.https.http(name="HTTP2") +http_2.profile = "Apache" +http_2.version = "HTTP11" +http_2.connection_persistence = "ConnectionPersistenceEnabled" +(http_server,) = http_2.servers.server() + +(tp1,) = config.trafficprofile.trafficprofile() +(segment1, segment2) = tp1.segment.segment().segment() +segment1.name = "Linear segment1" +segment1.duration = 40 +segment2.name = "Linear segment2" +segment2.duration = 70 +tp1.timeline = [segment1.name, segment2.name] +tp1.objective_type = ["Connections per second", "Simulated users"] +tp1.objective_value = [100, 200] +(obj1, obj2) = tp1.objectives.objective().objective() + +print("In test before set_config") +response = api.set_config(config) +print("In test after set_config") +print(response) +api.close() + +cs = api.control_state() +cs.app.state = "start" # cs.app.state.START +response1 = api.set_control_state(cs) +print(response1) +cs.app.state = "stop" # cs.app.state.START +api.set_control_state(cs) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..65d4ec8 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,17 @@ +mock +ipaddr==2.2.0 +netaddr==0.8.0 +ipaddress==1.0.23 +flake8 +dpkt +requests +black; python_version > '3.6' +PyYAML +flask +urllib3 +simplejson +requests +tabulate +pandas +requests_toolbelt +timer \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..4cc76aa --- /dev/null +++ b/setup.py @@ -0,0 +1,46 @@ +""" +To build distribution: python setup.py sdist bdist_wheel --universal +""" + +import os +import setuptools + +pkg_name = "snappi_cyperf" +version = "0.0.1" + +# read long description from readme.md +base_dir = os.path.abspath(os.path.dirname(__file__)) +with open(os.path.join(base_dir, "readme.md")) as fd: + long_description = fd.read() +print(setuptools.find_packages()) +setuptools.setup( + name=pkg_name, + version=version, + description="The Snappi Cyperf Open Traffic Generator Python Package", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/open-traffic-generator/snappi-cyperf", + author="dipendughosh", + author_email="dipendu.ghosh@keysight.com", + license="MIT", + classifiers=[ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Topic :: Software Development :: Testing :: Traffic Generation", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 2.7", + "Programming Language :: Python :: 3", + ], + keywords="snappi cyperf testing open traffic generator automation", + include_package_data=True, + packages=setuptools.find_packages(), + python_requires=">=2.7, <4", + install_requires=["requests"], + extras_require={ + "testing": [ + "pytest", + "mock", + "dpkt==1.9.4", + ] + }, +) diff --git a/snappi/snappi-1.6.2-py2.py3-none-any.whl b/snappi/snappi-1.6.2-py2.py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..fa93814960efc730fed5a48b7da909af991d6bbf GIT binary patch literal 396823 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⋘%3{nij-k@+nsv^VzG#2d+HK=j#oFX)Qj=_%DU0T7S1iU`yo!OU&2VwE>11^B2tWn zm1xP20iQU&KIf8QAe5*0Gv|H&t~vTM=j{PM5Va)1y8|{Y;|H#iD;<&KyaCr?+FCi= z4A@Db1Ch)FnE)6c=ZyhdI0g|U4WDajn^P_QMWhtWO#-Gr8fOILNq?C*jl2I6id^Z+ z2uG-f9~%8}IIn5Pjnp}J6zKcZ{)UfJLql_y;Z35|DbCr*2fqlvn^~X6_lSIUOb~@u z66JDPXQqK)`HWEU4ocs?sEz~=vHyHv^vZ?o9ZSt75wC<*V?*RiNs{B*4us7$1M4(t zh^1O!b^El&Sn4W`JZ6+1#d!rXkW~g0jBRoARzqsv_2FUv{|$$u*y!#yL_oy9Y_qM$ z!@c7}My!$lU|`hDw;e`dj~#*-a(5?Ji%-pQD1uW3#S^dCF^pK#Fz+@VxiCFh=8+6b z4TjcBJf^{9fS<5Dh0i(FHyi6s9+T4y@HZ5KQrZaisnHD22a@^2mEvN1j}i+v#qb

)=b=Bnas<)A@4lpuqQ9zzxOw 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%0Dg(L^YKYBF!C!Vip{i`fv%e%Hm>KCXhBW1Q=ft zP^siO((WjV7o3ht?q&(@e|(3)l+%L(VK|1h@gWA9dqY&&5)o_Nvqa{f)F0^#RpMTp zX|nJ}OifE%=Yy?Q_R_a8nm#yB8Du5@1t{IdZ63s{kRYifm`|PwJ_^g2A~C6VzLxI0 z9~Yc!eW-o1e-5;S&~ewzXLoame5*}k9__e`q`pdM)OmykBL6!l$iLUGG~2>W96Q;Y zEKN+!l@|BTn>Qu#{2dz>b2{Xh`5>s2eH+0WgSbijUe(!w*E)&(A+>Pq_KCu2_JK0| zKwXrh!G@&-N8hF5(Ec(U`APDtbg?YcGp}??l98xifSF^y#h~r3%U)t^$hYG^g z`isO^bRLJ6A1|SX9W5fF^Q~S+sP(;>=AaU=!W99l6R^?Dri)c!6g2IV2~0_Jwm_Gs zpOa+!ZJ9niMyf4SU|ut5{<^i%B5tc;G+HS3gUKw2=e0MR@y#rvSf{A{i|hA*0DeDM zf8acv_ecw2$(g@2w`%Fg9qfa20^AKrHqJgeDvv4n+&OwU9DCy~*_Hf4 zHA1^XiIjMVjDyo*c*&C^V_ZP;Ra>%(9YK+)U*gVn{iG|lB0VOvWVS$>&uiWd^LJ4+ zmpPf2(b*SQl{GKYqddEV555qS_sZ=208iuNELEej0!%377Rc!5npmPLLyfKGyVLf1 zqE!;kDLI#JMOKH?a9?opbF*g&gK&by7s$64pMms&dRIShq|qFQgP2B<{bUaVfjA{| zPe$B1UZd246x`7vKGn4m=c}+v{#F&ak2-MjQezMZ#J=l0G$h16>*X3t zqeP}WApz{5Yl#3)i|>v4W5uAm_<#;4J#M6Jl5rk|GDB_>NuF)D2e{=~v1Lf50~(y6 zvW}2q+p?~mHvQa8(Y~}yfjVz(qNRe1F+2guB7vZ*2A&K{PT+*`FX1TJx+)ar+kZq- z@wd^5zS6Uj;fcPUj*mDcXCLa7#Z-pTbZF8U&CkE%lOk!U0p_O;e5r<$B>%?PK;@jr zHTmbAQXtEx1Qm%Dz6rg|JSuRi*s@*9Gj|YdV9w@urPGYmkW>Mjb>GoA=#`4k*?cv$2I|A&EW)k{~QGRCaJN}uhb0ryiM?>VLIv+ZvC4r1DxRG-B@vtD&fe{P*Cqj(J=l5SnRP8TsU~vI{ zmX2`mJd`osN4o#$K6TY;tpWE(yP$XHIRwV_*ZKB#( z0cuCQq?gB9xQK$djDtuFwUq5IYbB4J;_%0AFB@@>(gO0cJaP0Q*A@%MWgiVH$4{It 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 F{}&`P{M`Tm literal 0 HcmV?d00001 diff --git a/snappi_cyperf/RESTasV3.py b/snappi_cyperf/RESTasV3.py new file mode 100644 index 0000000..cfaab6b --- /dev/null +++ b/snappi_cyperf/RESTasV3.py @@ -0,0 +1,3074 @@ +import os +import io +import sys +import glob +import time +import urllib +import urllib3 +import requests +import simplejson as json +from zipfile import ZipFile +from datetime import datetime +from requests_toolbelt import MultipartEncoder + + +class RESTasV3: + + def __init__(self, ipAddress, username, password, client_id, verify=True): + print("In RESTasV3 init") + self.ipAddress = ipAddress + self.username = username + self.password = password + self.client_id = client_id + self.verify = verify + self.connect_to_mdw() + self.startTime = None + self.startingStartTime = None + self.configuringStartTime = None + self.startTrafficTime = None + self.stopTrafficTime = None + self.stopTime = None + self.configID = None + self.sessionID = None + self.config = None + self.app_list = None + self.strike_list = None + self.attack_list = None + self.testDuration = 60 + + def connect_to_mdw(self): + self.session = requests.Session() + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + self.session.verify = False + self.host = "https://{}".format(self.ipAddress) + self.cookie = self.get_automation_token() + self.headers = {"authorization": self.cookie} + + def __sendPost(self, url, payload, customHeaders=None, files=None, debug=True): + print("url:-", url) + expectedResponse = [200, 201, 202, 204] + print("POST at URL: {} with payload: {}".format(url, payload)) + payload = json.dumps(payload) if customHeaders is None else payload + response = self.session.post( + "{}{}".format(self.host, url), + headers=customHeaders if customHeaders else self.headers, + data=payload, + files=files, + verify=False, + ) + if debug: + print( + "POST response message: {}, response code: {}".format( + response.content, response.status_code + ) + ) + if response.status_code == 401: + print("Token has expired, resending request") + self.refresh_access_token() + response = self.session.post( + "{}{}".format(self.host, url), + headers=customHeaders if customHeaders else self.headers, + data=payload, + files=files, + verify=False, + ) + print( + "POST response message: {}, response code: {}".format( + response.content, response.status_code + ) + ) + if self.verify and response.status_code not in expectedResponse: + raise Exception( + "Unexpected response code. Actual: {} Expected: {}".format( + response.status_code, expectedResponse + ) + ) + + return response + + def __sendGet(self, url, expectedResponse, customHeaders=None, debug=True): + print("GET at URL: {}".format(url)) + response = self.session.get( + "{}{}".format(self.host, url), + headers=customHeaders if customHeaders else self.headers, + ) + if debug: + print( + "GET response message: {}, response code: {}".format( + response.content, response.status_code + ) + ) + if response.status_code == 401: + print("Token has expired, resending request") + self.refresh_access_token() + response = self.session.get( + "{}{}".format(self.host, url), + headers=customHeaders if customHeaders else self.headers, + ) + print( + "GET response message: {}, response code: {}".format( + response.content, response.status_code + ) + ) + if self.verify and response.status_code != expectedResponse: + raise Exception( + "Unexpected response code. Actual: {} Expected: {}".format( + response.status_code, expectedResponse + ) + ) + + return response + + def __sendPut(self, url, payload, customHeaders=None, debug=True): + print("PUT at URL: {} with payload: {}".format(url, payload)) + expectedResponse = [200, 204] + response = self.session.put( + "{}{}".format(self.host, url), + headers=customHeaders if customHeaders else self.headers, + data=json.dumps(payload), + ) + if debug: + print( + "PUT response message: {}, response code: {}".format( + response.content, response.status_code + ) + ) + if response.status_code == 401: + print("Token has expired, resending request") + self.refresh_access_token() + response = self.session.put( + "{}{}".format(self.host, url), + headers=customHeaders if customHeaders else self.headers, + data=json.dumps(payload), + ) + print( + "PUT response message: {}, response code: {}".format( + response.content, response.status_code + ) + ) + if self.verify and response.status_code not in expectedResponse: + raise Exception( + "Unexpected response code. Actual: {} Expected: {}".format( + response.status_code, expectedResponse + ) + ) + + return response + + def __sendPatch(self, url, payload, debug=True): + print("PATCH at URL: {} with payload: {}".format(url, payload)) + expectedResponse = [200, 204] + response = self.session.patch( + "{}{}".format(self.host, url), + headers=self.headers, + data=json.dumps(payload), + ) + if debug: + print( + "PATCH response message: {}, response code: {}".format( + response.content, response.status_code + ) + ) + if response.status_code == 401: + print("Token has expired, resending request") + self.refresh_access_token() + response = self.session.patch( + "{}{}".format(self.host, url), + headers=self.headers, + data=json.dumps(payload), + ) + print( + "PATCH response message: {}, response code: {}".format( + response.content, response.status_code + ) + ) + if self.verify and response.status_code not in expectedResponse: + raise Exception( + "Unexpected response code. Actual: {} Expected: {}".format( + response.status_code, expectedResponse + ) + ) + + return response + + def __sendDelete(self, url, headers=None, debug=True): + print("DELETE at URL: {}".format(url)) + expectedResponse = [200, 202, 204] + response = self.session.delete("%s%s" % (self.host, url), headers=headers) + if debug: + print( + "DELETE response message: {}, response code: {}".format( + response.content, response.status_code + ) + ) + if response.status_code == 401: + print("Token has expired, resending request") + self.refresh_access_token() + response = self.session.delete("%s%s" % (self.host, url), headers=headers) + print( + "DELETE response message: {}, response code: {}".format( + response.content, response.status_code + ) + ) + if self.verify and response.status_code not in expectedResponse: + raise Exception( + "Unexpected response code. Actual: {} Expected: {}".format( + response.status_code, expectedResponse + ) + ) + + return response + + def get_automation_token(self): + apiPath = "/auth/realms/keysight/protocol/openid-connect/token" + headers = {"content-type": "application/x-www-form-urlencoded"} + payload = { + "username": self.username, + "password": self.password, + "grant_type": "password", + "client_id": self.client_id, + } + + response = self.__sendPost(apiPath, payload, customHeaders=headers) + if self.verify: + if response.headers.get("content-type") == "application/json": + response = response.json() + print("Access Token: {}".format(response["access_token"])) + return response["access_token"] + else: + raise Exception("Fail to obtain authentication token") + return response + + def add_new_user(self, **kwargs): + """ + A method to add new users to keycloak + """ + apiPath = "/auth/admin/realms/keysight/users" + + user_credentials = { + "enabled": True, + "attributes": {}, + "groups": [], + "emailVerified": "", + "username": "luke_cywalker", + "email": "perfsaber@lightmail.com", + "firstName": "Luke", + "lastName": "CyWalker", + } + customHeaders = { + "Authorization": f"Bearer {self.cookie}", + "Content-Type": "application/json", + "Accept": "application/json", + } + bad_keys = [k for k in kwargs.keys() if k not in user_credentials] + if not bad_keys: + user_credentials.update(kwargs) + new_user = json.dumps(user_credentials) + response = self.__sendPost( + apiPath, payload=new_user, customHeaders=customHeaders + ) + print(response.text) + return response + + def __get_configured_users(self, start_point=0, max_no_of_users_in_resp=20): + apiPath = f"/auth/admin/realms/keysight/users?briefRepresentation=true&first={start_point}&max={max_no_of_users_in_resp}" + customHeaders = { + "Authorization": f"Bearer {self.cookie}", + "Content-Type": "application/json", + } + response = self.__sendGet(apiPath, 200, customHeaders=customHeaders).json() + return response + + def get_user_id_from_username(self, username): + configured_users = self.__get_configured_users() + for user in configured_users: + if user["username"] == username: + return user["id"] + else: + continue + raise f"{username} is not a configured user on this MDW" + + def change_user_role(self, username, user_role): + user_id = self.get_user_id_from_username(username) + apiPath = ( + f"/auth/admin/realms/keysight/users/{user_id}/role-mappings/realm/available" + ) + customHeaders = { + "Authorization": f"Bearer {self.cookie}", + "Content-Type": "application/json", + "Accept": "application/json", + } + user_roles = [ + "cyperf-admin", + "cyperf-user", + "uma_authorization", + "offline_access", + ] + if user_role not in user_roles: + raise f"The role {user_role} you are trying to assign does not exist" + available_user_roles = self.__sendGet( + apiPath, 200, customHeaders=customHeaders + ).json() + user_role_payload = [] + for index in range(0, len(available_user_roles)): + if available_user_roles[index]["name"] == user_role: + user_role_payload.append(available_user_roles[index]) + apiPath = f"/auth/admin/realms/keysight/users/{user_id}/role-mappings/realm" + new_role = json.dumps(user_role_payload) + response = self.__sendPost( + apiPath, payload=new_role, customHeaders=customHeaders + ) + return response + + def change_user_password(self, username, password): + user_id = self.get_user_id_from_username(username) + customHeaders = { + "Authorization": f"Bearer {self.cookie}", + "Content-Type": "application/json", + } + apiPath = f"/auth/admin/realms/keysight/users/{user_id}/reset-password" + payload = {"type": "password", "value": password, "temporary": False} + self.__sendPut(apiPath, payload=payload, customHeaders=customHeaders) + + def delete_user_by_username(self, username): + apiPath = "/auth/admin/realms/keysight/users" + configured_users = self.__get_configured_users() + user_id = "" + for user in configured_users: + if user["username"] == username: + user_id = user["id"] + customHeaders = { + "Authorization": f"Bearer {self.cookie}", + "Content-Type": "application/json", + "Accept": "application/json", + } + response = self.__sendDelete(apiPath + "/" + user_id, headers=customHeaders) + return response + + def get_cluster_info(self): + """ + This method can be used to get versions of all the charts available in the mdw. + E.g.: self.get_cluster_info()['ati-updates'] will return the ati version currently installed on the mdw machine + """ + apiPath = "/api/v2/deployment/helm/cluster/releases" + response = self.__sendGet(apiPath, 200).json() + charts = {} + for chart in response: + charts[chart["name"]] = chart["chartDeployment"]["chartVersion"] + return charts + + def refresh_access_token(self): + access_token = self.get_automation_token() + self.headers = {"authorization": access_token} + print("Authentication token refreshed!") + + def setup(self, config=None): + if config: + self.configID = self.import_config(config) + else: + self.configID = "appsec-two-arm-base" + self.sessionID = self.open_config() + self.config = self.get_session_config() + + def get_session(self, session_id): + apiPath = "/api/v2/sessions/{}".format(session_id) + response = self.__sendGet(apiPath, 200).json() + return response + + def create_session(self, configID): + apiPath = "/api/v2/sessions" + # payload = {} + self.configID = configID + response = self.__sendPost(apiPath, payload={"configUrl": self.configID}) + if response: + self.sessionID = response.json()[0]["id"] + print("create_session response - ", response) + return response + + def delete_session(self, session_id): + """ + Delete a session by its id + :param session_id: The id got from getSessions + """ + apiPath = "/api/v2/sessions/{}".format(session_id) + self.__sendDelete(apiPath, headers=self.headers) + + def delete_current_session(self): + """ + Delete the current session + return: None + """ + apiPath = "/api/v2/sessions/{}".format(self.sessionID) + self.__sendDelete(apiPath, headers=self.headers) + + def get_all_sessions(self): + apiPath = "/api/v2/sessions" + response = self.__sendGet(apiPath, 200).json() + return response + + def delete_all_sessions(self): + """ + Delete all the current sessions opened on the application + :return: None + """ + print("Deleting all sessions...") + session_list = self.get_all_sessions() + for i in range(0, len(session_list)): + try: + self.delete_session(session_list[i]["id"]) + except Exception as e: + print( + "{} could not be deleted because: {}".format( + session_list[i]["id"], e + ) + ) + pass + if len(self.get_all_sessions()) > 0: + raise Exception("Not all sessions could be deleted!") + else: + print("No sessions opened!") + + def get_test_details(self, session_id): + apiPath = "/api/v2/sessions/{}/test".format(session_id) + response = self.__sendGet(apiPath, 200).json() + return response + + def set_license_server(self, licenseServerIP): + apiPath = "/api/v2/license-servers" + self.__sendPost(apiPath, payload={"hostName": licenseServerIP}) + + def get_license_servers(self): + apiPath = "/api/v2/license-servers" + return self.__sendGet(apiPath, 200).json() + + def wait_event_success(self, apiPath, timeout): + counter = 1 + while timeout > 0: + response = self.__sendGet(apiPath, 200).json() + if response["state"] == "SUCCESS": + return response + else: + timeout -= counter + time.sleep(counter) + + def activate_license(self, activation_code, quantity=1, timeout=60): + apiPath = "/api/v2/licensing/operations/activate" + response = self.__sendPost( + apiPath, payload=[{"activationCode": activation_code, "quantity": quantity}] + ).json() + apiPath = "/api/v2/licensing/operations/activate/{}".format(response["id"]) + if not self.wait_event_success(apiPath, timeout): + raise TimeoutError( + "Failed to activate license. Timeout reached = {} seconds".format( + timeout + ) + ) + + def deactivate_license(self, activation_code, quantity=1, timeout=60): + apiPath = "/api/v2/licensing/operations/deactivate" + response = self.__sendPost( + apiPath, payload=[{"activationCode": activation_code, "quantity": quantity}] + ).json() + apiPath = "/api/v2/licensing/operations/deactivate/{}".format(response["id"]) + if ( + "The Activation Code : '{}' is not installed.".format(activation_code) + == self.__sendGet(apiPath, 200).json()["message"] + ): + print("License code {} is not installed".format(activation_code)) + elif not self.wait_event_success(apiPath, timeout): + raise TimeoutError( + "Failed to deactivate license. Timeout reached = {} seconds".format( + timeout + ) + ) + + def get_license_statistics(self, timeout=30): + apiPath = "/api/v2/licensing/operations/retrieve-counted-feature-stats" + response = self.__sendPost(apiPath, payload={}).json() + apiPath = ( + "/api/v2/licensing/operations/retrieve-counted-feature-stats/{}".format( + response["id"] + ) + ) + if not self.wait_event_success(apiPath, timeout): + raise TimeoutError( + "Failed to obtain license stats. Timeout reached = {} seconds".format( + timeout + ) + ) + apiPath = "/api/v2/licensing/operations/retrieve-counted-feature-stats/{}/result".format( + response["id"] + ) + response = self.__sendGet(apiPath, 200).json() + return response + + def nats_update_route(self, nats_address): + apiPath = "/api/v2/brokers" + self.__sendPost(apiPath, payload={"host": nats_address}) + + def import_config(self, config): + apiPath = "/api/v2/configs" + if config.endswith(".json"): + config = json.loads(open(config, "r").read()) + response = self.__sendPost(apiPath, config) + elif config.endswith(".zip"): + zip_file_path = {"archive": (config, open(config, "rb"), "application/zip")} + response = self.__sendPost( + apiPath, None, customHeaders=self.headers, files=zip_file_path + ) + else: + raise Exception("Config type not supported. Requires zip or json.") + if response: + print( + "Config successfully imported, config ID: {}".format( + response.json()[0]["id"] + ) + ) + return response.json()[0]["id"] + else: + raise Exception("Failed to import test config") + + def export_config(self, export_path=None): + config_id = self.configID + apiPath = "/api/v2/configs/{}?include=all&resolveDependencies=true".format( + config_id + ) + customHeaders = self.headers + customHeaders["Accept"] = "application/zip" + response = self.__sendGet(apiPath, 200, customHeaders=customHeaders) + + file_name = response.headers.get("content-disposition").split("=")[1].strip('"') + + if export_path: + file_name = os.path.join(export_path, file_name) + print("Export path/file: {}".format(file_name)) + with open(file_name, "wb") as archive: + archive.write(response.content) + return file_name + + def export_config_by_name(self, export_path=None, config_name=None): + config_id = self.get_config_id(config_name) + apiPath = "/api/v2/configs/{}?include=all&resolveDependencies=true".format( + config_id + ) + customHeaders = self.headers + customHeaders["Accept"] = "application/zip" + response = self.__sendGet(apiPath, 200, customHeaders=customHeaders) + + file_name = response.headers.get("content-disposition").split("=")[1].strip('"') + + if export_path: + file_name = os.path.join(export_path, file_name) + print("Export path/file: {}".format(file_name)) + with open(file_name, "wb") as archive: + archive.write(response.content) + return file_name + + def open_config(self): + apiPath = "/api/v2/sessions" + response = self.__sendPost(apiPath, payload={"configUrl": self.configID}) + if response: + print( + "Config successfully opened, session ID: {}".format( + response.json()[0]["id"] + ) + ) + return response.json()[0]["id"] + + def get_session_config(self, sessionId=None): + sessionId = sessionId if sessionId else self.sessionID + apiPath = "/api/v2/sessions/{}/config?include=all".format(sessionId) + return self.__sendGet(apiPath, 200, debug=False).json() + + def delete_config(self, config_id): + """ + Delete a config after you've specified its id + :param config_id: The id of the config + :return: None + """ + apiPath = "/api/v2/configs/{}".format(config_id) + self.__sendDelete(apiPath, self.headers) + + def delete_config_by_name(self, config_name=None): + config_id = self.get_config_id(config_name) + apiPath = "/api/v2/configs/{}".format(config_id) + self.__sendDelete(apiPath, self.headers) + + def add_network_segment(self): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment".format( + self.sessionID + ) + self.__sendPost(apiPath, {}) + + def wait_agents_connect(self, agents_nr=3, timeout=300): + response = [] + init_timeout = timeout + print("Waiting for agents to connect to the CyPerf controller...") + while timeout > 0: + response = self.get_agents() + if len(response) >= agents_nr: + print( + "There are {} agents connected to the CyPerf controller".format( + len(response) + ) + ) + return True + else: + time.sleep(10) + timeout -= 10 + else: + raise Exception( + "Expected {} agents connected after {}s. Got only {}.".format( + agents_nr, init_timeout, len(response) + ) + ) + + def get_agents(self): + apiPath = "/api/v2/agents" + return self.__sendGet(apiPath, 200).json() + + def check_agents_status(self, timeout=60): + waiting_time = 0 + print("Waiting for agents to be available") + while True: + agents_status = [agent["Status"] for agent in self.get_agents()] + if all(status == "STOPPED" for status in agents_status): + if waiting_time <= timeout: + print("Agents are available") + return True + else: + raise Exception( + "The agents were not available for the next test in {}s, but after {}s".format( + timeout, waiting_time + ) + ) + time.sleep(10) + waiting_time += 10 + + def get_agents_ids(self, agentIPs=None, wait=None): + if wait: + self.wait_agents_connect() + agentsIDs = list() + response = self.get_agents() + print("Found {} agents".format(len(response))) + if type(agentIPs) is str: + agentIPs = [agentIPs] + for agentIP in agentIPs: + for agent in response: + if agent["IP"] == agentIP: + print("agent_IP: {}, agent_ID: {}".format(agent["IP"], agent["id"])) + agentsIDs.append(agent["id"]) + break + return agentsIDs + + def get_agents_ips(self, wait=None): + if wait: + self.wait_agents_connect() + agentsIPs = list() + response = self.get_agents() + print("Found {} agents".format(len(response))) + # fixme B2B only - ClientAgent is excluded in AWS scenario + for agent in response: + agentsIPs.append(agent["IP"]) + print("Agents IP List: {}".format(agentsIPs)) + return agentsIPs + + def assign_agents(self): + agents_ips = self.get_agents_ips() + self.assign_agents_by_ip(agents_ips=agents_ips[0], network_segment=1) + self.assign_agents_by_ip(agents_ips=agents_ips[1], network_segment=2) + + def assign_agents_by_ip(self, agents_ips, network_segment): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/agentAssignments".format( + self.sessionID, network_segment + ) + payload = {"ByID": [], "ByTag": []} + agents_ids = self.get_agents_ids(agentIPs=agents_ips) + for agent_id in agents_ids: + payload["ByID"].append({"agentId": agent_id}) + self.__sendPatch(apiPath, payload) + + def test_warmup_value(self, value): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/ObjectivesAndTimeline/AdvancedSettings".format( + self.sessionID + ) + payload = {"WarmUpPeriod": int(value)} + self.__sendPatch(apiPath, payload) + + def assign_agents_by_tag(self, agents_tags, network_segment): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/agentAssignments".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"ByID": [], "ByTag": [agents_tags]}) + + def set_traffic_capture( + self, + agents_ips, + network_segment, + is_enabled=True, + capture_latest_packets=False, + max_capture_size=104857600, + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/agentAssignments".format( + self.sessionID, network_segment + ) + payload = {"ByID": []} + capture_settings = { + "captureEnabled": is_enabled, + "captureLatestPackets": capture_latest_packets, + "maxCaptureSize": max_capture_size, + } + agents_ids = self.get_agents_ids(agentIPs=agents_ips) + for agent_id in agents_ids: + payload["ByID"].append( + {"agentId": agent_id, "captureSettings": capture_settings} + ) + self.__sendPatch(apiPath, payload) + + def get_capture_files(self, captureLocation, exportTimeout=180): + self.get_result_ended() + test_id = self.get_test_id() + apiPath = "/api/v2/results/{}/operations/generate-results".format(test_id) + response = self.__sendPost(apiPath, None).json() + apiPath = response["url"][len(self.host) :] + response = self.wait_event_success(apiPath, timeout=exportTimeout) + if not response: + raise TimeoutError( + "Failed to download Captures. Timeout reached = {} seconds".format( + exportTimeout + ) + ) + apiPath = response["resultUrl"] + response = self.__sendGet(apiPath, 200, debug=False) + zf = ZipFile(io.BytesIO(response.content), "r") + zf.extractall(captureLocation) + for arh in glob.iglob(os.path.join(captureLocation, "*.zip")): + files = os.path.splitext(os.path.basename(arh))[0] + zf = ZipFile(arh) + zf.extractall(path=os.path.join(captureLocation, "pcaps", files)) + return response + + def add_dut(self): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment".format( + self.sessionID + ) + response = self.__sendPost(apiPath, payload={}).json() + return response + + def delete_dut(self, network_segment): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}".format( + self.sessionID, network_segment + ) + self.__sendDelete(apiPath, self.headers) + + def set_dut(self, active=True, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"active": active}) + + def check_if_dut_is_active(self, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}".format( + self.sessionID, network_segment + ) + response = self.__sendGet(apiPath, 200).json() + return response["active"] + + def set_dut_host(self, host, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"host": host}) + + def set_active_dut_configure_host(self, hostname, active=True, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"active": active, "ServerDUTHost": hostname}) + + def set_client_http_proxy(self, host, client_port, connect_mode, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"active": True}) + self.__sendPatch(apiPath, payload={"ConfigSettings": "ADVANCED_MODE"}) + self.__sendPatch(apiPath, payload={"ClientDUTActive": True}) + self.__sendPatch(apiPath, payload={"ClientDUTHost": host}) + self.__sendPatch(apiPath, payload={"ClientDUTPort": int(client_port)}) + self.__sendPatch(apiPath, payload={"HttpForwardProxyMode": connect_mode}) + self.__sendPatch(apiPath, payload={"ServerDUTActive": False}) + + def set_http_health_check(self, enabled=True, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/HTTPHealthCheck".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"Enabled": enabled}) + + def set_http_health_check_port(self, port, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/HTTPHealthCheck".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"Port": port}) + + def set_http_health_check_url(self, target_url, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/HTTPHealthCheck".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath + "/Params/1", payload={"Value": target_url}) + + def set_http_health_check_payload(self, payload_file, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/HTTPHealthCheck".format( + self.sessionID, network_segment + ) + if isinstance(payload_file, float): + self.__sendPatch(apiPath + "/Params/2", payload={"Value": payload_file}) + else: + self.set_custom_payload(apiPath + "/Params/2", payload_file) + + def set_http_health_check_version(self, http_version, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/HTTPHealthCheck".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath + "/Params/3", payload={"Value": http_version}) + + def set_https_health_check(self, enabled=True, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/HTTPSHealthCheck".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"Enabled": enabled}) + + def set_https_health_check_port(self, port, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/HTTPSHealthCheck".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"Port": port}) + + def set_https_health_check_url(self, target_url, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/HTTPSHealthCheck".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath + "/Params/1", payload={"Value": target_url}) + + def set_https_health_check_payload(self, payload_file, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/HTTPSHealthCheck".format( + self.sessionID, network_segment + ) + if isinstance(payload_file, float): + self.__sendPatch(apiPath + "/Params/2", payload={"Value": payload_file}) + else: + self.set_custom_payload(apiPath + "/Params/2", payload_file) + + def set_https_health_check_version(self, https_version, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/HTTPHealthCheck".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath + "/Params/3", payload={"Value": https_version}) + + def set_tcp_health_check(self, enabled=True, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/TCPHealthCheck".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"Enabled": enabled}) + + def set_tcp_health_check_port(self, port, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/{}/TCPHealthCheck".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"Port": port}) + + def set_client_recieve_buffer_size_attack_profile(self, value): + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/1/TrafficSettings/DefaultTransportProfile/ClientTcpProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"RxBuffer": value}) + + def set_client_tcp_profile(self, tcp_profile): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ClientTcpProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, tcp_profile) + + def set_server_tcp_profile(self, tcp_profile): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ServerTcpProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, tcp_profile) + + def get_client_tcp_profile(self): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ClientTcpProfile".format( + self.sessionID + ) + response = self.__sendGet(apiPath, 200).json() + return response + + def get_server_tcp_profile(self): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ServerTcpProfile".format( + self.sessionID + ) + response = self.__sendGet(apiPath, 200).json() + return response + + def set_client_http_profile(self, http_profile): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ClientHTTPProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, http_profile) + + def set_server_http_profile(self, http_profile): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ServerHTTPProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, http_profile) + + def get_client_http_profile(self): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ClientHTTPProfile".format( + self.sessionID + ) + response = self.__sendGet(apiPath, 200).json() + return response + + def get_server_http_profile(self): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ServerHTTPProfile".format( + self.sessionID + ) + response = self.__sendGet(apiPath, 200).json() + return response + + def get_config_config(self): + apiPath = ( + "/api/v2/sessions/{}/config/config/TrafficProfiles/1/Applications".format( + self.sessionID + ) + ) + response = self.__sendGet(apiPath, 200).json() + return response + + def set_client_transmit_buffer_size_attack_profile(self, value): + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/1/TrafficSettings/DefaultTransportProfile/ClientTcpProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"TxBuffer": value}) + + def set_client_recieve_buffer_size_traffic_profile(self, value): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ClientTcpProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"RxBuffer": value}) + + def set_client_transmit_buffer_size_traffic_profile(self, value): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ClientTcpProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"TxBuffer": value}) + + def set_server_recieve_buffer_size_attack_profile(self, value): + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/1/TrafficSettings/DefaultTransportProfile/ServerTcpProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"RxBuffer": value}) + + def set_server_transmit_buffer_size_attack_profile(self, value): + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/1/TrafficSettings/DefaultTransportProfile/ServerTcpProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"TxBuffer": value}) + + def set_server_recieve_buffer_size_traffic_profile(self, value): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ServerTcpProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"RxBuffer": value}) + + def set_server_transmit_buffer_size_traffic_profile(self, value): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/TrafficSettings/DefaultTransportProfile/ServerTcpProfile".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"TxBuffer": value}) + + def set_ip_network_segment(self, active=True, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"active": active}) + + def set_network_tags(self, tags="Client", network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"networkTags": [tags]}) + + def set_application_client_network_tags(self, tags, app_nr): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/Applications/{}/operations/modify-tags-recursively".format( + self.sessionID, app_nr + ) + self.__sendPost( + apiPath, payload={"SelectTags": True, "ClientNetworkTags": [tags]} + ) + + def remove_application_client_network_tags(self, tags, app_nr): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/Applications/{}/operations/modify-tags-recursively".format( + self.sessionID, app_nr + ) + self.__sendPost( + apiPath, payload={"SelectTags": False, "ClientNetworkTags": [tags]} + ) + + def set_network_min_agents(self, min_agents=1, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"minAgents": min_agents}) + + def add_eth_range(self, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment".format( + self.sessionID + ) + response = self.__sendPost(apiPath, payload={}).json() + return response[-1]["id"] + + def add_ip_range(self, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges".format( + self.sessionID, network_segment + ) + response = self.__sendPost(apiPath, payload={}).json() + return response[-1]["id"] + + def delete_ip_range(self, network_segment=1, ip_range=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendDelete(apiPath, self.headers) + + def set_ip_range_automatic_ip( + self, + ip_auto=True, + network_segment=1, + ip_range=1, + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"IpAuto": ip_auto}) + + def set_ip_range_ip_start( + self, + ip_start, + network_segment=1, + ip_range=1, + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"IpStart": ip_start}) + self.__sendPatch(apiPath, payload={"IpAuto": False}) + + def set_ip_range_ip_start_if_enabled( + self, + ip_start, + network_segment=1, + ip_range=1, + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"IpStart": ip_start}) + + def set_ip_range_ip_increment( + self, ip_increment="0.0.0.1", network_segment=1, ip_range=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"IpIncr": ip_increment}) + + def set_ip_range_ip_count(self, count=1, network_segment=1, ip_range=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"Count": count}) + + def set_ip_range_max_count_per_agent( + self, max_count_per_agent=1, network_segment=1, ip_range=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"maxCountPerAgent": max_count_per_agent}) + + def set_ip_range_automatic_netmask( + self, netmask_auto=True, network_segment=1, ip_range=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"NetMaskAuto": netmask_auto}) + + def set_ip_range_netmask(self, netmask=16, network_segment=1, ip_range=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"NetMask": netmask}) + + def set_ip_range_automatic_gateway( + self, gateway_auto=True, network_segment=1, ip_range=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"GwAuto": gateway_auto}) + + def set_ip_range_gateway(self, gateway="10.0.0.1", network_segment=1, ip_range=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"GwStart": gateway}) + self.__sendPatch(apiPath, payload={"GwAuto": False}) + + def set_ip_range_gateway_if_enabled( + self, gateway="10.0.0.1", network_segment=1, ip_range=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"GwStart": gateway}) + + def set_ip_range_network_tags(self, tags, network_segment=1, ip_range=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"networkTags": [tags]}) + + def set_ip_range_mss(self, mss=1460, network_segment=1, ip_range=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch(apiPath, payload={"Mss": mss}) + + def set_eth_range( + self, + payload, + network_segment=1, + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/EthRange".format( + self.sessionID, network_segment + ) + self.__sendPatch( + apiPath, + payload, + ) + + def get_eth_range( + self, + network_segment=1, + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}".format( + self.sessionID, network_segment + ) + response = self.__sendGet(apiPath, 200).json() + return response + + def set_ip_range( + self, + payload, + network_segment=1, + ip_range=1, + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch( + apiPath, + payload, + ) + + def set_ip_range_innervlan_range( + self, + payload, + network_segment=1, + ip_range=1, + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}/InnerVlanRange".format( + self.sessionID, network_segment, ip_range + ) + self.__sendPatch( + apiPath, + payload, + ) + + def set_eth_range_mac_auto_false(self, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/EthRange".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"MacAuto": False}) + + def set_eth_range_mac_start(self, mac_start, network_segment=1): + self.set_eth_range_mac_auto_false(network_segment) + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/EthRange".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"MacStart": mac_start}) + + def set_eth_range_mac_increment(self, mac_increment, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/EthRange".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"MacIncr": mac_increment}) + + def set_eth_range_one_mac_per_ip_false(self, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/EthRange".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"OneMacPerIP": False}) + + def set_eth_range_max_mac_count(self, count, network_segment=1): + self.set_eth_range_one_mac_per_ip_false(network_segment) + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/EthRange".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"Count": count}) + + def set_eth_range_max_mac_count_per_agent( + self, max_count_per_agent, network_segment=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/EthRange".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"maxCountPerAgent": max_count_per_agent}) + + def set_dns_resolver(self, name_server, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/DNSResolver".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"nameServers": [{"name": name_server}]}) + + def set_dns_resolver_cache_timeout(self, timeout=0, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/DNSResolver".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"cacheTimeout": timeout}) + + def set_dut_connections(self, connections, network_segment=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}".format( + self.sessionID, network_segment + ) + self.__sendPatch(apiPath, payload={"DUTConnections": connections}) + + def set_profile_duration(self, profile_type, value): + apiPath = "/api/v2/sessions/{}/config/config/{}/1/ObjectivesAndTimeline/TimelineSegments/1".format( + self.sessionID, profile_type + ) + self.__sendPatch(apiPath, payload={"Duration": value}) + + def get_iteration_count_info(self, ap_id=1): + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/{}/ObjectivesAndTimeline/TimelineSegments/1".format( + self.sessionID, ap_id + ) + config_type = self.get_config_type() + if config_type["traffic"]: + print("Parameter not available in traffic profile") + if config_type["attack"]: + response = self.__sendGet(apiPath, 200).json() + return response["IterationCount"] + + def get_profile_duration(self, profile_type): + apiPath = "/api/v2/sessions/{}/config/config/{}/1/ObjectivesAndTimeline/TimelineSegments/1".format( + self.sessionID, profile_type + ) + response = self.__sendGet(apiPath, 200).json() + return response["Duration"] + + def set_test_duration(self, value): + config_type = self.get_config_type() + if config_type["traffic"]: + self.set_profile_duration(profile_type="TrafficProfiles", value=int(value)) + if config_type["attack"]: + self.set_profile_duration(profile_type="AttackProfiles", value=int(value)) + self.testDuration = int(value) + + def read_test_duration(self): + TrafficProfilesDuration = 0 + AttackProfilesDuration = 0 + config_type = self.get_config_type() + if config_type["traffic"]: + TrafficProfilesDuration = self.get_profile_duration( + profile_type="TrafficProfiles" + ) + if config_type["attack"]: + AttackProfilesDuration = self.get_profile_duration( + profile_type="AttackProfiles" + ) + self.testDuration = max(TrafficProfilesDuration, AttackProfilesDuration) + + def send_modified_config(self): + apiPath = "/api/v2/sessions/{}/config".format(self.sessionID) + self.__sendPut(apiPath, self.config) + + def get_CPUCoresNR(self): + agent_info = self.get_agents() + l = [i["cpuInfo"] for i in agent_info] + count = list(map(len, l)) + return count[0] + + def get_CC_min_value(self, configured_cc_value, agent_cpu_cores): + favoured_sessions_no = 1 # static value + global_cc_min_value = 0 + app_info = {} + config = self.get_session_config() + traffic_profiles = config["Config"]["TrafficProfiles"][0]["Applications"] + total_weight = sum(app["ObjectiveWeight"] for app in traffic_profiles) + for i in range(len(config["Config"]["TrafficProfiles"][0]["Applications"])): + app_info[i] = { + "weight": config["Config"]["TrafficProfiles"][0]["Applications"][i][ + "ObjectiveWeight" + ], + "connections_no": len( + config["Config"]["TrafficProfiles"][0]["Applications"][i][ + "Connections" + ] + ), + } + for app_no, app_details in app_info.items(): + individual_app_cc_value = configured_cc_value * ( + app_details["weight"] / total_weight + ) + individual_app_cc_min_value = min( + individual_app_cc_value + - 2 * app_details["connections_no"] * agent_cpu_cores, + individual_app_cc_value + - min( + max(0.1 * individual_app_cc_value, agent_cpu_cores), + 40 * agent_cpu_cores, + ), + ) + min_alowed_cc_value = ( + app_details["connections_no"] * favoured_sessions_no + + app_details["connections_no"] + ) * agent_cpu_cores + global_cc_min_value += int( + max(individual_app_cc_min_value, min_alowed_cc_value) + ) + return global_cc_min_value + + def get_config_type(self): + self.config = self.get_session_config() + config_type = { + "traffic": False, + "traffic_profiles": [], + "tls_applications": [], + "tp_primary_obj": None, + "primary_obj_adv_time_params": [], + "tp_secondary_obj": None, + "tp_ssl": False, + "attack": False, + "attack_profiles": [], + "tls_attacks": [], + "att_obj": False, + "at_ssl": False, + "dut": False, + "tunnel_count_per_outer_ip": None, + "redirect_info": {}, + "ipsec": None, + "CPUCoresNr": self.get_CPUCoresNR(), + "test_duration": self.testDuration, + } + if len(self.config["Config"]["TrafficProfiles"]) > 0: + config_type["traffic"] = ( + True if self.config["Config"]["TrafficProfiles"][0]["Active"] else False + ) + tp_profiles = self.config["Config"]["TrafficProfiles"][0] + redirect_info = {} + for application in tp_profiles["Applications"]: + if application["ProtocolID"] not in config_type["traffic_profiles"]: + ###TODO: THIS IS A PROVISORY WORKAROUND BECAUSE CONFIG DOES NOT HOLD INFORMATION OF ENABLED APPS + try: + if application["Active"] == True: + config_type["traffic_profiles"].append( + application["ProtocolID"] + ) + if ( + application["ClientTLSProfile"]["tls12Enabled"] + or application["ClientTLSProfile"]["tls13Enabled"] + ): + config_type["tls_applications"].append( + application["ProtocolID"] + ) + except KeyError: + config_type["traffic_profiles"].append( + application["ProtocolID"] + ) + if ( + application["ClientTLSProfile"]["tls12Enabled"] + or application["ClientTLSProfile"]["tls13Enabled"] + ): + config_type["tls_applications"].append( + application["ProtocolID"] + ) + if application["ProtocolID"] == "HTTP": + for param in application["Params"]: + if param["Name"] == "Follow HTTP Redirects": + redirect_info[application["Name"]] = param["Value"] + config_type["redirect_info"] = redirect_info + objectives = tp_profiles["ObjectivesAndTimeline"] + objective_dm = { + "type": objectives["PrimaryObjective"]["Type"], + "unit": objectives["TimelineSegments"][0]["PrimaryObjectiveUnit"], + "value": objectives["TimelineSegments"][0]["PrimaryObjectiveValue"], + "steady_step_duration": objectives["TimelineSegments"][0]["Duration"], + } + if objectives["PrimaryObjective"]["Type"] == "Concurrent connections": + objective_dm["concurrent_connections_min"] = self.get_CC_min_value( + objectives["TimelineSegments"][0]["PrimaryObjectiveValue"], + config_type["CPUCoresNr"], + ) + config_type["tp_primary_obj"] = objective_dm + advance_timeline_params = [None, None] + if objectives["PrimaryObjective"]["Timeline"][0]["Enabled"]: + step_ramp_up = { + "Duration": objectives["PrimaryObjective"]["Timeline"][0][ + "Duration" + ], + "NumberOfSteps": objectives["PrimaryObjective"]["Timeline"][0][ + "NumberOfSteps" + ], + } + advance_timeline_params[0] = step_ramp_up + if objectives["PrimaryObjective"]["Timeline"][2]["Enabled"]: + step_ramp_down = { + "Duration": objectives["PrimaryObjective"]["Timeline"][2][ + "Duration" + ], + "NumberOfSteps": objectives["PrimaryObjective"]["Timeline"][2][ + "NumberOfSteps" + ], + } + advance_timeline_params[1] = step_ramp_down + config_type["primary_objective_adv_time_params"] = advance_timeline_params + if ( + len(objectives["TimelineSegments"][0]["SecondaryObjectiveValues"]) > 0 + and len(objectives["SecondaryObjectives"]) > 0 + ): + objective_dm = { + "type": objectives["SecondaryObjectives"][0]["Type"], + "unit": objectives["TimelineSegments"][0][ + "SecondaryObjectiveValues" + ][0]["Unit"], + "value": objectives["TimelineSegments"][0][ + "SecondaryObjectiveValues" + ][0]["Value"], + } + if ( + objectives["SecondaryObjectives"][0]["Type"] + == "Concurrent connections" + ): + objective_dm["concurrent_connections_min"] = self.get_CC_min_value( + objectives["TimelineSegments"][0]["SecondaryObjectiveValues"][ + 0 + ]["Value"], + config_type["CPUCoresNr"], + ) + config_type["tp_secondary_obj"] = objective_dm + if tp_profiles["TrafficSettings"]["DefaultTransportProfile"][ + "ClientTLSProfile" + ]["version"]: + config_type["tp_ssl"] = True + + if len(self.config["Config"]["AttackProfiles"]) > 0: + config_type["attack"] = ( + True if self.config["Config"]["AttackProfiles"][0]["Active"] else False + ) + at_profiles = self.config["Config"]["AttackProfiles"][0] + for attack in at_profiles["Attacks"]: + if attack["ProtocolID"] not in config_type["attack_profiles"]: + ###TODO: THIS IS A PROVISORY WORKAROUND BECAUSE CONFIG DOES NOT HOLD INFORMATION OF ENABLED ATTACKS + try: + if attack["Active"] == True: + config_type["attack_profiles"].append(attack["ProtocolID"]) + if ( + attack["ClientTLSProfile"]["tls12Enabled"] + or attack["ClientTLSProfile"]["tls13Enabled"] + ): + config_type["tls_attacks"].append(attack["ProtocolID"]) + except KeyError: + config_type["attack_profiles"].append(attack["ProtocolID"]) + if ( + attack["ClientTLSProfile"]["tls12Enabled"] + or attack["ClientTLSProfile"]["tls13Enabled"] + ): + config_type["tls_attacks"].append(attack["ProtocolID"]) + objective_dm = { + "attack_rate": at_profiles["ObjectivesAndTimeline"]["TimelineSegments"][ + 0 + ]["AttackRate"], + "max_concurrent_attack": at_profiles["ObjectivesAndTimeline"][ + "TimelineSegments" + ][0]["MaxConcurrentAttack"], + } + config_type["att_obj"] = objective_dm + if at_profiles["TrafficSettings"]["DefaultTransportProfile"][ + "ClientTLSProfile" + ]["version"]: + config_type["tp_ssl"] = True + + if self.config["Config"]["NetworkProfiles"][0]["DUTNetworkSegment"][0][ + "active" + ]: + config_type["dut"] = True + + tunnel_stacks = self.config["Config"]["NetworkProfiles"][0]["IPNetworkSegment"][ + 0 + ]["TunnelStacks"] + if len(tunnel_stacks) > 0: + config_type["tunnel_count_per_outer_ip"] = tunnel_stacks[0]["TunnelRange"][ + "TunnelCountPerOuterIP" + ] + + ipsec_stacks = self.config["Config"]["NetworkProfiles"][0]["IPNetworkSegment"][ + 0 + ]["IPSecStacks"] + if len(ipsec_stacks) > 0: + config_type["ipsec"] = { + "host_count_per_tunnel": ipsec_stacks[0]["EmulatedSubConfig"][ + "HostCountPerTunnel" + ], + "outer_ip_count": ipsec_stacks[0]["OuterIPRange"]["Count"], + "rekey_margin": ipsec_stacks[0]["RekeyMargin"], + "lifetime_phase_1": ipsec_stacks[0]["IPSecRange"]["IKEPhase1Config"][ + "Lifetime" + ], + "lifetime_phase_2": ipsec_stacks[0]["IPSecRange"]["IKEPhase2Config"][ + "Lifetime" + ], + } + return config_type + + def start_test(self, initializationTimeout=60): + apiPath = "/api/v2/sessions/{}/test-run/operations/start".format(self.sessionID) + response = self.__sendPost(apiPath, payload={}).json() + self.startTime = self.__getEpochTime() + self.read_test_duration() + print("Waiting for the test to start...") + response = self.get_test_status() + actual_duration = 0 + counter = 1 + while actual_duration < initializationTimeout: + response = self.get_test_status() + if response["status"] == "STARTING" and not self.startingStartTime: + self.startingStartTime = self.__getEpochTime() + if response["status"] == "CONFIGURING" and not self.configuringStartTime: + self.configuringStartTime = self.__getEpochTime() + if response["status"] == "STARTED": + if not self.startTrafficTime: + self.startTrafficTime = self.__getEpochTime() + return self.startTrafficTime + if response["status"] == "ERROR": + raise Exception( + "Error when starting the test! {}".format( + self.get_test_details(self.sessionID) + ) + ) + actual_duration += counter + time.sleep(counter) + else: + raise Exception( + "ERROR! Test could not start in {} seconds, test state: {}".format( + initializationTimeout, response + ) + ) + + def stop_test(self, stopTimeout=60): + apiPath = "/api/v2/sessions/{}/test-run/operations/stop".format(self.sessionID) + response = self.__sendPost(apiPath, payload={}).json() + stopID = response["id"] + print("Stop ID : {}".format(stopID)) + progressPath = "/api/v2/sessions/{}/test-run/operations/stop/{}".format( + self.sessionID, stopID + ) + self.__sendGet(progressPath, 200).json() + counter = 2 + iteration = 0 + while iteration < stopTimeout: + response = self.__sendGet(progressPath, 200).json() + print("Stop Test Progress: {}".format(response["progress"])) + if response["state"] == "SUCCESS": + break + if response["state"] == "ERROR": + raise Exception( + "Error when stopping the test! {}".format( + self.get_test_details(self.sessionID) + ) + ) + iteration += counter + time.sleep(counter) + + def abort_test(self, abortTimeout=60): + apiPath = "/api/v2/sessions/{}/test-run/operations/abort".format(self.sessionID) + response = self.__sendPost(apiPath, payload={}).json() + stopID = response["id"] + print("Abort ID : {}".format(stopID)) + progressPath = "/api/v2/sessions/{}/test-run/operations/abort/{}".format( + self.sessionID, stopID + ) + self.__sendGet(progressPath, 200).json() + counter = 2 + iteration = 0 + while iteration < abortTimeout: + response = self.__sendGet(progressPath, 200).json() + print("Abort Test Progress: {}".format(response["progress"])) + if response["state"] == "SUCCESS": + break + if response["state"] == "ERROR": + raise Exception( + "Error when aborting the test! {}".format( + self.get_test_details(self.sessionID) + ) + ) + iteration += counter + time.sleep(counter) + + def get_error_notifications_for_session(self, notif_type="error"): + apiPath = "/api/v2/notifications?exclude=links&includeSeen=true&severity={}&sessionId={}".format( + notif_type, self.sessionID + ) + return self.__sendGet(apiPath, 200).json() + + def get_error_notifications_for_test(self, notif_type="error"): + apiPath = "/api/v2/notifications?exclude=links&includeSeen=true&severity={}&sessionId={}".format( + notif_type, self.sessionID + ) + error_notifs = self.__sendGet(apiPath, 200).json() + test_id = self.get_test_id() + return [ + notif + for notif in error_notifs + if "TestId" in notif["tags"] and notif["tags"]["TestId"] == test_id + ] + + def get_test_status(self): + apiPath = "/api/v2/sessions/{}/test".format(self.sessionID) + return self.__sendGet(apiPath, 200).json() + + def wait_test_finished(self, timeout=300): + print("Waiting for the test to finish...") + response = self.get_test_status() + actual_duration = 0 + counter = 1 + while actual_duration < self.testDuration + timeout: + response = self.get_test_status() + if response["status"] == "STOPPING" and not self.stopTrafficTime: + self.stopTrafficTime = self.__getEpochTime() + if response["status"] == "STOPPED": + if response["testElapsed"] >= response["testDuration"]: + print("Test gracefully finished") + self.stopTime = self.__getEpochTime() + return self.stopTime + else: + raise Exception( + "Error! Test stopped before reaching the configured duration = {}; Elapsed = {}".format( + response["testDuration"], response["testElapsed"] + ) + ) + else: + print( + "Test duration = {}; Elapsed = {}".format( + response["testDuration"], response["testElapsed"] + ) + ) + actual_duration += counter + time.sleep(counter) + else: + print( + "Test did not stop after timeout {}s. Test status= {}. Force stopping the test!".format( + timeout, response["status"] + ) + ) + self.stop_test() + raise Exception( + "Error! Test failed to stop after timeout {}s.".format(timeout) + ) + + @staticmethod + def __getEpochTime(): + pattern = "%d.%m.%Y %H:%M:%S" + timeH = datetime.now().strftime(pattern) + epoch = int(time.mktime(time.strptime(timeH, pattern))) + return epoch + + def get_test_id(self): + apiPath = "/api/v2/sessions/{}/test".format(self.sessionID) + response = self.__sendGet(apiPath, 200).json() + return response["testId"] + + def get_available_stats_name(self): + apiPath = "/api/v2/results/{}/stats".format(self.get_test_id()) + response = self.__sendGet(apiPath, 200).json() + available_stats = [] + for stat in response: + available_stats.append(stat["name"]) + return available_stats + + def get_stats_values(self, statName): + print("Get the values for {}".format(statName)) + apiPath = "/api/v2/results/{}/stats/{}".format(self.get_test_id(), statName) + response = self.__sendGet(apiPath, 200).json() + return response + + def get_all_stats(self, csvLocation, exportTimeout=180): + test_id = self.get_test_id() + apiPath = "/api/v2/results/{}/operations/generate-csv".format(test_id) + response = self.__sendPost(apiPath, None).json() + apiPath = response["url"][len(self.host) :] + response = self.wait_event_success(apiPath, timeout=exportTimeout) + if not response: + raise TimeoutError( + "Failed to download CSVs. Timeout reached = {} seconds".format( + exportTimeout + ) + ) + apiPath = response["resultUrl"] + response = self.__sendGet(apiPath, 200, debug=False) + zf = ZipFile(io.BytesIO(response.content), "r") + zf.extractall(csvLocation) + return response + + def get_result_ended(self, timeout=5): + apiPath = "/api/v2/results/{}".format(self.get_test_id()) + while timeout > 0: + print("Pending result availability...") + response = self.__sendGet(apiPath, 200).json() + result_end_time = response["endTime"] + result_availability = result_end_time > 0 + if result_availability: + print("Result may now be downloaded...") + return result_availability + else: + time.sleep(1) + timeout -= 1 + raise Exception("Result are not available for {}".format(self.get_test_id())) + + def get_applications(self): + apiPath = "/api/v2/resources/apps?include=all" + response = self.__sendGet(apiPath, 200, debug=False).json() + return response + + def get_applications_by_pages(self, take=50, skip=0): + apiPath = "/api/v2/resources/apps?take={}&skip={}&exclude=links".format( + take, skip + ) + response = self.__sendGet(apiPath, 200, debug=False).json() + return response + + def get_configured_applications(self): + """ + return: returns a list of tuples containing application name(index 0) / configured app position in UI(index 1) + """ + configured = self.get_session_config(self.sessionID) + applications = configured["Config"]["TrafficProfiles"][0]["Applications"] + configured_applications = [app["Name"] for app in applications] + apps_in_test = [] + for item in configured_applications: + application_position = item.split()[-1] + application_name = " ".join( + [word for word in item.split() if not word.isdigit()] + ) + apps_in_test.append((application_name, application_position)) + return apps_in_test + + def switch_application_order(self, new_apps_order): + """ + Gets current order of the apps and reorders them the same order as the given list. + + :parameter new_apps_order: a list with new indexes representing the new order of the apps. + :return: list + """ + configured = self.get_session_config(self.sessionID) + applications = configured["Config"]["TrafficProfiles"][0]["Applications"] + reordered_applications = [applications[index] for index in new_apps_order] + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"Applications": reordered_applications}) + + def get_applications_with_filter_applied( + self, *args, filter_mode="and", take=50, skip=0 + ): + filter_by = ",".join(args) + apiPath = f"/api/v2/resources/apps?take={take}&skip={skip}&exclude=links&searchCol=Name,Description&searchVal={filter_by}&filterMode={filter_mode}" + result = self.__sendGet(apiPath, 200).json() + filtered_applications = [ + (item["Name"], item["Description"]) for item in result["data"] + ] + return filtered_applications + + def get_attacks_with_filter_applied( + self, *args, filter_mode="and", take=50, skip=0 + ): + filter_by = ",".join(args) + apiPath = f"/api/v2/resources/attacks?take={take}&skip={skip}&exclude=links&include=Metadata&searchCol=Name,Description,Direction,Severity,Keywords,References&searchVal={filter_by}&filterMode={filter_mode}" + result = self.__sendGet(apiPath, 200).json() + filtered_applications = [ + ( + item["Name"], + item["Description"], + item["Metadata"]["Direction"], + item["Metadata"]["Severity"], + ) + for item in result["data"] + ] + return filtered_applications + + def get_attacks(self, filter_by, take=50, skip=0): + apiPath = f"/api/v2/resources/attacks?take={take}&skip={skip}&exclude=links&include=Metadata&searchCol=Name&searchVal={urllib.parse.quote(filter_by)}&filterMode=and" + response = self.__sendGet(apiPath, 200, debug=False).json() + return response + + def get_strikes(self): + apiPath = "/api/v2/resources/strikes?include=all" + response = self.__sendGet(apiPath, 200).json() + return response + + def get_application_id(self, app_name): + if not self.app_list: + self.app_list = self.get_applications() + print("Getting application {} ID...".format(app_name)) + for app in self.app_list: + if app["Name"] == app_name: + print("Application ID = {}".format(app["id"])) + return app["id"] + + def get_strike_id(self, strike_name): + if not self.strike_list: + self.strike_list = self.get_strikes() + for strike in self.strike_list: + if strike["Name"] == strike_name: + print("Strike ID = {}".format(strike["id"])) + return strike["id"] + + def get_attack_id(self, attack_name): + self.attack_list = self.get_attacks(attack_name) + for attack in self.attack_list["data"]: + if attack_name == attack["Name"]: + return attack["id"] + + def set_agent_optimization_mode(self, mode: str, tp_id=1): + """ + Configures the agent optimization mode. + Currently the 2 modes supported: + RATE_MODE, BALANCED_MODE + """ + if mode in ["RATE_MODE", "BALANCED_MODE"]: + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/AdvancedSettings".format( + self.sessionID, tp_id + ) + self.__sendPatch(apiPath, payload={"AgentOptimizationMode": mode}) + else: + raise ValueError("{} is not supported".format(mode)) + + def set_attack_warmup_period(self, warmup_period, ap_id=1): + """ + Sets the warmup period for the Attack profile + """ + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/{}/ObjectivesAndTimeline/TimelineSegments/1".format( + self.sessionID, ap_id + ) + self.__sendPatch(apiPath, payload={"WarmUpPeriod": int(warmup_period)}) + + def set_traffic_warmup_period(self, warmup_period, tp_id=1): + """ + Sets the warmup period for the Traffic profile + """ + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/AdvancedSettings".format( + self.sessionID, tp_id + ) + self.__sendPatch(apiPath, payload={"WarmUpPeriod": int(warmup_period)}) + + def add_attack(self, attack_name, ap_id=1): + app_id = self.get_attack_id(attack_name=attack_name) + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/{}/Attacks".format( + self.sessionID, ap_id + ) + response = self.__sendPost( + apiPath, payload={"ExternalResourceURL": app_id} + ).json() + return response[-1]["id"] + + def add_strike_as_attack(self, strike_name, ap_id=1): + app_id = self.get_strike_id(strike_name=strike_name) + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/{}/Attacks".format( + self.sessionID, ap_id + ) + response = self.__sendPost(apiPath, payload={"ProtocolID": app_id}).json() + return response[-1]["id"] + + def create_customized_attack( + self, application_name, strike_name, insert_at_position + ): + app_id = self.get_application_id(app_name=application_name) + api_path = "/api/v2/sessions/{}/config/config/AttackProfiles/1/Attacks/operations/create".format( + self.sessionID + ) + payload = { + "Actions": [ + {"ProtocolID": strike_name, "InsertAtIndex": insert_at_position} + ], + "ResourceURL": f"api/v2/resources/apps/{app_id}", + } + response = self.__sendPost(api_path, payload=payload).json() + status_url = response["url"].split("/")[-1] + api_path = "/api/v2/sessions/{}/config/config/AttackProfiles/1/Attacks/operations/create/{}".format( + self.sessionID, status_url + ) + for index in range(10): + response = self.__sendGet(api_path, 200).json() + time.sleep(1) + if response["state"] == "SUCCESS": + return + else: + continue + raise Exception("Application action was not added after 10 seconds") + + def insert_attack_action_at_exact_position( + self, attack_id, action_id, insert_at_position + ): + api_path = f"/api/v2/sessions/{self.sessionID}/config/config/AttackProfiles/1/Attacks/{attack_id}/Tracks/1/operations/add-actions" + response = self.__sendPost( + api_path, + payload={ + "Actions": [ + {"ActionID": action_id, "InsertAtIndex": insert_at_position} + ] + }, + ).json() + status_url = response["url"].split("/")[-1] + api_path = f"/api/v2/sessions/{self.sessionID}/config/config/AttackProfiles/1/Attacks/{attack_id}/Tracks/1/operations/add-actions/{status_url}" + for index in range(10): + response = self.__sendGet(api_path, 200).json() + time.sleep(1) + if response["state"] == "SUCCESS": + return response["result"][insert_at_position]["id"] + else: + continue + + def add_application(self, app_name, tp_id=1): + app_id = self.get_application_id(app_name=app_name) + apiPath = ( + "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/Applications".format( + self.sessionID, tp_id + ) + ) + response = self.__sendPost( + apiPath, payload={"ExternalResourceURL": app_id} + ).json() + return response[-1]["id"] + + def get_application_profile(self, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}".format( + self.sessionID, tp_id + ) + response = self.__sendGet(apiPath, 200, debug=False).json() + return response + + # Not working need to check + def add_application_profile(self, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles".format( + self.sessionID + ) + response = self.__sendPost( + apiPath, payload={"id": 1, "Active": True, "Name": "Application Profile"} + ).json() + return response[-1]["id"] + + def insert_application_at_action_exact_position(self, app_id, action_id, position): + api_path = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/Applications/{app_id}/Tracks/1/operations/add-actions" + response = self.__sendPost( + api_path, + payload={"Actions": [{"ActionID": action_id, "InsertAtIndex": position}]}, + ).json() + status_url = response["url"].split("/")[-1] + api_path = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/Applications/{app_id}/Tracks/1/operations/add-actions/{status_url}" + for index in range(10): + response = self.__sendGet(api_path, 200).json() + time.sleep(1) + if response["state"] == "SUCCESS": + return response["result"][position]["id"] + else: + continue + raise Exception("Application action was not added after 10 seconds") + + def add_application_action(self, app_id, action_name, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/Applications/{}/Tracks/1/Actions".format( + self.sessionID, tp_id, app_id + ) + self.__sendPost(apiPath, payload={"Name": action_name}).json() + + def set_application_action_value( + self, app_id, action_id, param_id, value, file_value=None, source=None, tp_id=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/Applications/{}/Tracks/1/Actions/{}/Params/{}".format( + self.sessionID, tp_id, app_id, action_id, param_id + ) + payload = {"Value": value, "FileValue": file_value, "Source": source} + self.__sendPatch(apiPath, payload) + + def get_application_actions(self, app_id): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/Applications/{app_id}/Tracks/1/Actions" + response = self.__sendGet(apiPath, 200, debug=False).json() + return response + + def set_application_actions_values( + self, payload, app_id, action_id, param_id, tp_id=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/Applications/{}/Tracks/1/Actions/{}/Params/{}".format( + self.sessionID, tp_id, app_id, action_id, param_id + ) + self.__sendPatch(apiPath, payload) + + def get_application_actions_values(self, app_id, action_id): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/Applications/{}/Tracks/1/Actions/{}/Params".format( + self.sessionID, app_id, action_id + ) + response = self.__sendGet(apiPath, 200, debug=False).json() + return response + + def delete_application_action(self, app_id, action_id, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/Applications/{}/Tracks/1/Actions/{}".format( + self.sessionID, tp_id, app_id, action_id + ) + self.__sendDelete(apiPath, self.headers) + + def add_attack_action(self, att_id, action_name, ap_id=1): + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/{}/Attacks/{}/Tracks/1/Actions".format( + self.sessionID, ap_id, att_id + ) + self.__sendPost(apiPath, payload={"Name": action_name}).json() + + def add_attack_profile(self): + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles".format( + self.sessionID + ) + response = self.__sendPost(apiPath, payload={}).json() + return response[-1]["id"] + + def add_traffic_profile(self): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles".format( + self.sessionID + ) + response = self.__sendPost(apiPath, payload={}).json() + return response[-1]["id"] + + def set_traffic_profile_timeline( + self, duration, objective_value, objective_unit=None, pr_id=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/TimelineSegments/1".format( + self.sessionID, pr_id + ) + payload = { + "Duration": duration, + "PrimaryObjectiveValue": objective_value, + "PrimaryObjectiveUnit": objective_unit, + } + self.__sendPatch(apiPath, payload) + + def set_application_simulated_users_timeline( + self, max_su_per_second, max_pending_su, objective_unit=None, pr_id=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/ObjectivesAndTimeline/PrimaryObjective".format( + self.sessionID + ) + payload = { + "MaxSimulatedUsersPerInterval": max_su_per_second, + "MaxPendingSimulatedUsers": max_pending_su, + } + self.__sendPatch(apiPath, payload) + + def set_primary_objective(self, payload, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/PrimaryObjective".format( + self.sessionID, tp_id + ) + self.__sendPatch(apiPath, payload) + + def get_primary_objective(self, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/PrimaryObjective".format( + self.sessionID, tp_id + ) + response = self.__sendGet(apiPath, 200, debug=False).json() + return response + + def set_secondary_objective(self, payload, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/SecondaryObjective".format( + self.sessionID, tp_id + ) + self.__sendPatch(apiPath, payload) + + def get_secondary_objective(self, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/SecondaryObjective".format( + self.sessionID, tp_id + ) + response = self.__sendGet(apiPath, 200, debug=False).json() + return response + + def add_primary_objective(self, objective, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/PrimaryObjective".format( + self.sessionID, tp_id + ) + self.__sendPatch(apiPath, payload={"Type": objective, "Unit": ""}) + + def add_secondary_objective(self, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/SecondaryObjectives".format( + self.sessionID, tp_id + ) + self.__sendPost(apiPath, payload={}).json() + + def add_secondary_objective_value( + self, objective, objective_value, objective_unit=None, tp_id=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/SecondaryObjectives/1".format( + self.sessionID, tp_id + ) + self.__sendPatch(apiPath, payload={"Type": objective}) + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/TimelineSegments/1/SecondaryObjectiveValues/1".format( + self.sessionID, tp_id + ) + self.__sendPatch(apiPath, payload={"Value": objective_value}) + if objective_unit: + self.__sendPatch(apiPath, payload={"Unit": objective_unit}) + + def set_traffic_profile_client_tls(self, version, status, pr_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/TrafficSettings/DefaultTransportProfile/ClientTLSProfile".format( + self.sessionID, pr_id + ) + self.__sendPatch(apiPath, payload={version: status}) + + def set_traffic_profile_server_tls(self, version, status, pr_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/TrafficSettings/DefaultTransportProfile/ServerTLSProfile".format( + self.sessionID, pr_id + ) + self.__sendPatch(apiPath, payload={version: status}) + + def set_attack_profile_timeline( + self, + duration, + objective_value, + max_concurrent_attacks=None, + iteration_count=0, + ap_id=1, + ): + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/{}/ObjectivesAndTimeline/TimelineSegments/1".format( + self.sessionID, ap_id + ) + payload = { + "Duration": duration, + "AttackRate": objective_value, + "MaxConcurrentAttack": max_concurrent_attacks, + "IterationCount": iteration_count, + } + self.__sendPatch(apiPath, payload) + + def set_attack_profile_client_tls(self, version, status, pr_id=1): + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/{}/TrafficSettings/DefaultTransportProfile/ClientTLSProfile".format( + self.sessionID, pr_id + ) + self.__sendPatch(apiPath, payload={version: status}) + + def set_attack_profile_server_tls(self, version, status, pr_id=1): + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/{}/TrafficSettings/DefaultTransportProfile/ServerTLSProfile".format( + self.sessionID, pr_id + ) + self.__sendPatch(apiPath, payload={version: status}) + + def set_custom_payload(self, apiPath, fileName): + resp = self.__sendPatch(apiPath, payload={"Source": "PayloadProfile"}) + if resp.status_code != 204: + print("Error patching payload type: {}".format(resp.json())) + uploadUrl = "/api/v2/resources/payloads" + payload = self.get_resource(uploadUrl, name=os.path.basename(fileName)) + if not payload: + payloadFile = open(fileName, "rb") + resp = self.__sendPost( + uploadUrl, + payload=None, + customHeaders=self.headers, + files={"file": payloadFile}, + ).json() + payload = { + "FileValue": { + "fileName": resp["fileName"], + "resourceURL": resp["resourceURL"], + } + } + else: + payload = { + "FileValue": { + "fileName": payload["name"], + "resourceURL": payload["links"][0]["href"], + } + } + self.__sendPatch(apiPath, payload=payload) + + def set_application_custom_payload(self, appName, actionName, paramName, fileName): + config = self.get_session_config()["Config"] + applicationsByName = { + app["Name"]: app for app in config["TrafficProfiles"][0]["Applications"] + } + httpApp = applicationsByName[appName] + actionsByName = { + action["Name"]: action for action in httpApp["Tracks"][0]["Actions"] + } + postAction = actionsByName[actionName] + actionParametersByName = { + param["Name"]: param for param in postAction["Params"] + } + bodyParam = actionParametersByName[paramName] + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/1/Applications/{}/Tracks/1/Actions/{}/Params/{}".format( + self.sessionID, httpApp["id"], postAction["id"], bodyParam["id"] + ) + self.set_custom_payload(apiPath, fileName) + + def set_custom_playlist(self, apiPath, fileName, value=None): + resp = self.__sendPatch(apiPath, payload={"Source": "Playlist"}) + if resp.status_code != 204: + print("Error patching payload type: {}".format(resp.json())) + uploadUrl = "/api/v2/resources/playlists" + playlist = self.get_resource(uploadUrl, name=os.path.basename(fileName)) + if not playlist: + playlistFile = open(fileName, "rb") + resp = self.__sendPost( + uploadUrl, + payload=None, + customHeaders=self.headers, + files={"file": playlistFile}, + ).json() + payload = { + "FileValue": { + "fileName": resp["fileName"], + "resourceURL": resp["resourceURL"], + "Value": value, + } + } + else: + payload = { + "FileValue": { + "fileName": playlist["name"], + "resourceURL": playlist["links"][0]["href"], + "Value": value, + } + } + self.__sendPatch(apiPath, payload=payload) + + def set_attack_custom_playlist( + self, attackName, actionName, paramName, fileName, value="Query" + ): + config = self.get_session_config()["Config"] + attacksByName = { + app["Name"]: app for app in config["AttackProfiles"][0]["Attacks"] + } + attack = attacksByName[attackName] + actionsByName = { + action["Name"]: action for action in attack["Tracks"][0]["Actions"] + } + postAction = actionsByName[actionName] + actionParametersByName = { + param["Name"]: param for param in postAction["Params"] + } + bodyParam = actionParametersByName[paramName] + apiPath = "/api/v2/sessions/{}/config/config/AttackProfiles/1/Attacks/{}/Tracks/1/Actions/{}/Params/{}".format( + self.sessionID, attack["id"], postAction["id"], bodyParam["id"] + ) + self.set_custom_playlist(apiPath, fileName, value) + + def get_all_configs(self): + apiPath = "/api/v2/configs" + response = self.__sendGet(apiPath, 200).json() + return response + + def get_config_id(self, test_name): + configs = self.get_all_configs() + for config in configs: + if config["displayName"] == test_name: + print("Config ID = {}".format(config["id"])) + return config["id"] + + def get_resource(self, apiPath, name): + resp = self.__sendGet(apiPath, 200).json() + for resource in resp: + if resource["name"] == name: + return resource + + def save_config(self, test_name, timeout=10): + apiPath = "/api/v2/sessions/{}/config/operations/save".format(self.sessionID) + response = self.__sendPost(apiPath, payload={"Name": test_name}).json() + apiPath = "/api/v2/sessions/{}/config/operations/save/{}".format( + self.sessionID, response["id"] + ) + if not self.wait_event_success(apiPath, timeout): + raise TimeoutError( + "Could not save copy for test= {}. Timeout reached = {} seconds".format( + test_name, timeout + ) + ) + + def load_config(self, test_name): + configID = self.get_config_id(test_name=test_name) + apiPath = "/api/v2/sessions" + response = self.__sendPost(apiPath, payload={"configUrl": configID}).json() + if response: + print( + "Test= {} was loaded with ID= {}".format(test_name, response[-1]["id"]) + ) + self.sessionID = response[-1]["id"] + return + else: + raise Exception("Failed to load test= {}".format(test_name)) + + def collect_diagnostics(self, timeout=600): + apiPath = "/api/v2/diagnostics/operations/export" + response = self.__sendPost( + apiPath, payload={"componentList": [], "sessionId": self.sessionID} + ).json() + apiPath = "/api/v2/diagnostics/operations/export/{}".format(response["id"]) + response = self.wait_event_success(apiPath, timeout) + + return response["id"] + + def set_diagnostics_level(self, log_level): + apiPath = "/api/v2/log-config" + response = self.__sendPut(apiPath, payload={"level": log_level}) + + return response + + def add_tunnel_stack(self, network_segment_number=1): + """ + Add a tunnel stack + """ + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/NetworkProfiles/1/IPNetworkSegment/{network_segment_number}/TunnelStacks" + self.__sendPost(apiPath, payload={}) + + def get_tunnel_stack(self): + """ + Obtain information about tunnel stack configuration on client. + """ + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/NetworkProfiles/1/IPNetworkSegment/1/TunnelStacks" + return self.__sendGet(apiPath, 200).json() + + def get_tunnel_outer_ip(self): + """ + Obtain information about tunnel stack configuration on client. + """ + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/NetworkProfiles/1/IPNetworkSegment/1/TunnelStacks/1/OuterIPRange" + return self.__sendGet(apiPath, 200).json() + + def set_tunnel_stack_gateway_vpn_ip( + self, tunnel_type, gw_vpn_ip, network_segment_number=1 + ): + """ + Set the value for VPN gateway IP. + + :params tunnel_type: (str) CiscoAnyConnectSettings, FortinetSettings, PANGPSettings + """ + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/NetworkProfiles/1/IPNetworkSegment/{network_segment_number}/TunnelStacks/1/TunnelRange/{tunnel_type}" + response = self.get_tunnel_stack() + if response: + self.__sendPatch(apiPath, payload={"VPNGateway": gw_vpn_ip}) + else: + self.add_tunnel_stack() + self.__sendPatch(apiPath, payload={"VPNGateway": gw_vpn_ip}) + + def set_tunnel_stack_type(self, tunnel_type, network_segment_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/TunnelRange".format( + self.sessionID, network_segment_number + ) + self.__sendPatch(apiPath, payload={"VendorType": tunnel_type}) + + def set_tunnel_count(self, number_of_tunnels, network_segment_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/TunnelRange".format( + self.sessionID, network_segment_number + ) + resp = self.__sendPatch( + apiPath, payload={"TunnelCountPerOuterIP": int(number_of_tunnels)} + ) + if resp.status_code != 204: + print("Error setting VPN tunnel count per outer IP: {}".format(resp.json())) + + def set_tunnel_establisment_timeout(self, tunnel_timeout, network_segment_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/TunnelRange".format( + self.sessionID, network_segment_number + ) + self.__sendPatch( + apiPath, payload={"TunnelEstablishmentTimeout": tunnel_timeout} + ) + + def set_pan_tunnel_portal_hostname(self, portal_hostname, network_segment_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/TunnelRange/PANGPSettings".format( + self.sessionID, network_segment_number + ) + self.__sendPatch(apiPath, payload={"PortalHostname": portal_hostname}) + + def set_tunnel_pan_vpn_gateways( + self, tunnel_type, vpn_gateways, network_segment_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/TunnelRange/{}".format( + self.sessionID, network_segment_number, tunnel_type + ) + self.__sendPatch( + apiPath, payload={"VPNGateways": list(vpn_gateways.split(" "))} + ) + + def set_tunnel_cisco_vpn_gateway( + self, tunnel_type, vpn_gateways, network_segment_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/TunnelRange/{}".format( + self.sessionID, network_segment_number, tunnel_type + ) + self.__sendPatch(apiPath, payload={"VPNGateway": vpn_gateways}) + + def set_tunnel_cisco_connection_profiles( + self, connection_profiles, network_segment_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/TunnelRange/CiscoAnyConnectSettings".format( + self.sessionID, network_segment_number + ) + self.__sendPatch( + apiPath, + payload={"ConnectionProfiles": list(connection_profiles.split(" "))}, + ) + + def set_tunnel_auth_settings( + self, tunnel_type, field, value, source, network_segment_number=1 + ): + # Field can be UsernamesParam or PasswordsParam + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/TunnelRange/{}/AuthSettings/{}".format( + self.sessionID, network_segment_number, tunnel_type, field + ) + self.__sendPatch(apiPath, payload={"Value": value, "Source": source}) + + def set_tunnel_outer_ip_gateway(self, gateway_ip, network_segment_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/OuterIPRange".format( + self.sessionID, network_segment_number + ) + self.__sendPatch(apiPath, payload={"GwAuto": False}) + resp = self.__sendPatch(apiPath, payload={"GwStart": gateway_ip}) + if resp.status_code != 204: + print("Error network tags in Inncer IP range: {}".format(resp.json())) + + def set_tunnel_automatic_gateway( + self, gateway_auto=True, network_segment=1, tunnel_stack=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/{}/OuterIPRange".format( + self.sessionID, network_segment, tunnel_stack + ) + self.__sendPatch(apiPath, payload={"GwAuto": gateway_auto}) + + def set_tunnel_outer_ip_range( + self, ip_start, count, max_count, network_segment_number=1, ip_incr="0.0.0.1" + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/OuterIPRange".format( + self.sessionID, network_segment_number + ) + self.__sendPatch(apiPath, payload={"IpAuto": False}) + self.__sendPatch(apiPath, payload={"IpStart": ip_start}) + self.__sendPatch(apiPath, payload={"IpIncr": ip_incr}) + self.__sendPatch(apiPath, payload={"Count": count}) + self.__sendPatch(apiPath, payload={"maxCountPerAgent": max_count}) + + def set_tunnel_outer_ip_start(self, ip_start, network_segment_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/OuterIPRange".format( + self.sessionID, network_segment_number + ) + self.__sendPatch(apiPath, payload={"IpStart": ip_start}) + + def set_tunnel_stack_dns_servers(self, servers, network_segment_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/TunnelRange/DNSResolver".format( + self.sessionID, network_segment_number + ) + serverList = list(map(lambda x: {"name": x}, list(servers.split(",")))) + self.__sendPatch(apiPath, payload={"nameServers": serverList}) + + def delete_ip_stack(self, network_segment_number=1, ip_stack_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment_number, ip_stack_number + ) + self.__sendDelete(apiPath, self.headers) + + def set_tunnel_inner_ip_network_tags(self, network_tags, network_segment_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/InnerIPRange".format( + self.sessionID, network_segment_number + ) + self.__sendPatch(apiPath, payload={"networkTags": network_tags}) + + def set_tunnel_udp_port( + self, tunnel_type, encapsulation_type, udp_port, network_segment_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/1/TunnelRange/{}/{}".format( + self.sessionID, network_segment_number, tunnel_type, encapsulation_type + ) + self.__sendPatch(apiPath, payload={"UdpPort": udp_port}) + + def __get_status_for_advance_timeline(self): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/ObjectivesAndTimeline/PrimaryObjective/Timeline" + result = self.__sendGet(apiPath, 200) + return result.json() + + def set_primary_timeline(self, payload, segment_id, tp_id=1): + apiPath = "/api/v2/sessions/{}/config/config/TrafficProfiles/{}/ObjectivesAndTimeline/PrimaryObjective/Timeline/{}".format( + self.sessionID, tp_id, segment_id + ) + self.__sendPatch(apiPath, payload) + + def get_primary_timeline(self): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/ObjectivesAndTimeline/PrimaryObjective/Timeline" + result = self.__sendGet(apiPath, 200) + return result.json() + + def get_specific_value_from_given_ramp_segment(self, segment_type, given_key): + acceptable_keys = [ + "Duration", + "SegmentType", + "Enabled", + "AutomaticObjectiveValue", + "NumberOfSteps", + "PrimaryObjectiveValue", + "SecondaryObjectiveValues", + "ObjectiveValue", + "ObjectiveUnit", + ] + if given_key not in acceptable_keys: + raise Exception( + f"Cannot find key {given_key}, make sure the key exists in this list {acceptable_keys}" + ) + response = self.__get_status_for_advance_timeline() + return response[segment_type - 1][given_key] + + def enable_step_ramp_down_or_up(self, segment_type=None): + """ + A method to activate the step ramp-up feature + + :params segment_type: default set to enable for both ramp up or down, could receive a string "up"/"down" if + ... only one segment is to be enabled. + """ + if segment_type: + self.__setStepRamp(True, segment_type) + else: + for segment in [1, 3]: + self.__setStepRamp(True, segment) + + def disable_step_ramp_down_or_up(self, segment_type=None): + """ + A method to activate the step ramp-up feature + + :params segment_type: default set to enable for both ramp up or down, could receive a string "up"/"down" if + ... only one segment is to be enabled. + """ + if segment_type: + self.__setStepRamp(False, segment_type) + else: + for segment in [1, 3]: + self.__setStepRamp(False, segment) + + def __setStepRamp(self, action, segment_type): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/ObjectivesAndTimeline/PrimaryObjective/Timeline/{segment_type}" + self.__sendPatch(apiPath, payload={"Enabled": action}) + + def set_specific_value_for_given_ramp_segment(self, segment_type, key, value): + """ + A method to set different parameters at the timeline segment + + :params key: one of the endpoint keys, must fit in the acceptable_keys list + :params value: any value + :params segment_type: specify which one of the RampUpDown segment to use must be "UP" / "DOWN" + """ + acceptable_keys = [ + "Duration", + "NumberOfSteps", + "ObjectiveValue", + "ObjectiveUnit", + ] + if key not in acceptable_keys: + raise Exception( + f"Cannot find key {key}, make sure the key exists in this list {acceptable_keys}" + ) + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/ObjectivesAndTimeline/PrimaryObjective/Timeline/{segment_type}" + self.__sendPatch(apiPath, payload={key: value}) + if self.get_specific_value_from_given_ramp_segment(segment_type, key) != value: + raise Exception( + f"An error has occured, setting {key} to {value} did not work!" + ) + return True + + def delete_added_application(self, app_id): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/Applications/{app_id}" + self.__sendDelete(apiPath, self.headers) + + def get_disk_usage_info(self): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/ExpectedDiskSpace" + result = self.__sendGet(apiPath, 200) + return result.json() + + def __set_traffic_profile(self, option): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1" + self.__sendPatch(apiPath, payload={"Active": option}) + + def __set_attack_profile(self, option): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/AttackProfiles/1" + self.__sendPatch(apiPath, payload={"Active": option}) + + def enable_traffic_profile(self): + self.__set_traffic_profile(True) + + def disable_traffic_profile(self): + self.__set_traffic_profile(False) + + def enable_attack_profile(self): + self.__set_attack_profile(True) + + def disable_attack_profile(self): + self.__set_attack_profile(False) + + def enable_application_inherit_tls(self, app_id): + """ + enable inherit tls for any added application + """ + pass + self.__set_application_inherit_tls_status(True, app_id) + + def disable_application_inherit_tls(self, app_id): + """ + disable inherit tls for any added application + + :param app_id: application index in the added order + """ + self.__set_application_inherit_tls_status(False, app_id) + + def enable_attack_inherit_tls(self, attack_id): + """ + enable inherit tls for any added attack + + :param attack_id: attack index in the added order + """ + self.__set_attack_inherit_tls_status(True, attack_id) + + def disable_attack_inherit_tls(self, attack_id): + """ + enable inherit tls for any added attack + + :param attack_id: attack index in the added order + """ + self.__set_attack_inherit_tls_status(False, attack_id) + + def __set_application_inherit_tls_status(self, status, app_id): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/Applications/{app_id}" + self.__sendPatch(apiPath, payload={"InheritTLS": status}) + + def __set_attack_inherit_tls_status(self, status, attack_id): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/AttackProfiles/1/Attacks/{attack_id}" + self.__sendPatch(apiPath, payload={"InheritTLS": status}) + + def clear_agent_ownership(self, agents_ips=None): + agents_ids = [] + result_id = self.get_current_session_result() + if agents_ips: + for agent_ip in agents_ips: + agents_ids.append(self.get_agents_ids(agent_ip)[0]) + apiPath = "/api/v2/agents/operations/release" + agents_to_release = [] + for agent_id in agents_ids: + agents_to_release.append({"agentId": agent_id}) + payload = {"sessionId": result_id, "agentsData": agents_to_release} + response = self.__sendPost(apiPath, payload=payload).json() + status_url = response["id"] + api_path = f"/api/v2/agents/operations/release/{status_url}" + for index in range(10): + response = self.__sendGet(api_path, 200).json() + time.sleep(1) + if response["state"] == "SUCCESS": + return True + else: + continue + + def __get_results_list(self): + apiPath = "/api/v2/results?exclude=links" + result = self.__sendGet(apiPath, 200) + return result.json() + + def get_current_session_result(self): + sessions_results = self.__get_results_list() + for index in range(0, len(sessions_results)): + if sessions_results[index]["activeSession"] == self.sessionID: + return sessions_results[index]["testName"] + else: + continue + + def configure_attack_client_tls_settings( + self, attack_id, config_endpoint, config_change + ): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/AttackProfiles/1/Attacks/{attack_id}/ClientTLSProfile" + available_endpoints = [ + "tls12Enabled", + "tls13Enabled", + "ciphers12", + "ciphers13", + "immediateClose", + "middleBoxEnabled", + ] + if config_endpoint not in available_endpoints: + raise ("The endpoint you are trying to configure doesn't exist!") + self.__sendPatch(apiPath, payload={config_endpoint: config_change}) + + def configure_attack_server_tls_settings( + self, attack_id, config_endpoint, config_change + ): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/AttackProfiles/1/Attacks/{attack_id}/ServerTLSProfile" + available_endpoints = [ + "tls12Enabled", + "tls13Enabled", + "ciphers12", + "ciphers13", + "immediateClose", + "middleBoxEnabled", + ] + if config_endpoint not in available_endpoints: + raise ("The endpoint you are trying to configure doesn't exist!") + self.__sendPatch(apiPath, payload={config_endpoint: config_change}) + + def configure_application_client_tls_settings( + self, app_id, config_endpoint, config_change + ): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/Applications/{app_id}/ClientTLSProfile" + available_endpoints = [ + "tls12Enabled", + "tls13Enabled", + "ciphers12", + "ciphers13", + "immediateClose", + "middleBoxEnabled", + ] + if config_endpoint not in available_endpoints: + raise ("The endpoint you are trying to configure doesn't exist!") + self.__sendPatch(apiPath, payload={config_endpoint: config_change}) + + def configure_application_server_tls_settings( + self, app_id, config_endpoint, config_change + ): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/Applications/{app_id}/ServerTLSProfile" + available_endpoints = [ + "tls12Enabled", + "tls13Enabled", + "ciphers12", + "ciphers13", + "immediateClose", + "middleBoxEnabled", + ] + if config_endpoint not in available_endpoints: + raise ("The endpoint you are trying to configure doesn't exist!") + self.__sendPatch(apiPath, payload={config_endpoint: config_change}) + + def enable_configured_application(self, app_id): + self.__set_configured_applications(True, app_id) + + def disable_configured_application(self, app_id): + self.__set_configured_applications(False, app_id) + + def enable_configured_attack(self, app_id): + self.__set_configured_attacks(True, app_id) + + def disable_configured_attack(self, attack_id): + self.__set_configured_attacks(False, attack_id) + + def __set_configured_applications(self, option, application): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/TrafficProfiles/1/Applications/{application}" + self.__sendPatch(apiPath, payload={"Active": option}) + + def __set_configured_attacks(self, option, attack): + apiPath = f"/api/v2/sessions/{self.sessionID}/config/config/AttackProfiles/1/Attacks/{attack}" + self.__sendPatch(apiPath, payload={"Active": option}) + + def set_sack(self, profile, tcp_profile, value=True): + apiPath = "/api/v2/sessions/{}/config/config/{}/1/TrafficSettings/DefaultTransportProfile/{}".format( + self.sessionID, profile, tcp_profile + ) + self.__sendPatch(apiPath, payload={"SackEnabled": value}) + + def add_ipsec_stack(self, network_segment_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks".format( + self.sessionID, network_segment_number + ) + self.__sendPost(apiPath, {}) + + def set_ipsec_stack_role(self, network_segment_number, ipstack_role): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/1".format( + self.sessionID, network_segment_number + ) + self.__sendPatch(apiPath, payload={"StackRole": ipstack_role}) + + def set_ipsec_tunnel_reattempt_count( + self, tunnel_reattempt_count, network_segment_number + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/1".format( + self.sessionID, network_segment_number + ) + self.__sendPatch(apiPath, payload={"RetryCount": tunnel_reattempt_count}) + + def set_ipsec_emulated_subnet_settings( + self, + startIP, + increment, + prefix=24, + host_count_per_tunnel=1, + network_segment_number=1, + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/1/EmulatedSubConfig".format( + self.sessionID, network_segment_number + ) + payload = { + "Start": startIP, + "Increment": increment, + "Prefix": prefix, + "HostCountPerTunnel": host_count_per_tunnel, + } + self.__sendPatch(apiPath, payload) + + def set_ph1_ipsec_algorithms( + self, ph1_algorithms, network_segment_number=1, ipsec_stack_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/IPSecRange/IKEPhase1Config".format( + self.sessionID, network_segment_number, ipsec_stack_number + ) + algorithms = list(ph1_algorithms.split(" ")) + payload = { + "EncAlgorithm": algorithms[0], + "HashAlgorithm": algorithms[1], + "DHGroup": algorithms[2], + "PrfAlgorithm": algorithms[3], + } + self.__sendPatch(apiPath, payload) + + def set_ph2_ipsec_algorithms( + self, ph2_algorithms, network_segment_number=1, ipsec_stack_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/IPSecRange/IKEPhase2Config".format( + self.sessionID, network_segment_number, ipsec_stack_number + ) + algorithms = list(ph2_algorithms.split(" ")) + payload = { + "EncAlgorithm": algorithms[0], + "HashAlgorithm": algorithms[1], + "PfsGroup": algorithms[2], + } + self.__sendPatch(apiPath, payload) + + def set_ipsec_public_peer( + self, public_peer_ip, network_segment_number=1, ipsec_stack_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/IPSecRange".format( + self.sessionID, network_segment_number, ipsec_stack_number + ) + self.__sendPatch(apiPath, {"PublicPeer": public_peer_ip}) + + def set_ipsec_public_peer_increment( + self, public_peer_increment, network_segment_number=1, ipsec_stack_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/IPSecRange".format( + self.sessionID, network_segment_number, ipsec_stack_number + ) + self.__sendPatch(apiPath, {"PublicPeerIncrement": public_peer_increment}) + + def set_ipsec_protected_subnet_start( + self, protected_subnet_start, network_segment_number=1, ipsec_stack_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/IPSecRange/ProtectedSubConfig".format( + self.sessionID, network_segment_number, ipsec_stack_number + ) + self.__sendPatch(apiPath, {"Start": protected_subnet_start}) + + def set_ipsec_protected_subnet_increment( + self, increment, network_segment_number=1, ipsec_stack_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/IPSecRange/ProtectedSubConfig".format( + self.sessionID, network_segment_number, ipsec_stack_number + ) + self.__sendPatch(apiPath, {"Increment": increment}) + + def set_ipsec_preshared_key( + self, sharedkey, network_segment_number, ipsec_stack_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/IPSecRange/AuthSettings".format( + self.sessionID, network_segment_number, ipsec_stack_number + ) + self.__sendPatch(apiPath, {"SharedKey": sharedkey}) + + def set_ipsec_outer_ip_range_start( + self, outer_ip_range_start, network_segment_number=1, ipsec_stack_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/OuterIPRange".format( + self.sessionID, network_segment_number, ipsec_stack_number + ) + self.__sendPatch(apiPath, {"IpStart": outer_ip_range_start}) + + def set_ipsec_outer_ip_range_gateway( + self, outer_ip_range_gateway, network_segment_number=1, ipsec_stack_number=1 + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/OuterIPRange".format( + self.sessionID, network_segment_number, ipsec_stack_number + ) + self.__sendPatch(apiPath, {"GwStart": outer_ip_range_gateway}) + + def set_ipsec_outer_ip_range_params( + self, + startIP, + increment, + count, + maxcountperagent, + netmask, + gateway, + network_segment_number, + ipsec_stack_number=1, + ): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/OuterIPRange".format( + self.sessionID, network_segment_number, ipsec_stack_number + ) + payload = { + "IpAuto": False, + "IpStart": startIP, + "IpIncr": increment, + "Count": count, + "maxCountPerAgent": maxcountperagent, + "NetMask": netmask, + "GwStart": gateway, + } + self.__sendPatch(apiPath, payload) + + def check_ER_status(self, network_segment_number=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/EmulatedRouter".format( + self.sessionID, network_segment_number + ) + response = self.__sendGet(apiPath, 200).json() + return response["Enabled"] + + def get_IP_stack_IP_start(self, network_segment_number=1, IP_range=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPRanges/{}".format( + self.sessionID, network_segment_number, IP_range + ) + response = self.__sendGet(apiPath, 200).json() + return response["IpStart"] + + def get_TLS_VPN_IP_start(self, network_segment_number=1, tunnel_stack=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/TunnelStacks/{}/OuterIPRange".format( + self.sessionID, network_segment_number, tunnel_stack + ) + response = self.__sendGet(apiPath, 200).json() + return response["IpStart"] + + def get_IPsec_IP_start(self, network_segment_number=1, IPsec_stack=1): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/IPNetworkSegment/{}/IPSecStacks/{}/OuterIPRange".format( + self.sessionID, network_segment_number, IPsec_stack + ) + response = self.__sendGet(apiPath, 200).json() + return response["IpStart"] + + def create_session_precanned_config(self, config_name): + config_lookup = { + config["displayName"]: config["id"] for config in self.get_all_configs() + } + config_id = config_lookup.get(config_name) + if config_id is None: + raise ValueError( + f"Pre-canned config with name '{config_name}' was not found" + ) + self.configID = config_id + self.sessionID = self.open_config() + + def set_base_path_url(self, server_test_ip): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/1/PepDUT/AuthProfileParams/3".format( + self.sessionID + ) + concated_ip = "/http/" + server_test_ip + self.__sendPatch(apiPath, payload={"Value": concated_ip}) + + def set_okta_credentials_ep(self, okta_username, okta_password): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/1/PepDUT/AuthProfileParams/4".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"Value": okta_username}) + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/1/PepDUT/AuthProfileParams/5".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"Value": okta_password}) + + def set_okta_credentials_gp(self, okta_username, okta_password): + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/1/PepDUT/AuthProfileParams/1".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"Value": okta_username}) + apiPath = "/api/v2/sessions/{}/config/config/NetworkProfiles/1/DUTNetworkSegment/1/PepDUT/AuthProfileParams/2".format( + self.sessionID + ) + self.__sendPatch(apiPath, payload={"Value": okta_password}) + + def export_controller(self, export_path=None, file_name="mycontroller.zip"): + apiPath = "/api/v2/controller-migration/operations/export" + payload = { + "keycloak": True, + "config": True, + "licenseServers": True, + "externalNatsBrokers": True, + "results": True, + } + result = self.__sendPost(apiPath, payload=payload).json() + apiPath = apiPath + "/" + str(result["id"]) + for index in range(36): + time.sleep(10) + result = self.__sendGet(apiPath, 200).json() + if result["state"] == "SUCCESS": + download_url = result["resultUrl"] + break + elif result["state"] == "FAILURE": + raise "Export controller operation did not succeeded after 5 minutes" + customHeaders = self.headers + customHeaders["Accept"] = "application/zip" + response = self.session.get( + "{}{}".format(self.host, "/" + download_url), + headers=customHeaders, + stream=True, + ) + if export_path: + file_name = os.path.join(export_path, file_name) + with open(file_name, "wb") as fd: + for chunk in response.iter_content(chunk_size=256): + fd.write(chunk) + + def import_controller(self, import_path=None, file_name="fakenews.zip"): + apiPath = "/api/v2/controller-migration/operations/import" + customHeaders = self.headers + customHeaders["Accept"] = "application/json" + if import_path: + file_to_open = import_path + file_name + else: + file_to_open = file_name + mp_encoder = MultipartEncoder( + fields={ + "request": json.dumps( + { + "keycloak": True, + "config": True, + "licenseServers": True, + "externalNatsBrokers": True, + "results": True, + } + ), + "file": (file_name, open(file_to_open, "rb"), "application/zip"), + } + ) + + customHeaders["content-type"] = mp_encoder.content_type + result = self.__sendPost( + apiPath, payload=mp_encoder, customHeaders=self.headers + ).json() + print(f"This is post {result}") + + apiPath = apiPath + "/" + str(result["id"]) + for index in range(360): + time.sleep(3) + result = self.__sendGet(apiPath, 200).json() + if result["state"] == "SUCCESS": + self.session.close() + elif result["state"] == "ERROR": + self.session.close() + raise "Import was not succesful" diff --git a/snappi_cyperf/Test_l47.py b/snappi_cyperf/Test_l47.py new file mode 100644 index 0000000..d827955 --- /dev/null +++ b/snappi_cyperf/Test_l47.py @@ -0,0 +1,149 @@ +import sys + +# sys.path.append("C:\\Users\\waseebai\\Documents\\GitHub\\snappi\\artifacts\\snappi") +sys.path.insert(0, "/home/dipendu/otg/open_traffic_generator/snappi/artifacts/snappi") + +import snappi + +api = snappi.api(location="http://127.0.0.1:5000", verify=False) +config = api.config() + +# port_1_ip = config.ports.port(name="p1", location="10.39.44.120")[-1] +# port_2_ip = config.ports.port(name="p2", location="10.39.44.195")[-1] + +tx = config.ports.port(name="tx", location="10.39.44.147")[-1] +rx = config.ports.port(name="rx", location="10.39.44.190")[-1] +# port_1_tag = config.ports.port(name="p1", location="user:port1")[-1] +# port_2_tag = config.ports.port(name="p2", location="user:port2")[-1] + +(d1, d2) = config.devices.device(name="d1").device(name="d2") +(e1,) = d1.ethernets.ethernet(name="d1.e1") +e1.connection.port_name = "tx" +e1.mac = "01:02:03:04:05:06" +e1.step = "00:00:00:00:00:01" +e1.count = 1 +# e1.max_count = 100 +e1.mtu = 1488 + +(e2,) = d2.ethernets.ethernet(name="d2.e2") +e2.connection.port_name = "rx" +e2.mac = "01:02:03:04:06:06" +e2.step = "00:00:00:00:00:01" +e2.count = 2 +# e2.max_count = 100 +e2.mtu = 1488 + +(vlan1,) = e1.vlans.vlan(name="vlan1") +vlan1.id = 1 +vlan1.priority = 1 +vlan1.tpid = "x8100" +vlan1.count = 1 +vlan1.step = 1 +vlan1.per_count = 1 + +(vlan2,) = e2.vlans.vlan(name="vlan2") +vlan2.id = 1 +vlan2.priority = 1 +vlan2.tpid = "x8100" +vlan2.count = 1 +vlan2.step = 1 +vlan2.per_count = 1 + +(ip1,) = e1.ipv4_addresses.ipv4(name="e1.ipv4") +ip1.address = "10.0.0.10" +ip1.gateway = "10.0.0.1" +ip1.step = "0.0.0.1" +ip1.count = 1 +# ip1.max_count = 1 +ip1.prefix = 16 + +(ip2,) = e2.ipv4_addresses.ipv4(name="e2.ipv4") +ip2.address = "10.0.0.20" +ip2.gateway = "10.0.0.1" +ip2.step = "0.0.0.1" +ip2.count = 1 +# ip2.max_count = 1 +ip2.prefix = 16 + +# TCP/UDP configs + +(t1,) = d1.tcps.tcp(name="Tcp1") +t1.ip_interface_name = ip1.name +t1.receive_buffer_size = 1111 +t1.transmit_buffer_size = 1112 +t1.retransmission_minimum_timeout = 100 +t1.retransmission_maximum_timeout = 1001 +t1.minimum_source_port = 100 +t1.maximum_source_port = 101 +# t1.data_content_source = "SyntheticData" +# t1.data_content_value = "30000" +# t1.direction = "client_to_server" + +(t2,) = d2.tcps.tcp(name="Tcp2") +t2.ip_interface_name = ip2.name +t2.receive_buffer_size = 2222 +t2.transmit_buffer_size = 2221 +t2.retransmission_minimum_timeout = 200 +t2.retransmission_maximum_timeout = 2002 +t2.minimum_source_port = 200 +t2.maximum_source_port = 202 + +(http_1,) = d1.https.http(name="HTTP1") +http_1.profile = "Chrome" +http_1.version = "HTTP11" +http_1.connection_persistence = "ConnectionPersistenceStandard" +(http_client,) = http_1.clients.client() +http_client.cookie_reject_probability = False +http_client.max_persistent_requests = 1 + +(http_2,) = d2.https.http(name="HTTP2") +http_2.profile = "Apache" +http_2.version = "HTTP11" +http_2.connection_persistence = "ConnectionPersistenceEnabled" +(http_server,) = http_2.servers.server() + +# (get_a, post_a) = http_client.methods.method().method() +# (get1,) = get_a.get.get() + +# get1.destination = "Traffic2_HTTPServer1:80" +# get1.page = "./1b.html" +# get1.destination = "Traffic2_HTTPServer1:80" #real http server ip or emulated http object get1.destination = "http2:80"\ +# get1.name_value_args = "name1=val1" +# for http server emulation +# get1.destination = http_2.name +# (post1,) = post1_a.post.post() +# post1.destination = "Traffic2_HTTPServer1:80" +# post1.page = "./1b.html" +# (delete1,) = delete_a.delete.delete() +# delete1.destination = "Traffic2_HTTPServer1:80" +# delete1.page = "./1b.html" + +(tp1,) = config.trafficprofile.trafficprofile() +(segment1, segment2) = tp1.segment.segment().segment() +segment1.name = "Linear segment1" +segment1.duration = 40 +# segment1.enable_ramp_up = True +# segment1.ramp_down_time = 50 +# segment1.ramp_down_value = 100 +# segment1.enable_ramp_down = True +# segment1.ramp_up_time = 60 +# segment1.ramp_up_value = 100 +segment2.name = "Linear segment2" +segment2.duration = 70 +tp1.timeline = [segment1.name, segment2.name] +tp1.objective_type = ["Connections per second", "Simulated users"] +tp1.objective_value = [100, 200] +(obj1, obj2) = tp1.objectives.objective().objective() + +print("In test before set_config") +response = api.set_config(config) +print("In test after set_config") +print(response) +api.close() + +cs = api.control_state() +cs.app.state = "start" # cs.app.state.START +response1 = api.set_control_state(cs) +print(response1) +# cs.app.state = "stop" # cs.app.state.START +# api.set_control_state(cs) diff --git a/snappi_cyperf/__init__.py b/snappi_cyperf/__init__.py new file mode 100644 index 0000000..60f26d0 --- /dev/null +++ b/snappi_cyperf/__init__.py @@ -0,0 +1 @@ +from snappi_cyperf.cyperfapi import Api diff --git a/snappi_cyperf/common.py b/snappi_cyperf/common.py new file mode 100644 index 0000000..418f432 --- /dev/null +++ b/snappi_cyperf/common.py @@ -0,0 +1,41 @@ +from snappi_cyperf.logger import get_cyperf_logger + + +class Common(object): + def __init__(self): + self.logger = get_cyperf_logger(__name__) + + def get_ip_name(self, name): + """ + return the IP config from statefull flow endpoints. + """ + for app in self._api._apps: + for flow in app.stateful_flows: + if flow.client.protocol == name: + for endpoint in flow.client.endpoints: + return "e1.ipv4" + elif flow.server.protocol == name: + for endpoint in flow.server.endpoints: + return "e2.ipv4" + + def get_protocol_ip(self, apps_obj): + return_list = [] + for app in apps_obj.apps: + for flow in app.stateful_flows: + if flow.client.endpoints and flow.server.endpoints: + temp_dict, client, server = {}, {}, {} + for endpoint in flow.client.endpoints: + temp_dict[flow.client.protocol] = endpoint.ip_interface_name + for endpoint in flow.server.endpoints: + temp_dict[flow.server.protocol] = endpoint.dest.name + # temp_dict['client'] = client + # temp_dict['server'] = server + # return_list.append(temp_dict) + return temp_dict + + def get_community_url(self, url): + import re + + match = re.match(r"(.*\/communityList\/)(\d+)", url) + if match: + return match.group(1) + match.group(2) + "/" diff --git a/snappi_cyperf/cyperfapi.py b/snappi_cyperf/cyperfapi.py new file mode 100644 index 0000000..1e4a241 --- /dev/null +++ b/snappi_cyperf/cyperfapi.py @@ -0,0 +1,397 @@ +import inspect +import json +import time, re +import sys +import logging + +# import ixrestutils as http_transport +from collections import namedtuple + +# import sys +# sys.path.insert(0, "/home/dipendu/otg/open_traffic_generator/snappi/artifacts/snappi") +import snappi +from snappi_cyperf.RESTasV3 import RESTasV3 +import snappi_cyperf.ixrestutils as http_transport +from snappi_cyperf.ports import port +from snappi_cyperf.interface import interfaces +from snappi_cyperf.tcp import tcp_config +from snappi_cyperf.http_config import http_config +from snappi_cyperf.objectiveandtimeline import objectiveandtimeline + +# from snappi_cyperf.http_config import client_config + +# from snappi_cyperf.http_server_config import server_config +from snappi_cyperf.logger import setup_cyperf_logger +from snappi_cyperf.common import Common +from snappi_cyperf.exceptions import Snappil47Exception + + +# from protocols import protocols +# from snappi_cyperf.chassis import chassis +# from stats import stats + +WAP_USERNAME = "admin" +WAP_PASSWORD = "CyPerf&Keysight#1" +WAP_CLIENT_ID = "clt-wap" +TOKEN_ENDPOINT = "/auth/realms/keysight/protocol/openid-connect/token" + + +class Api(snappi.Api): + """ """ + + def __init__( + self, + host, + version, + username, + password, + gateway_port=8080, + log_level="info", + **kwargs, + ): + """Create a session + - address (str): The ip address of the TestPlatform to connect to + where test sessions will be created or connected to. + - port (str): The rest port of the TestPlatform to connect to. + - username (str): The username to be used for authentication + - password (str): The password to be used for authentication + """ + print("In cyperfAPI init") + super().__init__(**kwargs) + # host='https://127.0.0.1:11009' if host is None else host + # ) + self.rest = RESTasV3( + ipAddress=host, + username=WAP_USERNAME, + password=WAP_PASSWORD, + client_id=WAP_CLIENT_ID, + ) + self._host = host + self._address, self._port = self._get_addr_port(self._host) + self._username = username + self._password = password + self._config_url = {} + self._network_segments = {} + self._ip_ranges = {} + self.configID = None + self.session_id = None + + self.cyperf_version = version + self._gateway_port = gateway_port + self._l4config = None + self._assistant = None + self._config_type = self.config() + self.interfaces = interfaces(self) + self.tcp = tcp_config(self) + self.common = Common() + self.http = http_config(self) + self.objectiveandtimeline = objectiveandtimeline(self) + # self.http_sr = server_config(self) + self.port = port(self) + self._log_level = ( + logging.INFO if kwargs.get("loglevel") is None else kwargs.get("loglevel") + ) + self.logger = setup_cyperf_logger(self.log_level, module_name=__name__) + # self.protocols = protocols(self) + # self.chassis = chassis(self) + # self.stats = stats(self) + + def _get_addr_port(self, host): + items = host.split("/") + items = items[-1].split(":") + + addr = items[0] + if len(items) == 2: + return addr, items[-1] + else: + if host.startswith("https"): + return addr, "443" + else: + return addr, "80" + + @property + def _config(self): + return self._config + + @property + def log_level(self): + return self._log_level + + def _request_detail(self): + request_detail = snappi.Warning() + errors = self._errors + warnings = list() + if errors: + Snappil47Exception(errors) + warnings.append("") + request_detail.warnings = warnings + return request_detail + + def set_config(self, config): + """Set or update the configuration""" + try: + if isinstance(config, (type(self._config_type), str)) is False: + raise TypeError("The content must be of type Union[Config, str]") + + if isinstance(config, str) is True: + config = self._config_type.deserialize(config) + self._config_objects = {} + self._device_encap = {} + self._cyperf_objects = {} + self._connect() + # self._ip_list = self.common.get_protocol_ip(config) + self._l47config = config + self.interfaces.config(self.rest) + # self.tcp.config(self.rest) + # self.http.config(self.rest) + # self.objectiveandtimeline.config(self.rest) + self.port.config(self.rest) + # self._apply_config() + except Exception as err: + self.logger.info(f"error:{err}") + raise Snappil47Exception(err) + return self._request_detail() + + def add_error(self, error): + """Add an error to the global errors""" + if isinstance(error, str) is False: + self._errors.append("%s %s" % (type(error), str(error))) + else: + self._errors.append(error) + + def get_config(self): + return self._l47config + + def set_control_state(self, config): + try: + if config.app.state == "start": + self.start_test(self.rest) + + elif config.app.state == "stop": + self.stop_test(self.rest) + elif config.app.state == "abort": + self.abort_test(self.rest) + except Exception as err: + self.logger.info(f"error:{err}") + raise Snappil47Exception(err) + return self._request_detail() + + def stats(self, config): + """Set or update the configuration""" + try: + if isinstance(config, (type(self._config_type), str)) is False: + raise TypeError("The content must be of type Union[Config, str]") + + if isinstance(config, str) is True: + config = self._config_type.deserialize(config) + self._config = config + except Exception as err: + print(err) + + def _apply_config(self): + """ + Apply configs + """ + + url = self._cyperf + "cyperf/test/operations/applyConfiguration" + payload = {} + reply = self._request("POST", url, payload, option=1) + if not reply.ok: + raise Exception(reply.text) + self._wait_for_action_to_finish(reply, url) + + def start_test(self, rest): + """ + start test + """ + rest.start_test() + + def stop_test(self, rest): + """ + stop test + """ + rest.stop_test() + + def abort_test(self, rest): + """ + abort test + """ + rest.abort_test() + + def get_current_state(self): + """ + This method gets the test current state. (for example - running, unconfigured, ..) + """ + url = "%s/cyperf/test/activeTest" % (self._cyperf) + reply = self._request("GET", url, option=1) + return reply["currentState"] + + def strip_api_and_version_from_url(self, url): + """ + #remove the slash (if any) at the beginning of the url + """ + if url[0] == "/": + url = url[1:] + url_elements = url.split("/") + if "api" in url: + # strip the api/v0 part of the url + url_elements = url_elements[2:] + return "/".join(url_elements) + + def session_assistance(self): + """ """ + # self.connection = http_transport.get_connection( + # self._host, self._gateway_port, http_redirect=True + # ) + # session_url = "sessions" + # data = {"cyperfVersion": self.cyperf_version} + # data = json.dumps(data) + # reply = self.connection.http_post(url=session_url, data=data) + # if not reply.ok: + # raise Exception(reply.text) + # try: + # new_obj_path = reply.headers["location"] + # except: + # raise Exception( + # "Location header is not present. Please check if the action was created successfully." + # ) + # session_id = new_obj_path.split("/")[-1] + # self._cyperf = "%s/%s" % (session_url, session_id) + # start_session_url = "%s/operations/start" % (self._cyperf) + # reply = self.connection.http_post(url=start_session_url, data={}) + # if not reply.ok: + # Snappil47Exception.status_code = reply.status_code + # raise Exception(reply.text) + # action_result_url = reply.headers.get("location") + # if action_result_url: + # action_result_url = self.strip_api_and_version_from_url(action_result_url) + # action_finished = False + # while not action_finished: + # action_status_obj = self.connection.http_get(url=action_result_url) + # if action_status_obj.state == "finished": + # if action_status_obj.status == "Successful": + # action_finished = True + # self._cyperf = self._cyperf + "/" + # self.logger.info( + # "Connected to L47, Session ID:%s" % (self._cyperf) + # ) + # msg = "Successfully connected to cyperf" + # # self.add_error(msg) + # self.warning(msg) + # else: + # error_msg = ( + # "Error while executing action '%s'." % start_session_url + # ) + # if action_status_obj.status == "Error": + # error_msg += action_status_obj.error + # raise Exception(error_msg) + # else: + # time.sleep(0.1) + # self.configID = "appsec-appmix-and-attack" + # self.configID = "appsec-empty-config" + self.configID = "appsec-appmix" + response = self.rest.create_session(self.configID) + if response: + self.session_id = response.json()[0]["id"] + print("Config successfully opened, session ID: {}".format(self.session_id)) + + def _connect(self): + """Connect to s Cyperf API Server.""" + self._errors = [] + self.logger = setup_cyperf_logger(self.log_level, module_name=__name__) + self.logger.info("Connecting to Cyperf") + if self._assistant is None: + self.session_assistance() + + def _request( + self, method, url, payload=None, params=None, headers=None, option=None + ): + """ """ + data = json.dumps(payload) + response = self.connection._request( + method=method, + url=url, + data=data, + params=params, + headers=headers, + option=option, + ) + return response + + def _wait_for_action_to_finish(self, reply_obj, action_url): + """ + This method waits for an action to finish executing. after a POST request is sent in order to start an action, + The HTTP reply will contain, in the header, a 'location' field, that contains an URL. + The action URL contains the status of the action. we perform a GET on that URL every 0.5 seconds until the action finishes with a success. + If the action fails, we will throw an error and print the action's error message. + Args: + - reply_obj the reply object holding the location + - rt_handle - the url pointing to the operation + """ + action_result_url = reply_obj.headers.get("location") + if action_result_url: + action_result_url = self.strip_api_and_version_from_url(action_result_url) + action_finished = False + while not action_finished: + action_status_obj = self._request("GET", action_result_url) + # action_status_obj = rt_handle.invoke('http_get', url=action_result_url) + if action_status_obj.state == "finished": + if action_status_obj.status == "Successful": + action_finished = True + else: + error_msg = "Error while executing action '%s'." % action_url + if action_status_obj.status == "Error": + error_msg += action_status_obj.error + raise Exception(error_msg) + else: + time.sleep(0.1) + + def strip_api_and_version_from_url(self, url): + """ + #remove the slash (if any) at the beginning of the url + """ + if url[0] == "/": + url = url[1:] + url_elements = url.split("/") + if "api" in url: + # strip the api/v0 part of the url + url_elements = url_elements[2:] + return "/".join(url_elements) + + def _get_url(self, parent, child): + """ """ + try: + pattern = re.search(r"(.*)(\{id\})(.*)", child) + if pattern: + url1 = parent + pattern.group(1) + url2 = pattern.group(3) + return (url1, url2) + except Exception: + raise Exception( + "can not get url for parent %s and child %s" % (parent, child) + ) + + def _set_payload(self, snappi_obj, attr_map): + properties = snappi_obj._properties + payload = {} + for snappi_attr, ixl_map in attr_map.items(): + value = snappi_obj.get(snappi_attr) + payload[ixl_map] = value + + # for prop_name in properties: + + # if prop_name != 'url' and isinstance(properties[prop_name], (str, int, float, list)): + # prop_name_new = self._convert_camel(prop_name) + # payload[prop_name_new] = properties[prop_name] + return payload + + def _convert_camel(self, argument): + word_regex_pattern = re.compile("[^A-Za-z]+") + words = word_regex_pattern.split(argument) + return "".join(w.lower() if i == 0 else w.title() for i, w in enumerate(words)) + + def info(self, message): + print("working %s" % message) + + def warning(self, message): + logging.warning(message) diff --git a/snappi_cyperf/exceptions.py b/snappi_cyperf/exceptions.py new file mode 100644 index 0000000..ccc47c8 --- /dev/null +++ b/snappi_cyperf/exceptions.py @@ -0,0 +1,70 @@ +# import errors as err +import sys +import traceback + +# sys.path.insert(0, "/home/dipendu/otg/open_traffic_generator/snappi/artifacts/snappi") +import snappi + + +class Snappil47Exception(Exception): + def __init__(self, *args): + super(Snappil47Exception, self).__init__(*args) + self._args = args + self._message = None + self._status_code = None + self._url = None + self.process_exception() + + @property + def args(self): + return ( + self._status_code, + ([self._message] if not isinstance(self._message, list) else self._message), + self._url, + ) + + @property + def message(self): + return self._message.args[0] + + @property + def url(self): + return self._url + + @property + def status_code(self): + return self._status_code + + def process_exception(self): + # import pdb + + # pdb.set_trace() + if isinstance(self._args[0].args, tuple) and len(self._args[0].args) == 1: + if "Max retries exceeded" in str(self._args[0].args[0]): + self._status_code = 500 + self._message = self._args[0] + return (self._message, self._status_code) + if isinstance(self._args[0].args[0], (str, list)): + self._status_code = ( + 400 if self._status_code is None else self._status_code + ) + self._message = self._args[0].args[0] + return (self._message, self._status_code) + if isinstance( + self._args[0], + (NameError, TypeError, ValueError, KeyError, AttributeError), + ): + self._status_code = 400 + self._message = self._args[0].args + return (self._status_code, self._message) + if isinstance(self._args[0], (ImportError, RuntimeError)): + self._status_code = 400 + self._message = self._args[0] + return (self._status_code, self._message) + else: + self._status_code = 400 + self._message = self._args + return (self._status_code, self._message) + else: + self._message = self._args + return diff --git a/snappi_cyperf/hero.py b/snappi_cyperf/hero.py new file mode 100644 index 0000000..c12f81e --- /dev/null +++ b/snappi_cyperf/hero.py @@ -0,0 +1,161 @@ +import sys +import pprint +import socket +import struct +import macaddress +import ipaddress +from copy import deepcopy +from munch import DefaultMunch + +# utils +socket_inet_ntoa = socket.inet_ntoa +struct_pack = struct.pack + + +class MAC(macaddress.MAC): + formats = ("xx:xx:xx:xx:xx:xx",) + macaddress.MAC.formats + + +maca = MAC # optimization so the . does not get executed multiple times + +dflt_params = { # CONFIG VALUE # DEFAULT VALUE + "SCHEMA_VER": "0.0.4", + "DC_START": "220.0.1.1", # '220.0.1.2' + "DC_STEP": "0.0.1.0", # '0.0.1.0' + "LOOPBACK": "221.0.0.1", # '221.0.0.1' + "PAL": "221.1.0.0", # '221.1.0.1' + "PAR": "221.2.0.0", # '221.2.0.1' + "GATEWAY": "222.0.0.1", # '222.0.0.1' + "DPUS": 8, # 1 + "ENI_START": 1, # 1 + "ENI_COUNT": 256, # 32 + "ENI_STEP": 1, # 1 + "ENI_L2R_STEP": 0, # 1000 + "VNET_PER_ENI": 1, # 16 TODO: partialy implemented + "ACL_NSG_COUNT": 5, # 5 (per direction per ENI) + "ACL_RULES_NSG": 1000, # 1000 + "IP_PER_ACL_RULE": 1, # 100 + "ACL_MAPPED_PER_NSG": 500, # 500, efective is 250 because denny are skiped + "MAC_L_START": "00:1A:C5:00:00:01", + "MAC_R_START": "00:1B:6E:00:00:01", + "MAC_STEP_ENI": "00:00:00:18:00:00", # '00:00:00:18:00:00' + "MAC_STEP_NSG": "00:00:00:02:00:00", + "MAC_STEP_ACL": "00:00:00:00:01:00", + "IP_L_START": "1.1.0.1", # local, eni + "IP_R_START": "1.4.0.1", # remote, the world + "IP_STEP1": "0.0.0.1", + "IP_STEP_ENI": "0.64.0.0", + "IP_STEP_NSG": "0.2.0.0", + "IP_STEP_ACL": "0.0.1.0", + "IP_STEPE": "0.0.0.2", + "TOTAL_OUTBOUND_ROUTES": 25600000, # ENI_COUNT * 100K +} + +params_dict = deepcopy(dflt_params) + +cooked_params_dict = {} +for ip in [ + "IP_STEP1", + "IP_STEP_ENI", + "IP_STEP_NSG", + "IP_STEP_ACL", + "IP_STEPE", + "IP_L_START", + "IP_R_START", + "PAL", + "PAR", + "GATEWAY", +]: + cooked_params_dict[ip] = int(ipaddress.ip_address((params_dict[ip]))) +for mac in [ + "MAC_L_START", + "MAC_R_START", + "MAC_STEP_ENI", + "MAC_STEP_NSG", + "MAC_STEP_ACL", +]: + cooked_params_dict[mac] = int(maca(params_dict[mac])) + + +params = DefaultMunch.fromDict(params_dict) +cooked_params = DefaultMunch.fromDict(cooked_params_dict) + + +p = params +ip_int = cooked_params + + +################################################################################### + + +sys.path.insert(0, "/home/dipendu/otg/open_traffic_generator/snappi/artifacts/snappi") +import snappi + + +ixl_api = snappi.api(location="http://127.0.0.1:5000", verify=False) +# ixl_api = snappi.api(location="http://127.0.0.1:5000", verify=False, ext="ixload") +ixlc = ixl_api.config() + +port_1 = ixlc.ports.port(name="p1", location="10.39.44.147")[-1] +port_2 = ixlc.ports.port(name="p2", location="10.39.44.190")[-1] + +c_device = ixlc.devices.add(name="client") +s_device = ixlc.devices.add(name="server") + +# c_device.port = port_1 +# S_device.port = port_2 + + +for eni_index, eni in enumerate( + range(p.ENI_START, p.ENI_START + p.ENI_COUNT * p.ENI_STEP, p.ENI_STEP) +): # Per ENI + + # vtep_remote = socket_inet_ntoa(struct_pack('>L', ip_int.PAR + ip_int.IP_STEP1 * eni_index)) + # gateway_ip = socket_inet_ntoa(struct_pack('>L', ip_int.GATEWAY + ip_int.IP_STEP1 * eni_index)) + remote_ip_a_eni = ip_int.IP_R_START + eni_index * ip_int.IP_STEP_ENI + remote_mac_a_eni = ip_int.MAC_R_START + eni_index * ip_int.MAC_STEP_ENI + gateway_mac = str(maca(remote_mac_a_eni)) + + # add mapping for ENI itself SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY + + r_vni_id = eni + p.ENI_L2R_STEP + + c_eth = c_device.ethernets.add() + c_eth.name = "NETMAC%d" % eni + c_eth.mac = str(maca(remote_mac_a_eni)) + + c_vlan = c_eth.vlans.add() + c_vlan.name = "NETVLAN%d" % eni + c_vlan.id = r_vni_id + + c_ip = c_eth.ipv4_addresses.add() + c_ip.name = "NETIP%d" % eni + c_ip.address = socket_inet_ntoa(struct_pack(">L", remote_ip_a_eni)) + c_ip.gateway = "0.0.0.0" + c_ip.prefix = 10 + + eni_ip = socket_inet_ntoa( + struct_pack(">L", ip_int.IP_L_START + eni_index * ip_int.IP_STEP_ENI) + ) + eni_mac = str(maca(ip_int.MAC_L_START + eni_index * ip_int.MAC_STEP_ENI)) + + # import pdb; pdb.set_trace() + + s_eth = s_device.ethernets.add() + s_eth.name = "ENIMAC%d" % eni + s_eth.mac = eni_mac + + s_vlan = s_eth.vlans.add() + s_vlan.name = "ENIVLAN%d" % eni + s_vlan.id = eni + + s_ip = s_eth.ipv4_addresses.add() + s_ip.name = "ENIIP%d" % eni + s_ip.address = eni_ip + s_ip.gateway = "0.0.0.0" + s_ip.prefix = 10 + + +# import pdb; pdb.set_trace() +response = ixl_api.set_config(ixlc) +print(response) diff --git a/snappi_cyperf/hero_1.py b/snappi_cyperf/hero_1.py new file mode 100644 index 0000000..0b14c9c --- /dev/null +++ b/snappi_cyperf/hero_1.py @@ -0,0 +1,161 @@ +import sys +import pprint +import socket +import struct +import macaddress +import ipaddress +from copy import deepcopy +from munch import DefaultMunch + +# utils +socket_inet_ntoa = socket.inet_ntoa +struct_pack = struct.pack + + +class MAC(macaddress.MAC): + formats = ("xx:xx:xx:xx:xx:xx",) + macaddress.MAC.formats + + +maca = MAC # optimization so the . does not get executed multiple times + +dflt_params = { # CONFIG VALUE # DEFAULT VALUE + "SCHEMA_VER": "0.0.4", + "DC_START": "220.0.1.1", # '220.0.1.2' + "DC_STEP": "0.0.1.0", # '0.0.1.0' + "LOOPBACK": "221.0.0.1", # '221.0.0.1' + "PAL": "221.1.0.0", # '221.1.0.1' + "PAR": "221.2.0.0", # '221.2.0.1' + "GATEWAY": "222.0.0.1", # '222.0.0.1' + "DPUS": 8, # 1 + "ENI_START": 1, # 1 + "ENI_COUNT": 2, # 32 + "ENI_STEP": 1, # 1 + "ENI_L2R_STEP": 0, # 1000 + "VNET_PER_ENI": 1, # 16 TODO: partialy implemented + "ACL_NSG_COUNT": 5, # 5 (per direction per ENI) + "ACL_RULES_NSG": 1000, # 1000 + "IP_PER_ACL_RULE": 1, # 100 + "ACL_MAPPED_PER_NSG": 500, # 500, efective is 250 because denny are skiped + "MAC_L_START": "00:1A:C5:00:00:01", + "MAC_R_START": "00:1B:6E:00:00:01", + "MAC_STEP_ENI": "00:00:00:18:00:00", # '00:00:00:18:00:00' + "MAC_STEP_NSG": "00:00:00:02:00:00", + "MAC_STEP_ACL": "00:00:00:00:01:00", + "IP_L_START": "1.1.0.1", # local, eni + "IP_R_START": "1.4.0.1", # remote, the world + "IP_STEP1": "0.0.0.1", + "IP_STEP_ENI": "0.64.0.0", + "IP_STEP_NSG": "0.2.0.0", + "IP_STEP_ACL": "0.0.1.0", + "IP_STEPE": "0.0.0.2", + "TOTAL_OUTBOUND_ROUTES": 200, # ENI_COUNT * 100K +} + +params_dict = deepcopy(dflt_params) + +cooked_params_dict = {} +for ip in [ + "IP_STEP1", + "IP_STEP_ENI", + "IP_STEP_NSG", + "IP_STEP_ACL", + "IP_STEPE", + "IP_L_START", + "IP_R_START", + "PAL", + "PAR", + "GATEWAY", +]: + cooked_params_dict[ip] = int(ipaddress.ip_address((params_dict[ip]))) +for mac in [ + "MAC_L_START", + "MAC_R_START", + "MAC_STEP_ENI", + "MAC_STEP_NSG", + "MAC_STEP_ACL", +]: + cooked_params_dict[mac] = int(maca(params_dict[mac])) + + +params = DefaultMunch.fromDict(params_dict) +cooked_params = DefaultMunch.fromDict(cooked_params_dict) + + +p = params +ip_int = cooked_params + + +################################################################################### + + +sys.path.insert(0, "/home/dipendu/otg/open_traffic_generator/snappi/artifacts/snappi") +import snappi + + +ixl_api = snappi.api(location="http://127.0.0.1:5000", verify=False) +# ixl_api = snappi.api(location="http://127.0.0.1:5000", verify=False, ext="ixload") +ixlc = ixl_api.config() + +port_1 = ixlc.ports.port(name="p1", location="10.39.44.147")[-1] +port_2 = ixlc.ports.port(name="p2", location="10.39.44.190")[-1] + +c_device = ixlc.devices.add(name="client") +s_device = ixlc.devices.add(name="server") + +# c_device.port = port_1 +# S_device.port = port_2 + + +for eni_index, eni in enumerate( + range(p.ENI_START, p.ENI_START + p.ENI_COUNT * p.ENI_STEP, p.ENI_STEP) +): # Per ENI + + # vtep_remote = socket_inet_ntoa(struct_pack('>L', ip_int.PAR + ip_int.IP_STEP1 * eni_index)) + # gateway_ip = socket_inet_ntoa(struct_pack('>L', ip_int.GATEWAY + ip_int.IP_STEP1 * eni_index)) + remote_ip_a_eni = ip_int.IP_R_START + eni_index * ip_int.IP_STEP_ENI + remote_mac_a_eni = ip_int.MAC_R_START + eni_index * ip_int.MAC_STEP_ENI + gateway_mac = str(maca(remote_mac_a_eni)) + + # add mapping for ENI itself SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY + + r_vni_id = eni + p.ENI_L2R_STEP + + c_eth = c_device.ethernets.add() + c_eth.name = "NETMAC%d" % eni + c_eth.mac = str(maca(remote_mac_a_eni)) + + c_vlan = c_eth.vlans.add() + c_vlan.name = "NETVLAN%d" % eni + c_vlan.id = r_vni_id + + c_ip = c_eth.ipv4_addresses.add() + c_ip.name = "NETIP%d" % eni + c_ip.address = socket_inet_ntoa(struct_pack(">L", remote_ip_a_eni)) + c_ip.gateway = "0.0.0.0" + c_ip.prefix = 10 + + eni_ip = socket_inet_ntoa( + struct_pack(">L", ip_int.IP_L_START + eni_index * ip_int.IP_STEP_ENI) + ) + eni_mac = str(maca(ip_int.MAC_L_START + eni_index * ip_int.MAC_STEP_ENI)) + + # import pdb; pdb.set_trace() + + s_eth = s_device.ethernets.add() + s_eth.name = "ENIMAC%d" % eni + s_eth.mac = eni_mac + + s_vlan = s_eth.vlans.add() + s_vlan.name = "ENIVLAN%d" % eni + s_vlan.id = eni + + s_ip = s_eth.ipv4_addresses.add() + s_ip.name = "ENIIP%d" % eni + s_ip.address = eni_ip + s_ip.gateway = "0.0.0.0" + s_ip.prefix = 10 + + +# import pdb; pdb.set_trace() +response = ixl_api.set_config(ixlc) +print(response) diff --git a/snappi_cyperf/hero_2.py b/snappi_cyperf/hero_2.py new file mode 100644 index 0000000..b6fee75 --- /dev/null +++ b/snappi_cyperf/hero_2.py @@ -0,0 +1,165 @@ +import sys +import pprint +import socket +import struct +import macaddress +import ipaddress +from copy import deepcopy +from munch import DefaultMunch + +# utils +socket_inet_ntoa = socket.inet_ntoa +struct_pack = struct.pack + + +class MAC(macaddress.MAC): + formats = ("xx:xx:xx:xx:xx:xx",) + macaddress.MAC.formats + + +maca = MAC # optimization so the . does not get executed multiple times + +dflt_params = { # CONFIG VALUE # DEFAULT VALUE + "SCHEMA_VER": "0.0.4", + "DC_START": "220.0.1.1", # '220.0.1.2' + "DC_STEP": "0.0.1.0", # '0.0.1.0' + "LOOPBACK": "221.0.0.1", # '221.0.0.1' + "PAL": "221.1.0.0", # '221.1.0.1' + "PAR": "221.2.0.0", # '221.2.0.1' + "GATEWAY": "222.0.0.1", # '222.0.0.1' + "DPUS": 8, # 1 + "ENI_START": 1, # 1 + "ENI_COUNT": 2, # 32 + "ENI_STEP": 1, # 1 + "ENI_L2R_STEP": 0, # 1000 + "VNET_PER_ENI": 1, # 16 TODO: partialy implemented + "ACL_NSG_COUNT": 5, # 5 (per direction per ENI) + "ACL_RULES_NSG": 1000, # 1000 + "IP_PER_ACL_RULE": 1, # 100 + "ACL_MAPPED_PER_NSG": 500, # 500, efective is 250 because denny are skiped + "MAC_L_START": "00:1A:C5:00:00:01", + "MAC_R_START": "00:1B:6E:00:00:01", + "MAC_STEP_ENI": "00:00:00:18:00:00", # '00:00:00:18:00:00' + "MAC_STEP_NSG": "00:00:00:02:00:00", + "MAC_STEP_ACL": "00:00:00:00:01:00", + "IP_L_START": "1.1.0.1", # local, eni + "IP_R_START": "1.4.0.1", # remote, the world + "IP_STEP1": "0.0.0.1", + "IP_STEP_ENI": "0.64.0.0", + "IP_STEP_NSG": "0.2.0.0", + "IP_STEP_ACL": "0.0.1.0", + "IP_STEPE": "0.0.0.2", + "TOTAL_OUTBOUND_ROUTES": 200, # ENI_COUNT * 100K +} + +params_dict = deepcopy(dflt_params) + +cooked_params_dict = {} +for ip in [ + "IP_STEP1", + "IP_STEP_ENI", + "IP_STEP_NSG", + "IP_STEP_ACL", + "IP_STEPE", + "IP_L_START", + "IP_R_START", + "PAL", + "PAR", + "GATEWAY", +]: + cooked_params_dict[ip] = int(ipaddress.ip_address((params_dict[ip]))) +for mac in [ + "MAC_L_START", + "MAC_R_START", + "MAC_STEP_ENI", + "MAC_STEP_NSG", + "MAC_STEP_ACL", +]: + cooked_params_dict[mac] = int(maca(params_dict[mac])) + + +params = DefaultMunch.fromDict(params_dict) +cooked_params = DefaultMunch.fromDict(cooked_params_dict) + + +p = params +ip_int = cooked_params + + +################################################################################### + + +sys.path.insert(0, "/home/dipendu/otg/open_traffic_generator/snappi/artifacts/snappi") +import snappi + + +ixl_api = snappi.api(location="http://127.0.0.1:5000", verify=False) +# ixl_api = snappi.api(location="http://127.0.0.1:5000", verify=False, ext="ixload") +ixlc = ixl_api.config() + +port_1 = ixlc.ports.port(name="p1", location="10.39.44.147")[-1] +port_2 = ixlc.ports.port(name="p2", location="10.39.44.190")[-1] + +c_device = ixlc.devices.add(name="client") +s_device = ixlc.devices.add(name="server") + +# c_device.port = port_1 +# S_device.port = port_2 + +for eni_index2, eni2 in enumerate( + range(p.ENI_START, p.ENI_START + p.ENI_COUNT * p.ENI_STEP, p.ENI_STEP) +): # Per ENI + remote_mac_a_eni = ip_int.MAC_R_START + eni_index2 * ip_int.MAC_STEP_ENI + gateway_mac = str(maca(remote_mac_a_eni)) + + c_eth = c_device.ethernets.add() + c_eth.name = "NETMAC%d" % eni2 + c_eth.mac = str(maca(remote_mac_a_eni)) + + eni_mac = str(maca(ip_int.MAC_L_START + eni_index2 * ip_int.MAC_STEP_ENI)) + + s_eth = s_device.ethernets.add() + s_eth.name = "ENIMAC%d" % eni2 + s_eth.mac = eni_mac + + for eni_index, eni in enumerate( + range(p.ENI_START, p.ENI_START + p.ENI_COUNT * p.ENI_STEP, p.ENI_STEP) + ): # Per ENI + + # vtep_remote = socket_inet_ntoa(struct_pack('>L', ip_int.PAR + ip_int.IP_STEP1 * eni_index)) + # gateway_ip = socket_inet_ntoa(struct_pack('>L', ip_int.GATEWAY + ip_int.IP_STEP1 * eni_index)) + remote_ip_a_eni = ip_int.IP_R_START + eni_index * ip_int.IP_STEP_ENI + + # add mapping for ENI itself SAI_OBJECT_TYPE_ENI_ETHER_ADDRESS_MAP_ENTRY + + r_vni_id = eni + p.ENI_L2R_STEP + + c_vlan = c_eth.vlans.add() + c_vlan.name = "NETVLAN%d" % eni + c_vlan.id = r_vni_id + + c_ip = c_eth.ipv4_addresses.add() + c_ip.name = "NETIP%d" % eni + c_ip.address = socket_inet_ntoa(struct_pack(">L", remote_ip_a_eni)) + c_ip.gateway = "0.0.0.0" + c_ip.prefix = 10 + + eni_ip = socket_inet_ntoa( + struct_pack(">L", ip_int.IP_L_START + eni_index * ip_int.IP_STEP_ENI) + ) + + # import pdb; pdb.set_trace() + + s_vlan = s_eth.vlans.add() + s_vlan.name = "ENIVLAN%d" % eni + s_vlan.id = eni + + s_ip = s_eth.ipv4_addresses.add() + s_ip.name = "ENIIP%d" % eni + s_ip.address = eni_ip + s_ip.gateway = "0.0.0.0" + s_ip.prefix = 10 + + +# import pdb; pdb.set_trace() +response = ixl_api.set_config(ixlc) +print(response) diff --git a/snappi_cyperf/http_config.py b/snappi_cyperf/http_config.py new file mode 100644 index 0000000..23f5a16 --- /dev/null +++ b/snappi_cyperf/http_config.py @@ -0,0 +1,363 @@ +import json +import re +import time +from snappi_cyperf.timer import Timer + + +class http_config: + """ """ + + _HTTP_CLIENT = { + # "enable_tos": "enableTos", + # "priority_flow_control_class" : "pfcClass", + # "precedence_tos" : "precedenceTOS", + # "delay_tos" : "delayTOS", + # "throughput_tos" : "throughputTOS", + # "reliability_tos" : "reliabilityTOS", + # "url_stats_count": "urlStatsCount", + # "disable_priority_flow_control": "disablePfc", + # "enable_vlan_priority": "enableVlanPriority", + # "vlan_priority": "vlanPriority", + # "esm": "esm", + # "enable_esm": "enableEsm", + # "time_to_live_value": "ttlValue", + # "tcp_close_option" : "tcpCloseOption", + # "enable_integrity_check_support" : "enableIntegrityCheckSupport", + # "type_of_service": "tos", + # "high_perf_with_simulated_user": "highPerfWithSU", + "profile": "Name", + "version": "HTTPVersion", + "connection_persistence": "ConnectionPersistence", + } + _HTTP_SERVER = { + # "enable_tos": "enableTos", + # "priority_flow_control_class" : "pfcClass", + # "precedence_tos" : "precedenceTOS", + # "delay_tos" : "delayTOS", + # "throughput_tos" : "throughputTOS", + # "reliability_tos" : "reliabilityTOS", + # "url_stats_count": "urlStatsCount", + # "disable_priority_flow_control": "disablePfc", + # "enable_vlan_priority": "enableVlanPriority", + # "vlan_priority": "vlanPriority", + # "esm": "esm", + # "enable_esm": "enableEsm", + # "time_to_live_value": "ttlValue", + # "tcp_close_option" : "tcpCloseOption", + # "enable_integrity_check_support" : "enableIntegrityCheckSupport", + # "type_of_service": "tos", + # "high_perf_with_simulated_user": "highPerfWithSU", + "profile": "Name", + "version": "HTTPVersion", + "connection_persistence": "ConnectionPersistence", + } + _HTTP_CLIENTS = { + # "browser_emulation_name": "Name", + # "version": "httpVersion", + # "cookie_jar_size": "cookieJarSize", + # "cookie_reject_probability": "cookieRejectProbability", + # "enable_cookie_support": "enableCookieSupport", + # "command_timeout": "commandTimeout", + # "command_timeout_ms": "commandTimeout_ms", + # "enable_proxy": "enableHttpProxy", + # "proxy" : "httpProxy", + # "keep_alive": "keepAlive", + # "max_sessions": "maxSessions", + # "max_streams": "maxStreams", + # "max_pipeline": "maxPipeline", + "max_persistent_requests": "ConnectionsMaxTransactions", + # "exact_transactions": "exactTransactions", + # "follow_http_redirects": "followHttpRedirects", + # "enable_decompress_support": "enableDecompressSupport", + # "enable_per_conn_cookie_support": "enablePerConnCookieSupport", + # "ip_preference" : "ipPreference", + # "enable_large_header": "enableLargeHeader", + # "max_header_len": "maxHeaderLen", + # "per_header_percent_dist": "perHeaderPercentDist", + # "enable_auth": "enableAuth", + # "piggy_back_ack": "piggybackAck", + # "tcp_fast_open": "tcpFastOpen", + # "content_length_deviation_tolerance": "contentLengthDeviationTolerance", + # "disable_dns_resolution_cache": "disableDnsResolutionCache", + # "enable_consecutive_ips_per_session": "enableConsecutiveIpsPerSession", + # "enable_achieve_cc_first": "enableAchieveCCFirst", + # "enable_traffic_distribution_for_cc": "enableTrafficDistributionForCC", + # "browser_emulation_name": "browserEmulationName", + } + _HTTP_SERVERS = { + # "rst_timeout": "rstTimeout", + # "enable_http2": "enableHTTP2", + # "port": "httpPort", + # "request_timeout": "requestTimeout", + # "maximum_response_delay": "maxResponseDelay", + # "minimum_response_delay": "minResponseDelay", + # "dont_expect_upgrade": "dontExpectUpgrade", + # "enable_per_server_per_url_stat": "enablePerServerPerURLstat", + # "url_page_size": "urlPageSize", + # "enable_chunk_encoding": "enableChunkEncoding", + # # "integrity_check_option" : "integrityCheckOption", + # "enable_md5_checksum": "enableMD5Checksum", + } + _HTTP_GET = { + # "destination": "destination", + # "page": "pageObject", + # "abort" : "abort", + # "profile": "profile", + # "name_value_args": "namevalueargs", + # "enable_direct_server_return": "enableDi", + } + + _HTTP_DELETE = { + # "destination": "destination", + # "page": "pageObject", + # "abort": "abort", + # "profile": "profile", + } + + _HTTP_POST = { + # "destination": "destination", + # "page": "pageObject", + # "abort": "abort", + # "profile": "profile", + # "name_value_args": "namevalueargs", + # "arguments": "arguments", + # "sending_chunk_size": "sendingChunkSize", + # "send_md5_chksum_header": "sendMD5ChkSumHeader", + } + _HTTP_PUT = { + # "destination": "destination", + # "page": "pageObject", + # "abort": "abort", + # "profile": "profile", + # "name_value_args": "namevalueargs", + # "arguments": "arguments", + # "sending_chunk_size": "sendingChunkSize", + # "send_md5_check_sum_header": "sendMD5ChkSumHeader", + } + _HTTP_HEADER = { + # "destination": "destination", + # "page": "pageObject", + # "abort": "abort", + # "profile": "profile", + # "name_value_args": "namevalueargs", + } + + _TCP = {"keep_alive_time": "tcp_keepalive_time"} + + def __init__(self, cyperfapi): + self._api = cyperfapi + + def config(self, rest): + """ """ + print("config 1") + self._devices_config = self._api._l47config.devices + app_id = rest.add_application("HTTP App") + # response = rest.get_application_actions(app_id) + # print("HTTP Actions :- ", response) + # response = rest.get_application_actions_values(app_id, 1) + # print("HTTP Action Get values :- ", response) + # response = rest.get_application_actions_values(app_id, 2) + # print("HTTP Action POST values :- ", response) + print("config 2") + with Timer(self._api, "HTTP client Configurations"): + self._create_client_app(rest) + self._create_server_app(rest) + + def _create_client_app(self, rest): + """Add any scenarios to the api server that do not already exist""" + print("_create_client_app") + for device in self._devices_config: + self._create_http_client(device, rest) + + def _create_http_client(self, device, rest): + """Add any scenarios to the api server that do not already exist""" + for http_client in device.https: + payload = self._api._set_payload(http_client, http_config._HTTP_CLIENT) + print("payload ", payload) + for http_clients in http_client.clients: + new_payload = self._api._set_payload( + http_clients, http_config._HTTP_CLIENTS + ) + payload["ExternalResourceURL"] = ( + "/api/v2/resources/http-profiles/" + payload["Name"] + ) + payload.update(new_payload) + print("client payload - ", payload) + rest.set_client_http_profile(payload) + name_payload = {} + name_payload["Name"] = payload["Name"] + rest.set_client_http_profile(name_payload) + # for client in app_config.http_client: + # ip_object = self._api.common.get_ip_name(client.client.name) + # url = self._api._config_url.get(self._api._ip_list.get(client.client.name)) + # url = self._api.common.get_community_url(url) + # protocol_url = url+"activityList/" + # options = {} + # options.update({'protocolAndType': "HTTP Client"}) + # response = self._api._request('POST', protocol_url, options) + # protocol_url = protocol_url+response + # self._api._config_url[client.client.name] = protocol_url + # payload = self._api._set_payload(client.client, client_config._HTTP_CLIENT) + # response = self._api._request('PATCH', protocol_url+"/agent", payload) + # self._update_tcp_client(app_config, client) + # self._create_method(app_config, client, protocol_url) + # return + + def _create_server_app(self, rest): + """Add any scenarios to the api server that do not already exist""" + for device in self._devices_config: + self._create_http_server(device, rest) + + def _create_http_server(self, device, rest): + """Add any scenarios to the api server that do not already exist""" + # + for http_server in device.https: + payload = self._api._set_payload(http_server, http_config._HTTP_SERVER) + for http_servers in http_server.servers: + payload["ExternalResourceURL"] = ( + "/api/v2/resources/http-profiles/" + payload["Name"] + ) + print("server payload - ", payload) + rest.set_server_http_profile(payload) + + def _update_tcp_client(self, app_config, client): + # ip_object = self._api.common.get_ip_name(client.client.name) + for tcp in app_config.tcp: + # url = self._api._config_url.get(ip_object) + url = self._api._config_url.get(self._api._ip_list.get(client.client.name)) + url = self._api.common.get_community_url(url) + tcp_child_url = "%snetwork/globalPlugins" % url + response_list = self._api._request("GET", tcp_child_url) + for index in range(len(response_list)): + if response_list[index]["itemType"] == "TCPPlugin": + tcp_url = "%s/%s" % ( + tcp_child_url, + response_list[index]["objectID"], + ) + payload = self._api._set_payload(tcp, client_config._TCP) + response = self._api._request("PATCH", tcp_url, payload) + + def _create_method(self, http_client, protocol_url): + for method in http_client.methods: + for post in method.post: + payload = self._api._set_payload(post, client_config._HTTP_POST) + payload.update({"commandType": "POST"}) + command_url = protocol_url + "/agent/actionList" + response = self._api._request("POST", command_url, payload) + for get in method.get: + payload = self._api._set_payload(get, client_config._HTTP_GET) + payload.update({"commandType": "GET"}) + command_url = protocol_url + "/agent/actionList" + response = self._api._request("POST", command_url, payload) + for delete in method.delete: + payload = self._api._set_payload(delete, client_config._HTTP_DELETE) + payload.update({"commandType": "DELETE"}) + command_url = protocol_url + "/agent/actionList" + response = self._api._request("POST", command_url, payload) + for put in method.put: + payload = self._api._set_payload(put, client_config._HTTP_PUT) + payload.update({"commandType": "PUT"}) + command_url = protocol_url + "/agent/actionList" + response = self._api._request("POST", command_url, payload) + for header in method.header: + payload = self._api._set_payload(header, client_config._HTTP_HEADER) + payload.update({"commandType": "HEAD"}) + command_url = protocol_url + "/agent/actionList" + response = self._api._request("POST", command_url, payload) + + +class server_config: + """ """ + + _HTTP_SERVER = { + "enable_tos": "enableTos", + # "priority_flow_control_class" : "pfcClass", + # "precedence_tos" : "precedenceTOS", + # "delay_tos" : "delayTOS", + # "throughput_tos" : "throughputTOS", + "url_stats_count": "urlStatsCount", + "disable_priority_flow_control": "disablePfc", + "enable_vlan_priority": "enableVlanPriority", + "vlan_priority": "vlanPriority", + "esm": "esm", + "enable_esm": "enableEsm", + "time_to_live_value": "ttlValue", + # "tcp_close_option" : "tcpCloseOption", + "type_of_service": "tos", + "high_perf_with_simulated_user": "highPerfWithSU", + } + + _HTTP_SERVERS = { + "profile": "Name", + "version": "HTTPVersion", + "connection_persistence": "ConnectionPersistence", + "rst_timeout": "rstTimeout", + "enable_http2": "enableHTTP2", + "port": "httpPort", + "request_timeout": "requestTimeout", + "maximum_response_delay": "maxResponseDelay", + "minimum_response_delay": "minResponseDelay", + "dont_expect_upgrade": "dontExpectUpgrade", + "enable_per_server_per_url_stat": "enablePerServerPerURLstat", + "url_page_size": "urlPageSize", + "enable_chunk_encoding": "enableChunkEncoding", + # "integrity_check_option" : "integrityCheckOption", + "enable_md5_checksum": "enableMD5Checksum", + } + + _TCP = {"keep_alive_time": "tcp_keepalive_time"} + + def __init__(self, cyperfapi): + self._api = cyperfapi + + def config(self): + """ """ + self._devices_config = self._api._l47config.devices + with Timer(self._api, "HTTP server Configurations"): + self._create_server_app() + + def _create_server_app(self): + """Add any scenarios to the api server that do not already exist""" + for device in self._devices_config: + self._create_http_server(device) + + def _create_http_server(self, device): + """Add any scenarios to the api server that do not already exist""" + for http in device.https: + for http_server in http.servers: + # ip_object = self._ip_list(server.server.name) + # ip_object = "e2.ipv4" + url = self._api._config_url.get(http.tcp_name) + url = self._api.common.get_community_url(url) + # url = self._api._cyperf+"cyperf/test/activeTest/communityList/1" + protocol_url = url + "activityList/" + options = {} + options.update({"protocolAndType": "HTTP Server"}) + response = self._api._request("POST", protocol_url, options) + protocol_url = protocol_url + response + # self._api._config_url[server.server.name] = protocol_url + payload = self._api._set_payload(http, server_config._HTTP_SERVER) + response = self._api._request("PATCH", protocol_url + "/agent", payload) + payload = self._api._set_payload( + http_server, server_config._HTTP_SERVERS + ) + response = self._api._request("PATCH", protocol_url + "/agent", payload) + del http + # self._update_tcp_server(app_config, server) + + def _update_tcp_server(self, app_config, server): + # ip_object = self._api.common.get_ip_name(self._server_config, server.server.name) + for tcp in app_config.tcp: + url = self._api._config_url.get(self._api._ip_list.get(server.server.name)) + # url = self._api._config_url.get(ip_object) + url = self._api.common.get_community_url(url) + tcp_child_url = "%snetwork/globalPlugins" % url + response_list = self._api._request("GET", tcp_child_url) + for index in range(len(response_list)): + if response_list[index]["itemType"] == "TCPPlugin": + tcp_url = "%s/%s" % ( + tcp_child_url, + response_list[index]["objectID"], + ) + payload = self._api._set_payload(tcp, server_config._TCP) + response = self._api._request("PATCH", tcp_url, payload) diff --git a/snappi_cyperf/interface.py b/snappi_cyperf/interface.py new file mode 100644 index 0000000..eaeab57 --- /dev/null +++ b/snappi_cyperf/interface.py @@ -0,0 +1,139 @@ +import json +import re +import time +from snappi_cyperf.timer import Timer + + +class interfaces(object): + """Transforms OpenAPI objects into IxNetwork objects + - Lag to /lag + Args + ---- + - cyperfapi (Api): instance of the Api class + + """ + + _ETHERNET = { + "mac": "MacStart", + "step": "MacIncr", + "count": "Count", + "max_count": "maxCountPerAgent", + } + + _IP = { + "address": "IpStart", + "gateway": "GwStart", + "prefix": "NetMask", + "name": "networkTags", + "step": "IpIncr", + "count": "Count", + "max_count": "maxCountPerAgent", + } + + _MTU_MSS = { + "mtu": "Mss", + } + + _VLAN = { + "id": "VlanId", + "step": "VlanIncr", + "count": "Count", + "per_count": "CountPerAgent", + "priority": "Priority", + "tpid": "TagProtocolId", + } + + def __init__(self, cyperfapi): + self._api = cyperfapi + self._device_cnt = 0 + self._network_segment_cnt = 0 + self._ip_range_cnt = 0 + self._total_ip_networks = 0 + + def config(self, rest): + """T""" + self._devices_config = self._api._l47config.devices + with Timer(self._api, "Interface Configuration"): + self._create_devices(rest) + + def _create_devices(self, rest): + """Add any scenarios to the api server that do not already exist""" + self._total_ip_networks = 1 + for device in self._devices_config: + for ethernet in device.ethernets: + if self._total_ip_networks > 2: + response = rest.add_eth_range(self._network_segment_cnt) + self._total_ip_networks = self._total_ip_networks + 1 + self._modify_devices(rest) + + def _modify_devices(self, rest): + self._device_cnt = 1 + for device in self._devices_config: + self._network_segment_cnt = self._device_cnt + self._create_ethernet(device, rest) + self._device_cnt = self._device_cnt + 1 + + def _create_ethernet(self, device, rest): + """Add any scenarios to the api server that do not already exist""" + for ethernet in device.ethernets: + self._api._network_segments[ethernet.name] = self._network_segment_cnt + self._api._network_segments[ethernet.connection.port_name] = ( + self._network_segment_cnt + ) + payload = self._api._set_payload(ethernet, interfaces._ETHERNET) + payload["MacAuto"] = False + payload["OneMacPerIP"] = False + if self._device_cnt % 2 == self._network_segment_cnt % 2: + rest.set_eth_range( + payload, + self._network_segment_cnt, + ) + self._create_ipv4(ethernet, rest) + self._network_segment_cnt = self._network_segment_cnt + 2 + + def _create_ipv4(self, ethernet, rest): + """ + Add any ipv4 to the api server that do not already exist + """ + ipv4_addresses = ethernet.get("ipv4_addresses") + if ipv4_addresses is None: + return + self._ip_range_cnt = 1 + for ipv4 in ethernet.ipv4_addresses: + self._api._ip_ranges[ipv4.name] = self._ip_range_cnt + payload = self._api._set_payload(ipv4, interfaces._IP) + payload["IpAuto"] = False + payload["NetMaskAuto"] = False + payload["GwAuto"] = False + payload.update(self._api._set_payload(ethernet, interfaces._MTU_MSS)) + mss = payload["Mss"] + payload["Mss"] = mss - 28 + network_tag = payload["networkTags"] + payload["networkTags"] = [network_tag] + response = self._ip_range_cnt + if self._ip_range_cnt > 1: + response = rest.add_ip_range(self._network_segment_cnt) + rest.set_ip_range( + payload, + self._network_segment_cnt, + response, + ) + self._create_vlan(ethernet, ipv4, rest) + self._ip_range_cnt = self._ip_range_cnt + 1 + + def _create_vlan(self, ethernet, ipv4, rest): + """ + Add any ipv4 to the api server that do not already exist + """ + vlans = ethernet.get("vlans") + if vlans is None: + return + for vlan in ethernet.vlans: + payload = self._api._set_payload(vlan, interfaces._VLAN) + payload["VlanEnabled"] = True + payload["TagProtocolId"] = 33024 + rest.set_ip_range_innervlan_range( + payload, + self._api._network_segments[ethernet.name], + self._api._ip_ranges[ipv4.name], + ) diff --git a/snappi_cyperf/ixrestutils.py b/snappi_cyperf/ixrestutils.py new file mode 100644 index 0000000..7a17175 --- /dev/null +++ b/snappi_cyperf/ixrestutils.py @@ -0,0 +1,296 @@ +""" + DESCRIPTION + IxRestUtils is a collection of classes that offer a generic wrapper around a raw REST API. + It handles: + - Creating a connection; + - Running HTTP methods for an active connection + Abstracting the RAW HTTP input / output to tangible objects that will act as an interface to the REST API. +""" + +import requests +from urllib.parse import urljoin +import json +import re + +try: + requests.packages.urllib3.disable_warnings() +except Exception: + pass + + +# Gets a Connection instance, that will be used to make the HTTP requests to the application +def get_connection(server, port, http_redirect=False): + """ + getconnection perform connection to Cyperf and returns session Url. + """ + transport_type = "https" if not http_redirect else "http" + connection_url = "%s://%s:%s/" % (transport_type, server, port) + conn = Connection(connection_url, "v0", http_redirect) + return conn + + +class Connection(object): + """ + Class that executes the HTTP requests to the application instance. + It handles creating the HTTP session and executing HTTP methods. + + """ + + kHeaderContentType = "content-type" + kContentJson = "application/json" + kApiKeyHeader = "X-Api-Key" + kApiKey = "" + + def __init__(self, siteUrl, apiVersion, http_redirect=False): + """ + Args: + - siteUrl is the actual url to which the Connection instance will be made. + - apiVersion is the actual version of the REST API that the Connection instance will use. + The HTTP session will be created when the first http request is made. + """ + self.http_session = None + self.http_redirect = http_redirect + self.url = Connection.urljoin(siteUrl, "api") + self.url = Connection.urljoin(self.url, apiVersion) + + @staticmethod + def set_api_key(api_key): + """ + set_api_key will set connection key for REST calls. + """ + Connection.kApiKey = api_key + + def _get_http_session(self): + """ + This is a lazy initializer for the HTTP session. + It does not need to be active until it is required. + """ + if self.http_session is None: + self.http_session = requests.Session() + if not self.http_redirect: + from requests.adapters import HTTPAdapter + from requests.packages.urllib3.poolmanager import PoolManager + import ssl + + http_adapter = HTTPAdapter() + http_adapter.poolmanager = PoolManager(ssl_version=ssl.PROTOCOL_TLSv1) + self.http_session.mount("https://", http_adapter) + return self.http_session + + @classmethod + def urljoin(cls, base, end): + """Join two URLs. If the second URL is absolute, the base is ignored. + Use this instead of urlparse.urljoin directly so that we can customize its behavior if necessary. + Currently differs in that it + 1. appends a / to base if not present. + 2. casts end to a str as a convenience + """ + if base and not base.endswith("/"): + base = base + "/" + return urljoin(base, str(end)) + + def _request(self, method, url="", data="", option=None, params=None, headers=None): + """ """ + if method == "POST": + reply = self.http_post(url, data, params, headers) + if not reply.ok: + raise Exception(reply.text) + try: + new_obj_path = reply.headers["location"] + except: + raise Exception( + "Location header is not present. Please check if the action was created successfully." + ) + if option: + return reply + response = new_obj_path.split("/")[-1] + return response + elif method == "GET": + response = self.http_get(url=url, option=option) + return response + elif method == "PATCH": + reply = self.http_patch(url, data, params, headers) + if not reply.ok: + raise Exception(reply.text) + return reply + elif method == "DELETE": + reply = self.http_delete(url, data, params, headers) + if not reply.ok: + raise Exception(reply.text) + return reply + + def http_request(self, method, url="", data="", params=None, headers=None): + """ + Args: + + - Method (mandatory) represents the HTTP method that will be executed. + - url (optional) is the url that will be appended to the application url. + - data (optional) is the data that needs to be sent along with the HTTP method as the JSON payload + - params (optional) the payload python dict not necessary if data is used. + - headers (optional) these are the HTTP headers that will be sent along with the request. If left blank will use default + + Method for making a HTTP request. The method type (GET, POST, PATCH, DELETE) will be sent as a parameter. + Along with the url and request data. The HTTP response is returned + """ + params = {} if params is None else params + headers = {} if headers is None else headers + headers[Connection.kHeaderContentType] = Connection.kContentJson + if Connection.kApiKey != "": + headers[Connection.kApiKeyHeader] = Connection.kApiKey + if isinstance(data, dict): + data = json.dumps(data) + abs_url = Connection.urljoin(self.url, url) + result = self._get_http_session().request( + method, + abs_url, + data=str(data), + params=params, + headers=headers, + verify=False, + ) + return result + + def http_get( + self, url="", data="", option=None, params=None, headers=None, error_codes=None + ): + """ + Method for calling HTTP GET. This will return a WebObject that has the fields returned + in JSON format by the GET operation. + """ + params = {} if params is None else params + headers = {} if headers is None else headers + error_codes = [] if error_codes is None else error_codes + reply = self.http_request("GET", url, data, params, headers) + if reply.status_code in error_codes: + raise Exception( + "Error on executing GET request on url %s: %s" % (url, reply.text) + ) + if option: + return reply.json() + else: + return _format_response(reply.json(), url) + + def http_options( + self, url="", data="", params=None, headers=None, error_codes=None + ): + """ + Method for calling HTTP Option. This will return a WebObject that has the fields returned + in JSON format by the Option operation. + """ + params = {} if params is None else params + headers = {} if headers is None else headers + error_codes = [] if error_codes is None else error_codes + reply = self.http_request("OPTIONS", url, data, params, headers) + if reply.status_code in error_codes: + raise Exception( + "Error on executing Options request on url %s: %s" % (url, reply.text) + ) + return _format_response(reply.json(), url) + + def http_post(self, url="", data="", params=None, headers=None): + """ + Method for calling HTTP POST. Will return the HTTP reply. + """ + params = {} if params is None else params + headers = {} if headers is None else headers + return self.http_request("POST", url, data, params, headers) + + def http_patch(self, url="", data="", params=None, headers=None): + """ + Method for calling HTTP PATCH. Will return the HTTP reply. + """ + params = {} if params is None else params + headers = {} if headers is None else headers + return self.http_request("PATCH", url, data, params, headers) + + def http_delete(self, url="", data="", params=None, headers=None): + """ + Method for calling HTTP DELETE. Will return the HTTP reply. + """ + params = {} if params is None else params + headers = {} if headers is None else headers + return self.http_request("DELETE", url, data, params, headers) + + +def _format_response(value, _url_=None): + """ + Method used for creating a wrapper object corresponding to the JSON string received on a GET request. + """ + if isinstance(value, dict): + if _url_ and bool(re.search(r"[\w.-]+/cyperf/stats/[\w().-]+/values", _url_)): + pass #'values' resources only have name and value of the stats, don't need the url + else: + value["_url_"] = _url_ + result = WebObject(**value) + # result = value + elif isinstance(value, list): + # result = WebList(entries=value, _url_=_url_) + result = value + else: + result = value + return result + + +class WebList(list): + """ + Using this class a JSON list will be transformed in a list of WebObject instances. + """ + + def __init__(self, entries=None, _url_=None): + """ + Create a WebList from a list of items that are processed by the _format_response function + """ + list.__init__(self) + entries = [] if entries is None else entries + self._url_ = _url_ + url = _url_ + filter_syntax = "?filter=" # we need to remove the query param syntax from all chindren of the list. + if url and filter_syntax in url: + url = url.split(filter_syntax)[ + 0 + ] # get everything on the left of the filter, removing the query param + for item in entries: + item_url = None + if "objectID" in item: + item_url = "%s/%s" % (url, item["objectID"]) + self.append(_format_response(item, item_url)) + + def copy_data(self, new_obj): + """ + copy date and retrun json + """ + self[:] = [] + for item in new_obj: + self.append(item) + + +class WebObject(object): + """ + A WebObject instance will have its fields set to correspond to the JSON format received on a GET request. + for example: a response in the format: {"caption": "http"} will return an object that has obj.caption="http" + """ + + def __init__(self, **entries): + """ + Create a WebObject instance by providing a dict having a property - value structure. + """ + self.json_options = {} + for key, value in entries.items(): + web_obj = _format_response(value) + self.json_options[key] = web_obj + self.__dict__[key] = web_obj + + def copy_data(self, new_obj): + """ + copy date and retrun json + """ + self.json_options = {} + for key, obj in new_obj.json_options.items(): + self.json_options[key] = obj + self.__dict__[key] = obj + + def get_options(self): + """ + Get the JSON dictionary which represents the WebObject Instance + """ + return self.json_options diff --git a/snappi_cyperf/l47server.py b/snappi_cyperf/l47server.py new file mode 100644 index 0000000..abb5b12 --- /dev/null +++ b/snappi_cyperf/l47server.py @@ -0,0 +1,108 @@ +from flask import Flask, request, jsonify, Response + +# from exceptions import Snappil47Exception +import sys + +# sys.path.insert(0, "/home/dipendu/otg/open_traffic_generator/snappi/artifacts/snappi") + +import snappi + +app = Flask(__name__) + +global CONFIG +CONFIG = snappi.Config() +CS = snappi.ControlState() +GM = snappi.MetricsRequest() +# sys.path.append("/home/dipendu/otg/open_traffic_generator/snappi-cyperf") +from snappi_cyperf import cyperfapi + +API = cyperfapi.Api( + host="10.39.44.178", + version="10.00.0.152", + username="admin", + password="CyPerf&Keysight#1", +) +# API = cyperfapi.Api(host="10.39.47.88", version="10.00.0.152") + + +@app.route("/config", methods=["POST"]) +def set_config(): + # print("server ----> ", request.data) + CONFIG.deserialize(request.data.decode("utf-8")) + try: + response = API.set_config(CONFIG) + warn = snappi.Warning() + warn.warnings = ["Successfully configured Cyperf"] + return Response(warn.serialize(), mimetype="application/json", status=200) + except Exception as err: + error = snappi.Error() + error.code = err._status_code + error.kind = "validation" + error.errors = [err._message] + print(err) + return Response( + status=400, + response=error.serialize(), + headers={"Content-Type": "application/json"}, + ) + return Response(err.status_code) + # return Response(response=err.message, mimetype="application/json", status=err.status_code) + # try: + # response = API.set_config(CONFIG) + # except Exception as error: + # print("error") + + # warn = snappi.Warning() + # warn.warnings = ["Successfully configured Cyperf"] + # return Response(warn.serialize(), mimetype="application/json", status=200) + + +@app.route("/config", methods=["GET"]) +def get_config(): + try: + config = API.get_config() + return Response(config.serialize(), mimetype="application/json", status=200) + + except Exception as error: + print("error") + + +@app.route("/control/state", methods=["POST"]) +def set_control_state(): + CS.deserialize(request.data.decode("utf-8")) + + try: + + config = API.set_control_state(CS) + return Response(config.serialize(), mimetype="application/json", status=200) + # return Response(config.serialize(), + # mimetype='application/json', + # status=200) + except Exception as err: + error = snappi.Error() + error.code = err._status_code + error.kind = "validation" + error.errors = [err._message] + print(err) + return Response( + status=400, + response=error.serialize(), + headers={"Content-Type": "application/json"}, + ) + + +@app.route("/monitor/metrics", methods=["POST"]) +def get_metrics(): + GM.deserialize(request.data.decode("utf-8")) + + try: + + config = API.metrics_request(CS) + return Response(config.serialize(), mimetype="application/json", status=200) + except Exception as error: + print(error) + + +# main driver function +if __name__ == "__main__": + app.run() diff --git a/snappi_cyperf/logger.py b/snappi_cyperf/logger.py new file mode 100644 index 0000000..a5c2cd7 --- /dev/null +++ b/snappi_cyperf/logger.py @@ -0,0 +1,30 @@ +import sys +import logging + +APP_LOGGER_NAME = "snappi_cyperf" + + +def setup_cyperf_logger(log_level, file_name=None, module_name=None): + logger = logging.getLogger(APP_LOGGER_NAME) + logger.setLevel(log_level) + formatter = logging.Formatter( + fmt="%(asctime)s [%(name)s] [%(levelname)s] %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + ) + sh = logging.StreamHandler(sys.stdout) + sh.setFormatter(formatter) + if len(logger.handlers) > 0: + del logger.handlers[:] + logger.addHandler(sh) + if file_name: + fh = logging.FileHandler(file_name) + fh.setFormatter(formatter) + logger.addHandler(fh) + if module_name is not None: + logger = get_cyperf_logger(module_name) + return logger + + +def get_cyperf_logger(module_name): + module_name = ".".join(str(module_name).split(".")[1:]) + return logging.getLogger(APP_LOGGER_NAME).getChild(module_name) diff --git a/snappi_cyperf/objectiveandtimeline.py b/snappi_cyperf/objectiveandtimeline.py new file mode 100644 index 0000000..6852131 --- /dev/null +++ b/snappi_cyperf/objectiveandtimeline.py @@ -0,0 +1,138 @@ +import ipaddress +import json +import re +import time +from snappi_cyperf.timer import Timer + + +class objectiveandtimeline(object): + """ + Args + ---- + - Cyperfapi (Api): instance of the Api class + + """ + + def __init__(self, cyperfapi): + self._api = cyperfapi + + def config(self, rest): + """T""" + self._config = self._api._l47config + with Timer(self._api, "Traffic Profile"): + self._create_objectives(rest) + + def _create_objectives(self, rest): + trafficprofile_config = self._config.trafficprofile + for tp in trafficprofile_config: + primary_objective = True + for ( + segment, + timeline, + objective_type, + objective_value, + objectives, + ) in zip( + tp.segment, + tp.timeline, + tp.objective_type, + tp.objective_value, + tp.objectives, + ): + objective_payload = self._get_objective_payload( + objective_type, objective_value, objectives, primary_objective + ) + + if primary_objective: + rest.set_primary_objective(objective_payload) + timeline_payload = self._get_timeline_payload( + segment, + objective_value, + objectives, + ) + id = 1 + for payload in timeline_payload: + rest.set_primary_timeline(payload, id) + id = id + 1 + primary_objective = False + else: + rest.set_secondary_objective(objective_payload) + rest.set_secondary_objective(objective_payload) + + def _get_objective_payload( + self, objective_type, objective_value, objectives, primary_objective + ): + payload = {} + payload["Type"] = objective_type + if objectives.simulated_user.max_pending_user != None: + payload["MaxPendingSimulatedUsers"] = ( + objectives.simulated_user.max_pending_user + ) + if objectives.simulated_user.max_user_per_second != None: + payload["MaxSimulatedUsersPerInterval"] = ( + objectives.simulated_user.max_user_per_second + ) + if not primary_objective: + payload["Enabled"] = True + if objective_value != None: + payload["ObjectiveValue"] = objective_value + if objectives.throughput.throughput_unit != None: + payload["ObjectiveUnit"] = objectives.throughput.throughput_unit + + return payload + + def _get_timeline_payload( + self, + segment, + objective_value, + objectives, + ): + step_up_payload = self._get_segment_payload( + segment.enable_ramp_up, + "1", + "StepUpSegment", + segment.ramp_up_time, + segment.ramp_up_value, + "", + ) + step_steady_payload = self._get_segment_payload( + True, + "2", + "SteadySegment", + segment.duration, + objective_value, + objectives.throughput.throughput_unit, + ) + step_down_payload = self._get_segment_payload( + segment.enable_ramp_down, + "3", + "StepDownSegment", + segment.ramp_down_time, + segment.ramp_down_value, + "", + ) + + payload = [step_up_payload, step_steady_payload, step_down_payload] + + return payload + + def _get_segment_payload( + self, + segment_enabled, + segment_id, + segment_type, + segment_duration, + segment_value, + segment_unit, + ): + payload = {} + payload["Enabled"] = segment_enabled + payload["id"] = segment_id + payload["SegmentType"] = segment_type + payload["Duration"] = segment_duration + if segment_value != None: + payload["ObjectiveValue"] = segment_value + if segment_unit != None: + payload["ObjectiveUnit"] = segment_unit + + return payload diff --git a/snappi_cyperf/ports.py b/snappi_cyperf/ports.py new file mode 100644 index 0000000..a27585f --- /dev/null +++ b/snappi_cyperf/ports.py @@ -0,0 +1,45 @@ +import ipaddress +import json +import re +import time +from snappi_cyperf.timer import Timer + + +class port(object): + """ + Args + ---- + - Cyperfapi (Api): instance of the Api class + + """ + + def __init__(self, cyperfapi): + self._api = cyperfapi + + def config(self, rest): + """T""" + self._config = self._api._l47config + with Timer(self._api, "Port Configuration"): + port_config = self._config.ports + for port in port_config: + if self._is_valid_ip(port.location): + self._assign_agents_by_ip( + rest, port.location, self._api._network_segments[port.name] + ) + else: + self._assign_agents_by_tag( + rest, port.location, self._api._network_segments[port.name] + ) + + def _is_valid_ip(self, ip): + try: + ipaddress.ip_address(ip) + return True + except ValueError: + return False + + def _assign_agents_by_ip(self, rest, location, network_segment): + rest.assign_agents_by_ip(location, network_segment) + + def _assign_agents_by_tag(self, rest, location, network_segment): + rest.assign_agents_by_tag(location, network_segment) diff --git a/snappi_cyperf/tcp.py b/snappi_cyperf/tcp.py new file mode 100644 index 0000000..6866164 --- /dev/null +++ b/snappi_cyperf/tcp.py @@ -0,0 +1,74 @@ +import json +import re +import time +from snappi_cyperf.timer import Timer +from snappi_cyperf.common import Common + + +class tcp_config(Common): + """Transforms OpenAPI objects into IxNetwork objects + - Lag to /lag + Args + ---- + - Cyperfapi (Api): instance of the Api class + + """ + + _TCP = { + "receive_buffer_size": "RxBuffer", + "transmit_buffer_size": "TxBuffer", + "retransmission_minimum_timeout": "MinRto", + "retransmission_maximum_timeout": "MaxRto", + "minimum_source_port": "MinSrcPort", + "maximum_source_port": "MaxSrcPort", + } + + def __init__(self, cyperfapi): + self._api = cyperfapi + + def config(self, rest): + """ """ + self._devices_config = self._api._l47config.devices + with Timer(self._api, "Tcp Configurations"): + self._update_tcp(rest) + + def _update_tcp(self, rest): + """Add any scenarios to the api server that do not already exist""" + app_id = rest.add_application("TCP App") + response = rest.get_application_actions(app_id) + action_id = response[-1]["id"] + client = True + for device in self._devices_config: + # + self._update_tcp_config(device, client, rest, app_id, action_id) + client = False + + def _update_tcp_config(self, device, client, rest, app_id, action_id): + """Add any scenarios to the api server that do not already exist""" + for tcp in device.tcps: + payload = self._api._set_payload(tcp, tcp_config._TCP) + payload["DeferAccept"] = True + payload["PingPong"] = True + payload["CloseWithReset"] = False + payload["EcnEnabled"] = False + payload["TimestampHdrEnabled"] = True + payload["RecycleTwEnabled"] = True + payload["ReuseTwEnabled"] = True + payload["SackEnabled"] = False + payload["WscaleEnabled"] = False + payload["PmtuDiscDisabled"] = False + payload["Reordering"] = False + if client: + rest.set_client_tcp_profile(payload) + # self._update_tcp_properties(tcp, rest, app_id, action_id) + else: + rest.set_server_tcp_profile(payload) + + # def _update_tcp_properties(self, tcp, rest, app_id, action_id): + # payload_data_content = {} + # payload_data_content["Source"] = tcp.data_content_source + # payload_data_content["Value"] = tcp.data_content_value + # rest.set_application_actions_values(payload_data_content, app_id, action_id, 0) + # payload_direction = {} + # payload_direction["Value"] = tcp.direction + # rest.set_application_actions_values(payload_direction, app_id, action_id, 1) diff --git a/snappi_cyperf/timer.py b/snappi_cyperf/timer.py new file mode 100644 index 0000000..10ea15c --- /dev/null +++ b/snappi_cyperf/timer.py @@ -0,0 +1,16 @@ +import time + + +class Timer: + def __init__(self, api, msg): + self._api = api + self._msg = msg + + def __enter__(self): + """Start a new timer as a context manager""" + self._start = time.time() + return self + + def __exit__(self, *exc_info): + """Stop the context manager timer""" + self._api.info(self._msg + " %.3fs" % (time.time() - self._start)) diff --git a/tests/Test_l47.py b/tests/Test_l47.py new file mode 100644 index 0000000..a045f7e --- /dev/null +++ b/tests/Test_l47.py @@ -0,0 +1,122 @@ +import sys + +""" +Configure a raw TCP flow with, +- tx port as source to rx port as destination +- frame count 10000, each of size 128 bytes +- transmit rate of 1000 packets per second +Validate, +- frames transmitted and received for configured flow is as expected +""" + +import snappi + +# host is Cyperf API Server +api = snappi.api(location="http://127.0.0.1:5000", verify=False) +config = api.config() +# port location is agent-ip +tx = config.ports.port(name="tx", location="10.39.44.147")[-1] +rx = config.ports.port(name="rx", location="10.39.44.190")[-1] + +(d1, d2) = config.devices.device(name="d1").device(name="d2") +(e1,) = d1.ethernets.ethernet(name="d1.e1") +e1.connection.port_name = "tx" +e1.mac = "01:02:03:04:05:06" +e1.step = "00:00:00:00:00:01" +e1.count = 1 +e1.mtu = 1488 + +(e2,) = d2.ethernets.ethernet(name="d2.e2") +e2.connection.port_name = "rx" +e2.mac = "01:02:03:04:06:06" +e2.step = "00:00:00:00:00:01" +e2.count = 2 +e2.mtu = 1488 + +(vlan1,) = e1.vlans.vlan(name="vlan1") +vlan1.id = 1 +vlan1.priority = 1 +vlan1.tpid = "x8100" +vlan1.count = 1 +vlan1.step = 1 +vlan1.per_count = 1 + +(vlan2,) = e2.vlans.vlan(name="vlan2") +vlan2.id = 1 +vlan2.priority = 1 +vlan2.tpid = "x8100" +vlan2.count = 1 +vlan2.step = 1 +vlan2.per_count = 1 + +(ip1,) = e1.ipv4_addresses.ipv4(name="e1.ipv4") +ip1.address = "10.0.0.10" +ip1.gateway = "10.0.0.1" +ip1.step = "0.0.0.1" +ip1.count = 1 +ip1.prefix = 16 + +(ip2,) = e2.ipv4_addresses.ipv4(name="e2.ipv4") +ip2.address = "10.0.0.20" +ip2.gateway = "10.0.0.1" +ip2.step = "0.0.0.1" +ip2.count = 1 +ip2.prefix = 16 + +# TCP/UDP configs + +(t1,) = d1.tcps.tcp(name="Tcp1") +t1.ip_interface_name = ip1.name +t1.receive_buffer_size = 1111 +t1.transmit_buffer_size = 1112 +t1.retransmission_minimum_timeout = 100 +t1.retransmission_maximum_timeout = 1001 +t1.minimum_source_port = 100 +t1.maximum_source_port = 101 + +(t2,) = d2.tcps.tcp(name="Tcp2") +t2.ip_interface_name = ip2.name +t2.receive_buffer_size = 2222 +t2.transmit_buffer_size = 2221 +t2.retransmission_minimum_timeout = 200 +t2.retransmission_maximum_timeout = 2002 +t2.minimum_source_port = 200 +t2.maximum_source_port = 202 + +(http_1,) = d1.https.http(name="HTTP1") +http_1.profile = "Chrome" +http_1.version = "HTTP11" +http_1.connection_persistence = "ConnectionPersistenceStandard" +(http_client,) = http_1.clients.client() +http_client.cookie_reject_probability = False +http_client.max_persistent_requests = 1 + +(http_2,) = d2.https.http(name="HTTP2") +http_2.profile = "Apache" +http_2.version = "HTTP11" +http_2.connection_persistence = "ConnectionPersistenceEnabled" +(http_server,) = http_2.servers.server() + +(tp1,) = config.trafficprofile.trafficprofile() +(segment1, segment2) = tp1.segment.segment().segment() +segment1.name = "Linear segment1" +segment1.duration = 40 +segment2.name = "Linear segment2" +segment2.duration = 70 +tp1.timeline = [segment1.name, segment2.name] +tp1.objective_type = ["Connections per second", "Simulated users"] +tp1.objective_value = [100, 200] +(obj1, obj2) = tp1.objectives.objective().objective() + +print("In test before set_config") +response = api.set_config(config) +print("In test after set_config") +print(response) +api.close() + +cs = api.control_state() +cs.app.state = "start" # cs.app.state.START +response1 = api.set_control_state(cs) +print(response1) +cs.app.state = "stop" # cs.app.state.START +api.set_control_state(cs)