Improving wifi capacity to ghost function

Signed-off-by: Matthew Stidham <stidmatt@gmail.com>
This commit is contained in:
Matthew Stidham
2021-06-09 17:29:33 -07:00
parent 94b571df3f
commit c2e5bfae0a
2 changed files with 277 additions and 35 deletions

View File

@@ -1,8 +1,10 @@
#!/usr/bin/env python3
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Class holds default settings for json requests to Grafana -
# Class holds default settings for json requests to Ghost -
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
import ast
import os
import sys
if sys.version_info[0] != 3:
@@ -13,25 +15,69 @@ import requests
import jwt
from datetime import datetime as date
import json
import subprocess
from scp import SCPClient
import paramiko
class CSVReader:
def read_csv(self,
file,
sep=','):
csv = open(file).read().split('\n')
rows = list()
for x in csv:
if len(x) > 0:
rows.append(x.split(sep))
length = list(range(0, len(df[0])))
columns = dict(zip(df[0], length))
return rows
def get_column(df, value):
index = df[0].index(value)
values = []
for row in df[1:]:
values.append(row[index])
return values
class GhostRequest:
def __init__(self,
_ghostjson_host,
_ghostjson_port,
_ghost_json_host,
_ghost_json_port,
_api_token=None,
_headers=dict(),
_overwrite='false',
debug_=False,
die_on_error_=False):
self.debug = debug_
self.die_on_error = die_on_error_
self.ghostjson_url = "http://%s:%s/ghost/api/v3" % (_ghostjson_host, _ghostjson_port)
self.ghost_json_host = _ghost_json_host
self.ghost_json_port = _ghost_json_port
self.ghost_json_url = "http://%s:%s/ghost/api/v3" % (_ghost_json_host, _ghost_json_port)
self.data = dict()
self.data['overwrite'] = _overwrite
self.ghostjson_login = self.ghostjson_url + '/admin/session/'
self.ghost_json_login = self.ghost_json_url + '/admin/session/'
self.api_token = _api_token
self.images = list()
self.pdfs = list()
def encode_token(self):
# Split the key into ID and SECRET
key_id, secret = self.api_token.split(':')
# Prepare header and payload
iat = int(date.now().timestamp())
header = {'alg': 'HS256', 'typ': 'JWT', 'kid': key_id}
payload = {
'iat': iat,
'exp': iat + 5 * 60,
'aud': '/v3/admin/'
}
token = jwt.encode(payload, bytes.fromhex(secret), algorithm='HS256', headers=header)
return token
def create_post(self,
title=None,
@@ -39,15 +85,7 @@ class GhostRequest:
tags=None,
authors=None,
status="published"):
ghostjson_url = self.ghostjson_url + '/admin/posts/'
datastore = dict()
datastore['title'] = title
if tags is not None:
datastore['tags'] = tags
if authors is not None:
datastore['authors'] = authors
datastore['html'] = text
datastore['status'] = status
ghost_json_url = self.ghost_json_url + '/admin/posts/?source=html'
post = dict()
posts = list()
datastore = dict()
@@ -59,18 +97,132 @@ class GhostRequest:
headers = dict()
# Split the key into ID and SECRET
id, secret = self.api_token.split(':')
# Prepare header and payload
iat = int(date.now().timestamp())
header = {'alg': 'HS256', 'typ': 'JWT', 'kid': id}
payload = {
'iat': iat,
'exp': iat + 5 * 60,
'aud': '/v3/admin/'
}
token = jwt.encode(payload, bytes.fromhex(secret), algorithm='HS256', headers=header)
token = self.encode_token()
headers['Authorization'] = 'Ghost {}'.format(token)
requests.post(ghostjson_url, json=post, headers=headers)
response = requests.post(ghost_json_url, json=post, headers=headers)
if self.debug:
print(datastore)
print(ghost_json_url)
print('\n')
print(post)
print('\n')
print(headers)
print(response.headers)
def upload_image(self,
image):
print(image)
ghost_json_url = self.ghost_json_url + '/admin/images/upload/'
token = self.encode_token()
bashCommand = "curl -X POST -F 'file=@%s' -H \"Authorization: Ghost %s\" %s" % (image, token, ghost_json_url)
proc = subprocess.Popen(bashCommand, shell=True, stdout=subprocess.PIPE)
output = proc.stdout.read().decode('utf-8')
print(output)
self.images.append(json.loads(output)['images'][0]['url'])
def upload_images(self,
folder):
for image in os.listdir(folder):
if 'kpi' in image:
if 'png' in image:
self.upload_image(folder + '/' + image)
print('images %s' % self.images)
def custom_post(self,
folder,
authors,
title='custom'):
self.upload_images(folder)
head = '''<p>This is a custom post created via a script</p>'''
for picture in self.images:
head = head + '<img src="%s"></img>' % picture
head = head + '''<p>This is the end of the example</p>'''
self.create_post(title=title,
text=head,
tags='custom',
authors=authors)
def wifi_capacity_to_ghost(self,
authors,
folders,
title='Wifi Capacity',
server_pull=None,
ghost_host=None,
port='22',
user_pull='lanforge',
password_pull='lanforge',
user_push=None,
password_push=None,
customer=None,
testbed=None,
test_run=None):
text = '''The Candela WiFi Capacity test is designed to measure performance of an Access Point when handling
different amounts of WiFi Stations. The test allows the user to increase the number of stations in user
defined steps for each test iteration and measure the per station and the overall throughput for each trial.
Along with throughput other measurements made are client connection times, Fairness, % packet loss,
DHCP times and more. The expected behavior is for the AP to be able to handle several stations (within the
limitations of the AP specs) and make sure all stations get a fair amount of airtime both in the upstream and
downstream. An AP that scales well will not show a significant over-all throughput decrease as more stations
are added.
Realtime Graph shows summary download and upload RX bps of connections created by this test.<br />'''
if test_run is None:
test_run = sorted(folders)[0].split('/')[-1]
for folder in folders:
ssh_pull = paramiko.SSHClient()
ssh_pull.set_missing_host_key_policy(paramiko.client.AutoAddPolicy)
ssh_pull.connect(server_pull,
port,
username=user_pull,
password=password_pull,
allow_agent=False,
look_for_keys=False)
scp_pull = SCPClient(ssh_pull.get_transport())
scp_pull.get(folder, recursive=True)
ssh_push = paramiko.SSHClient()
ssh_push.set_missing_host_key_policy(paramiko.client.AutoAddPolicy)
ssh_push.connect(ghost_host,
port,
username=user_push,
password=password_push,
allow_agent=False,
look_for_keys=False)
scp_push = SCPClient(ssh_push.get_transport())
local_path = '/home/%s/%s/%s/%s' % (user_push, customer, testbed, test_run)
transport = paramiko.Transport((ghost_host, port))
transport.connect(None, user_push, password_push)
sftp = paramiko.sftp_client.SFTPClient.from_transport(transport)
print(local_path)
sftp.mkdir(local_path)
target_folder = folder.split('/')[-1]
print(target_folder)
scp_push.put(target_folder, recursive=True, remote_path=local_path)
files = sftp.listdir(local_path + '/' + target_folder)
print('Files: %s' % files)
for file in files:
if 'pdf' in file:
self.pdfs.append(file)
#df = CSVReader.read_csv(local_path + '/' + target_folder + '/' + 'kpi.csv')
#testbed = CSVReader.get_column(df, 'test-rig')[0]
print('PDFs %s' % self.pdfs)
scp_pull.close()
scp_push.close()
self.upload_images(target_folder)
for pdf in self.pdfs:
url = 'http://%s/%s/%s/%s/%s/%s' % (ghost_host, customer, testbed, test_run, target_folder, pdf)
text = text + 'PDF of results: <a href="%s">%s</a>' % (url, url)
for image in self.images:
if 'kpi-' in image:
if '-print' not in image:
text = text + '<img src="%s"></img>' % image
self.create_post(title=title,
text=text,
tags='custom',
authors=authors)

