mirror of
				https://github.com/Telecominfraproject/wlan-lanforge-scripts.git
				synced 2025-10-30 18:27:53 +00:00 
			
		
		
		
	Improving wifi capacity to ghost function
Signed-off-by: Matthew Stidham <stidmatt@gmail.com>
This commit is contained in:
		| @@ -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) | ||||
|   | ||||
| @@ -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() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Matthew Stidham
					Matthew Stidham