Merge "provide REST api for frontend of testing-scheduler"
authorYang (Gabriel) Yu <Gabriel.yuyang@huawei.com>
Tue, 4 Sep 2018 10:53:26 +0000 (10:53 +0000)
committerGerrit Code Review <gerrit@opnfv.org>
Tue, 4 Sep 2018 10:53:26 +0000 (10:53 +0000)
50 files changed:
monitor/monitoring.sh
monitor/uninstall.py
requirements/requirements.txt
testing-scheduler/server/__init__.py [new file with mode: 0644]
testing-scheduler/server/conductorclient/__init__.py [new file with mode: 0644]
testing-scheduler/server/conductorclient/mock_tasks.json [new file with mode: 0644]
testing-scheduler/server/conductorclient/mock_workflow.json [new file with mode: 0644]
testing-scheduler/server/conductorclient/run_new_workflow.py [new file with mode: 0644]
testing-scheduler/server/python_modules.txt [new file with mode: 0644]
testing-scheduler/server/setup.py [new file with mode: 0644]
testing-scheduler/server/src/__init__.py [new file with mode: 0644]
testing-scheduler/server/src/conductor_processor/__init__.py [new file with mode: 0644]
testing-scheduler/server/src/conductor_processor/defaultTaskFile.json [new file with mode: 0644]
testing-scheduler/server/src/conductor_processor/defaultWorkflowFile.json [new file with mode: 0644]
testing-scheduler/server/src/conductor_processor/task.py [new file with mode: 0644]
testing-scheduler/server/src/conductor_processor/workflow.py [new file with mode: 0644]
testing-scheduler/server/src/env/context/context.yaml [new file with mode: 0644]
testing-scheduler/server/src/env/service/ansible.yaml [new file with mode: 0644]
testing-scheduler/server/src/env/service/greet.yaml [new file with mode: 0644]
testing-scheduler/server/src/step/__init__.py [new file with mode: 0644]
testing-scheduler/server/src/step/general_test_step.py [new file with mode: 0644]
testing-scheduler/server/src/step/monitor.py [new file with mode: 0644]
testing-scheduler/server/src/step/step_manager.py [new file with mode: 0644]
testing-scheduler/server/src/step/test_step.py [new file with mode: 0644]
testing-scheduler/server/src/step/workload.py [new file with mode: 0644]
testing-scheduler/server/src/test_parser.py [new file with mode: 0644]
testing-scheduler/server/test/__init__.py [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic/tc_logic_00.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic/tc_logic_01.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic/tc_logic_02.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic/tc_logic_03.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic/tc_logic_04.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic/tc_logic_05.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic/tc_logic_06.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic/tc_logic_07.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic/tc_logic_08.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic_in_out/tc_cxt_01.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic_in_out/tc_io_01.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/logic_in_out/tc_io_02.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/suite_test/tc_suitetest_00.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/suite_test/tc_suitetest_01.yaml [new file with mode: 0644]
testing-scheduler/server/test/test_case/suite_test/tc_suitetest_02.yaml [new file with mode: 0644]
utils/env_prepare/config_prepare.sh
utils/infra_setup/heat/common.py
utils/k8s_setup/__init__.py [new file with mode: 0644]
utils/k8s_setup/golang_install.sh [new file with mode: 0644]
utils/k8s_setup/k8s_config_pre.sh [new file with mode: 0644]
utils/k8s_setup/k8s_env.sh [new file with mode: 0644]
utils/k8s_setup/k8s_utils.py [new file with mode: 0644]
utils/k8s_setup/kubectl_install.sh [new file with mode: 0644]

index 26b63fc..758f77e 100644 (file)
@@ -52,7 +52,7 @@ while [[ $# > 0 ]]
             INSTALLER_TYPE="$2"
             shift
         ;;
-        -i|--openstack-env)
+        -o|--openstack-env)
             OPENSTACK_ENV="$2"
             shift
         ;;
@@ -104,7 +104,6 @@ sudo docker run --name bottlenecks-node-exporter \
   -v "/proc:/host/proc:ro" \
   -v "/sys:/host/sys:ro" \
   -v "/:/rootfs:ro" \
-  --net="host" \
   quay.io/prometheus/node-exporter:v0.14.0 \
     -collector.procfs /host/proc \
     -collector.sysfs /host/sys \
index 3a9cf0c..2635172 100644 (file)
@@ -50,3 +50,4 @@ local_del_docker('cadvisor')
 local_del_docker('barometer')
 local_del_docker('grafana')
 local_del_docker('collectd')
+local_del_docker('openstack-exporter')
index dacffce..381cb5c 100644 (file)
@@ -18,3 +18,4 @@ nose==1.3.7
 pyroute2==0.4.10
 elasticsearch==5.0.1
 docker==2.0.2
+kubernetes==6.0.0
diff --git a/testing-scheduler/server/__init__.py b/testing-scheduler/server/__init__.py
new file mode 100644 (file)
index 0000000..e819800
--- /dev/null
@@ -0,0 +1,8 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
diff --git a/testing-scheduler/server/conductorclient/__init__.py b/testing-scheduler/server/conductorclient/__init__.py
new file mode 100644 (file)
index 0000000..bb02be1
--- /dev/null
@@ -0,0 +1,8 @@
+##############################################################################\r
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd. and others\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
diff --git a/testing-scheduler/server/conductorclient/mock_tasks.json b/testing-scheduler/server/conductorclient/mock_tasks.json
new file mode 100644 (file)
index 0000000..4fea48b
--- /dev/null
@@ -0,0 +1,13 @@
+{\r
+    "task_group_1":[\r
+        {\r
+            "name": "http_yardstick_test",\r
+            "retryCount": 3,\r
+            "timeOutSeconds": 1200,\r
+            "timeOutPolicy": "TIME_OUT_WF",\r
+            "retryLogic": "FIXED",\r
+            "retryDelaySeconds": 600,\r
+            "responseTimeOutSeconds": 3600\r
+        }\r
+    ]\r
+}
\ No newline at end of file
diff --git a/testing-scheduler/server/conductorclient/mock_workflow.json b/testing-scheduler/server/conductorclient/mock_workflow.json
new file mode 100644 (file)
index 0000000..8f6251c
--- /dev/null
@@ -0,0 +1,24 @@
+{\r
+    "name": "workflow_demo_05",\r
+    "description": "run a workflow of yardstick test service",\r
+    "version": 1,\r
+    "tasks": [\r
+        {\r
+            "name": "http_yardstick_test",\r
+            "taskReferenceName": "ping_test",\r
+            "inputParameters": {\r
+                "http_request": {\r
+                    "uri": "http://192.168.199.105:8080/greet",\r
+                    "method": "GET"\r
+                }\r
+            },\r
+            "type": "HTTP"\r
+        }\r
+    ],\r
+    "outputParameters": {\r
+        "header": "${ping_test.output.response.headers}",\r
+        "response": "${ping_test.output.response.body}",\r
+        "status": "${ping_test.output.response.statusCode}"\r
+    },\r
+    "schemaVersion": 2\r
+}
\ No newline at end of file
diff --git a/testing-scheduler/server/conductorclient/run_new_workflow.py b/testing-scheduler/server/conductorclient/run_new_workflow.py
new file mode 100644 (file)
index 0000000..0acb96a
--- /dev/null
@@ -0,0 +1,71 @@
+##############################################################################\r
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd. and others\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+from conductor import conductor\r
+import json\r
+\r
+\r
+class WorkflowMgr(object):\r
+    def __init__(self, serverAddr):\r
+        self._serverAddr = serverAddr + '/api'\r
+        self._metaDataClient = conductor.MetadataClient(self._serverAddr)\r
+        self._workflowClient = conductor.WorkflowClient(self._serverAddr)\r
+        self._tasksDefined = False\r
+        self._workflowDefined = False\r
+        self._workflowName = ""\r
+\r
+    def setTaskDef(self, taskJson):\r
+        jsonObj = json.loads(taskJson)\r
+        print "define tasks:\n", taskJson\r
+        for (k, v) in jsonObj.items():\r
+            self._metaDataClient.registerTaskDefs(v)\r
+        self._tasksDefined = True\r
+\r
+    def setWorkflowDef(self, workflowJson):\r
+        jsonObj = json.loads(workflowJson)\r
+        print "define workflow:\n", workflowJson\r
+        try:\r
+            self._metaDataClient.createWorkflowDef(jsonObj)\r
+        except Exception as e:\r
+            print e\r
+        self._workflowName = jsonObj['name']\r
+        self._workflowDefined = True\r
+\r
+    def startWorkflow(self, param={}):\r
+        workflowId = ''\r
+        if not self._tasksDefined:\r
+            print "error: please define the task at first\n"\r
+        elif not self._workflowDefined:\r
+            print "error: please define the workflow at first\n"\r
+        else:\r
+            workflowId = self._workflowClient.startWorkflow(\r
+                self._workflowName, param)\r
+        return workflowId\r
+\r
+    def setTaskDefFromFile(self, taskFilePath):\r
+        with open(taskFilePath, 'r') as f:\r
+            self.setTaskDef(f.read())\r
+\r
+    def setWorkflowFromFile(self, workflowFilePath):\r
+        with open(workflowFilePath, 'r') as f:\r
+            self.setWorkflowDef(f.read())\r
+\r
+\r
+# test demo\r
+def main():\r
+    serverAddr = "http://192.168.199.131:8080"\r
+    wfMgr = WorkflowMgr(serverAddr)\r
+    wfMgr.setTaskDefFromFile('mock_tasks.json')\r
+    wfMgr.setWorkflowFromFile('mock_workflow.json')\r
+    inputParam = {'input': 'fake'}\r
+    wfMgr.startWorkflow(inputParam)\r
+\r
+\r
+if __name__ == "__main__":\r
+    main()\r
diff --git a/testing-scheduler/server/python_modules.txt b/testing-scheduler/server/python_modules.txt
new file mode 100644 (file)
index 0000000..62da9c2
--- /dev/null
@@ -0,0 +1,14 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+flask\r
+flask_cors\r
+pyyaml\r
+pyaml\r
+requests
\ No newline at end of file
diff --git a/testing-scheduler/server/setup.py b/testing-scheduler/server/setup.py
new file mode 100644 (file)
index 0000000..398f876
--- /dev/null
@@ -0,0 +1,31 @@
+#!/usr/bin/env python\r
+##############################################################################\r
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+'''This file realize the function of how to setup server of testing-scheduler\r
+to your environment. This use setuptools tool to setup'''\r
+\r
+from setuptools import setup, find_packages\r
+\r
+\r
+setup(\r
+    name="testing-scheduler-server",\r
+    version="0.1",\r
+    packages=find_packages(),\r
+    include_package_data=True,\r
+    package_data={\r
+        'src': [\r
+            'env/context/*.yaml',\r
+            'env/service/*.yaml',\r
+            'conductor_processor/*.json'\r
+        ],\r
+        'test': [\r
+            'test_case/*/*.yaml'\r
+        ]\r
+    }\r
+)\r
diff --git a/testing-scheduler/server/src/__init__.py b/testing-scheduler/server/src/__init__.py
new file mode 100644 (file)
index 0000000..e819800
--- /dev/null
@@ -0,0 +1,8 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
diff --git a/testing-scheduler/server/src/conductor_processor/__init__.py b/testing-scheduler/server/src/conductor_processor/__init__.py
new file mode 100644 (file)
index 0000000..bb02be1
--- /dev/null
@@ -0,0 +1,8 @@
+##############################################################################\r
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd. and others\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
diff --git a/testing-scheduler/server/src/conductor_processor/defaultTaskFile.json b/testing-scheduler/server/src/conductor_processor/defaultTaskFile.json
new file mode 100644 (file)
index 0000000..a98a581
--- /dev/null
@@ -0,0 +1,9 @@
+{\r
+    "name": "",\r
+    "retryCount": 6,\r
+    "timeOutSeconds": 1200,\r
+    "timeOutPolicy": "TIME_OUT_WF",\r
+    "retryLogic": "FIXED",\r
+    "retryDelaySeconds": 3,\r
+    "responseTimeOutSeconds": 3600\r
+}
\ No newline at end of file
diff --git a/testing-scheduler/server/src/conductor_processor/defaultWorkflowFile.json b/testing-scheduler/server/src/conductor_processor/defaultWorkflowFile.json
new file mode 100644 (file)
index 0000000..8f6251c
--- /dev/null
@@ -0,0 +1,24 @@
+{\r
+    "name": "workflow_demo_05",\r
+    "description": "run a workflow of yardstick test service",\r
+    "version": 1,\r
+    "tasks": [\r
+        {\r
+            "name": "http_yardstick_test",\r
+            "taskReferenceName": "ping_test",\r
+            "inputParameters": {\r
+                "http_request": {\r
+                    "uri": "http://192.168.199.105:8080/greet",\r
+                    "method": "GET"\r
+                }\r
+            },\r
+            "type": "HTTP"\r
+        }\r
+    ],\r
+    "outputParameters": {\r
+        "header": "${ping_test.output.response.headers}",\r
+        "response": "${ping_test.output.response.body}",\r
+        "status": "${ping_test.output.response.statusCode}"\r
+    },\r
+    "schemaVersion": 2\r
+}
\ No newline at end of file
diff --git a/testing-scheduler/server/src/conductor_processor/task.py b/testing-scheduler/server/src/conductor_processor/task.py
new file mode 100644 (file)
index 0000000..6f25aef
--- /dev/null
@@ -0,0 +1,28 @@
+##############################################################################\r
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd. and others\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+import json\r
+import os\r
+\r
+\r
+class TaskFile(object):\r
+    def __init__(self, taskName='task_0'):\r
+        self._defaultConfFile = self._getFilePath("defaultTaskFile.json")\r
+        with open(self._defaultConfFile) as defaultConf:\r
+            self._jsonObj = json.load(defaultConf)\r
+        self._jsonObj['name'] = taskName\r
+\r
+    def generateFromStep(self, stepObject):\r
+        self._jsonObj['name'] = stepObject.getName()\r
+        print "taskFile:", self._jsonObj['name']\r
+        return self._jsonObj\r
+\r
+    def _getFilePath(self, fileName):\r
+        dirPath = os.path.dirname(os.path.realpath(__file__))\r
+        return os.path.join(dirPath, fileName)\r
diff --git a/testing-scheduler/server/src/conductor_processor/workflow.py b/testing-scheduler/server/src/conductor_processor/workflow.py
new file mode 100644 (file)
index 0000000..19f0896
--- /dev/null
@@ -0,0 +1,243 @@
+##############################################################################\r
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd. and others\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+import random\r
+import collections\r
+import re\r
+from src.conductor_processor.task import TaskFile\r
+\r
+\r
+class WorkflowFile(object):\r
+    def __init__(self, name):\r
+        self._name = "workflow_" + name + "(%s)" % getRandString(10)\r
+        self._description = ''\r
+        self._version = 1\r
+        self._schemaVersion = 2\r
+        self._tasks = []\r
+        self._outputParameters = {}\r
+\r
+    def getDict(self):\r
+        d = collections.OrderedDict()\r
+        d['name'] = self._name\r
+        d['description'] = self._description\r
+        d['version'] = self._version\r
+        d['schemaVersion'] = self._schemaVersion\r
+        d['tasks'] = self._tasks\r
+        d['outputParameters'] = self._outputParameters\r
+\r
+        return d\r
+\r
+    def generateMetaData(self, flowList, stepObjArr):\r
+        flowParser = FlowParser(flowList, stepObjArr)\r
+        self._tasks, taskMetaList = flowParser.parseMainFlow()\r
+        normalTasks = flowParser.getNormalTaskList()\r
+        for normalTask in normalTasks:\r
+            taskName = normalTask['name']\r
+            referenceName = normalTask['taskReferenceName']\r
+            self._outputParameters["%s(%s)" % (taskName, referenceName)] = \\r
+                "${%s.output.response.body}" % referenceName\r
+        return self.getDict(), taskMetaList\r
+\r
+\r
+class FlowParser(object):\r
+    def __init__(self, flowList, stepObjArr):\r
+        self._mainFlow = {}\r
+        self._subFlowDict = {}\r
+        self._stepObjArr = stepObjArr\r
+        self._normalTasks = []\r
+        for flow in flowList:\r
+            if flow['name'] == "main":\r
+                self._mainFlow = flow\r
+            else:\r
+                self._subFlowDict[flow['name']] = flow\r
+\r
+    def parseMainFlow(self):\r
+        return self.parseOrderList(self._mainFlow['orders'], self._stepObjArr)\r
+\r
+    def parse(self, obj, stepObjArr):\r
+        if isinstance(obj, str):\r
+            return self.parseFlow(obj, stepObjArr)\r
+        else:\r
+            return self.parseOrderList(obj, stepObjArr)\r
+\r
+    def parseFlow(self, flowName, stepObjArr):\r
+        orderList = self._subFlowDict[flowName]['orders']\r
+        return self.parseOrderList(orderList, stepObjArr)\r
+\r
+    def parseOrderList(self, orderList, stepObjArr):\r
+        tasks = []\r
+        taskMetaAllList = []\r
+        for order in orderList:\r
+            if order['type'] == "normal":\r
+                genTask = NormalTask(order, stepObjArr, self)\r
+                self._normalTasks.append(genTask)\r
+            elif order['type'] == "switch":\r
+                genTask = SwitchTask(order, stepObjArr, self)\r
+            elif order['type'] == "parallel":\r
+                genTask = ParallelTask(order, stepObjArr, self)\r
+            tasks.append(genTask.getDict())\r
+\r
+            if order['type'] == "parallel":\r
+                joinTask = genTask.getJoinTask()\r
+                tasks.append(joinTask.getDict())\r
+\r
+            taskMetaList = genTask.getTaskMetaList()\r
+            if taskMetaList is not None:\r
+                taskMetaAllList.extend(taskMetaList)\r
+        return tasks, taskMetaAllList\r
+\r
+    def getNormalTaskList(self):\r
+        normalTasksDict = []\r
+        for normalTask in self._normalTasks:\r
+            normalTasksDict.append(normalTask.getDict())\r
+        return normalTasksDict\r
+\r
+    def getNormalTask(self, stepId):\r
+        for normalTask in self._normalTasks:\r
+            if normalTask.getStepId() == stepId:\r
+                return normalTask\r
+        return None\r
+\r
+\r
+class BaseWorkflowTask(object):\r
+    def __init__(self, name):\r
+        self._name = name\r
+        self._taskReferenceName = self._name + "_task_%s" % getRandString(10)\r
+        self._type = ''\r
+        self._args = {}\r
+\r
+    def __str__(self):\r
+        dictObj = self.getDict()\r
+        return str(dictObj)\r
+\r
+    def getDict(self):\r
+        d1 = {\r
+            "name": self._name,\r
+            "taskReferenceName": self._taskReferenceName,\r
+            "type": self._type\r
+        }\r
+        return dict(d1, **self._args)\r
+\r
+    def getName(self):\r
+        return self._name\r
+\r
+    def getReferenceName(self):\r
+        return self._taskReferenceName\r
+\r
+    def getTaskMetaList(self):\r
+        taskFile = TaskFile()\r
+        return [taskFile.generateFromStep(self)]\r
+\r
+\r
+class NormalTask(BaseWorkflowTask):\r
+    def __init__(self, order, stepObjArr, flowParser):\r
+        relatedStepObj = stepObjArr[order['step'] - 1]\r
+        super(NormalTask, self).__init__(relatedStepObj.getName())\r
+        self._taskReferenceName = "task_%s" % getRandString(10)\r
+        self._stepId = relatedStepObj.getId()\r
+        self._type = "HTTP"\r
+        self._args['inputParameters'] = relatedStepObj.getArgs()\r
+        self._paramTransform(self._args['inputParameters'], flowParser)\r
+        print "NormalTask:----------------------\n", relatedStepObj.getArgs()\r
+\r
+    def _paramTransform(self, argsDict, flowParser):\r
+        for (k, v) in argsDict.items():\r
+            if isinstance(v, str):\r
+                if re.match("^\(\(\d+\..*\)\)", v):\r
+                    v = v[2:-2]\r
+                    stepId, outputParam = v.split(".")\r
+                    stepId = int(stepId)\r
+                    normalTask = flowParser.getNormalTask(stepId)\r
+                    if normalTask is None:\r
+                        continue\r
+                    argsDict[k] = "${%s.output.response.body.%s}" %  \\r
+                        (normalTask.getReferenceName(), outputParam)\r
+            elif isinstance(v, dict):\r
+                self._paramTransform(v, flowParser)\r
+\r
+    def getStepId(self):\r
+        return self._stepId\r
+\r
+\r
+class SwitchTask(BaseWorkflowTask):\r
+    seqNumber = 0\r
+\r
+    def __init__(self, order, stepObjArr, flowParser):\r
+        super(SwitchTask, self).__init__("switch_" + str(SwitchTask.seqNumber))\r
+        SwitchTask.seqNumber = SwitchTask.seqNumber + 1\r
+        if 'name' in order:\r
+            self._name = order['name']\r
+        self._type = "DECISION"\r
+        caseValueParam = 'value'\r
+        order['value'] = order['value'][2:-2]\r
+        stepId, outputParam = order['value'].split(".")\r
+        stepId = int(stepId)\r
+        normalTask = flowParser.getNormalTask(stepId)\r
+        caseValue = "${%s.output.response.body.%s}" % \\r
+            (normalTask.getReferenceName(), outputParam)\r
+        self._args['inputParameters'] = {caseValueParam: caseValue}\r
+        self._args['caseValueParam'] = caseValueParam\r
+        self._args['decisionCases'] = {}\r
+        self._childTaskMetaList = []\r
+        for case, caseOrders in order['cases'].items():\r
+            self._args['decisionCases'][case], taskMetaList =  \\r
+                flowParser.parse(caseOrders, stepObjArr)\r
+            if taskMetaList is not None:\r
+                self._childTaskMetaList.extend(taskMetaList)\r
+\r
+    def getTaskMetaList(self):\r
+        selfTaskMetaList = super(SwitchTask, self).getTaskMetaList()\r
+        selfTaskMetaList.extend(self._childTaskMetaList)\r
+        return selfTaskMetaList\r
+\r
+\r
+class ParallelTask(BaseWorkflowTask):\r
+    seqNumber = 0\r
+\r
+    def __init__(self, order, stepObjArr, flowParser):\r
+        InstSeqNumber = ParallelTask.seqNumber\r
+        super(ParallelTask, self).__init__("parallel_" + str(InstSeqNumber))\r
+        ParallelTask.seqNumber = ParallelTask.seqNumber + 1\r
+        if 'name' in order:\r
+            self._name = order['name']\r
+        self._type = "FORK_JOIN"\r
+        self._args['forkTasks'] = []\r
+        self._childTaskMetaList = []\r
+        lastTasksNameList = []\r
+        parallelList = order['parallel'].items()\r
+        parallelList.sort()\r
+        for key, orderList in parallelList:\r
+            print orderList\r
+            taskList, taskMetaList = flowParser.parse(orderList, stepObjArr)\r
+            self._args['forkTasks'].append(taskList)\r
+            lastTasksNameList.append(taskList[-1]['taskReferenceName'])\r
+            if taskMetaList is not None:\r
+                self._childTaskMetaList.extend(taskMetaList)\r
+        self._joinTaskObj = ParallelJoinTask(InstSeqNumber, lastTasksNameList)\r
+\r
+    def getTaskMetaList(self):\r
+        selfTaskMetaList = super(ParallelTask, self).getTaskMetaList()\r
+        selfTaskMetaList.extend(self._childTaskMetaList)\r
+        selfTaskMetaList.extend(self._joinTaskObj.getTaskMetaList())\r
+        return selfTaskMetaList\r
+\r
+    def getJoinTask(self):\r
+        return self._joinTaskObj\r
+\r
+\r
+class ParallelJoinTask(BaseWorkflowTask):\r
+    def __init__(self, seqNumber, joinOnList):\r
+        super(ParallelJoinTask, self).__init__(\r
+            "paralleljoin_" + str(seqNumber))\r
+        self._type = "JOIN"\r
+        self._args['joinOn'] = joinOnList\r
+\r
+\r
+def getRandString(length):\r
+    return "".join(random.choice(str("0123456789")) for i in range(length))\r
diff --git a/testing-scheduler/server/src/env/context/context.yaml b/testing-scheduler/server/src/env/context/context.yaml
new file mode 100644 (file)
index 0000000..58ed461
--- /dev/null
@@ -0,0 +1,75 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+\r
+hosts:\r
+    node26:\r
+        name: node26\r
+        ip: 192.168.1.26\r
+        port: 22\r
+        user: root\r
+        password: 123456\r
+\r
+    node27:\r
+        name: node27\r
+        ip: 192.168.1.27\r
+        port: 22\r
+        user: root\r
+        password: 123456\r
+\r
+    node28:\r
+        name: node28\r
+        ip: 192.168.1.28\r
+        port: 22\r
+        user: root\r
+        password: 123456\r
+\r
+    node29:\r
+        name: node29\r
+        ip: 192.168.1.29\r
+        port: 22\r
+        user: root\r
+        password: 123456\r
+\r
+    node30:\r
+        name: node30\r
+        ip: 192.168.1.30\r
+        port: 22\r
+        user: root\r
+        password: 123456\r
+\r
+    node31:\r
+        name: node31\r
+        ip: 192.168.1.31\r
+        port: 22\r
+        user: root\r
+        password: 123456\r
+\r
+    node32:\r
+        name: node32\r
+        ip: 192.168.1.32\r
+        port: 22\r
+        user: root\r
+        password: 123456\r
+\r
+\r
+cassandra:\r
+    name: node24\r
+    ip: 192.168.1.24\r
+    port: 22\r
+    user: root\r
+    password: 123456\r
+\r
+sprout:\r
+    name: node32\r
+    ip: 192.168.1.32\r
+    port: 22\r
+    user: root\r
+    password: 123456
\ No newline at end of file
diff --git a/testing-scheduler/server/src/env/service/ansible.yaml b/testing-scheduler/server/src/env/service/ansible.yaml
new file mode 100644 (file)
index 0000000..7b97602
--- /dev/null
@@ -0,0 +1,65 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+\r
+ansible:\r
+  apis:\r
+  - method: POST\r
+    name: faultload\r
+    params:\r
+    - description: call user count\r
+      name: call_user\r
+    - description: workload time\r
+      name: duration\r
+    - description: faultload time\r
+      name: fault_duration\r
+    - description: register speed\r
+      name: initial_reg_rate\r
+    - description: multiplier\r
+      name: multiplier\r
+    - description: register user count\r
+      name: reg_user\r
+    baseuri: faultload\r
+    template:\r
+      uri: ((baseuri))\r
+      body:\r
+        call_user: ((call_user))\r
+        duration: ((duration))\r
+        fault_duration: ((fault_duration))\r
+        initial_reg_rate: ((initial_reg_rate))\r
+        multiplier: ((multiplier))\r
+        reg_user: ((reg_user))\r
+\r
+  - method: POST\r
+    name: workload\r
+    params:\r
+    - description: call user count\r
+      name: call_user\r
+    - description: workload time\r
+      name: duration\r
+    - description: register speed\r
+      name: initial_reg_rate\r
+    - description: multiplier\r
+      name: multiplier\r
+    - description: register user count\r
+      name: reg_user\r
+    baseuri: workload\r
+    template:\r
+      uri: ((baseuri))\r
+      body:\r
+        call_user: ((call_user))\r
+        duration: ((duration))\r
+        fault_duration: ((fault_duration))\r
+        initial_reg_rate: ((initial_reg_rate))\r
+        multiplier: ((multiplier))\r
+        reg_user: ((reg_user))\r
+\r
+  ip: 100.64.227.222\r
+  port: 9006\r
diff --git a/testing-scheduler/server/src/env/service/greet.yaml b/testing-scheduler/server/src/env/service/greet.yaml
new file mode 100644 (file)
index 0000000..1b21f41
--- /dev/null
@@ -0,0 +1,68 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+\r
+greet:\r
+  ip: t-scheduler-server\r
+  port: 5312\r
+  apis:\r
+    -\r
+      name: greet\r
+      method: GET\r
+      baseuri: greet\r
+      params:\r
+        - name: name\r
+          description: user name\r
+      template:\r
+        uri: ((baseuri))?name=((name))\r
+      response:\r
+        result: int\r
+        next:\r
+          aa: str\r
+          bb: int\r
+    -\r
+      name: answer\r
+      method: POST\r
+      baseuri: answer\r
+      params:\r
+        - name: ping\r
+          description: param ping\r
+      template:\r
+        uri: ((baseuri))\r
+        body:\r
+          ping: ((ping))\r
+\r
+    -\r
+      name: ten\r
+      method: GET\r
+      baseuri: ten\r
+      template:\r
+        uri: ((baseuri))\r
+\r
+\r
+    -\r
+      name: switch\r
+      method: GET\r
+      baseuri: switch\r
+      template:\r
+        uri: ((baseuri))\r
+      return:\r
+        -\r
+          result\r
+\r
+    -\r
+      name: switch_2\r
+      method: GET\r
+      baseuri: switch_2\r
+      template:\r
+        uri: ((baseuri))\r
+      return:\r
+        -\r
+          result\r
diff --git a/testing-scheduler/server/src/step/__init__.py b/testing-scheduler/server/src/step/__init__.py
new file mode 100644 (file)
index 0000000..e819800
--- /dev/null
@@ -0,0 +1,8 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
diff --git a/testing-scheduler/server/src/step/general_test_step.py b/testing-scheduler/server/src/step/general_test_step.py
new file mode 100644 (file)
index 0000000..2f9e8bc
--- /dev/null
@@ -0,0 +1,87 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+from src.step.test_step import TestStep\r
+import os\r
+import yaml\r
+import re\r
+\r
+\r
+class GeneralTestStep(TestStep):\r
+    __step_type__ = "test"\r
+\r
+    def __init__(self, id, name, service, action, args, context):\r
+        super(GeneralTestStep, self).__init__(\r
+            self.__step_type__, id, name, service, action, args, context)\r
+        self._stepParse()\r
+        self.action()\r
+\r
+    def _contextTransform(self, argsDict):\r
+        for (k, v) in argsDict.items():\r
+            if isinstance(v, str):\r
+                if re.match('^\(\(context\..*\)\)', v):\r
+                    v = v[10:-2]\r
+                    layers = v.split(".")\r
+                    contextData = self._context\r
+                    for layer in layers:\r
+                        contextData = contextData[layer]\r
+                    argsDict[k] = contextData\r
+            elif isinstance(v, dict):\r
+                self._contextTransform(v)\r
+\r
+    def _stepParse(self):\r
+        self._args_temp = self._args\r
+        self._args = {}\r
+\r
+        # transform the service config\r
+        envFilePath = os.path.join(\r
+            self._getCurrentDir(), "..", "env",\r
+            "service", self._serviceName + ".yaml")\r
+        requestParam = {}\r
+        with open(envFilePath, 'r') as f:\r
+            conf = yaml.load(f)\r
+            conf = conf[self._serviceName]\r
+        for apiItem in conf["apis"]:\r
+            if apiItem['name'] == self._serviceInterface:\r
+                interfaceConf = apiItem\r
+        if interfaceConf is None:\r
+            return\r
+\r
+        # transform the args config\r
+        self._contextTransform(self._args_temp)\r
+\r
+        interfaceUri = interfaceConf['baseuri'] +  \\r
+            interfaceConf['template']['uri'][11:]\r
+        interfaceUri = "http://%s:%s/%s" % (\r
+            conf['ip'], conf['port'], interfaceUri)\r
+        requestParam['uri'] = self._uriTransform(interfaceUri)\r
+\r
+        requestParam['method'] = interfaceConf['method']\r
+        if requestParam["method"] == "POST":\r
+            requestParam['body'] = interfaceConf['template']['body']\r
+            self._paramTransform(requestParam['body'], self._args_temp)\r
+        self._args['http_request'] = requestParam\r
+\r
+    def _uriTransform(self, uri):\r
+        return re.sub("\(\(.*?\)\)", self._uriResReplace, uri)\r
+\r
+    def _uriResReplace(self, match):\r
+        matchTrim = match.group()[2:-2]\r
+        return self._args_temp[matchTrim]\r
+\r
+    def _paramTransform(self, argsTemplate, argsDict):\r
+        for (k, v) in argsTemplate.items():\r
+            if isinstance(v, str):\r
+                if re.match('^\(\(.*\)\)', v):\r
+                    argsTemplate[k] = argsDict[v[2:-2]]\r
+            elif isinstance(v, dict):\r
+                self._paramTransform(v, argsDict)\r
+\r
+    def start(self):\r
+        pass\r
diff --git a/testing-scheduler/server/src/step/monitor.py b/testing-scheduler/server/src/step/monitor.py
new file mode 100644 (file)
index 0000000..6deb9e2
--- /dev/null
@@ -0,0 +1,57 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+import json\r
+import os\r
+from src.step.test_step import TestStep\r
+\r
+\r
+class MonitorStep(TestStep):\r
+    __step_type__ = 'monitor'\r
+\r
+    def __init__(self, name, service, action, args):\r
+        super(MonitorStep, self).__init__(name, service, action, args)\r
+        self._argsParse()\r
+        self.action()\r
+\r
+    def _argsParse(self):\r
+        if self._call == "REST":\r
+            currentDirPath = os.path.dirname(os.path.abspath(__file__))\r
+            envDirPath = os.path.abspath(os.path.join(\r
+                currentDirPath, os.pardir, os.pardir, 'env'))\r
+            envFilePath = os.path.join(\r
+                envDirPath, "%s.json" % self._service['name'])\r
+            with open(envFilePath) as f:\r
+                propDict = json.load(f)\r
+                self._args['ip'] = propDict['ip']\r
+                self._args['port'] = propDict['port']\r
+                self._args['api'] = "%s/%s" % (\r
+                    propDict['api_map']['workload'], self._args['command'])\r
+                exclude = {'ip', 'port', 'api', 'command', 'method'}\r
+                self._args['req_body'] = {\r
+                    key: value for key, value in\r
+                    self._args.items() if key not in exclude}\r
+\r
+    def setUp(self):\r
+        print "monitor setUp"\r
+\r
+    def uninstall(self):\r
+        print "monitor uninstall"\r
+\r
+    def start(self):\r
+        print "monitor start...."\r
+\r
+    def stop(self):\r
+        print "monitor stop"\r
+\r
+\r
+if __name__ == "__main__":\r
+    service = {"name": "ansible", "call": "REST"}\r
+    monitor = MonitorStep(\r
+        "monitor_cpu", service, "start", **{"target": "abc:qq"})\r
diff --git a/testing-scheduler/server/src/step/step_manager.py b/testing-scheduler/server/src/step/step_manager.py
new file mode 100644 (file)
index 0000000..8d76c67
--- /dev/null
@@ -0,0 +1,41 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+from src.step.test_step import TestStep\r
+import os\r
+import sys\r
+\r
+\r
+class TestStepManager(object):\r
+    def __init__(self, context):\r
+        self._context = context\r
+\r
+        currentDirPath = os.path.dirname(os.path.abspath(__file__))\r
+        sys.path.append(currentDirPath)\r
+\r
+        excludeFiles = ('__init__.py', 'step_manager.py', 'test_step.py')\r
+        for fileName in os.listdir(currentDirPath):\r
+            if os.path.isfile(os.path.join(currentDirPath, fileName)) and \\r
+                os.path.splitext(fileName)[1] == '.py' and \\r
+                    fileName not in excludeFiles:\r
+                __import__(os.path.splitext(fileName)[0])\r
+\r
+    def getStepObj(self, type, id, name, service, action, args):\r
+        for subclass in TestStep.__subclasses__():\r
+            if type == subclass.__step_type__:\r
+                return subclass(id, name, service, action, args, self._context)\r
+\r
+\r
+if __name__ == "__main__":\r
+    tsMgr = TestStepManager()\r
+    args = {'command': 'greet', 'method': 'POST', 'args': {'name': 'leo'}}\r
+    stepObj = tsMgr.getStepObj('test', 1, 'test_cpu', {\r
+        'name': 'greet', 'call': 'REST'}, 'start', args)\r
+    print stepObj\r
+    print stepObj.__class__.__mro__\r
diff --git a/testing-scheduler/server/src/step/test_step.py b/testing-scheduler/server/src/step/test_step.py
new file mode 100644 (file)
index 0000000..363c480
--- /dev/null
@@ -0,0 +1,56 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+import os\r
+\r
+\r
+class TestStep(object):\r
+    def __init__(self, type, id, name, service, action, args, context):\r
+        self._type = type\r
+        self._id = id\r
+        self._name = name\r
+        self._serviceName = service['name']\r
+        self._serviceInterface = service['interface']\r
+        self._action = action\r
+        self._args = args\r
+        self._context = context\r
+\r
+    def getId(self):\r
+        return self._id\r
+\r
+    def getName(self):\r
+        return self._name\r
+\r
+    def getServiceName(self):\r
+        return self._serviceName\r
+\r
+    def getCallFunction(self):\r
+        return self._callType\r
+\r
+    def getArgs(self):\r
+        return self._args\r
+\r
+    def action(self):\r
+        f = getattr(self, self._action)\r
+        f()\r
+\r
+    def _argsParse(self):\r
+        pass\r
+\r
+    def _getCurrentDir(self):\r
+        return os.path.dirname(__file__)\r
+\r
+    def __str__(self):\r
+        return str(self.__dict__)\r
+\r
+\r
+if __name__ == "__main__":\r
+    args = {'command': 'start'}\r
+    stepObj = TestStep('test_cpu', 'ansible', 'REST', **args)\r
+    print stepObj\r
diff --git a/testing-scheduler/server/src/step/workload.py b/testing-scheduler/server/src/step/workload.py
new file mode 100644 (file)
index 0000000..265b9a6
--- /dev/null
@@ -0,0 +1,46 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+import json\r
+import os\r
+from src.step.test_step import TestStep\r
+\r
+\r
+class WorkloadStep(TestStep):\r
+    __step_type__ = 'workload'\r
+\r
+    def __init__(self, id, name, service, action, args):\r
+        super(WorkloadStep, self).__init__(\r
+            self.__step_type__, id, name, service, action, args)\r
+        self._argsParse()\r
+        self._action()\r
+\r
+    def _argsParse(self):\r
+        if self._callType == "REST":\r
+            currentDirPath = os.path.dirname(os.path.abspath(__file__))\r
+            envDirPath = os.path.abspath(\r
+                os.path.join(currentDirPath, os.pardir, os.pardir, 'env'))\r
+            envFilePath = os.path.join(\r
+                envDirPath, "%s.json" % self._service['name'])\r
+            with open(envFilePath) as f:\r
+                propDict = json.load(f)\r
+                self._args['ip'] = propDict['ip']\r
+                self._args['port'] = propDict['port']\r
+                self._args['api'] = "%s/%s" % (\r
+                    propDict['api_map']['workload'], self._args['command'])\r
+                exclude = {'ip', 'port', 'api', 'command', 'method'}\r
+                self._args['req_body'] = {\r
+                    key: value for key, value in\r
+                    self._args.items() if key not in exclude}\r
+\r
+    def _start(self):\r
+        print "workload start"\r
+\r
+    def _stop(self):\r
+        print "workload stop"\r
diff --git a/testing-scheduler/server/src/test_parser.py b/testing-scheduler/server/src/test_parser.py
new file mode 100644 (file)
index 0000000..7b47151
--- /dev/null
@@ -0,0 +1,315 @@
+#!/usr/bin/env python\r
+\r
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+import click\r
+import os\r
+import yaml\r
+import json\r
+import collections\r
+from src.step.step_manager import TestStepManager\r
+from src.conductor_processor.workflow import WorkflowFile\r
+from conductorclient.run_new_workflow import WorkflowMgr\r
+\r
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))\r
+CONDUCTOR_SERVER_ADDR = "http://conductor_conductor-server_1:8080"\r
+STORE_TASK_PATH = "/tmp/generate_task.json"\r
+STORE_WF_PATH = "/tmp/generate_workflow.json"\r
+\r
+\r
+@click.command()\r
+@click.option("--filepath", help="file path of test case")\r
+def cmdParse(filepath):\r
+    parse(filepath)\r
+\r
+\r
+def parse(filepath):\r
+    filePrefix, fileName = os.path.split(filepath)\r
+    print '------------ start to parse the test case:' + \\r
+        '%s ----------------' % fileName\r
+    with open(filepath) as f:\r
+        yaml_file = yaml.load(f)\r
+        parseTestcase(yaml_file['schema'], fileName)\r
+\r
+    workflowId = runWorkFlow()\r
+    print '------------------- parse executes end -------------------------'\r
+\r
+    return workflowId\r
+\r
+\r
+def parseTestcase(schema, tcName='testcase0'):\r
+    if schema is None:\r
+        return parseLog(False, reason='schema not found.')\r
+    steps = schema['steps']\r
+    if steps is None:\r
+        return parseLog(False, reason='steps is invalid.')\r
+    flows = schema['flows']\r
+    if flows is None:\r
+        return parseLog(False, reasion='flows is invalid.')\r
+    # steps is a list, step is dict. no json here.\r
+    # steps = sorted(steps, sortById)\r
+\r
+    # load context\r
+    contextDict = {}\r
+    contextDir = os.path.join(BASE_DIR, "env", "context", "context.yaml")\r
+    with open(contextDir, "r") as f:\r
+        contextDict = yaml.load(f)\r
+    #\r
+    testStepMgr = TestStepManager(contextDict)\r
+\r
+    stepObjArr = []\r
+    for step in steps:\r
+        if 'args' not in step:\r
+            step['args'] = {}\r
+        # type and action can be extended, default couple is 'test' & 'start'.\r
+        if 'type' not in step:\r
+            step['type'] = 'test'\r
+            step['action'] = 'start'\r
+\r
+        stepObj = testStepMgr.getStepObj(\r
+            step['type'], step['id'], step['name'], step['service'],\r
+            step['action'], step['args'])\r
+        stepObjArr.append(stepObj)\r
+\r
+    # generate workflow by 'flow' and 'step'\r
+    tcName = os.path.splitext(tcName)[0]\r
+    wfFileObj = WorkflowFile(tcName)\r
+    workflowDict, taskMetaList = wfFileObj.generateMetaData(flows, stepObjArr)\r
+\r
+    with open(STORE_TASK_PATH, 'w') as f:\r
+        f.write(json.dumps({'task_group': taskMetaList}, indent=True))\r
+    with open(STORE_WF_PATH, 'w') as f:\r
+        f.write(json.dumps(workflowDict, indent=True))\r
+\r
+\r
+def parseWebTestcase(webTestcase):\r
+    print 'parseWebTestcase----------------------------'\r
+\r
+    stepList = webTestcase['stepList']\r
+    mainOrdersList = webTestcase['mainOrdersList']\r
+    subflowList = webTestcase['subflowList']\r
+\r
+    parseData = collections.OrderedDict()\r
+    parseData['schema'] = collections.OrderedDict()\r
+    parseData['schema']['steps'] = []\r
+    parseData['schema']['flows'] = []\r
+\r
+    parseStepList = parseData['schema']['steps']\r
+    parseFlowList = parseData['schema']['flows']\r
+    stepIndexDict = {}\r
+    # parse stepList\r
+    for index in range(len(stepList)):\r
+        stepItem = stepList[index]\r
+        parseStep = collections.OrderedDict()\r
+\r
+        parseStep['id'] = index + 1\r
+        parseStep['name'] = stepItem['name']\r
+        parseStep['service'] = collections.OrderedDict()\r
+        parseStep['service']['name'] = stepItem['service']\r
+        parseStep['service']['interface'] = stepItem['action']\r
+        parseStep['action'] = 'start'\r
+        parseStep['args'] = {}\r
+        for paramItem in stepItem['params']:\r
+            parseStep['args'][paramItem['key']] = transParamString(\r
+                paramItem['value'])\r
+\r
+        parseStepList.append(parseStep)\r
+        stepIndexDict[parseStep['name']] = parseStep['id']\r
+    # parse flows\r
+    # parse mainflow\r
+    print stepIndexDict\r
+    typeDict = {1: 'normal', 2: 'switch', 3: 'parallel'}\r
+    mainFlow = collections.OrderedDict()\r
+    mainFlow['name'] = 'main'\r
+    mainFlow['orders'] = []\r
+    mainFlow['orders'] = parseOrderList(\r
+        mainOrdersList, stepIndexDict, typeDict)\r
+    parseFlowList.append(mainFlow)\r
+\r
+    # parse subflow\r
+    for subflowItem in subflowList:\r
+        replaceSubflow = collections.OrderedDict()\r
+        replaceSubflow['name'] = subflowItem['name']\r
+        replaceSubflow['orders'] = parseOrderList(\r
+            subflowItem['orderList'], stepIndexDict, typeDict)\r
+        parseFlowList.append(replaceSubflow)\r
+\r
+    print 'END parseWebTestcase----------------------------'\r
+    return parseData\r
+\r
+\r
+# parse orderlist from web edition to server edition\r
+def parseOrderList(orderList, stepIndexDict, typeDict):\r
+    replaceList = []\r
+    for orderItem in orderList:\r
+        replaceOrder = collections.OrderedDict()\r
+        orderType = typeDict[orderItem['type']]\r
+        replaceOrder['type'] = orderType\r
+        if orderType == 'normal':\r
+            stepId = stepIndexDict[orderItem['step']]\r
+            replaceOrder['step'] = stepId\r
+        elif orderType == 'switch':\r
+            replaceOrder['value'] = orderItem['value']\r
+            replaceOrder['cases'] = collections.OrderedDict()\r
+            for caseItem in orderItem['cases']:\r
+                caseValue = caseItem['value']\r
+                caseOrderType = caseItem['orderType']\r
+                caseOrderValue = caseItem['orderValue']\r
+                if caseOrderType == "step":\r
+                    orderInCase = collections.OrderedDict()\r
+                    orderInCase['type'] = 'normal'\r
+                    orderInCase['step'] = stepIndexDict[caseOrderValue]\r
+                    replaceOrder['cases'][caseValue] = [orderInCase]\r
+                else:\r
+                    replaceOrder['cases'][caseValue] = caseOrderValue\r
+        else:\r
+            replaceOrder['parallel'] = collections.OrderedDict()\r
+            pIndex = 1\r
+            for branchItem in orderItem['branches']:\r
+                pKey = 'p' + str(pIndex)\r
+                branchOrderType = branchItem['orderType']\r
+                branchOrderValue = branchItem['orderValue']\r
+                if branchOrderType == "step":\r
+                    replaceBranchItem = collections.OrderedDict()\r
+                    replaceBranchItem['type'] = 'normal'\r
+                    replaceBranchItem['step'] = stepIndexDict[branchOrderValue]\r
+                    replaceOrder['parallel'][pKey] = [replaceBranchItem]\r
+                else:\r
+                    replaceOrder['parallel'][pKey] = branchOrderValue\r
+                pIndex += 1\r
+        replaceList.append(replaceOrder)\r
+    return replaceList\r
+\r
+\r
+def transParamString(val):\r
+    if type(val) != str:\r
+        return val\r
+    if '.' not in val:\r
+        if val.isdigit():\r
+            return int(val)\r
+    try:\r
+        f = float(val)\r
+        return f\r
+    except ValueError:\r
+        return val\r
+\r
+\r
+def getWebTestcase(originTcDict):\r
+    print "getWebTestcase----------------------------------"\r
+    webTcDict = {\r
+        "stepList": [],\r
+        "mainOrdersList": [],\r
+        "subflowList": []\r
+    }\r
+    stepList = webTcDict['stepList']\r
+    subflowList = webTcDict['subflowList']\r
+    if originTcDict is None:\r
+        return webTcDict\r
+    originContent = originTcDict['schema']\r
+    originSteps = originContent['steps']\r
+    stepIndexDict = {}\r
+    # transform steps to stepList\r
+    for stepItem in originSteps:\r
+        replaceStep = {}\r
+        replaceStep['name'] = stepItem['name']\r
+        replaceStep['service'] = stepItem['service']['name']\r
+        replaceStep['action'] = stepItem['service']['interface']\r
+        replaceStep['params'] = []\r
+        if 'args' in stepItem:\r
+            for (key, value) in stepItem['args'].items():\r
+                replaceParam = {}\r
+                replaceParam['key'] = key\r
+                replaceParam['value'] = value\r
+                replaceStep['params'].append(replaceParam)\r
+        stepList.append(replaceStep)\r
+        stepIndexDict[stepItem['id']] = stepItem['name']\r
+\r
+    # transform main flow\r
+    originFlows = originContent['flows']\r
+    originMainflow = {}\r
+    for flowIndex in range(len(originFlows)):\r
+        flowItem = originFlows[flowIndex]\r
+        if flowItem['name'] == 'main':\r
+            originMainflow = flowItem\r
+            originFlows.pop(flowIndex)\r
+            break\r
+    typeDict = {'normal': 1, 'switch': 2, 'parallel': 3}\r
+    webTcDict['mainOrdersList'] = getOrderList(\r
+        originMainflow['orders'], stepIndexDict, typeDict)\r
+\r
+    # transform subflows\r
+    for originSubflow in originFlows:\r
+        replaceSubflow = {}\r
+        replaceSubflow['name'] = originSubflow['name']\r
+        replaceSubflow['orderList'] = getOrderList(\r
+            originSubflow['orders'], stepIndexDict, typeDict)\r
+        subflowList.append(replaceSubflow)\r
+\r
+    # return web edition of testcase\r
+    print "END getWebTestcase----------------------------------"\r
+    return webTcDict\r
+\r
+\r
+def getOrderList(originOrderList, stepIndexDict, typeDict):\r
+    replaceOrderList = []\r
+    for orderItem in originOrderList:\r
+        replaceOrderItem = {}\r
+        orderType = orderItem['type']\r
+        replaceOrderItem['type'] = typeDict[orderType]\r
+        if orderType == 'normal':\r
+            stepName = stepIndexDict[orderItem['step']]\r
+            replaceOrderItem['step'] = stepName\r
+        elif orderType == 'switch':\r
+            replaceOrderItem['value'] = orderItem['value']\r
+            replaceOrderItem['cases'] = []\r
+            for (caseValue, ordersInCase) in orderItem['cases'].items():\r
+                replaceCase = {}\r
+                replaceCase['value'] = caseValue\r
+                if type(ordersInCase) == list:\r
+                    replaceCase['orderType'] = 'step'\r
+                    caseStepName = stepIndexDict[ordersInCase[0]['step']]\r
+                    replaceCase['orderValue'] = caseStepName\r
+                else:\r
+                    replaceCase['orderType'] = 'flow'\r
+                    replaceCase['orderValue'] = ordersInCase\r
+                replaceOrderItem['cases'].append(replaceCase)\r
+        else:\r
+            replaceOrderItem['branches'] = []\r
+            for paraIndex in orderItem['parallel']:\r
+                paraItem = orderItem['parallel'][paraIndex]\r
+                replaceBranch = {}\r
+                if type(paraItem) == list:\r
+                    replaceBranch['orderType'] = 'step'\r
+                    branchStepName = stepIndexDict[paraItem[0]['step']]\r
+                    replaceBranch['orderValue'] = branchStepName\r
+                else:\r
+                    replaceBranch['orderType'] = 'flow'\r
+                    replaceBranch['orderValue'] = paraItem\r
+                replaceOrderItem['branches'].append(replaceBranch)\r
+        replaceOrderList.append(replaceOrderItem)\r
+\r
+    return replaceOrderList\r
+\r
+\r
+def runWorkFlow():\r
+    wfMgr = WorkflowMgr(CONDUCTOR_SERVER_ADDR)\r
+    wfMgr.setTaskDefFromFile(STORE_TASK_PATH)\r
+    wfMgr.setWorkflowFromFile(STORE_WF_PATH)\r
+    inputParam = {'input': 'fake'}\r
+    workflowId = wfMgr.startWorkflow(inputParam)\r
+    return workflowId\r
+\r
+\r
+def parseLog(flag, **msg):\r
+    return {'result': flag, 'message': msg}\r
+\r
+\r
+if __name__ == "__main__":\r
+    cmdParse()\r
diff --git a/testing-scheduler/server/test/__init__.py b/testing-scheduler/server/test/__init__.py
new file mode 100644 (file)
index 0000000..e819800
--- /dev/null
@@ -0,0 +1,8 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
diff --git a/testing-scheduler/server/test/test_case/logic/tc_logic_00.yaml b/testing-scheduler/server/test/test_case/logic/tc_logic_00.yaml
new file mode 100644 (file)
index 0000000..6a4eeea
--- /dev/null
@@ -0,0 +1,30 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test conductor basic logic\r
+# this testcase contains a single step for scheduling.\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: make_a_greet\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      args:\r
+        name: leo\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1
\ No newline at end of file
diff --git a/testing-scheduler/server/test/test_case/logic/tc_logic_01.yaml b/testing-scheduler/server/test/test_case/logic/tc_logic_01.yaml
new file mode 100644 (file)
index 0000000..3f8f4f4
--- /dev/null
@@ -0,0 +1,73 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test conductor basic logic\r
+# 5 steps while only 2 in them will be executed.\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: make_a_greet\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      args:\r
+        name: leo\r
+\r
+    -\r
+      id: 2\r
+      name: response_the_greet\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      args:\r
+        ping: ping_from_leo\r
+\r
+    -\r
+      id: 3\r
+      name: make_a_greet_3\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      args:\r
+        name: leo_@\r
+\r
+    -\r
+      id: 4\r
+      name: make_a_greet_4\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      args:\r
+        name: leo_@\r
+\r
+    -\r
+      id: 5\r
+      name: make_a_greet_5\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: normal\r
+          step: 2\r
diff --git a/testing-scheduler/server/test/test_case/logic/tc_logic_02.yaml b/testing-scheduler/server/test/test_case/logic/tc_logic_02.yaml
new file mode 100644 (file)
index 0000000..ce7197d
--- /dev/null
@@ -0,0 +1,71 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test conductor basic logic of switch\r
+# switch will determine the next case to execute based\r
+# on the "value", and "value" can be assigned by the\r
+# previous step's output.\r
+# The testcase below is an example.\r
+# To referring the step's output, using ((x.y)).\r
+# x is the id of the step,\r
+# y is the output key of the step.\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: choose_greet_type\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: switch\r
+      action: start\r
+\r
+    -\r
+      id: 2\r
+      name: response_the_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      action: start\r
+      args:\r
+        ping: ping_from_leo\r
+\r
+    -\r
+      id: 3\r
+      name: make_a_greet_2\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: switch\r
+          value: ((1.result))\r
+          cases:\r
+            A:\r
+              -\r
+                type: normal\r
+                step: 2\r
+            B:\r
+              -\r
+                type: normal\r
+                step: 3\r
diff --git a/testing-scheduler/server/test/test_case/logic/tc_logic_03.yaml b/testing-scheduler/server/test/test_case/logic/tc_logic_03.yaml
new file mode 100644 (file)
index 0000000..2cb8943
--- /dev/null
@@ -0,0 +1,86 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test useless sub workflow\r
+# In this testcase, there is a subflow whose name\r
+# is 'flow-1' which will not be executed because no\r
+# other flow refers to it.\r
+# This testcase is used to test that besides main flow,\r
+# whether subflow can be parsed without exception.\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: choose_greet_type\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: switch\r
+      action: start\r
+\r
+    -\r
+      id: 2\r
+      name: response_the_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      action: start\r
+      args:\r
+        ping: ping_from_leo\r
+\r
+    -\r
+      id: 3\r
+      name: make_a_greet_2\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+    -\r
+      id: 4\r
+      name: make_a_greet_3\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: switch\r
+          value: ((1.result))\r
+          cases:\r
+            A:\r
+              -\r
+                type: normal\r
+                step: 2\r
+            B:\r
+              -\r
+                type: normal\r
+                step: 3\r
+    -\r
+      name: flow-1\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 4\r
diff --git a/testing-scheduler/server/test/test_case/logic/tc_logic_04.yaml b/testing-scheduler/server/test/test_case/logic/tc_logic_04.yaml
new file mode 100644 (file)
index 0000000..67847ff
--- /dev/null
@@ -0,0 +1,70 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test conductor basic logic of sub flow.\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: choose_greet_type\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: switch\r
+      action: start\r
+\r
+    -\r
+      id: 2\r
+      name: response_the_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      action: start\r
+      args:\r
+        ping: ping_from_leo\r
+\r
+    -\r
+      id: 3\r
+      name: make_a_greet_2\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: switch\r
+          value: ((1.result))\r
+          cases:\r
+            A: flow-1\r
+            B: flow-2\r
+    -\r
+      name: flow-1\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 2\r
+    -\r
+      name: flow-2\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 3\r
diff --git a/testing-scheduler/server/test/test_case/logic/tc_logic_05.yaml b/testing-scheduler/server/test/test_case/logic/tc_logic_05.yaml
new file mode 100644 (file)
index 0000000..ac0f81c
--- /dev/null
@@ -0,0 +1,100 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test conductor basic logic of switch.\r
+# switch nested in switch by using subflow.\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: choose_greet_type\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: switch\r
+      action: start\r
+\r
+    -\r
+      id: 2\r
+      name: response_the_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      action: start\r
+      args:\r
+        ping: ping_from_leo\r
+\r
+    -\r
+      id: 3\r
+      name: choose_greet_type_2\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: switch_2\r
+      action: start\r
+\r
+    -\r
+      id: 4\r
+      name: make_a_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+    -\r
+      id: 5\r
+      name: response_the_greet_2\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      action: start\r
+      args:\r
+        ping: ping_from_leo_2\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: switch\r
+          value: ((1.result))\r
+          cases:\r
+            A:\r
+              -\r
+                type: normal\r
+                step: 2\r
+            B: flow-1\r
+    -\r
+      name: flow-1\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 3\r
+        -\r
+          type: switch\r
+          value: ((3.result))\r
+          cases:\r
+            C:\r
+              -\r
+                type: normal\r
+                step: 4\r
+            D:\r
+              -\r
+                type: normal\r
+                step: 5\r
diff --git a/testing-scheduler/server/test/test_case/logic/tc_logic_06.yaml b/testing-scheduler/server/test/test_case/logic/tc_logic_06.yaml
new file mode 100644 (file)
index 0000000..7c14d01
--- /dev/null
@@ -0,0 +1,80 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test conductor basic logic of parallel\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: choose_greet_type\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: switch\r
+      action: start\r
+\r
+    -\r
+      id: 2\r
+      name: response_the_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      action: start\r
+      args:\r
+        ping: ping_from_leo\r
+\r
+    -\r
+      id: 3\r
+      name: make_a_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+    -\r
+      id: 4\r
+      name: make_a_greet_2\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: parallel\r
+          parallel:\r
+            p1: flow-1\r
+            p2:\r
+              -\r
+                type: normal\r
+                step: 4\r
+    -\r
+      name: flow-1\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 2\r
+        -\r
+          type: normal\r
+          step: 3\r
diff --git a/testing-scheduler/server/test/test_case/logic/tc_logic_07.yaml b/testing-scheduler/server/test/test_case/logic/tc_logic_07.yaml
new file mode 100644 (file)
index 0000000..5fa7122
--- /dev/null
@@ -0,0 +1,100 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test conductor basic logic of parallel + switch\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: make_a_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+    -\r
+      id: 2\r
+      name: choose_greet_type\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: switch\r
+      action: start\r
+\r
+    -\r
+      id: 3\r
+      name: response_the_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      action: start\r
+      args:\r
+        ping: ping_from_leo\r
+\r
+    -\r
+      id: 4\r
+      name: make_a_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+    -\r
+      id: 5\r
+      name: make_a_greet_2\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: parallel\r
+          parallel:\r
+            p1: flow-1\r
+            p2:\r
+              -\r
+                type: normal\r
+                step: 5\r
+    -\r
+      name: flow-1\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 2\r
+        -\r
+          type: switch\r
+          value: ((2.result))\r
+          cases:\r
+            A:\r
+              -\r
+                type: normal\r
+                step: 3\r
+            B:\r
+              -\r
+                type: normal\r
+                step: 4
\ No newline at end of file
diff --git a/testing-scheduler/server/test/test_case/logic/tc_logic_08.yaml b/testing-scheduler/server/test/test_case/logic/tc_logic_08.yaml
new file mode 100644 (file)
index 0000000..e5da14f
--- /dev/null
@@ -0,0 +1,114 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test conductor basic logic of parallel.\r
+# parallel nested in parallel using subflow\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: make_a_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+    -\r
+      id: 2\r
+      name: choose_greet_type\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: switch\r
+      action: start\r
+\r
+    -\r
+      id: 3\r
+      name: response_the_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      action: start\r
+      args:\r
+        ping: ping_from_leo\r
+\r
+    -\r
+      id: 4\r
+      name: make_a_greet\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+    -\r
+      id: 5\r
+      name: make_a_greet_2\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+    -\r
+      id: 6\r
+      name: make_a_greet_3\r
+      type: test\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      action: start\r
+      args:\r
+        name: leo_@\r
+\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: parallel\r
+          parallel:\r
+            p1: flow-p1\r
+            p2:\r
+              -\r
+                type: normal\r
+                step: 6\r
+    -\r
+      name: flow-p1\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 2\r
+        -\r
+          type: parallel\r
+          parallel:\r
+            p1:\r
+              -\r
+                type: normal\r
+                step: 3\r
+            p2:\r
+              -\r
+                type: normal\r
+                step: 4\r
+              -\r
+                type: normal\r
+                step: 5
\ No newline at end of file
diff --git a/testing-scheduler/server/test/test_case/logic_in_out/tc_cxt_01.yaml b/testing-scheduler/server/test/test_case/logic_in_out/tc_cxt_01.yaml
new file mode 100644 (file)
index 0000000..583bc1c
--- /dev/null
@@ -0,0 +1,47 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test use param of the context\r
+# we can using the context param just like environment variable by\r
+# writting ((context.a.b.c)).\r
+# 'context' is a constant string,\r
+# a, b, c is the key in the context yaml file (src/env/context/context.yaml).\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: make_a_greet\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      args:\r
+        name: leo\r
+\r
+    -\r
+      id: 2\r
+      name: response_the_greet\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      args:\r
+        ping: ((context.sprout.name))\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: normal\r
+          step: 2\r
+  context: clearwater-conf.yaml\r
diff --git a/testing-scheduler/server/test/test_case/logic_in_out/tc_io_01.yaml b/testing-scheduler/server/test/test_case/logic_in_out/tc_io_01.yaml
new file mode 100644 (file)
index 0000000..b5ce203
--- /dev/null
@@ -0,0 +1,63 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test switch value used step-1's output.\r
+# to referring the step's output, using ((x.y)).\r
+# x is the id of the step,\r
+# y is the output key of the step.\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: get-switch\r
+      service:\r
+        name: greet\r
+        interface: switch\r
+      args:\r
+        name: leo\r
+\r
+    -\r
+      id: 2\r
+      name: greet1\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      args:\r
+        ping: ping_from_Leo\r
+\r
+    -\r
+      id: 3\r
+      name: greet2\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      args:\r
+        ping: ping_from_Leo_2\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: switch\r
+          value: ((1.result))\r
+          cases:\r
+            A:\r
+              -\r
+                type: normal\r
+                step: 2\r
+            B:\r
+              -\r
+                type: normal\r
+                step: 3
\ No newline at end of file
diff --git a/testing-scheduler/server/test/test_case/logic_in_out/tc_io_02.yaml b/testing-scheduler/server/test/test_case/logic_in_out/tc_io_02.yaml
new file mode 100644 (file)
index 0000000..804a679
--- /dev/null
@@ -0,0 +1,60 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+# description: test switch and step-2 used step-1's output\r
+\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: get-switch\r
+      service:\r
+        name: greet\r
+        interface: switch\r
+      args:\r
+        name: leo\r
+\r
+    -\r
+      id: 2\r
+      name: greet1\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      args:\r
+        ping: ((1.result))\r
+\r
+    -\r
+      id: 3\r
+      name: greet2\r
+      service:\r
+        name: greet\r
+        interface: answer\r
+      args:\r
+        ping: ping_from_Leo_2\r
+\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1\r
+        -\r
+          type: switch\r
+          value: ((1.result))\r
+          cases:\r
+            A:\r
+              -\r
+                type: normal\r
+                step: 2\r
+            B:\r
+              -\r
+                type: normal\r
+                step: 3
\ No newline at end of file
diff --git a/testing-scheduler/server/test/test_case/suite_test/tc_suitetest_00.yaml b/testing-scheduler/server/test/test_case/suite_test/tc_suitetest_00.yaml
new file mode 100644 (file)
index 0000000..06f8c4e
--- /dev/null
@@ -0,0 +1,27 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: suitetest_00\r
+      service:\r
+        name: greet\r
+        interface: ten\r
+      args:\r
+        name: leo\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1
\ No newline at end of file
diff --git a/testing-scheduler/server/test/test_case/suite_test/tc_suitetest_01.yaml b/testing-scheduler/server/test/test_case/suite_test/tc_suitetest_01.yaml
new file mode 100644 (file)
index 0000000..0189e7a
--- /dev/null
@@ -0,0 +1,27 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: suitetest_01\r
+      service:\r
+        name: greet\r
+        interface: ten\r
+      args:\r
+        name: leo\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1
\ No newline at end of file
diff --git a/testing-scheduler/server/test/test_case/suite_test/tc_suitetest_02.yaml b/testing-scheduler/server/test/test_case/suite_test/tc_suitetest_02.yaml
new file mode 100644 (file)
index 0000000..bc68924
--- /dev/null
@@ -0,0 +1,27 @@
+##############################################################################\r
+# Copyright (c) 2018 HUAWEI TECHNOLOGIES CO.,LTD and others.\r
+#\r
+# All rights reserved. This program and the accompanying materials\r
+# are made available under the terms of the Apache License, Version 2.0\r
+# which accompanies this distribution, and is available at\r
+# http://www.apache.org/licenses/LICENSE-2.0\r
+##############################################################################\r
+\r
+---\r
+schema:\r
+  steps:\r
+    -\r
+      id: 1\r
+      name: suitetest_01\r
+      service:\r
+        name: greet\r
+        interface: greet\r
+      args:\r
+        name: leo\r
+  flows:\r
+    -\r
+      name: main\r
+      orders:\r
+        -\r
+          type: normal\r
+          step: 1
\ No newline at end of file
index b13b5a0..8de6043 100644 (file)
@@ -155,7 +155,7 @@ if [[ ${INSTALLER_TYPE} != "" ]]; then
             echo "export OS_CACERT=${OS_CACERT}" >> ${OPENRC}
             cat ${OPENRC}
         else
