Skip to content

Commit

Permalink
9.0u3 release refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
nutu committed Apr 16, 2020
1 parent 455e93d commit c63a5d6
Show file tree
Hide file tree
Showing 30 changed files with 14,877 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "RestApi/Python/RestApi_v2/modules"]
path = RestApi/Python/RestApi_v2/modules
url = https://github.com/OpenIxia/bps_restpy.git
183 changes: 183 additions & 0 deletions RestApi/Python/RestApi_v2/BPSQT/suite_data_to_csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
# Title: suite_data_to_csv
# Note:This Python script using the bps_restpy and pytz package (pip install bps_restpy pytz)
# Actions: Exports the suite data to a csv
# 1. Login to BPSQT box
# 2. Based on the QT_SUITE_RUNID get each test result
# 3. Extract aditional data from the bps legacy report for the specific test (REPORT_SECTIONS)
# 4. write all to csv: OUT_RESULTS_CSV
# ================

import re
from pytz import timezone
from datetime import datetime, timedelta
from bps_restpy.bps import BPS


########################################
# Demo script global variables
# bps system info
bps_system = '10.36.83.240' # bpsqt system ip
bpsuser = 'admin' # system username
bpspass = 'admin' # system password

# go to BPSQT suite result that you are interested in
# set QT_SUITE_RUNID to the number found at the end of the link
QT_SUITE_RUNID = '692' # https://<chassisip>/bpse/ui/suites/netsecOpen/runSummary/692
#sections that should be extracted from BPS legacy report
REPORT_SECTIONS = [ 'Application Response Time',
'Application First Byte Time',
'Connection First Byte Time'
]
#results file output
OUT_RESULTS_CSV = 'QT_NSO_RESULT_ID' + QT_SUITE_RUNID + '.csv'
########################################
# Login to BPS box
bps = BPS(bps_system, bpsuser, bpspass)
bps.login()


def testStart2Date(datestr):
# 'Tue Sep 24 05:27:13 2019'
tmp = datestr.split()
tmp[-2] = ''
tmp = ' '.join(tmp)
date = datetime.strptime(tmp, '%a %b %d %H:%M:%S %Y')
date = timezone('US/Pacific').localize(date)
date = date.astimezone(timezone('UTC'))
return date


def suiteStart2Date(datestr):
# "2020-03-12T22:36:26.651-07:00"
tmp = datestr.split('.')
needsAdjustment = re.search(r'\d\d\d[+-](\d\d\:\d\d)',tmp[-1])
if needsAdjustment:
adjustemntTZ = datetime.strptime(needsAdjustment.group(1), '%H:%M')
# exclude ms and timezone adjutment and set date
tmp = ' '.join(tmp[:-1])
date = datetime.strptime(tmp, '%Y-%m-%dT%H:%M:%S')
date = date + timedelta(hours=adjustemntTZ.hour, minutes=adjustemntTZ.minute, seconds=0)
date = timezone('UTC').localize(date)
return date


def get_reports_data(bps, run_id):
# getReportContents 1st 'IP Summary' section
#'exceptions'
contents = bps.reports.getReportContents(runid=run_id)
report_results = {}
for section_to_get in REPORT_SECTIONS:
for section in contents:
if section['Section Name'] == section_to_get:
print("Report result: %s for runid: %s" % (section, run_id))
report_results[section_to_get] = bps.reports.getReportTable(
runid=run_id,
sectionId=section['Section ID'])
break
report_results_aggregated = {}
for section in REPORT_SECTIONS:
report_results_aggregated[section] = get_aggregated_value(report_results[section])

return report_results_aggregated

#compute min/max and avg for given report table() and last sustain in minutes
def get_aggregated_value(report_stat_data, sustain_duration=9, rampdown_duration=5):
# ex : report_results['Application Response Time'] is:
# [{u'Timestamp': [...]}, {u'Average Response Time': [...]}, {u'Instantaneous Response Time': [...]}]
#get sustain index
time_samples = report_stat_data[0]['Timestamp']
sustain_start_time = float(time_samples[-1]) - (60 * sustain_duration) - (60 * rampdown_duration)
sustain_last_time = float(time_samples[-1]) - (60 * rampdown_duration)
for sustain__start_index, val in enumerate(time_samples):
if float(val) > sustain_start_time:
break
for sustain_end_index, val in enumerate(time_samples):
if float(val) > sustain_last_time:
break
table_collumn_name = list(report_stat_data[2].keys())[0]
measurements = report_stat_data[2][table_collumn_name][sustain__start_index:sustain_end_index]
measurements = [float(y.strip('~')) for y in measurements]
try:
return_val = [min(measurements), average(measurements), max(measurements)]
except ValueError as e:
print('Problems when calculating average : %s' % str(e))
return_val = ['Err', 'Err', 'Err']
return return_val


