--- /dev/null
+# Copyright (c) 2019 AT&T Intellectual Property. #\r
+# #\r
+# Licensed under the Apache License, Version 2.0 (the "License"); #\r
+# you may not use this file except in compliance with the License. #\r
+# You may obtain a copy of the License at #\r
+# #\r
+# http://www.apache.org/licenses/LICENSE-2.0 #\r
+# #\r
+# Unless required by applicable law or agreed to in writing, software #\r
+# distributed under the License is distributed on an "AS IS" BASIS, #\r
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #\r
+# See the License for the specific language governing permissions and #\r
+# limitations under the License. #\r
+################################################################################\r
+\r
+\r
+from flask import Flask, request, make_response, jsonify, g\r
+import json\r
+import paramiko\r
+import datetime\r
+import logging\r
+import os\r
+from logging import FileHandler\r
+\r
+# redirect http to https\r
+app = Flask(__name__)\r
+\r
+\r
+# Prevents print statement every time an endpoint is triggered.\r
+logging.getLogger("werkzeug").setLevel(logging.WARNING)\r
+\r
+\r
+def unix_time_millis(dt):\r
+ epoch = datetime.datetime.utcfromtimestamp(0)\r
+ return (dt - epoch).total_seconds() * 1000.0\r
+\r
+\r
+@app.route("/otf/vth/ssh/v1/health", methods = ['GET'])\r
+def getHealth():\r
+ return "UP"\r
+\r
+\r
+@app.route('/otf/vth/ssh/v1', methods = ['POST'])\r
+def remoteSSH():\r
+ responseData = {\r
+ "vthResponse": {\r
+ "testDurationMS": "",\r
+ "dateTimeUTC": "",\r
+ "abstractMessage": "",\r
+ "resultData": {}\r
+ }\r
+ }\r
+\r
+ responseData['vthResponse']['dateTimeUTC'] = str(datetime.datetime.now())\r
+ start_time = unix_time_millis(datetime.datetime.now())\r
+\r
+ try:\r
+ if not request.is_json:\r
+ raise ValueError('Request must be a valid JSON object.')\r
+\r
+ request_data = request.get_json()\r
+\r
+ if 'vthInput' in request_data:\r
+ vth_input = request_data['vthInput']\r
+ expected_keys = ['vthName', 'testConfig', 'testData']\r
+ received_keys = vth_input.keys();\r
+ test_data = ""\r
+ test_config = ""\r
+\r
+ if sorted(expected_keys) == sorted(received_keys):\r
+ test_data = vth_input['testData']\r
+\r
+ if 'command' not in test_data:\r
+ raise ValueError('Must supply value testData.command')\r
+\r
+ else:\r
+ raise ValueError('Missing one or more expected keys: {expectedKeys}.'.format(expectedKeys=expected_keys))\r
+\r
+ test_config = vth_input['testConfig']\r
+\r
+ if 'jumpServer' not in test_config:\r
+ raise KeyError('Cannot use jump server when jumpServer key is missing.')\r
+\r
+ jump_server = test_config['jumpServer']\r
+\r
+ if 'host' not in test_config['jumpServer']:\r
+ raise KeyError('Missing host value in jumpServer.')\r
+\r
+ host = test_config['jumpServer']['host']\r
+\r
+ if 'credentials' not in jump_server:\r
+ raise KeyError('Missing credentials in jumpServer.')\r
+\r
+ credentials = jump_server['credentials']\r
+\r
+ if 'username' not in credentials:\r
+ raise KeyError('Missing username in credentials.')\r
+\r
+ username = credentials['username']\r
+\r
+ if 'password' not in credentials:\r
+ raise KeyError('Missing password in credentials.')\r
+\r
+ password = credentials['password']\r
+\r
+ ssh = paramiko.SSHClient()\r
+ ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())\r
+\r
+ if 'usePrivateKey' in test_config:\r
+ if test_config['usePrivateKey']:\r
+ key_passphrase = os.environ.get('id_otf_key_passphrase')\r
+ app.logger.info(key_passphrase)\r
+ ssh.connect(host, username=username, passphrase='passphrase', key_filename='./ssh/id_otf.key')\r
+ with open('./ssh/id_otf.key', 'r') as myfile:\r
+ data = myfile.read().replace('\n', '')\r
+\r
+ app.logger.info(data)\r
+ else:\r
+ ssh.connect(host, username=username, password=password)\r
+ command = test_data['command']\r
+ ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(command)\r
+\r
+ responseData['vthResponse']['resultData']['output'] = str(ssh_stdout.read()).replace('"', '\\"').replace('\n', '\\n')\r
+ responseData['vthResponse']['resultData']['error'] = str(ssh_stderr.read()).replace('"', '\\"').replace('\n', '\\n')\r
+\r
+ else:\r
+ raise KeyError('Missing vthInput parameter(s)')\r
+\r
+ # record the end time of the test\r
+ endTime = unix_time_millis(datetime.datetime.now())\r
+\r
+ # Calculate the total duration of the test\r
+ totalTime = endTime - start_time\r
+\r
+ # Set the test duration in the result\r
+ responseData['vthResponse']['testDurationMS'] = totalTime\r
+\r
+ responseData['vthResponse']['abstractMessage'] = 'done'\r
+\r
+ app.logger.info(str(responseData))\r
+\r
+ return jsonify(responseData)\r
+ except Exception as e:\r
+ app.logger.info(e)\r
+ responseData['vthResponse']['abstractMessage'] = str(e)\r
+ resp = make_response(json.dumps(responseData))\r
+ endTime = unix_time_millis(datetime.datetime.now())\r
+\r
+ totalTime = endTime - start_time\r
+ return resp\r
+\r
+\r
+if __name__ == '__main__':\r
+ logHandler = FileHandler('otf/logs/sshVTH.log', mode='a')\r
+ # logHandler = FileHandler('sshVTH.log', mode='a')\r
+ logHandler.setLevel(logging.INFO)\r
+ app.logger.setLevel(logging.INFO)\r
+ app.logger.addHandler(logHandler)\r
+ context = ('opt/cert/otf.pem', 'opt/cert/privateKey.pem')\r
+ app.run(debug = False, host = '0.0.0.0', port = 5000, ssl_context = context)\r
+ # app.run(debug = False, host = '0.0.0.0', port=5000)\r