-           error "Couldn't find openstack cacert file: ${OS_CACERT}, please check if the it's been properly provided."
+           info "Couldn't find openstack cacert file: ${OS_CACERT}, please check if the it's been properly provided."
        fi
     else
         error "Couldn't find openstack rc file: ${OPENRC}, please check if the it's been properly provided."
@@ -166,6 +166,6 @@ if [[ ${INSTALLER_TYPE} != "" ]]; then
     if [[ -f "/tmp/id_rsa" ]]; then
         info "Path of ssh key file for openstack nodes is /tmp/id_rsa"
     else
-        error "Couldn't find the ssh key file for openstack nodes. If you are using user/pwd in pod.yaml, please ignore."
+        info "Couldn't find the ssh key file for openstack nodes. If you are using user/pwd in pod.yaml, please ignore."
     fi
 fi
index a0d6d83..f0512b0 100755 (executable)
@@ -66,14 +66,16 @@ def get_session_auth():
 
 def get_session():
     auth = get_session_auth()
-    try:
-        cacert = os.environ['OS_CACERT']
-    except KeyError:
-        return session.Session(auth=auth)
-    else:
-        insecure = os.getenv('OS_INSECURE', '').lower() == 'true'
-        cacert = False if insecure else cacert
+    if os.getenv('OS_INSECURE', '').lower() == 'true':
+        cacert = False
         return session.Session(auth=auth, verify=cacert)