View File

@@ -6,6 +6,14 @@ PURPOSE: modify ghost database from the command line.
SETUP: A Ghost installation which the user has admin access to.
EXAMPLE: ./ghost_profile.py --article_text_file text.txt --title Test --authors Matthew --ghost_token SECRET_KEY --host 192.168.1.1
There is a specific class for uploading wifi capacity graphs called wifi_capacity.
EXAMPLE: ./ghost_profile.py --ghost_token TOKEN --ghost_host 192.168.100.147
--folders /home/lanforge/html-reports/wifi-capacity-2021-06-04-02-51-07
--wifi_capacity appl --authors Matthew --title 'wifi capacity 2021 06 04 02 51 07' --server 192.168.93.51
--user_pull lanforge --password_pull lanforge --customer candela --testbed heather --test_run test-run-6
--user_push matt --password_push PASSWORD
Matthew Stidham
Copyright 2021 Candela Technologies Inc
License: Free to distribute and modify. LANforge systems must be licensed.
@@ -23,9 +31,9 @@ if 'py-json' not in sys.path:
sys.path.append(os.path.join(os.path.abspath('..'), 'py-dashboard'))
from GhostRequest import GhostRequest
from LANforge.lfcli_base import LFCliBase
class UseGhost(LFCliBase):
class UseGhost():
def __init__(self,
_ghost_token=None,
host="localhost",
@@ -34,11 +42,13 @@ class UseGhost(LFCliBase):
_exit_on_fail=False,
_ghost_host="localhost",
_ghost_port=2368, ):
super().__init__(host, port, _debug=_debug_on, _exit_on_fail=_exit_on_fail)
self.ghost_host = _ghost_host
self.ghost_port = _ghost_port
self.ghost_token = _ghost_token
self.GP = GhostRequest(self.ghost_host, str(self.ghost_port), _api_token=self.ghost_token)
self.GP = GhostRequest(self.ghost_host,
str(self.ghost_port),
_api_token=self.ghost_token,
debug_=_debug_on)
def create_post(self, title, text, tags, authors):
return self.GP.create_post(title=title, text=text, tags=tags, authors=authors)
@@ -47,9 +57,46 @@ class UseGhost(LFCliBase):
text = open(file).read()
return self.GP.create_post(title=title, text=text, tags=tags, authors=authors)
def upload_image(self, image):
return self.GP.upload_image(image)
def upload_images(self, folder):
return self.GP.upload_images(folder)
def custom_post(self, folder, authors):
return self.GP.custom_post(folder, authors)
def wifi_capacity(self,
authors,
folders,
title,
server_pull,
ghost_host,
port,
user_pull,
password_pull,
user_push,
password_push,
customer,
testbed,
test_run):
return self.GP.wifi_capacity_to_ghost(authors,
folders,
title,
server_pull,
ghost_host,
port,
user_pull,
password_pull,
user_push,
password_push,
customer,
testbed,
test_run)
def main():
parser = LFCliBase.create_basic_argparse(
parser = argparse.ArgumentParser(
prog='ghost_profile.py',
formatter_class=argparse.RawTextHelpFormatter,
epilog='''Manage Ghost Website''',
@@ -71,17 +118,60 @@ def main():
optional.add_argument('--article_tags', action='append')
optional.add_argument('--authors', action='append')
optional.add_argument('--title', default=None)
optional.add_argument('--image', default=None)
optional.add_argument('--folder', default=None)
optional.add_argument('--custom_post', default=None)
optional.add_argument('--wifi_capacity', default=None)
optional.add_argument('--folders', action='append', default=None)
optional.add_argument('--server_pull')
optional.add_argument('--port', default=22)
optional.add_argument('--user_pull', default='lanforge')
optional.add_argument('--password_pull', default='lanforge')
optional.add_argument('--user_push')
optional.add_argument('--password_push')
optional.add_argument('--customer')
optional.add_argument('--testbed')
optional.add_argument('--test_run', default=None)
optional.add_argument('--debug')
args = parser.parse_args()
Ghost = UseGhost(_ghost_token=args.ghost_token,
_ghost_port=args.ghost_port,
_ghost_host=args.ghost_host)
_ghost_host=args.ghost_host,
_debug_on=args.debug)
if args.create_post is not None:
Ghost.create_post(args.title, args.article_text, args.article_tags, args.authors)
if args.article_text_file is not None:
Ghost.create_post_from_file(args.title, args.article_text_file, args.article_tags, args.authors)
if args.image is not None:
Ghost.upload_image(args.image)
if args.custom_post is not None:
if args.folders is not None:
Ghost.custom_post(args.folders, args.authors)
else:
Ghost.custom_post(args.folder, args.authors)
else:
if args.folder is not None:
Ghost.upload_images(args.folder)
if args.wifi_capacity is not None:
Ghost.wifi_capacity(args.authors,
args.folders,
args.title,
args.server_pull,
args.ghost_host,
args.port,
args.user_pull,
args.password_pull,
args.user_push,
args.password_push,
args.customer,
args.testbed,
args.test_run)
if __name__ == "__main__":
main()