summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthuva4 <tharma.thuva@gmail.com>2018-01-30 19:50:33 +0530
committerthuva4 <tharma.thuva@gmail.com>2018-02-08 14:55:43 +0530
commitc53fc432fc7ddf004d4e1eea9bd407f3c548908d (patch)
tree89a24a0e1432951194a89797deb58c825f4d4336
parentbd2e91686de6bc61b97ac66af47f830d1c82786a (diff)
create Testapi client
implement auth in testapi client implement pods in testapi client Change-Id: Idd5c9dcf938ad5994e655b55d49625ab462ab710 Signed-off-by: thuva4 <tharma.thuva@gmail.com>
-rw-r--r--.gitignore2
-rw-r--r--testapi/.gitignore3
-rw-r--r--testapi/testapi-client/etc/config.ini6
-rw-r--r--testapi/testapi-client/requirements.txt8
-rw-r--r--testapi/testapi-client/setup.cfg59
-rw-r--r--testapi/testapi-client/setup.py11
-rw-r--r--testapi/testapi-client/testapiclient/__init__.py8
-rw-r--r--testapi/testapi-client/testapiclient/auth.py22
-rw-r--r--testapi/testapi-client/testapiclient/authHandler.py16
-rw-r--r--testapi/testapi-client/testapiclient/config.py14
-rw-r--r--testapi/testapi-client/testapiclient/httpClient.py44
-rw-r--r--testapi/testapi-client/testapiclient/main.py40
-rw-r--r--testapi/testapi-client/testapiclient/pods.py87
-rw-r--r--testapi/testapi-client/testapiclient/user.py2
-rw-r--r--testapi/testapi-client/tox.ini32
15 files changed, 353 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 8cf2a3b..5881045 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,3 +25,5 @@ nosetests.xml
.tox
*.retry
job_output/
+.vscode
+testapi/testapi-client/pip-selfcheck.json
diff --git a/testapi/.gitignore b/testapi/.gitignore
index e34365e..5be8583 100644
--- a/testapi/.gitignore
+++ b/testapi/.gitignore
@@ -12,4 +12,5 @@ build
.ven
docs/_build
opnfv_testapi/tests/UI/coverage
-3rd_party/static/testapi-ui/testapi-ui \ No newline at end of file
+3rd_party/static/testapi-ui/testapi-ui
+
diff --git a/testapi/testapi-client/etc/config.ini b/testapi/testapi-client/etc/config.ini
new file mode 100644
index 0000000..dde4bdd
--- /dev/null
+++ b/testapi/testapi-client/etc/config.ini
@@ -0,0 +1,6 @@
+[api]
+url = http://localhost:8000/api/v1
+
+[cas]
+signin_return = /auth/signin_return
+auth_url = https://identity.linuxfoundation.org/user/login?destination=cas/login%3Fservice%3D \ No newline at end of file
diff --git a/testapi/testapi-client/requirements.txt b/testapi/testapi-client/requirements.txt
new file mode 100644
index 0000000..0c6ef77
--- /dev/null
+++ b/testapi/testapi-client/requirements.txt
@@ -0,0 +1,8 @@
+setuptools>=16.0,!=24.0.0,!=34.0.0,!=34.0.1,!=34.0.2,!=34.0.3,!=34.1.0,!=34.1.1,!=34.2.0,!=34.3.0,!=34.3.1,!=34.3.2 # PSF/ZPL
+
+pbr>=2.0.0,!=2.1.0 # Apache-2.0
+cmd2>=0.6.7 # MIT
+PrettyTable<0.8,>=0.7.1 # BSD
+pyparsing>=2.1.0 # MIT
+six>=1.10.0 # MIT
+cliff \ No newline at end of file
diff --git a/testapi/testapi-client/setup.cfg b/testapi/testapi-client/setup.cfg
new file mode 100644
index 0000000..1e25b73
--- /dev/null
+++ b/testapi/testapi-client/setup.cfg
@@ -0,0 +1,59 @@
+[metadata]
+name = testapi-client
+
+[global]
+setup-hooks =
+ pbr.hooks.setup_hook
+
+[files]
+packages =
+ testapiclient
+
+data_files =
+ /etc/testapiclient = etc/config.ini
+
+[entry_points]
+console_scripts =
+ testapi = testapiclient.main:main
+
+testapi =
+ auth = testapiclient.auth:Auth
+ pod create = testapiclient.pods:PodCreate
+ pod get = testapiclient.pods:PodGet
+ pod delete = testapiclient.pods:PodDelete
+ pod getone = testapiclient.pods:PodGetOne
+
+ project create = testapiclient.projects:ProjectCreate
+ project get = testapiclient.projects:ProjectGet
+ project delete = testapiclient.projects:ProjectDelete
+ project put = testapiclient.projects:ProjectPut
+
+ testcase create = testapiclient.testcase:TestCaseCreate
+ testcase get = testapiclient.testcase:TestCaseGet
+ testcase delete = testapiclient.testcase:TestCaseDelete
+ testcase put = testapiclient.testcase:TestCasePut
+
+ scenario create = testapiclient.scenario:ScenarioCreate
+ scenario get = testapiclient.scenario:ScenarioGet
+ scenario delete = testapiclient.scenario:ScenarioDelete
+ scenario put = testapiclient.scenario:ScenarioPut
+
+ scenario addscore = testapiclient.scenario:ScenarioAddScore
+
+ scenario addyi = testapiclient.scenario:ScenarioAddTI
+
+ scenario addcustom = testapiclient.scenario:ScenarioAddCustom
+ scenario updatecustom = testapiclient.scenario:ScenarioUpdateCustom
+ scenario deletecustom = testapiclient.scenario:ScenarioDeleteCustom
+
+ scenario addproject = testapiclient.scenario:ScenarioAddProject
+ scenario deleteproject = testapiclient.scenario:ScenarioDeleteProject
+
+ scenario addversion = testapiclient.scenario:ScenarioAddVersion
+ scenario deleteversion = testapiclient.scenario:ScenarioDeleteVersion
+
+ result get = testapiclient.results:ResultGet
+[egg_info]
+tag_build =
+tag_date = 0
+tag_svn_revision = 0
diff --git a/testapi/testapi-client/setup.py b/testapi/testapi-client/setup.py
new file mode 100644
index 0000000..96b6dbf
--- /dev/null
+++ b/testapi/testapi-client/setup.py
@@ -0,0 +1,11 @@
+
+import setuptools
+
+try:
+ import multiprocessing # noqa
+except ImportError:
+ pass
+
+setuptools.setup(
+ setup_requires=['pbr>=2.0.0'],
+ pbr=True)
diff --git a/testapi/testapi-client/testapiclient/__init__.py b/testapi/testapi-client/testapiclient/__init__.py
new file mode 100644
index 0000000..363bc38
--- /dev/null
+++ b/testapi/testapi-client/testapiclient/__init__.py
@@ -0,0 +1,8 @@
+##############################################################################
+# Copyright (c) 2016 ZTE Corporation
+# feng.xiaowei@zte.com.cn
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
diff --git a/testapi/testapi-client/testapiclient/auth.py b/testapi/testapi-client/testapiclient/auth.py
new file mode 100644
index 0000000..7799d60
--- /dev/null
+++ b/testapi/testapi-client/testapiclient/auth.py
@@ -0,0 +1,22 @@
+import logging
+from cliff.command import Command
+from authHandler import AuthHandler
+
+
+class Auth(Command):
+ "Handle Authentication for users"
+
+ log = logging.getLogger(__name__)
+
+ def get_parser(self, prog_name):
+ parser = super(Auth, self).get_parser(prog_name)
+ parser.add_argument('-u', type=str, required=True, help='Username for authentication')
+ parser.add_argument('-p', type=str, required=True, help='Password for authentication')
+ return parser
+
+ def take_action(self, parsed_args):
+ response = AuthHandler.authenticate(parsed_args.u, parsed_args.p)
+ if "login" in response.text:
+ print "Authentication has failed. Please check your username and password."
+ else:
+ print "Authentication has been successful!"
diff --git a/testapi/testapi-client/testapiclient/authHandler.py b/testapi/testapi-client/testapiclient/authHandler.py
new file mode 100644
index 0000000..a421cf8
--- /dev/null
+++ b/testapi/testapi-client/testapiclient/authHandler.py
@@ -0,0 +1,16 @@
+import requests
+from user import User
+from config import Config
+import urllib
+
+
+class AuthHandler:
+
+ @staticmethod
+ def authenticate(username, password):
+ session = requests.Session()
+ hostname = Config.config.get("cas", "auth_url") + urllib.quote(Config.config.get("api", "url")) + Config.config.get("cas", "signin_return")
+ data = {'name': username, 'pass': password, 'form_id': 'user_login'}
+ response = session.post(hostname, data)
+ User.session = session
+ return response
diff --git a/testapi/testapi-client/testapiclient/config.py b/testapi/testapi-client/testapiclient/config.py
new file mode 100644
index 0000000..7bc165f
--- /dev/null
+++ b/testapi/testapi-client/testapiclient/config.py
@@ -0,0 +1,14 @@
+import ConfigParser
+import io
+
+
+class Config:
+ # Load the configuration file
+ config = ''
+
+ @staticmethod
+ def parse_conf():
+ with open("/etc/testapiclient/config.ini") as f:
+ sample_config = f.read()
+ Config.config = ConfigParser.RawConfigParser(allow_no_value=True)
+ Config.config.readfp(io.BytesIO(sample_config))
diff --git a/testapi/testapi-client/testapiclient/httpClient.py b/testapi/testapi-client/testapiclient/httpClient.py
new file mode 100644
index 0000000..bc45f36
--- /dev/null
+++ b/testapi/testapi-client/testapiclient/httpClient.py
@@ -0,0 +1,44 @@
+import json
+import requests
+
+
+class HTTPClient():
+
+ __instance = None
+ headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
+
+ @staticmethod
+ def get_Instance():
+ """ Static access method. """
+ if HTTPClient.__instance is None:
+ HTTPClient()
+ return HTTPClient.__instance
+
+ def __init__(self):
+ """ Virtually private constructor. """
+ if HTTPClient.__instance is not None:
+ raise Exception("This class is a singleton!")
+ else:
+ HTTPClient.__instance = self
+
+ def get(self, url):
+ r = requests.get(url)
+ if r.status_code == 200:
+ return r.json()
+ else:
+ return r.text
+
+ def post(self, url, session, data):
+ r = session.post(url, data=json.dumps(data), headers=HTTPClient.headers)
+ return r
+
+ def put(self, url, session, data):
+ r = session.put(url, data=json.dumps(data), headers=HTTPClient.headers)
+ return r.text
+
+ def delete(self, url, session, *args):
+ if(args.__len__ > 0):
+ r = session.delete(url, data=json.dumps(args[0]), headers=HTTPClient.headers)
+ else:
+ r = session.delete(url)
+ return r.text
diff --git a/testapi/testapi-client/testapiclient/main.py b/testapi/testapi-client/testapiclient/main.py
new file mode 100644
index 0000000..07dbeb8
--- /dev/null
+++ b/testapi/testapi-client/testapiclient/main.py
@@ -0,0 +1,40 @@
+import sys
+import requests
+from user import User
+from config import Config
+from cliff.app import App
+from cliff.commandmanager import CommandManager
+
+
+class TestAPIClient(App):
+
+ def __init__(self):
+ super(TestAPIClient, self).__init__(
+ description='TestAPI Client',
+ version='0.1',
+ command_manager=CommandManager('testapi'),
+ deferred_help=True,
+ )
+ User.session = requests.Session()
+ # Configure development or Production mode
+ Config.parse_conf()
+
+ def initialize_app(self, argv):
+ self.LOG.debug('initialize_app')
+
+ def prepare_to_run_command(self, cmd):
+ self.LOG.debug('prepare_to_run_command %s', cmd.__class__.__name__)
+
+ def clean_up(self, cmd, result, err):
+ self.LOG.debug('clean_up %s', cmd.__class__.__name__)
+ if err:
+ self.LOG.debug('got an error: %s', err)
+
+
+def main(argv=sys.argv[1:]):
+ myapp = TestAPIClient()
+ return myapp.run(argv)
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/testapi/testapi-client/testapiclient/pods.py b/testapi/testapi-client/testapiclient/pods.py
new file mode 100644
index 0000000..f5e2fe9
--- /dev/null
+++ b/testapi/testapi-client/testapiclient/pods.py
@@ -0,0 +1,87 @@
+import json
+
+from user import User
+from cliff.command import Command
+from httpClient import HTTPClient
+from authHandler import AuthHandler
+from config import Config
+
+
+class PodBase(Command):
+ pods_url = Config.config.get("api", "url") + "/pods"
+
+
+class PodGet(PodBase):
+ "Handle get request for pods"
+
+ def get_parser(self, prog_name):
+ parser = super(PodGet, self).get_parser(prog_name)
+ parser.add_argument('-name', default='', help='Search pods using name')
+ return parser
+
+ def take_action(self, parsed_args):
+ http_client = HTTPClient.get_Instance()
+ url = PodGet.pods_url
+ if(parsed_args.name):
+ url = PodGet.pods_url + "?name=" + parsed_args.name
+ pods = http_client.get(url)
+ print pods
+
+
+class PodGetOne(PodBase):
+ "Handle get request for pod by name"
+
+ def get_parser(self, prog_name):
+ parser = super(PodGetOne, self).get_parser(prog_name)
+ parser.add_argument('-name', default='', help='Find pod using name', required=True)
+ return parser
+
+ def take_action(self, parsed_args):
+ http_client = HTTPClient.get_Instance()
+ pods = http_client.get(PodGetOne.pods_url + "/" + parsed_args.name)
+ print pods
+
+
+class PodCreate(PodBase):
+ "Handle post request for pods"
+
+ def get_parser(self, prog_name):
+ parser = super(PodCreate, self).get_parser(prog_name)
+ parser.add_argument('-u', type=str, help='Username for authentication')
+ parser.add_argument('-p', type=str, help='Password for authentication')
+ parser.add_argument('pod', type=json.loads, help='Pod create request format :\n\'{ "role": "", "name": "", "details": "", "mode": ""}\',\n role should be either "community-ci" or "production-ci", and mode should be either "metal" or "virtual.')
+ return parser
+
+ def take_action(self, parsed_args):
+ http_client = HTTPClient.get_Instance()
+ if(parsed_args.u and parsed_args.p):
+ response = AuthHandler.authenticate(parsed_args.u, parsed_args.p)
+ if "login" in response.text:
+ print "Authentication has failed. Please check your username and password."
+ return
+ response = http_client.post(PodCreate.pods_url, User.session, parsed_args.pod)
+ if response.status_code == 200:
+ print "Pod has been successfully created!"
+ else:
+ print response.text
+
+
+class PodDelete(PodBase):
+ "Handle delete request for pods"
+
+ def get_parser(self, prog_name):
+ parser = super(PodDelete, self).get_parser(prog_name)
+ parser.add_argument('-u', type=str, help='Username for authentication')
+ parser.add_argument('-p', type=str, help='Password for authentication')
+ parser.add_argument('-name', type=str, required=True, help='Delete pods using name')
+ return parser
+
+ def take_action(self, parsed_args):
+ http_client = HTTPClient.get_Instance()
+ if(parsed_args.u and parsed_args.p):
+ response = AuthHandler.authenticate(parsed_args.u, parsed_args.p)
+ if "login" in response.text:
+ print "Authentication has failed. Please check your username and password."
+ return
+ pods = http_client.delete(PodDelete.pods_url + "/" + parsed_args.name, User.session)
+ print pods
diff --git a/testapi/testapi-client/testapiclient/user.py b/testapi/testapi-client/testapiclient/user.py
new file mode 100644
index 0000000..7e72163
--- /dev/null
+++ b/testapi/testapi-client/testapiclient/user.py
@@ -0,0 +1,2 @@
+class User():
+ session = None
diff --git a/testapi/testapi-client/tox.ini b/testapi/testapi-client/tox.ini
new file mode 100644
index 0000000..cf73b91
--- /dev/null
+++ b/testapi/testapi-client/tox.ini
@@ -0,0 +1,32 @@
+# Tox (http://tox.testrun.org/) is a tool for running tests
+# in multiple virtualenvs. This configuration file will run the
+# test suite on all supported python versions. To use it, "pip install tox"
+# and then run "tox" from this directory.
+
+[tox]
+envlist = pep8,py27
+skipsdist = True
+sitepackages = True
+
+[testenv]
+usedevelop = True
+install_command = pip install -U {opts} {packages}
+deps =
+ -rrequirements.txt
+setenv=
+ HOME = {envtmpdir}
+ PYTHONPATH = {toxinidir}
+
+
+[testenv:pep8]
+deps = flake8
+commands = flake8 {toxinidir}
+
+[flake8]
+# H803 skipped on purpose per list discussion.
+# E123, E125 skipped as they are invalid PEP-8.
+
+show-source = True
+ignore = E123,E125,H803,E501
+builtins = _
+exclude = bin, build, dist, lib, local, .git, .eggs, .tox, .venv, venv, testapi_client.egg-info \ No newline at end of file