adding vth code as well as aaf and cert config
[it/otf.git] / otf-ping-test-head / otfPingTestHead.py
diff --git a/otf-ping-test-head/otfPingTestHead.py b/otf-ping-test-head/otfPingTestHead.py
new file mode 100644 (file)
index 0000000..1163034
--- /dev/null
@@ -0,0 +1,196 @@
+#   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
+from flask import Flask, request, make_response, jsonify, g\r
+import json\r
+import uuid\r
+import traceback\r
+import pyping\r
+import paramiko\r
+import socket\r
+import os\r
+import subprocess\r
+import datetime\r
+import logging\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
+def unix_time_millis(dt):\r
+       epoch = datetime.datetime.utcfromtimestamp(0)\r
+       return (dt - epoch).total_seconds() * 1000.0\r
+\r
+def pingServer(targetHost):\r
+       try:\r
+               response = subprocess.check_output(\r
+                       ['ping', '-c', '1', targetHost],        # execute the ping command\r
+                       stderr = subprocess.STDOUT,             # retrieve all the output\r
+                       universal_newlines = True                       # return as string\r
+               )\r
+       except subprocess.CalledProcessError as e:\r
+               app.logger.error(e)\r
+               app.logger.error('failed getting response from ' + str(targetHost))\r
+               response = None\r
+\r
+       return response\r
+\r
+@app.route("/otf/vth/ping/v1/health", methods = ['GET'])\r
+def getHealth():\r
+       return "UP"\r
+\r
+@app.route('/otf/vth/sample/v1', methods = ['POST'])\r
+def sample():\r
+       startTime = unix_time_millis(datetime.datetime.now())\r
+       responseData = {\r
+               "vthResponse": {\r
+                       "testDurationMS": "",\r
+                       "dateTimeUTC": "",\r
+                       "abstractMessage": "Success",\r
+                       "resultData": {}\r
+               }\r
+       }\r
+       responseData['vthResponse']['dateTimeUTC'] = str(datetime.datetime.now())\r
+       endTime = unix_time_millis(datetime.datetime.now())\r
+       responseData['vthResponse']['testDurationMS'] = endTime - startTime\r
+       responseData['vthResponse']['resultData']['result'] = "Executed test successfully in " + str(responseData['vthResponse']['testDurationMS']) + " milliseconds."\r
+       app.logger.info('hit sample endpoint. response: ' + str(responseData))\r
+       return jsonify(responseData)\r
+\r
+@app.route('/otf/vth/ping/v1', methods = ['POST'])\r
+def testHead():\r
+       responseData = {\r
+               "vthResponse": {\r
+                       "testDurationMS": "",\r
+                       "dateTimeUTC": "",\r
+                       "abstractMessage": "",\r
+                       "resultData": {}\r
+               }\r
+       }\r
+\r
+       responseData['vthResponse']['dateTimeUTC'] = str(datetime.datetime.now())\r
+       startTime = 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
+               requestData = request.get_json()\r
+               app.logger.info('ping endpoint. request: ' + str(requestData))\r
+\r
+               if 'vthInput' in requestData:\r
+                       vthInput = requestData['vthInput']\r
+                       expectedKeys = ['vthName', 'testConfig', 'testData']\r
+                       receivedKeys = vthInput.keys();\r
+                       testData = ""\r
+                       testConfig = ""\r
+\r
+                       if sorted(expectedKeys) == sorted(receivedKeys):\r
+                               testData = vthInput['testData']\r
+\r
+                               # Check if a target host is provided.\r
+                               if 'targetHost' not in testData:\r
+                                       raise KeyError('targetHost is required to ping server.')\r
+\r
+                               # Check if the target host IP address is in the correct format.\r
+                               # This excludes IPv6. Use IPy to check both IPv6/IPv4.\r
+                               try:\r
+                                       socket.inet_aton(testData['targetHost'])\r
+                               except socket.error:\r
+                                       raise ValueError('Invalid IP address assigned to targetHost')\r
+\r
+                               # Don't use a jump server by default.\r
+                               if 'useJumpServer' not in testData:\r
+                                       testData['useJumpServer'] = False\r
+                       else:\r
+                               raise ValueError('Missing one or more expected keys: {expectedKeys}.'.format(expectedKeys = expectedKeys))\r
+\r
+                       if testData['useJumpServer'] == False:\r
+                               responseData['vthResponse']['resultData']['result'] = pingServer(testData['targetHost'])\r
+                       else:\r
+                               testConfig = vthInput['testConfig']\r
+\r
+                               if 'jumpServer' not in testConfig:\r
+                                       raise KeyError('Cannot use jump server when jumpServer key is missing.')\r
+\r
+                               jumpServer = testConfig['jumpServer']\r
+\r
+                               if 'host' not in testConfig['jumpServer']:\r
+                                       raise KeyError('Missing host value in jumpServer.')\r
+\r
+                               host = testConfig['jumpServer']['host']\r
+\r
+                               if 'credentials' not in jumpServer:\r
+                                       raise KeyError('Missing credentials in jumpServer.')\r
+\r
+                               credentials = jumpServer['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
+                               ssh.connect(host, username = username, password = password)\r
+                               command = "ping -c 1 " + testData['targetHost']\r
+                               ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(command)\r
+                               output = ssh_stdout.read()\r
+                               error = ssh_stderr.read()\r
+\r
+                               responseData['vthResponse']['resultData']['result'] = output\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 - startTime\r
+\r
+               # Set the test duration in the result\r
+               responseData['vthResponse']['testDurationMS'] = totalTime\r
+\r
+               responseData['vthResponse']['abstractMessage'] = 'Result from pinging {host}'.format(host = testData['targetHost'])\r
+               app.logger.info('ping endpoint. response: ' + 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 - startTime\r
+               return resp\r
+\r
+if __name__ == '__main__':\r
+       logHandler = FileHandler('otf/logs/pingVTH.log', mode='a')\r
+       # logHandler = FileHandler('pingVTH.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