+    else:
+        try:
+            cacert = os.environ['OS_CACERT']
+        except KeyError:
+            return session.Session(auth=auth)
+        else:
+            return session.Session(auth=auth, verify=cacert)
 
 
 def get_endpoint(service_type, endpoint_type='publicURL'):
diff --git a/utils/k8s_setup/__init__.py b/utils/k8s_setup/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/utils/k8s_setup/golang_install.sh b/utils/k8s_setup/golang_install.sh
new file mode 100644 (file)
index 0000000..06c54ce
--- /dev/null
@@ -0,0 +1,100 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd and others.
+# 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
+##############################################################################
+usage="Script to install and config golang of specific version.
+
+usage:
+    bash $(basename "$0") [-h|--help] [-v|--version <version>] [--debug]
+
+where:
+    -h|--help         show the help text
+    -v|--version      input the version of golang
+    --debug           debug option switch
+examples:
+    $(basename "$0") -v 1.10.3"
+
+# Debug option
+redirect="/dev/null"
+
+# Process input variables
+while [[ $# > 0 ]]
+    do
+    key="$1"
+    case $key in
+        -h|--help)
+            echo "$usage"
+            exit 0
+            shift
+        ;;
+        -v|--version)
+            GOLANG_VERSION="$2"
+            shift
+        ;;
+        --debug)
+            redirect="/dev/stdout"
+            shift
+        ;;
+        *)
+            echo "unkown option $1 $2"
+            exit 1
+        ;;
+    esac
+    shift
+done
+
+#set -e
+
+echo "=======Downloading golang of version: ${GOLANG_VERSION}========"
+
+if [[ -f go${GOLANG_VERSION}.linux-amd64.tar.gz ]]; then
+    rm go${GOLANG_VERSION}.linux-amd64.tar.gz
+fi
+curl -O https://storage.googleapis.com/golang/go${GOLANG_VERSION}.linux-amd64.tar.gz >${redirect}
+
+echo "Installing golang of version: ${GOLANG_VERSION}"
+if [[ -d /usr/local/go ]]; then
+    rm -rf /usr/local/go
+fi
+
+tar -C /usr/local -xzf go${GOLANG_VERSION}.linux-amd64.tar.gz >${redirect}
+
+if [[ -d $HOME/go ]]; then
+    rm -rf ${HOME}/go
+    mkdir ${HOME}/go
+    mkdir ${HOME}/go/bin
+    mkdir ${HOME}/go/src
+else
+    mkdir ${HOME}/go
+    mkdir ${HOME}/go/bin
+    mkdir ${HOME}/go/src
+fi
+
+echo "Adding golang env to ~/.bashrc"
+GOROOT=/usr/local/go
+GOPATH=${HOME}/go
+
+if [[ $(cat ${HOME}/.bashrc | grep GOROOT) ]]; then
+    echo "golang env alreay in ${HOME}/.bashrc"
+else
+   cat <<EOF >> ${HOME}/.bashrc
+
+export GOROOT=/usr/local/go
+export GOPATH=${HOME}/go
+export PATH=${PATH}:${GOROOT}/bin:${GOPATH}/bin
+EOF
+fi
+
+export GOROOT=/usr/local/go
+export GOPATH=${HOME}/go
+export PATH=${PATH}:${GOROOT}/bin:${GOPATH}/bin
+
+echo "Running go version command:"
+go version
+
+echo "=======Installation of golang-${GOLANG_VERSION} complete======="
+
diff --git a/utils/k8s_setup/k8s_config_pre.sh b/utils/k8s_setup/k8s_config_pre.sh
new file mode 100644 (file)
index 0000000..f41ba78
--- /dev/null
@@ -0,0 +1,66 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2018 Huawei Tech and others.
+#
+# 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
+##############################################################################
+K8S_CONFIG="/tmp/k8s_conig"
+
+usage="Script to prepare kubenetes test configurations.
+
+usage:
+    bash $(basename "$0") [-h|--help] [-i|--installer <installer typer>] [-c|--config <k8s config>]
+
+where:
+    -h|--help         show the help text
+    -i|--installer    specify the installer for the system to be monitored
+      <installer type>
+                      one of the following:
+                              (compass)
+examples:
+    $(basename "$0") -i compass"
+
+
+info () {
+    logger -s -t "BOTTLENECKS INFO" "$*"
+}
+
+error () {
+    logger -s -t "BOTTLENECKS ERROR" "$*"
+    exit 1
+}
+
+# Process input variables
+while [[ $# > 0 ]]
+    do
+    key="$1"
+    case $key in
+        -h|--help)
+            echo "$usage"
+            exit 0
+            shift
+        ;;
+        -i|--installer)
+            INSTALLER_TYPE="$2"
+            shift
+        ;;
+        -c|--config)
+            K8S_CONFIG="$2"
+            shift
+        ;;
+        *)
+            error "unkown input options $1 $2"
+            exit 1
+        ;;
+     esac
+     shift
+done
+
+if [[  ${INSTALLER_TYPE} == 'compass' ]]; then
+    sshpass -p root scp root@192.16.1.222:~/.kube/config ${K8S_CONFIG}
+else
+    echo "BOTTLENECKS EROOR: unrecognized installer"
+fi
diff --git a/utils/k8s_setup/k8s_env.sh b/utils/k8s_setup/k8s_env.sh
new file mode 100644 (file)
index 0000000..855dea2
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd and others.
+# 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
+##############################################################################
+
+export GOROOT=/usr/local/go
+export GOPATH=${HOME}/go
+export PATH=${PATH}:${GOROOT}/bin:${GOPATH}/bin
+
diff --git a/utils/k8s_setup/k8s_utils.py b/utils/k8s_setup/k8s_utils.py
new file mode 100644 (file)
index 0000000..7195bf2
--- /dev/null
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+##############################################################################
+# Copyright (c) 2018 Huawei Technologies Co.,Ltd and others.
+#
+# 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
+##############################################################################
+
+import os
+import utils.logger as log
+from kubernetes import client, watch
+
+
+LOG = log.Logger(__name__).getLogger()
+INSTALLER_TYPE = os.getenv("INSTALLER_TYPE")
+
+
+def get_config_path(INSTALLER_TYPE=None, CONFIG_PATH="/tmp/k8s_config"):
+    if INSTALLER_TYPE:
+        CMD = "bash k8s_config_pre.sh -i " + INSTALLER_TYPE + \
+              " -c " + CONFIG_PATH
+        LOG.info("Executing command: " + CMD)
+        CONFIG_PATH = os.popen(CMD)
+    else:
+        if not os.path.exists(CONFIG_PATH):
+            raise Exception("Must at least specify the path \
+of k8s config!")
+    return CONFIG_PATH
+
+
+def get_core_api(version='v1'):
+    if version.lower() == 'v1':
+        API = client.CoreV1Api()
+        LOG.info(API)
+    else:
+        raise Exception("Must input a validate verison!")
+    return API
+
+
+def watch_namespace(namespace, count=3, stop=None, request_timeout=0):
+    w = watch.Watch()
+    LOG.debug("Watch object generated: {}".format(w))
+    LOG.info("Watch stream generated: {}".format(
+             w.stream(namespace, _request_timeout=request_timeout)))
+    for event in w.stream(namespace, _request_timeout=request_timeout):
+        LOG.info("Event: %s %s" %
+                 (event['type'], event['object'].metadata.name))
+        if event['object'].metadata.name == stop:
+            LOG.info("Namesapce successfully added.\n")
+            w.stop()
+        count -= 1
+        if not count:
+            LOG.info("Ended.\n")
+            w.stop()
diff --git a/utils/k8s_setup/kubectl_install.sh b/utils/k8s_setup/kubectl_install.sh
new file mode 100644 (file)
index 0000000..14f97f2
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/bash
+##############################################################################
+# Copyright (c) 2018 Huawei Tech and others.
+#
+# 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
+##############################################################################
+
+OS_TYPE=$(uname -a)
+OS_UBUNTU=$(echo $OS_TYPE | grep ubuntu)
+
+if [[ $OS_UBUNTU ]]; then
+    apt-get update && apt-get install -y apt-transport-https
+    curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
+    touch /etc/apt/sources.list.d/kubernetes.list
+    echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | tee -a /etc/apt/sources.list.d/kubernetes.list
+    apt-get update
+    apt-get install -y kubectl
+else
+    cat <<EOF > /etc/yum.repos.d/kubernetes.repo
+[kubernetes]
+name=Kubernetes
+baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
+enabled=1
+gpgcheck=1
+repo_gpgcheck=1
+gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
+EOF
+    yum install -y kubectl
+fi
+