def average(lst):
return sum(y for y in lst)/len(lst)


def get_app_times(testname, suiteStartTime, suiteDuration):
suite_start_date = suiteStart2Date(suiteStartTime)
suite_duration_date = datetime.strptime(suiteDuration, '%H:%M:%S')
suite_end_date = suite_start_date + \
timedelta(hours=suite_duration_date.hour, minutes=suite_duration_date.minute)
# query the last 200 bps results matching the test name
results = bps.reports.search(
searchString=testname, limit=200, sort='startTime', sortorder='descending')
for result in results:
if not result['startTime']:
continue
test_start_date = testStart2Date(result['startTime'])
print ("Test Date : %s Suite : %s <-> %s" % (test_start_date.strftime('%Y-%m-%dT%H:%M:%S'),
suite_start_date.strftime('%Y-%m-%dT%H:%M:%S'),
suite_end_date.strftime('%Y-%m-%dT%H:%M:%S')
)
)
if test_start_date >= suite_start_date and test_start_date <= suite_end_date:
avg_timings = get_reports_data(bps, result['runid'])
break
return avg_timings
#################################



#Using a GET request to obtain the status of the suite

params = {'responseDepth': '4'}
url = 'https://' + bps_system +'/bpse/api/v2/results/' + QT_SUITE_RUNID
r = bps.session.get(url, params=params)
if not r.status_code == 200:
raise Exception('Failed to get results for suite id: %s returned %s' % (QT_SUITE_RUNID, r.contents))
suite = r.json()
csv_handle = open(OUT_RESULTS_CSV, 'w+')
head_line_csv = ",".join([suite['suite'],
'startDate:' + suite['startDate'] +' duration:' + suite['duration'],
suite['state'],
suite['id']
])
head_line_csv = head_line_csv + ',' + ' min,avg,max,'.join(REPORT_SECTIONS)
print(head_line_csv)
csv_handle.write(head_line_csv + '\n')
suiteStartTime = suite['startDate']
suiteDuration = suite['duration']
for category in suite['categories']:
print(category['category'])
csv_handle.write(category['category'] + '\n')
for test in category['tests']:
if test['state'] == 'Skipped':
continue
match = re.search(r'achieved\s(\d*)', test['goals'][0]['result'])
val = 'x'
if match:
val = match.group(1)
durations = get_app_times(test['name'], suiteStartTime, suiteDuration)
test_csv_line = ", ".join([test['test'], test['grading']['description'], val, test['goals'][0]['units']])
for section in REPORT_SECTIONS:
if section in REPORT_SECTIONS:
try:
durations_to_strings = ['%.2f' % d for d in durations[section]]
except TypeError:
durations_to_strings = durations[section]
test_csv_line = test_csv_line + ',' + ','.join(durations_to_strings)
else:
test_csv_line = test_csv_line + ',' + ','.join(['0', '0', '0'])
print(test_csv_line)
csv_handle.write(test_csv_line + '\n')
csv_handle.close()

# logout bps session
print("Session logout")
bps.logout()
21 changes: 21 additions & 0 deletions RestApi/Python/RestApi_v2/Modules/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# MIT LICENSE
#
# Copyright 1997 - 2019 by IXIA Keysight
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
7 changes: 7 additions & 0 deletions RestApi/Python/RestApi_v2/Modules/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
include LICENSE
include README.md
include RELEASENOTES.md
include setup.py
include version.txt
recursive-include bps_restpy *.py
recursive-include bps_restpy *.bpt
141 changes: 141 additions & 0 deletions RestApi/Python/RestApi_v2/Modules/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
## The BreakingPoint RESTv2 API Python Wrapper
[![pypi](https://img.shields.io/pypi/v/bps-restpy.svg)](https://pypi.org/project/bps-restpy)
[![python](https://img.shields.io/pypi/pyversions/bps-restpy.svg)](https://pypi.python.org/pypi/bps-restpy)
[![license](https://img.shields.io/badge/license-MIT-green.svg)](https://en.wikipedia.org/wiki/MIT_License)
[![downloads](https://pepy.tech/badge/bps-restpy)](https://pepy.tech/project/bps-restpy)

## BreakingPoint detail
Network testing with [BreakingPoint®](https://www.ixiacom.com/products/network-security-testing-breakingpoint). By simulating real-world legitimate traffic, distributed denial of service (DDoS), exploits, malware, and fuzzing, BreakingPoint validates an organization’s security infrastructure, reduces the risk of network degradation by almost 80%, and increases attack readiness by nearly 70%. And with our new TrafficREWIND solution, you'll get even more realistic and high-fidelity validation by adding production network insight into BreakingPoint test traffic configuration
More details:

## Install the package
```
pip install --upgrade bps-restpy
```

## Start scripting
```python
"""This script demonstrates how to get started with bps_restpy scripting.
# Title: Python Script Sample To Run a Canned Test.
# Actions:
# 1. Login to BPS box
# 2. Reserve ports
# 3. Load a test from the box and start the run
# 4. Wait for the test to finish
# 5. Get test result
# 6. Get and print the Synopsis page from report
# 7. Unreserve ports
# 8. Logout
#================
########################################
import time, sys, os
# Import corresponding BPS RESTv2 python2.7/ 3 library from outside the folder with samples.
sys.path.insert(1, os.path.dirname(os.getcwd()))
from bps_restpy.bps import BPS, pp
########################################
########################################
# Demo script global variables
########################################
# Demo script global variables
canned_test_name = 'AppSim'
#bps system info
bps_system = '<BPS_BOX_IP/HOSTNAME>'
bpsuser = 'bps user'
bpspass = 'bps pass'
slot_number = 2
port_list = [0, 1]
########################################
########################################
# Login to BPS box
bps = BPS(bps_system, bpsuser, bpspass)
bps.login()
########################################
print("Load a canned test: ")
bps.testmodel.load(canned_test_name)
########################################
print("Reserve Ports")
for p in port_list:
bps.topology.reserve([{'slot': slot_number, 'port': p, 'group': 2}])
########################################
print("Run test and Get Stats:")
test_id_json = bps.testmodel.run(modelname=canned_test_name, group=2)
testid = str( test_id_json["runid"] )
run_id = 'TEST-' + testid
print("Test Run Id: %s"%run_id)
#get the ids for all tests running on the chassis
runningTests_Ids = [test['id'] for test in bps.topology.runningTest.get()]
#wait while the test is still running
while run_id in runningTests_Ids:
run_state = bps.topology.runningTest[run_id].get()
#print progress if test started
try: print ('progress: %s%% , runtime %ss' % (run_state['progress'], run_state['runtime'] ))
except: print ("Starting...")
time.sleep(2)
#update the current running tests
runningTests_Ids = [test['id'] for test in bps.topology.runningTest.get()]
print("~The test finished the execution.")
results = bps.reports.search(searchString=canned_test_name, limit=10, sort="endTime", sortorder="descending")
result = results[0]
print ("%s execution duration %s ended with status: %s " % (result['name'], result['duration'], result['result']) )
#getting 3.4 Section: Synopsys Summary of Results from the Report
tabledata = bps.reports.getReportTable(runid=testid, sectionId="3.4")
pp(tabledata)
print ("Unreserving the ports")
for p in port_list:
bps.topology.unreserve([{'slot': slot_number, 'port': p, 'group': 2}])
bps.logout()
```
wew
## Documentation
Documentation is available using the following methods:
* [Online web based documentation and samples](https://github.com/OpenIxia/BreakingPoint)
* On your BreakingPoint System RestApi found near the BreakingPoint App
* Documentation available in the online doc browser is also inlined in each class, property and method and can be viewed using the python help command
```python
from bps_restpy.bps import BPS, pp
#login to your Breaking Point System
help(BPS)
bps = BPS('your_bps_IP_or_FQDN', 'admin', 'admin')
help(bps.testmodel.importModel)
```
## Additional Samples
Visit the [OpenIxia breakingpoint-restpy sample site maintained by solution architects](https://github.com/OpenIxia/BreakingPoint) for in depth end-to-end samples that demonstrate the following:
* building a configuration
* from scratch
* from an existing BreakingPoint configuration
* running the configuration
* connecting ports to hardware
* starting protocols
* starting traffic
* getting statistics
* port stats
* traffic stats
6 changes: 6 additions & 0 deletions RestApi/Python/RestApi_v2/Modules/RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Release Notes

### Nov 2019
* 1.0.1
* Add BreakingPoint RESTv2 Python Wraper library and samples. (supported from BreakingPoint Release 9.0 Update2 +)
* Support for older versions and BreakingPoint RESTv1 API library files can be foudn in the build
Empty file.
29 changes: 29 additions & 0 deletions RestApi/Python/RestApi_v2/Modules/bps_restpy/bps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""
# MIT LICENSE
#
# Copyright 1997 - 2019 by IXIA Keysight
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
*Created with Breaking Point build : 9.00v9.00.108.12"""
import sys,os
#sys.path.insert(0,os.path.abspath(__file__+"/../.."))
if sys.version_info[0] >= 3:
from .restPyWrapper3 import BPS, pp
else:
from .restPyWrapper import BPS, pp
Empty file.
Loading

0 comments on commit c63a5d6

Please sign in to comment.