Create seed code of zte vnfm driver 85/5685/1
authorying.yunlong <ying.yunlong@zte.com.cn>
Thu, 6 Jul 2017 05:20:21 +0000 (13:20 +0800)
committerying.yunlong <ying.yunlong@zte.com.cn>
Thu, 6 Jul 2017 05:20:21 +0000 (13:20 +0800)
Upload the seed code to gerrit for the first time.

Change-Id: I62e8f0559d2e36338b7ca5850ccc2cecb5fe9f5c
Issue-ID: VFC-59
Signed-off-by: ying.yunlong <ying.yunlong@zte.com.cn>
30 files changed:
zte/vmanager/.idea/workspace.xml [new file with mode: 0644]
zte/vmanager/assembly.xml [new file with mode: 0644]
zte/vmanager/driver/__init__.py [new file with mode: 0644]
zte/vmanager/driver/interfaces/__init__.py [new file with mode: 0644]
zte/vmanager/driver/interfaces/tests.py [new file with mode: 0644]
zte/vmanager/driver/interfaces/urls.py [new file with mode: 0644]
zte/vmanager/driver/interfaces/views.py [new file with mode: 0644]
zte/vmanager/driver/pub/__init__.py [new file with mode: 0644]
zte/vmanager/driver/pub/config/__init__.py [new file with mode: 0644]
zte/vmanager/driver/pub/config/config.py [new file with mode: 0644]
zte/vmanager/driver/pub/database/__init__.py [new file with mode: 0644]
zte/vmanager/driver/pub/database/models.py [new file with mode: 0644]
zte/vmanager/driver/pub/utils/__init__.py [new file with mode: 0644]
zte/vmanager/driver/pub/utils/restcall.py [new file with mode: 0644]
zte/vmanager/driver/settings.py [new file with mode: 0644]
zte/vmanager/driver/swagger/__init__.py [new file with mode: 0644]
zte/vmanager/driver/swagger/swagger.json [new file with mode: 0644]
zte/vmanager/driver/swagger/tests.py [new file with mode: 0644]
zte/vmanager/driver/swagger/urls.py [new file with mode: 0644]
zte/vmanager/driver/swagger/views.py [new file with mode: 0644]
zte/vmanager/driver/urls.py [new file with mode: 0644]
zte/vmanager/driver/wsgi.py [new file with mode: 0644]
zte/vmanager/initialize.sh [new file with mode: 0644]
zte/vmanager/logs/empty.txt [new file with mode: 0644]
zte/vmanager/manage.py [new file with mode: 0644]
zte/vmanager/pom.xml [new file with mode: 0644]
zte/vmanager/requirements.txt [new file with mode: 0644]
zte/vmanager/run.sh [new file with mode: 0644]
zte/vmanager/stop.sh [new file with mode: 0644]
zte/vmanager/tox.ini [new file with mode: 0644]

diff --git a/zte/vmanager/.idea/workspace.xml b/zte/vmanager/.idea/workspace.xml
new file mode 100644 (file)
index 0000000..68e827d
--- /dev/null
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ChangeListManager">
+    <list default="true" id="6d1646d8-eb46-431d-9ff7-452938d22ec7" name="Default" comment="" />
+    <ignored path="vmanager.iws" />
+    <ignored path=".idea/workspace.xml" />
+    <ignored path=".idea/dataSources.local.xml" />
+    <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+    <option name="TRACKING_ENABLED" value="true" />
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="ChangesViewManager" flattened_view="true" show_ignored="false" />
+  <component name="CreatePatchCommitExecutor">
+    <option name="PATCH_PATH" value="" />
+  </component>
+  <component name="ExecutionTargetManager" SELECTED_TARGET="default_target" />
+  <component name="FavoritesManager">
+    <favorites_list name="vmanager" />
+  </component>
+  <component name="FileEditorManager">
+    <leaf>
+      <file leaf-file-name="views.py" pinned="false" current-in-tab="true">
+        <entry file="file://$PROJECT_DIR$/driver/interfaces/views.py">
+          <provider selected="true" editor-type-id="text-editor">
+            <state relative-caret-position="210">
+              <caret line="120" column="37" selection-start-line="120" selection-start-column="37" selection-end-line="120" selection-end-column="37" />
+              <folding />
+            </state>
+          </provider>
+        </entry>
+      </file>
+    </leaf>
+  </component>
+  <component name="IdeDocumentHistory">
+    <option name="CHANGED_PATHS">
+      <list>
+        <option value="$PROJECT_DIR$/driver/interfaces/views.py" />
+      </list>
+    </option>
+  </component>
+  <component name="JsBuildToolGruntFileManager" detection-done="true" sorting="DEFINITION_ORDER" />
+  <component name="JsBuildToolPackageJson" detection-done="true" sorting="DEFINITION_ORDER" />
+  <component name="JsGulpfileManager">
+    <detection-done>true</detection-done>
+    <sorting>DEFINITION_ORDER</sorting>
+  </component>
+  <component name="ProjectFrameBounds">
+    <option name="x" value="-8" />
+    <option name="y" value="-8" />
+    <option name="width" value="1612" />
+    <option name="height" value="876" />
+  </component>
+  <component name="ProjectLevelVcsManager" settingsEditedManually="false">
+    <OptionsSetting value="true" id="Add" />
+    <OptionsSetting value="true" id="Remove" />
+    <OptionsSetting value="true" id="Checkout" />
+    <OptionsSetting value="true" id="Update" />
+    <OptionsSetting value="true" id="Status" />
+    <OptionsSetting value="true" id="Edit" />
+    <ConfirmationsSetting value="0" id="Add" />
+    <ConfirmationsSetting value="0" id="Remove" />
+  </component>
+  <component name="ProjectView">
+    <navigator currentView="ProjectPane" proportions="" version="1">
+      <flattenPackages />
+      <showMembers />
+      <showModules />
+      <showLibraryContents />
+      <hideEmptyPackages />
+      <abbreviatePackageNames />
+      <autoscrollToSource />
+      <autoscrollFromSource />
+      <sortByType />
+      <manualOrder />
+      <foldersAlwaysOnTop value="true" />
+    </navigator>
+    <panes>
+      <pane id="Scratches" />
+      <pane id="Scope" />
+      <pane id="ProjectPane">
+        <subPane>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="vmanager" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="vmanager" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="vmanager" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="vmanager" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="vmanager" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="driver" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+          <PATH>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="vmanager" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="vmanager" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="driver" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+            <PATH_ELEMENT>
+              <option name="myItemId" value="interfaces" />
+              <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
+            </PATH_ELEMENT>
+          </PATH>
+        </subPane>
+      </pane>
+    </panes>
+  </component>
+  <component name="PropertiesComponent">
+    <property name="options.splitter.main.proportions" value="0.3" />
+    <property name="options.lastSelected" value="preferences.sourceCode" />
+    <property name="options.splitter.details.proportions" value="0.2" />
+    <property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PyActiveSdkModuleConfigurable" />
+    <property name="settings.editor.splitter.proportion" value="0.2" />
+    <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+    <property name="WebServerToolWindowFactoryState" value="false" />
+  </component>
+  <component name="RunManager" selected="Django server.vmanager">
+    <configuration default="true" type="Python.DjangoServer" factoryName="Django server">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="vmanager" />
+      <option name="launchJavascriptDebuger" value="false" />
+      <option name="port" value="8000" />
+      <option name="host" value="" />
+      <option name="additionalOptions" value="" />
+      <option name="browserUrl" value="" />
+      <option name="runTestServer" value="false" />
+      <option name="runNoReload" value="false" />
+      <option name="useCustomRunCommand" value="false" />
+      <option name="customRunCommand" value="" />
+      <method />
+    </configuration>
+    <configuration default="false" name="vmanager" type="Python.DjangoServer" factoryName="Django server">
+      <option name="INTERPRETER_OPTIONS" value="" />
+      <option name="PARENT_ENVS" value="true" />
+      <envs>
+        <env name="PYTHONUNBUFFERED" value="1" />
+      </envs>
+      <option name="SDK_HOME" value="" />
+      <option name="WORKING_DIRECTORY" value="" />
+      <option name="IS_MODULE_SDK" value="false" />
+      <option name="ADD_CONTENT_ROOTS" value="true" />
+      <option name="ADD_SOURCE_ROOTS" value="true" />
+      <module name="vmanager" />
+      <option name="launchJavascriptDebuger" value="false" />
+      <option name="port" value="8000" />
+      <option name="host" value="" />
+      <option name="additionalOptions" value="" />
+      <option name="browserUrl" value="" />
+      <option name="runTestServer" value="false" />
+      <option name="runNoReload" value="false" />
+      <option name="useCustomRunCommand" value="false" />
+      <option name="customRunCommand" value="" />
+      <method />
+    </configuration>
+    <list size="1">
+      <item index="0" class="java.lang.String" itemvalue="Django server.vmanager" />
+    </list>
+  </component>
+  <component name="ShelveChangesManager" show_recycled="false">
+    <option name="remove_strategy" value="false" />
+  </component>
+  <component name="SvnConfiguration" cleanupOnStartRun="true">
+    <configuration>C:\Users\10191177\AppData\Roaming\Subversion</configuration>
+  </component>
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="6d1646d8-eb46-431d-9ff7-452938d22ec7" name="Default" comment="" />
+      <created>1491809875990</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1491809875990</updated>
+    </task>
+    <servers />
+  </component>
+  <component name="ToolWindowManager">
+    <frame x="-8" y="-8" width="1612" height="876" extended-state="1" />
+    <editor active="false" />
+    <layout>
+      <window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.25322166" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="TODO" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="6" side_tool="false" content_ui="tabs" />
+      <window_info id="Event Log" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="Database" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Python Console" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Version Control" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Structure" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Terminal" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="false" content_ui="tabs" />
+      <window_info id="Favorites" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="-1" side_tool="true" content_ui="tabs" />
+      <window_info id="Cvs" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
+      <window_info id="Hierarchy" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="2" side_tool="false" content_ui="combo" />
+      <window_info id="Message" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Commander" active="false" anchor="right" auto_hide="false" internal_type="SLIDING" type="SLIDING" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="0" side_tool="false" content_ui="tabs" />
+      <window_info id="Find" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Inspection" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="5" side_tool="false" content_ui="tabs" />
+      <window_info id="Run" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="2" side_tool="false" content_ui="tabs" />
+      <window_info id="Ant Build" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="1" side_tool="false" content_ui="tabs" />
+      <window_info id="Debug" active="false" anchor="bottom" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.4" sideWeight="0.5" order="3" side_tool="false" content_ui="tabs" />
+    </layout>
+  </component>
+  <component name="Vcs.Log.UiProperties">
+    <option name="RECENTLY_FILTERED_USER_GROUPS">
+      <collection />
+    </option>
+    <option name="RECENTLY_FILTERED_BRANCH_GROUPS">
+      <collection />
+    </option>
+  </component>
+  <component name="VcsContentAnnotationSettings">
+    <option name="myLimit" value="2678400000" />
+  </component>
+  <component name="XDebuggerManager">
+    <breakpoint-manager />
+    <watches-manager />
+  </component>
+  <component name="editorHistoryManager">
+    <entry file="file://$PROJECT_DIR$/driver/interfaces/views.py">
+      <provider selected="true" editor-type-id="text-editor">
+        <state relative-caret-position="210">
+          <caret line="120" column="37" selection-start-line="120" selection-start-column="37" selection-end-line="120" selection-end-column="37" />
+          <folding />
+        </state>
+      </provider>
+    </entry>
+  </component>
+</project>
\ No newline at end of file
diff --git a/zte/vmanager/assembly.xml b/zte/vmanager/assembly.xml
new file mode 100644 (file)
index 0000000..cd9eda8
--- /dev/null
@@ -0,0 +1,51 @@
+<!--
+    Copyright 2016 ZTE Corporation.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" 
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
+    <id>drivers-vnfm-svnfm-zte-vmanager</id>
+    <formats>
+        <format>zip</format>
+    </formats>
+    <fileSets>
+        <fileSet>
+            <directory>driver</directory>
+            <outputDirectory>/driver</outputDirectory>
+            <includes>
+                <include>**/*.py</include>
+                <include>**/*.json</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>logs</directory>
+            <outputDirectory>/logs</outputDirectory>
+            <includes>
+                <include>*.txt</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>.</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>*.py</include>
+                <include>*.txt</include>
+                <include>*.sh</include>
+                <include>*.ini</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+    <baseDirectory>nfvo/drivers/vnfm/svnfm/zte/vmanager</baseDirectory>
+</assembly>
diff --git a/zte/vmanager/driver/__init__.py b/zte/vmanager/driver/__init__.py
new file mode 100644 (file)
index 0000000..5580cc3
--- /dev/null
@@ -0,0 +1,13 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/zte/vmanager/driver/interfaces/__init__.py b/zte/vmanager/driver/interfaces/__init__.py
new file mode 100644 (file)
index 0000000..5580cc3
--- /dev/null
@@ -0,0 +1,13 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/zte/vmanager/driver/interfaces/tests.py b/zte/vmanager/driver/interfaces/tests.py
new file mode 100644 (file)
index 0000000..0fc179f
--- /dev/null
@@ -0,0 +1,425 @@
+# Copyright 2016-2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import mock
+from django.test import Client
+from django.test import TestCase
+from rest_framework import status
+from driver.pub.utils import restcall
+
+
+class InterfacesTest(TestCase):
+    def setUp(self):
+        self.client = Client()
+
+    def tearDown(self):
+        pass
+
+    @mock.patch.object(restcall, 'call_req')
+    def test_instantiate_vnf_001(self, mock_call_req):
+        """
+        Initate_VNF
+        """
+        vnfm_info = {u'userName': u'admin',
+                     u'vendor': u'ZTE',
+                     u'name': u'ZTE_VNFM_237_62',
+                     u'vimId': u'516cee95-e8ca-4d26-9268-38e343c2e31e',
+                     u'url': u'http://192.168.237.165:2324',
+                     u'certificateUrl': u'',
+                     u'version': u'V1.0',
+                     u'vnfmId': u'b0797c9b-3da9-459c-b25c-3813e9d8fd70',
+                     u'password': u'admin',
+                     u'type': u'ztevmanagerdriver',
+                     u'createTime': u'2016-10-31 11:08:39',
+                     u'description': u''}
+        vnfd_info = {u'vnfInstanceInfo': [{u'vnfInstanceId': u'59b79a9f-9e37-4f6c-acaf-5f41d9cb3f76',
+                                           u'vnfInstanceName': u'VFW_59b79a9f-9e37-4f6c-acaf-5f41d9cb3f76'},
+                                          {u'vnfInstanceId': u'6c5e4bd3-e8a6-42d8-a7a4-53a8ef74c6ac',
+                                           u'vnfInstanceName': u'VFW_6c5e4bd3-e8a6-42d8-a7a4-53a8ef74c6ac'},
+                                          {u'vnfInstanceId': u'930de5c9-8043-41df-ace8-ede2262a3713',
+                                           u'vnfInstanceName': u'VFW_930de5c9-8043-41df-ace8-ede2262a3713'},
+                                          {u'vnfInstanceId': u'c677a305-a7bd-4baf-9eee-c383c588bb3c',
+                                           u'vnfInstanceName': u'VFW_c677a305-a7bd-4baf-9eee-c383c588bb3c'},
+                                          {u'vnfInstanceId': u'e708e5c5-bdf4-436a-b928-826887806d82',
+                                           u'vnfInstanceName': u'VFW_e708e5c5-bdf4-436a-b928-826887806d82'}],
+                     u'csarId': u'd852e1be-0aac-48f1-b1a4-cd825f6cdf9a',
+                     u'imageInfo': [
+                         {u'status': u'Enable', u'index': u'0',
+                          u'vimId': u'516cee95-e8ca-4d26-9268-38e343c2e31e',
+                          u'fileName': u'VFW_IMAGE_VCPE_ZTE',
+                          u'vimUser': u'admin',
+                          u'imageId': u'd2b73154-0414-466a-a1e6-51b9461b753a',
+                          u'tenant': u'admin'}],
+                     u'packageInfo': {u'usageState': u'NotInUse',
+                                      u'onBoardState': u'onBoarded',
+                                      u'name': u'VFW',
+                                      u'format': u'yaml',
+                                      u'provider': u'ZTE',
+                                      u'vnfdProvider': u'zte',
+                                      u'vnfdId': u'vcpe_vfw_zte_1_0',
+                                      u'deletionPending': False,
+                                      u'version': u'v1.0',
+                                      u'vnfVersion': u'1.0',
+                                      u'vnfdVersion': u'1.0.0',
+                                      u'processState': u'normal',
+                                      u'modifyTime': u'2016-10-31 16:21:32',
+                                      u'downloadUri': u'http://192.168.233.226:80/',
+                                      u'operationalState': u'Disabled',
+                                      u'createTime': u'2016-10-31 16:21:11',
+                                      u'size': u'12.1 MB'}}
+        packageInfo = {u'usageState': u'NotInUse',
+                       u'onBoardState': u'onBoarded',
+                       u'name': u'VFW',
+                       u'format': u'yaml',
+                       u'provider': u'ZTE',
+                       u'vnfdProvider': u'zte',
+                       u'vnfdId': u'vcpe_vfw_zte_1_0',
+                       u'deletionPending': False,
+                       u'version': u'v1.0',
+                       u'vnfVersion': u'1.0',
+                       u'vnfdVersion': u'1.0.0',
+                       u'processState': u'normal',
+                       u'modifyTime': u'2016-10-31 16:21:32',
+                       u'downloadUri': u'http://192.168.233.226:80/files/catalog-http/NFAR/ZTE/VFW/v1.0/VFW.csar',
+                       u'operationalState': u'Disabled',
+                       u'createTime': u'2016-10-31 16:21:11', u'size': u'12.1 MB'}
+
+        ret = [0, json.JSONEncoder().encode({"vnfInstanceId":"8",
+                                             "jobid":"NF-CREATE-8-b384535c-9f45-11e6-8749-fa163e91c2f9"}),
+               '200']
+
+        r1 = [0, json.JSONEncoder().encode(vnfm_info), "200"]
+
+        r2 = [0, json.JSONEncoder().encode(vnfd_info), "200"]
+
+        r3 = [0, json.JSONEncoder().encode(packageInfo), "200"]
+
+
+        mock_call_req.side_effect = [r1, r2, r3, ret]
+
+        req_data = {'vnfInstanceName': 'VFW_f88c0cb7-512a-44c4-bd09-891663f19367',
+                    'vnfPackageId': 'd852e1be-0aac-48f1-b1a4-cd825f6cdf9a',
+                    'vnfDescriptorId': 'vcpe_vfw_zte_1_0',
+                    'additionalParam': {'sdncontroller': 'e4d637f1-a4ec-4c59-8b20-4e8ab34daba9',
+                                        'NatIpRange': '192.167.0.10-192.168.0.20',
+                                        'm6000_mng_ip': '192.168.11.11',
+                                        'externalPluginManageNetworkName': 'plugin_net_2014',
+                                        'location': '516cee95-e8ca-4d26-9268-38e343c2e31e',
+                                        'externalManageNetworkName': 'mng_net_2017',
+                                        'sfc_data_network': 'sfc_data_net_2016',
+                                        'externalDataNetworkName': 'Flow_out_net',
+                                        'inputs':{}}}
+
+        response = self.client.post("/openoapi/ztevnfm/v1/ztevnfmid/vnfs",
+                                    data=json.dumps(req_data), content_type="application/json")
+        self.assertEqual(str(status.HTTP_200_OK), response.status_code)
+        expect_resp_data = {"jobid": "NF-CREATE-8-b384535c-9f45-11e6-8749-fa163e91c2f9", "vnfInstanceId": "8"}
+        self.assertEqual(expect_resp_data, response.data)
+
+    @mock.patch.object(restcall, 'call_req')
+    def test_terminate_vnf__002(self, mock_call_req):
+        """
+        Terminate_VNF
+        """
+        r1 = [0, json.JSONEncoder().encode({
+            "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
+            "name": "g_vnfm",
+            "type": "vnfm",
+            "vimId": "",
+            "vendor": "ZTE",
+            "version": "v1.0",
+            "description": "vnfm",
+            "certificateUrl": "",
+            "url": "http://10.74.44.11",
+            "userName": "admin",
+            "password": "admin",
+            "createTime": "2016-07-06 15:33:18"}), "200"]
+
+        r2 = [0, json.JSONEncoder().encode({"vnfInstanceId": "1", "JobId": "1"}), "200"]
+        mock_call_req.side_effect = [r1, r2]
+
+        response = self.client.post("/openoapi/ztevnfm/v1/ztevnfmid/vnfs/vbras_innstance_id/terminate")
+
+        self.assertEqual(str(status.HTTP_200_OK), response.status_code)
+        expect_resp_data = {"jobid": "1", "vnfInstanceId": "1"}
+        self.assertEqual(expect_resp_data, response.data)
+
+    @mock.patch.object(restcall, 'call_req')
+    def test_query_vnf_003(self, mock_call_req):
+        """
+        Query_VNF
+        """
+        r1 = [0, json.JSONEncoder().encode({
+            "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
+            "name": "g_vnfm",
+            "type": "vnfm",
+            "vimId": "",
+            "vendor": "ZTE",
+            "version": "v1.0",
+            "description": "vnfm",
+            "certificateUrl": "",
+            "url": "http://10.74.44.11",
+            "userName": "admin",
+            "password": "admin",
+            "createTime": "2016-07-06 15:33:18"}), "200"]
+
+        r2 = [0, json.JSONEncoder().encode({"vnfinstancestatus": "1"}), "200"]
+        mock_call_req.side_effect = [r1, r2]
+
+        response = self.client.get("/openoapi/ztevnfm/v1/ztevnfmid/vnfs/vbras_innstance_id")
+
+        self.assertEqual(str(status.HTTP_200_OK), response.status_code)
+
+        expect_resp_data = {"vnfInfo": {"vnfStatus": "1"}}
+        self.assertEqual(expect_resp_data, response.data)
+
+    @mock.patch.object(restcall, 'call_req')
+    def test_operation_status_004(self, mock_call_req):
+        """
+        Operation_status
+        """
+        vnfm_info = {u'userName': u'admin',
+                     u'vendor': u'ZTE',
+                     u'name': u'ZTE_VNFM_237_62',
+                     u'vimId': u'516cee95-e8ca-4d26-9268-38e343c2e31e',
+                     u'url': u'http://192.168.237.165:2324',
+                     u'certificateUrl': u'',
+                     u'version': u'V1.0',
+                     u'vnfmId': u'b0797c9b-3da9-459c-b25c-3813e9d8fd70',
+                     u'password': u'admin',
+                     u'type': u'ztevmanagerdriver',
+                     u'createTime': u'2016-10-31 11:08:39',
+                     u'description': u''}
+        resp_body = {"responsedescriptor":
+                         {"status": "processing", "responsehistorylist": [
+                             {"status": "error",
+                              "progress": 255,
+                              "errorcode": "",
+                              "responseid": 20,
+                              "statusdescription": "'JsonParser' object has no attribute 'parser_info'"}],
+                          "responseid": 21,
+                          "errorcode": "",
+                          "progress": 40,
+                          "statusdescription": "Create nf apply resource failed"},
+                     "jobid": "NF-CREATE-11-ec6c2f2a-9f48-11e6-9405-fa163e91c2f9"}
+        r1 = [0, json.JSONEncoder().encode(vnfm_info), '200']
+        r2 = [0, json.JSONEncoder().encode(resp_body), '200']
+        mock_call_req.side_effect = [r1, r2]
+        response = self.client.get("/openoapi/ztevmanagerdriver/v1/{vnfmid}/jobs/{jobid}?responseId={responseId}".
+            format(
+            vnfmid=vnfm_info["vnfmId"],
+            jobid=resp_body["jobid"],
+            responseId=resp_body["responsedescriptor"]["responseid"]))
+
+        self.assertEqual(str(status.HTTP_200_OK), response.status_code)
+
+        expect_resp_data = resp_body
+        self.assertDictEqual(expect_resp_data, response.data)
+
+    @mock.patch.object(restcall, 'call_req')
+    def test_grantvnf_005(self, mock_call_req):
+        """
+        Grant_VNF
+        """
+        ret = [0,
+               '{"vim":{"accessinfo":{"tenant":"admin"},"vimid":"516cee95-e8ca-4d26-9268-38e343c2e31e"}}',
+               '201']
+
+        req_data = {
+            "vnfmid": "13232222",
+            "nfvoid": "03212234",
+            "vimid": "12345678",
+            "exvimidlist ":
+                ["exvimid"],
+            "tenant": " tenant1",
+            "vnfistanceid": "1234",
+            "operationright": "0",
+            "vmlist": [
+                {
+                    "vmflavor": "SMP",
+                    "vmnumber": "3"},
+                {
+                    "vmflavor": "CMP",
+                    "vmnumber": "3"}
+            ]}
+
+        mock_call_req.return_value = ret
+        response = self.client.put("/openoapi/ztevmanagerdriver/v1/resource/grant",
+                                   data=json.dumps(req_data), content_type='application/json')
+
+        self.assertEqual(str(status.HTTP_201_CREATED), response.status_code)
+
+        expect_resp_data = {
+            "vimid": "516cee95-e8ca-4d26-9268-38e343c2e31e",
+            "tenant": "admin"}
+        self.assertDictEqual(expect_resp_data, response.data)
+
+    @mock.patch.object(restcall, 'call_req')
+    def test_notify_006(self, mock_call_req):
+        """
+        Notification
+        """
+        r1 = [0, json.JSONEncoder().encode({
+            "vnfmId": "19ecbb3a-3242-4fa3-9926-8dfb7ddc29ee",
+            "name": "g_vnfm",
+            "type": "vnfm",
+            "vimId": "",
+            "vendor": "ZTE",
+            "version": "v1.0",
+            "description": "vnfm",
+            "certificateUrl": "",
+            "url": "http://10.74.44.11",
+            "userName": "admin",
+            "password": "admin",
+            "createTime": "2016-07-06 15:33:18"}), "200"]
+
+        r2 = [0, json.JSONEncoder().encode(
+            {"vim":
+                {
+                    "vimInfoId": "111111",
+                    "vimId": "12345678",
+                    "interfaceInfo": {
+                        "vimType": "vnf",
+                        "apiVersion": "v1",
+                        "protocolType": "None"},
+                    "accessInfo": {
+                        "tenant": "tenant1",
+                        "username": "admin",
+                        "password": "password"},
+                    "interfaceEndpoint": "http://127.0.0.1/api/v1"},
+                "zone": "",
+                "addResource": {
+                    "resourceDefinitionId": "xxxxx",
+                    "vimId": "12345678",
+                    "zoneId": "000"},
+                "removeResource": "",
+                "vimAssets": {
+                    "computeResourceFlavour": {
+                        "vimId": "12345678",
+                        "vduId": "sdfasdf",
+                        "vimFlavourId": "12"},
+                    "softwareImage": {
+                        "vimId": "12345678",
+                        "imageName": "AAA",
+                        "vimImageId": ""}},
+                "additionalParam": ""
+             }), "200"]
+
+        req_data = {
+            "nfvoid": "1",
+            "vnfmid": "876543211",
+            "vimid": "6543211",
+            "timestamp": "1234567890",
+            "vnfinstanceid": "1",
+            "eventtype": "0",
+            "vmlist":
+                [
+                    {
+                        "vmflavor": "SMP",
+                        "vmnumber": "3",
+                        "vmidlist ": ["vmuuid"]},
+                    {
+                        "vmflavor": "CMP",
+                        "vmnumber": "3",
+                        "vmidlist ": ["vmuuid"]}]}
+        mock_call_req.side_effect = [r1, r2]
+        response = self.client.post("/openoapi/ztevmanagerdriver/v1/vnfs/lifecyclechangesnotification",
+                                    data=json.dumps(req_data), content_type='application/json')
+
+        self.assertEqual(str(status.HTTP_200_OK), response.status_code)
+
+        expect_resp_data = None
+        self.assertEqual(expect_resp_data, response.data)
+
+    '''
+    @mock.patch.object(restcall, 'call_req')
+    def test_scale(self,mock_call_req):
+        job_info = {"jobid":"801","nfInstanceId":"101"}
+        vnfm_info = {u'userName': u'admin',
+                     u'vendor': u'ZTE',
+                     u'name': u'ZTE_VNFM_237_62',
+                     u'vimId': u'516cee95-e8ca-4d26-9268-38e343c2e31e',
+                     u'url': u'http://192.168.237.165:2324',
+                     u'certificateUrl': u'',
+                     u'version': u'V1.0',
+                     u'vnfmId': u'b0797c9b-3da9-459c-b25c-3813e9d8fd70',
+                     u'password': u'admin',
+                     u'type': u'ztevmanagerdriver',
+                     u'createTime': u'2016-10-31 11:08:39',
+                     u'description': u''}
+
+        ret = [0, json.JSONEncoder().encode(job_info), "202"]
+        ret_vnfm = [0,json.JSONEncoder().encode(job_info), "200"]
+        mock_call_req.side_effect = [ret_vnfm, ret]
+
+        vnfd_info = {
+            "vnf_flavours":[
+                {
+                    "flavour_id":"flavour1",
+                    "description":"",
+                    "vdu_profiles":[
+                        {
+                            "vdu_id":"vdu1Id",
+                            "instances_minimum_number": 1,
+                            "instances_maximum_number": 4,
+                            "local_affinity_antiaffinity_rule":[
+                                {
+                                    "affinity_antiaffinity":"affinity",
+                                    "scope":"node",
+                                }
+                            ]
+                        }
+                    ],
+                    "scaling_aspects":[
+                        {
+                            "id": "demo_aspect",
+                            "name": "demo_aspect",
+                            "description": "demo_aspect",
+                            "associated_group": "elementGroup1",
+                            "max_scale_level": 5
+                        }
+                    ]
+                }
+            ],
+            "element_groups": [
+                  {
+                      "group_id": "elementGroup1",
+                      "description": "",
+                      "properties":{
+                          "name": "elementGroup1",
+                      },
+                      "members": ["gsu_vm","pfu_vm"],
+                  }
+            ]
+        }
+
+        scale_vnf_data = {
+            "type":"SCALE_OUT",
+            "aspectId":"demo_aspect",
+            "numberOfSteps":"3",
+            "additionalParam":{
+                "vnfdModel":vnfd_info
+            }
+        }
+
+
+        response = self.client.post("/openoapi/ztevnfm/v1/vnfmid/vnfs/101/scale",
+                                   data=json.dumps(scale_vnf_data), content_type='application/json')
+
+        self.assertEqual(str(status.HTTP_202_ACCEPTED), response.status_code)
+
+        expect_resp_data = {"jobid":"801","nfInstanceId":"101"}
+        self.assertDictEqual(expect_resp_data, response.data)
+    '''
diff --git a/zte/vmanager/driver/interfaces/urls.py b/zte/vmanager/driver/interfaces/urls.py
new file mode 100644 (file)
index 0000000..43eb40a
--- /dev/null
@@ -0,0 +1,36 @@
+# Copyright 2016-2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from django.conf.urls import url
+
+from driver.interfaces import views
+
+urlpatterns = [
+    url(r'^openoapi/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/vnfs$', views.instantiate_vnf,
+        name='instantiate_vnf'),
+    url(
+        r'^openoapi/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/vnfs/(?P<vnfInstanceId>'
+        r'[0-9a-zA-Z\-\_]+)/terminate$',
+        views.terminate_vnf, name='terminate_vnf'),
+    url(
+        r'^openoapi/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/vnfs/(?P<vnfInstanceId>'
+        r'[0-9a-zA-Z\-\_]+)$',
+        views.query_vnf, name='query_vnf'),
+    url(r'^openoapi/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/jobs/(?P<jobid>[0-9a-zA-Z\-\_]+)$',
+        views.operation_status, name='operation_status'),
+    url(r'^openoapi/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/resource/grant$', views.grantvnf, name='grantvnf'),
+    url(r'^openoapi/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/vnfs/lifecyclechangesnotification$', views.notify, name='notify'),
+    url(r'^openoapi/(?P<vnfmtype>[0-9a-zA-Z\-\_]+)/v1/(?P<vnfmid>[0-9a-zA-Z\-\_]+)/vnfs/(?P<nfInstanceId>[0-9a-zA-Z\-\_]+)/scale$',
+        views.scale, name='scale'),
+    url(r'^samples/$', views.samples, name='samples'), ]
diff --git a/zte/vmanager/driver/interfaces/views.py b/zte/vmanager/driver/interfaces/views.py
new file mode 100644 (file)
index 0000000..af316f0
--- /dev/null
@@ -0,0 +1,516 @@
+# Copyright 2016-2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import inspect
+import json
+import logging
+import traceback
+
+from rest_framework.decorators import api_view
+from rest_framework.response import Response
+
+from driver.pub.utils import restcall
+from driver.pub.utils.restcall import req_by_msb
+
+logger = logging.getLogger(__name__)
+
+
+def fun_name():
+    return "=================%s==================" % inspect.stack()[1][3]
+
+
+def ignorcase_get(args, key):
+    if not key:
+        return ""
+    if not args:
+        return ""
+    if key in args:
+        return args[key]
+    for old_key in args:
+        if old_key.upper() == key.upper():
+            return args[old_key]
+    return ""
+
+
+def mapping_conv(keyword_map, rest_return):
+    resp_data = {}
+    for param in keyword_map:
+        if keyword_map[param]:
+            resp_data[keyword_map[param]] = ignorcase_get(rest_return, param)
+    return resp_data
+
+
+query_vnfd_url = "openoapi/nslcm/v1/vnfpackage/%s"
+query_vnfm_url = "openoapi/extsys/v1/vnfms/%s"
+query_package_url = "openoapi/nslcm/v1/vnfpackage/%s"
+
+
+# Query VNFM by VNFMID
+def vnfm_get(vnfmid):
+    ret = req_by_msb("openoapi/extsys/v1/vnfms/%s" % vnfmid, "GET")
+    return ret
+
+
+def vnfd_get(vnfpackageid):
+    ret = req_by_msb("openoapi/nslcm/v1/vnfpackage/%s" % vnfpackageid, "GET")
+    return ret
+
+
+def vnfpackage_get(csarid):
+    ret = req_by_msb("openoapi/nslcm/v1/vnfpackage/%s" % csarid, "GET")
+    return ret
+
+
+# ==================================================
+create_vnf_url = "v1/vnfs"
+create_vnf_param_mapping = {
+    "packageUrl": "",
+    "instantiateUrl": "",
+    "instantiationLevel": "",
+    "vnfInstanceName": "",
+    "vnfPackageId": "",
+    "vnfDescriptorId": "",
+    "flavorId": "",
+    "vnfInstanceDescription": "",
+    "extVirtualLink": "",
+    "additionalParam": ""}
+create_vnf_resp_mapping = {
+    "VNFInstanceID": "vnfInstanceId",
+    "JobId": "jobid",}
+
+
+@api_view(http_method_names=['POST'])
+def instantiate_vnf(request, *args, **kwargs):
+    try:
+        logger.debug("[%s] request.data=%s", fun_name(), request.data)
+        vnfm_id = ignorcase_get(kwargs, "vnfmid")
+        ret = vnfm_get(vnfm_id)
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        vnfm_info = json.JSONDecoder().decode(ret[1])
+        logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
+        vnf_package_id = ignorcase_get(request.data, "vnfPackageId")
+        ret = vnfd_get(vnf_package_id)
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        vnfd_info = json.JSONDecoder().decode(ret[1])
+        logger.debug("[%s] vnfd_info=%s", fun_name(), vnfd_info)
+        csar_id = ignorcase_get(vnfd_info, "csarId")
+        ret = vnfpackage_get(csar_id)
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        vnf_package_info = json.JSONDecoder().decode(ret[1])
+        packageInfo = ignorcase_get(vnf_package_info, "packageInfo")
+        logger.debug("[%s] packageInfo=%s", fun_name(), packageInfo)
+        data = {}
+        data["NFVOID"] = 1
+        data["VNFMID"] = vnfm_id
+        # data["VNFD"] = ignorcase_get(packageInfo, "downloadUri")
+        # data["VNFURL"] = ignorcase_get(packageInfo, "downloadUri")
+        vnfdId = ignorcase_get(packageInfo, "vnfdId")
+        from urlparse import urlparse
+        vnfm_ip = urlparse(ignorcase_get(vnfm_info, "url")).netloc.split(':')[0]
+        if "vCSCF_NF_ZTE" == vnfdId:
+            data["VNFD"] = "ftp://VMVERSION:vmversion@" + "192.168.128.159" + ":21/CSCF"
+            data["VNFURL"] = "ftp://VMVERSION:vmversion@" + "192.168.128.159" + ":21/CSCF"
+        elif "vPCRF_NF_ZTE" == vnfdId:
+            data["VNFD"] = "ftp://VMVERSION:vmversion@" + "192.168.128.159" + ":21/PCRF"
+            data["VNFURL"] = "ftp://VMVERSION:vmversion@" + "192.168.128.159" + ":21/PCRF"
+        elif "vTAS_NF_ZTE" == vnfdId:
+            data["VNFD"] = "ftp://VMVERSION:vmversion@" + "192.168.128.159" + ":21/SSS"
+            data["VNFURL"] = "ftp://VMVERSION:vmversion@" + "192.168.128.159" + ":21/SSS"
+        elif "vSPGW_NF_ZTE" == vnfdId:
+            data["VNFD"] = "ftp://VMVERSION:vmversion@" + "192.168.237.159" + ":21/vgw31"
+            data["VNFURL"] = "ftp://VMVERSION:vmversion@" + "192.168.237.159" + ":21/vgw31"
+        else:
+            data["VNFD"] = ignorcase_get(packageInfo, "downloadUri")
+            data["VNFURL"] = ignorcase_get(packageInfo, "downloadUri")
+
+        data["extension"] = {}
+        inputs = []
+        for name, value in ignorcase_get(ignorcase_get(request.data, "additionalParam"), "inputs").items():
+            inputs.append({"name": name, "value": value})
+
+        logger.info(
+            "ignorcase_get(request.data, \"additionalParam\") = %s" % ignorcase_get(request.data, "additionalParam"))
+        data["extension"]["inputs"] = json.dumps(inputs)
+        data["extension"]["extVirtualLinks"] = ignorcase_get(
+            ignorcase_get(request.data, "additionalParam"), "extVirtualLinks")
+        data["extension"]["vnfinstancename"] = ignorcase_get(request.data, "vnfInstanceName")
+        data["extension"]["vnfid"] = data["VNFD"]
+        data["extension"]["multivim"] = 0
+        logger.debug("[%s] call_req data=%s", fun_name(), data)
+        ret = restcall.call_req(
+            base_url=ignorcase_get(vnfm_info, "url"),
+            user=ignorcase_get(vnfm_info, "userName"),
+            passwd=ignorcase_get(vnfm_info, "password"),
+            auth_type=restcall.rest_no_auth,
+            resource=create_vnf_url,
+            method='post',
+            content=json.JSONEncoder().encode(data))
+        logger.debug("[%s] call_req ret=%s", fun_name(), ret)
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        resp = json.JSONDecoder().decode(ret[1])
+        resp_data = mapping_conv(create_vnf_resp_mapping, resp)
+        logger.info("[%s]resp_data=%s", fun_name(), resp_data)
+    except Exception as e:
+        logger.error("Error occurred when instantiating VNF")
+        raise e
+    return Response(data=resp_data, status=ret[2])
+
+
+# ==================================================
+vnf_delete_url = "v1/vnfs/%s"
+vnf_delete_param_mapping = {
+    "terminationType": "terminationType",
+    "gracefulTerminationTimeout": "gracefulTerminationTimeout"}
+vnf_delete_resp_mapping = {
+    "vnfInstanceId": "vnfInstanceId",
+    "JobId": "jobid"}
+
+
+@api_view(http_method_names=['POST'])
+def terminate_vnf(request, *args, **kwargs):
+    try:
+        logger.debug("[%s] request.data=%s", fun_name(), request.data)
+        vnfm_id = ignorcase_get(kwargs, "vnfmid")
+        ret = vnfm_get(vnfm_id)
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        vnfm_info = json.JSONDecoder().decode(ret[1])
+        logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
+        data = {}
+        logger.debug("[%s]req_data=%s", fun_name(), data)
+        ret = restcall.call_req(
+            base_url=ignorcase_get(vnfm_info, "url"),
+            user=ignorcase_get(vnfm_info, "userName"),
+            passwd=ignorcase_get(vnfm_info, "password"),
+            auth_type=restcall.rest_no_auth,
+            resource=vnf_delete_url % (ignorcase_get(kwargs, "vnfInstanceID")),
+            method='delete',
+            content=json.JSONEncoder().encode(data))
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        resp = json.JSONDecoder().decode(ret[1])
+        resp_data = mapping_conv(vnf_delete_resp_mapping, resp)
+        logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
+    except Exception as e:
+        logger.error("Error occurred when terminating VNF")
+        raise e
+    return Response(data=resp_data, status=ret[2])
+
+
+# ==================================================
+
+
+vnf_detail_url = "v1/vnfs/%s"
+vnf_detail_resp_mapping = {
+    "VNFInstanseStatus": "status",}
+
+
+@api_view(http_method_names=['GET'])
+def query_vnf(request, *args, **kwargs):
+    try:
+        logger.debug("[%s] request.data=%s", fun_name(), request.data)
+        vnfm_id = ignorcase_get(kwargs, "vnfmid")
+        ret = vnfm_get(vnfm_id)
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        vnfm_info = json.JSONDecoder().decode(ret[1])
+        logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
+        data = {}
+        ret = restcall.call_req(
+            base_url=ignorcase_get(vnfm_info, "url"),
+            user=ignorcase_get(vnfm_info, "userName"),
+            passwd=ignorcase_get(vnfm_info, "password"),
+            auth_type=restcall.rest_no_auth,
+            resource=vnf_detail_url % (ignorcase_get(kwargs, "vnfInstanceID")),
+            method='get',
+            content=json.JSONEncoder().encode(data))
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        resp = json.JSONDecoder().decode(ret[1])
+        vnf_status = ignorcase_get(resp, "vnfinstancestatus")
+        resp_data = {"vnfInfo": {"vnfStatus": vnf_status}}
+        logger.debug("[%s]resp_data=%s", fun_name(), resp_data)
+    except Exception as e:
+        logger.error("Error occurred when querying VNF information.")
+        raise e
+    return Response(data=resp_data, status=ret[2])
+
+
+# Get Operation Status
+operation_status_url = '/v1/jobs/{jobId}?NFVOID={nfvoId}&VNFMID={vnfmId}&ResponseID={responseId}'
+operation_status_resp_map = {
+    "JobId": "jobId",
+    "Status": "status",
+    "Progress": "progress",
+    "StatusDescription": "currentStep",
+    "ErrorCode": "errorCode",
+    "ResponseId": "responseId",
+    "ResponseHistoryList": "responseHistoryList",
+    "ResponseDescriptor": "responseDescriptor",}
+
+
+@api_view(http_method_names=['GET'])
+def operation_status(request, *args, **kwargs):
+    data = {}
+    try:
+        logger.debug("[%s] request.data=%s", fun_name(), request.data)
+        vnfm_id = ignorcase_get(kwargs, "vnfmid")
+        ret = vnfm_get(vnfm_id)
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        vnfm_info = json.JSONDecoder().decode(ret[1])
+        logger.debug("[%s] vnfm_info=%s", fun_name(), vnfm_info)
+        ret = restcall.call_req(
+            base_url=ignorcase_get(vnfm_info, 'url'),
+            user=ignorcase_get(vnfm_info, 'userName'),
+            passwd=ignorcase_get(vnfm_info, 'password'),
+            auth_type=restcall.rest_no_auth,
+            resource=operation_status_url.format(jobId=ignorcase_get(kwargs, 'jobid'), nfvoId=1,
+                                                 vnfmId=ignorcase_get(kwargs, 'vnfmid'),
+                                                 responseId=ignorcase_get(request.GET, 'responseId')),
+            method='get',
+            content=json.JSONEncoder().encode(data))
+
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        resp_data = json.JSONDecoder().decode(ret[1])
+        logger.info("[%s]resp_data=%s", fun_name(), resp_data)
+    except Exception as e:
+        logger.error("Error occurred when getting operation status information.")
+        raise e
+    return Response(data=resp_data, status=ret[2])
+
+
+# Grant VNF Lifecycle Operation
+grant_vnf_url = 'openoapi/nslcm/v1/ns/grantvnf'
+grant_vnf_param_map = {
+    "VNFMID": "",
+    "NFVOID": "",
+    "VIMID": "",
+    "ExVIMIDList": "",
+    "ExVIMID": "",
+    "Tenant": "",
+    "VNFInstanceID": "vnfInstanceId",
+    "OperationRight": "",
+    "VMList": "",
+    "VMFlavor": "",
+    "VMNumber": ""}
+
+
+@api_view(http_method_names=['PUT'])
+def grantvnf(request, *args, **kwargs):
+    logger.info("=====grantvnf=====")
+    try:
+        resp_data = {}
+        logger.info("req_data = %s", request.data)
+        data = mapping_conv(grant_vnf_param_map, request.data)
+        logger.info("grant_vnf_url = %s", grant_vnf_url)
+        data["vnfDescriptorId"] = ""
+        if ignorcase_get(request.data, "operationright") == 0:
+            data["lifecycleOperation"] = "Instantiate"
+            data["addresource"] = []
+            for vm in ignorcase_get(request.data, "vmlist"):
+                for i in range(int(ignorcase_get(vm, "vmnumber"))):
+                    data["addresource"].append(
+                        {"type": "vdu",
+                         "resourceDefinitionId": i,
+                         "vdu": ignorcase_get(vm, "vmflavor"),
+                         "vimid": ignorcase_get(vm, "vimid"),
+                         "tenant": ignorcase_get(vm, "tenant")
+                         })
+
+        data["additionalparam"] = {}
+        data["additionalparam"]["vnfmid"] = ignorcase_get(request.data, "vnfmid")
+        data["additionalparam"]["vimid"] = ignorcase_get(request.data, "vimid")
+        data["additionalparam"]["tenant"] = ignorcase_get(request.data, "tenant")
+
+        logger.info("data = %s", data)
+        ret = req_by_msb(grant_vnf_url, "POST", content=json.JSONEncoder().encode(data))
+        logger.info("ret = %s", ret)
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        resp = json.JSONDecoder().decode(ret[1])
+
+        resp_data['vimid'] = ignorcase_get(resp['vim'], 'vimid')
+        resp_data['tenant'] = ignorcase_get(ignorcase_get(resp['vim'], 'accessinfo'), 'tenant')
+
+        logger.info("[%s]resp_data=%s", fun_name(), resp_data)
+    except Exception as e:
+        logger.error("Error occurred in Grant VNF.")
+        raise e
+    return Response(data=resp_data, status=ret[2])
+
+
+# Notify LCM Events
+notify_url = 'openoapi/nslcm/v1/ns/{vnfmid}/vnfs/{vnfInstanceId}/Notify'
+notify_param_map = {
+    "NFVOID": "",
+    "VNFMID": "VNFMID",
+    "VIMID": "vimid",
+    "VNFInstanceID": "vnfInstanceId",
+    "TimeStamp": "",
+    "EventType": "operation",
+    "VMList": "",
+    "VMFlavor": "",
+    "VMNumber": "",
+    "VMIDlist": "",
+    "VMUUID": "",}
+
+
+@api_view(http_method_names=['POST'])
+def notify(request, *args, **kwargs):
+    try:
+        logger.info("[%s]req_data = %s", fun_name(), request.data)
+        data = mapping_conv(notify_param_map, request.data)
+        logger.info("[%s]data = %s", fun_name(), data)
+
+        data["status"] = "result"
+        data["jobId"] = "notMust"
+        data["affectedVnfc"] = []
+        data["affectedVl"] = []
+        data["affectedVirtualStorage"] = []
+        data["affectedCp"] = []
+
+        affectedvnfcs = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedvnfc")
+        affectedvls = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedvl")
+        affectedcps = ignorcase_get(ignorcase_get(request.data, "extension"), "affectedcp")
+        vnfdmodule = ignorcase_get(ignorcase_get(request.data, "extension"), "vnfdmodule")
+
+        data["vnfdmodule"] = vnfdmodule
+
+        for affectedvnfc in affectedvnfcs:
+            data["affectedVnfc"].append({
+                "vnfcInstanceId": ignorcase_get(affectedvnfc, "vnfcinstanceid"),
+                "vduId": ignorcase_get(affectedvnfc, "vduId"),
+                "changeType": ignorcase_get(affectedvnfc, "changeType"),
+                "vimid": ignorcase_get(ignorcase_get(affectedvnfc, "computeresource"), "vimid"),
+                "vmId": ignorcase_get(ignorcase_get(affectedvnfc, "computeresource"), "resourceid"),
+                "vmName": ignorcase_get(ignorcase_get(affectedvnfc, "computeresource"), "resourcename")
+            })
+
+        for affectedvl in affectedvls:
+            data["affectedVl"].append({
+                "vlInstanceId": ignorcase_get(affectedvl, "virtuallinkinstanceid"),
+                "vimid": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "vimid"),
+                "vldid": ignorcase_get(affectedvl, "virtuallinkdescid"),
+                "vllid": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "resourceid"),
+                "vlName": ignorcase_get(ignorcase_get(affectedvl, "networkresource"), "resourcename")
+            })
+
+        for affectedcp in affectedcps:
+            data["affectedCp"].append(affectedcp)
+            #     {
+            #     "virtualLinkInstanceId": ignorcase_get(affectedcp, "virtuallinkinstanceid"),
+            #     "ownerId": ignorcase_get(affectedcp, "ownerId"),
+            #     "ownerType": ignorcase_get(affectedcp, "ownerType")
+            # }
+        ret = req_by_msb(notify_url.format(vnfmid=ignorcase_get(data, 'VNFMID'),
+                                           vnfInstanceId=ignorcase_get(data, 'vnfinstanceid')),
+                         "POST", content=json.JSONEncoder().encode(data))
+
+        logger.info("[%s]data = %s", fun_name(), ret)
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+    except Exception as e:
+        logger.error("Error occurred in LCM notification.")
+        raise e
+    return Response(data=None, status=ret[2])
+
+
+nf_scaling_url = '/v1/vnfs/{vnfInstanceID}/scale'
+
+
+@api_view(http_method_names=['POST'])
+def scale(request, *args, **kwargs):
+    logger.info("====scale_vnf===")
+    try:
+        logger.info("request.data = %s", request.data)
+        logger.info("requested_url = %s", request.get_full_path())
+        vnfm_id = ignorcase_get(kwargs, "vnfmid")
+        nf_instance_id = ignorcase_get(kwargs, "nfInstanceId")
+        ret = vnfm_get(vnfm_id)
+        if ret[0] != 0:
+            return Response(data={'error': ret[1]}, status=ret[2])
+        vnfm_info = json.JSONDecoder().decode(ret[1])
+        scale_type = ignorcase_get(request.data, "type")
+        aspect_id = ignorcase_get(request.data, "aspectId")
+        number_of_steps = ignorcase_get(request.data, "numberOfSteps")
+        extension = ignorcase_get(request.data, "additionalParam")
+        vnfd_model = ignorcase_get(extension, "vnfdModel")
+        data = {
+            'vnfmid': vnfm_id,
+            'nfvoid': 1,
+            'scaletype': '0' if scale_type == 'SCALE_OUT' else '1',
+            'vmlist': [{'VMNumber':number_of_steps,'VMFlavor':aspect_id}],
+            'extension':''
+        }
+        '''
+        for vdu_id in get_vdus(vnfd_model, aspect_id):
+            data['vmlist'].append({
+                "VMFlavor": vdu_id,
+                "VMNumber": number_of_steps
+            })
+        '''
+        logger.info("data = %s", data)
+        ret = restcall.call_req(
+            base_url=ignorcase_get(vnfm_info, "url"),
+            user=ignorcase_get(vnfm_info, "userName"),
+            passwd=ignorcase_get(vnfm_info, "password"),
+            auth_type=restcall.rest_no_auth,
+            resource=nf_scaling_url.format(vnfInstanceID=nf_instance_id),
+            method='put',  # POST
+            content=json.JSONEncoder().encode(data))
+        logger.info("ret=%s", ret)
+        if ret[0] != 0:
+            return Response(data={'error':'scale error'}, status=ret[2])
+        resp_data = json.JSONDecoder().decode(ret[1])
+        jobId = resp_data["jobid"]
+        logger.info("resp_data=%s", resp_data)
+    except Exception as e:
+        logger.error("Error occurred when scaling VNF")
+        logger.error(traceback.format_exc())
+        return Response(data={'error':'scale expection'}, status='500')
+    return Response(data=resp_data, status=ret[2])
+
+
+#@staticmethod
+def get_vdus(nf_model, aspect_id):
+    associated_group = ''
+    members = []
+    vnf_flavours = nf_model['vnf_flavours']
+    for vnf_flaour in vnf_flavours:
+        scaling_aspects = vnf_flaour['scaling_aspects']
+        for aspect in scaling_aspects:
+            if aspect_id == aspect['id']:
+                associated_group = aspect['associated_group']
+                break
+    if not associated_group:
+        logger.error('Cannot find the corresponding element group')
+        raise Exception('Cannot find the corresponding element group')
+    for element_group in nf_model['element_groups']:
+        if element_group['group_id'] == associated_group:
+            members = element_group['members']
+    if not members:
+        logger.error('Cannot find the corresponding members')
+        raise Exception('Cannot find the corresponding members')
+    return members
+
+
+@api_view(http_method_names=['GET'])
+def samples(request, *args, **kwargs):
+    return Response(data={"status": "ok"})
diff --git a/zte/vmanager/driver/pub/__init__.py b/zte/vmanager/driver/pub/__init__.py
new file mode 100644 (file)
index 0000000..5580cc3
--- /dev/null
@@ -0,0 +1,13 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/zte/vmanager/driver/pub/config/__init__.py b/zte/vmanager/driver/pub/config/__init__.py
new file mode 100644 (file)
index 0000000..5580cc3
--- /dev/null
@@ -0,0 +1,13 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/zte/vmanager/driver/pub/config/config.py b/zte/vmanager/driver/pub/config/config.py
new file mode 100644 (file)
index 0000000..206e851
--- /dev/null
@@ -0,0 +1,33 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# [MSB]
+MSB_SERVICE_IP = '127.0.0.1'
+MSB_SERVICE_PORT = '80'
+
+# [register]
+REG_TO_MSB_WHEN_START = True
+REG_TO_MSB_REG_URL = "/openoapi/microservices/v1/services"
+REG_TO_MSB_REG_PARAM = {
+    "serviceName": "ztevmanagerdriver",
+    "version": "v1",
+    "url": "/openoapi/ztevmanagerdriver/v1",
+    "protocol": "REST",
+    "visualRange": "1",
+    "nodes": [{
+        "ip": "127.0.0.1",
+        "port": "8410",
+        "ttl": 0
+    }]
+}
diff --git a/zte/vmanager/driver/pub/database/__init__.py b/zte/vmanager/driver/pub/database/__init__.py
new file mode 100644 (file)
index 0000000..5580cc3
--- /dev/null
@@ -0,0 +1,13 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/zte/vmanager/driver/pub/database/models.py b/zte/vmanager/driver/pub/database/models.py
new file mode 100644 (file)
index 0000000..5580cc3
--- /dev/null
@@ -0,0 +1,13 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/zte/vmanager/driver/pub/utils/__init__.py b/zte/vmanager/driver/pub/utils/__init__.py
new file mode 100644 (file)
index 0000000..5580cc3
--- /dev/null
@@ -0,0 +1,13 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/zte/vmanager/driver/pub/utils/restcall.py b/zte/vmanager/driver/pub/utils/restcall.py
new file mode 100644 (file)
index 0000000..ffde14d
--- /dev/null
@@ -0,0 +1,95 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import sys
+import traceback
+import logging
+import urllib2
+import uuid
+import httplib2
+
+from driver.pub.config.config import MSB_SERVICE_IP, MSB_SERVICE_PORT
+
+rest_no_auth, rest_oneway_auth, rest_bothway_auth = 0, 1, 2
+HTTP_200_OK, HTTP_201_CREATED, HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED = '200', '201', '204', '202'
+status_ok_list = [HTTP_200_OK, HTTP_201_CREATED, HTTP_204_NO_CONTENT, HTTP_202_ACCEPTED]
+HTTP_404_NOTFOUND, HTTP_403_FORBIDDEN, HTTP_401_UNAUTHORIZED, HTTP_400_BADREQUEST = '404', '403', '401', '400'
+
+logger = logging.getLogger(__name__)
+
+
+def call_req(base_url, user, passwd, auth_type, resource, method, content=''):
+    callid = str(uuid.uuid1())
+    logger.debug("[%s]call_req('%s','%s','%s',%s,'%s','%s','%s')" % (
+        callid, base_url, user, passwd, auth_type, resource, method, content))
+    ret = None
+    resp_status = ''
+    try:
+        full_url = combine_url(base_url, resource)
+        headers = {'content-type': 'application/json', 'accept': 'application/json'}
+        if user:
+            headers['Authorization'] = 'Basic ' + ('%s:%s' % (user, passwd)).encode("base64")
+        ca_certs = None
+        for retry_times in range(3):
+            http = httplib2.Http(ca_certs=ca_certs, disable_ssl_certificate_validation=(auth_type == rest_no_auth))
+            http.follow_all_redirects = True
+            try:
+                resp, resp_content = http.request(full_url, method=method.upper(), body=content, headers=headers)
+                resp_status, resp_body = resp['status'], resp_content.decode('UTF-8')
+                logger.debug("[%s][%d]status=%s,resp_body=%s)" % (callid, retry_times, resp_status, resp_body))
+                if resp_status in status_ok_list:
+                    ret = [0, resp_body, resp_status]
+                else:
+                    ret = [1, resp_body, resp_status]
+                break
+            except Exception as ex:
+                if 'httplib.ResponseNotReady' in str(sys.exc_info()):
+                    logger.debug("retry_times=%d", retry_times)
+                    logger.error(traceback.format_exc())
+                    ret = [1, "Unable to connect to %s" % full_url, resp_status]
+                    continue
+                raise ex
+    except urllib2.URLError as err:
+        ret = [2, str(err), resp_status]
+    except Exception as ex:
+        logger.error(traceback.format_exc())
+        logger.error("[%s]ret=%s" % (callid, str(sys.exc_info())))
+        res_info = str(sys.exc_info())
+        if 'httplib.ResponseNotReady' in res_info:
+            res_info = "The URL[%s] request failed or is not responding." % full_url
+        ret = [3, res_info, resp_status]
+    except:
+        logger.error(traceback.format_exc())
+        ret = [4, str(sys.exc_info()), resp_status]
+
+    logger.debug("[%s]ret=%s" % (callid, str(ret)))
+    return ret
+
+
+def req_by_msb(resource, method, content=''):
+    base_url = "http://%s:%s/" % (MSB_SERVICE_IP, MSB_SERVICE_PORT)
+    return call_req(base_url, "", "", rest_no_auth, resource, method, content)
+
+
+def combine_url(base_url, resource):
+    full_url = None
+    if base_url.endswith('/') and resource.startswith('/'):
+        full_url = base_url[:-1] + resource
+    elif base_url.endswith('/') and not resource.startswith('/'):
+        full_url = base_url + resource
+    elif not base_url.endswith('/') and resource.startswith('/'):
+        full_url = base_url + resource
+    else:
+        full_url = base_url + '/' + resource
+    return full_url
diff --git a/zte/vmanager/driver/settings.py b/zte/vmanager/driver/settings.py
new file mode 100644 (file)
index 0000000..8fec618
--- /dev/null
@@ -0,0 +1,124 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+
+import sys
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.9/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = '3o-wney!99y)^h3v)0$j16l9=fdjxcb+a8g+q3tfbahcnu2b0o'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.messages',
+    'django.contrib.staticfiles',
+    'rest_framework',
+    'driver.pub.database',
+    'driver.interfaces'
+ ]
+
+MIDDLEWARE_CLASSES = [
+    'django.middleware.security.SecurityMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.common.CommonMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+    'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ ]
+
+ROOT_URLCONF = 'driver.urls'
+
+WSGI_APPLICATION = 'driver.wsgi.application'
+
+
+REST_FRAMEWORK = {
+    'DEFAULT_RENDERER_CLASSES': (
+        'rest_framework.renderers.JSONRenderer',),
+
+    'DEFAULT_PARSER_CLASSES': (
+        'rest_framework.parsers.MultiPartParser',
+        'rest_framework.parsers.JSONParser')}
+"""
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.mysql',
+        'NAME': 'vmanager',
+        'HOST': 'localhost',
+        'USER': 'root',
+        'PASSWORD':'password',
+    },
+}
+
+redis_client = redis.StrictRedis(host='127.0.0.1', port=6379, password='', db=1)
+"""
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3',
+        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }}
+
+TIME_ZONE = 'UTC'
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.6/howto/static-files/
+
+STATIC_URL = '/static/'
+
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': True,
+    'formatters': {
+        'standard': {
+            'format': '%(asctime)s:[%(name)s]:[%(filename)s]-[%(lineno)d] [%(levelname)s]:%(message)s', }, },
+    'filters': {},
+    'handlers': {
+        'driver_handler': {
+            'level': 'DEBUG',
+            'class': 'logging.handlers.RotatingFileHandler',
+            'filename': os.path.join(BASE_DIR, 'logs/runtime_driver.log'),
+            'formatter': 'standard',
+            'maxBytes': 1024 * 1024 * 50,
+            'backupCount': 5, }, },
+
+    'loggers': {
+        'driver': {
+            'handlers': ['driver_handler'],
+            'level': 'DEBUG',
+            'propagate': False}, }}
+
+if 'test' in sys.argv:
+    import platform
+    if platform.system() == 'Linux':
+        TEST_RUNNER = 'xmlrunner.extra.djangotestrunner.XMLTestRunner'
+        TEST_OUTPUT_VERBOSE = True
+        TEST_OUTPUT_DESCRIPTIONS = True
+        TEST_OUTPUT_DIR = 'test-reports'
diff --git a/zte/vmanager/driver/swagger/__init__.py b/zte/vmanager/driver/swagger/__init__.py
new file mode 100644 (file)
index 0000000..c7b6818
--- /dev/null
@@ -0,0 +1,13 @@
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/zte/vmanager/driver/swagger/swagger.json b/zte/vmanager/driver/swagger/swagger.json
new file mode 100644 (file)
index 0000000..c15aa31
--- /dev/null
@@ -0,0 +1,545 @@
+{
+  "swagger": "2.0",
+  "info": {
+    "version": "1.0.0",
+    "title": "ZTE VNFM Driver Service rest API"
+  },
+  "basePath": "/openoapi/{vnfmtype}/v1",
+  "tags": [
+    {
+      "name": "ztevmanagerdriver"
+    }
+  ],
+  "paths": {
+    "/{vnfmid}/vnfs": {
+      "post": {
+        "tags": [
+          "vnf instantiate"
+        ],
+        "summary": "instantiate the vnf",
+        "description": "",
+        "operationId": "instantiate_vnf",
+        "consumes": [
+          "application/json"
+        ],
+        "produces": [
+          "application/json"
+        ],
+        "parameters": [
+          {
+            "name": "vnfmid",
+            "in": "path",
+            "description": "vnfm instance id",
+            "required": true,
+            "type": "string"
+          },
+          {
+            "name": "body",
+            "in": "body",
+            "description": "request parameters",
+            "required": true,
+            "schema": {
+              "$ref": "#/definitions/VnfRequestParams"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "successful operation",
+            "schema": {
+              "$ref": "#/definitions/VnfResult"
+            }
+          },
+          "404": {
+            "description": "the vnfm instance id is wrong"
+          },
+          "500": {
+            "description": "the url is invalid"
+          }
+        }
+      }
+    },
+    "/{vnfmid}/vnfs/{vnfInstanceId}/terminate": {
+      "post": {
+        "tags": [
+          "vnf terminate"
+        ],
+        "summary": "terminate the vnf",
+        "description": "",
+        "operationId": "terminate_vnf",
+        "consumes": [
+          "application/json"
+        ],
+        "produces": [
+          "application/json"
+        ],
+        "parameters": [
+          {
+            "name": "vnfmid",
+            "in": "path",
+            "description": "vnfm instance id",
+            "required": true,
+            "type": "string"
+          },
+          {
+            "name": "vnfInstanceId",
+            "in": "path",
+            "description": "vnf instance id",
+            "required": true,
+            "type": "string"
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "successful operation",
+            "schema": {
+              "$ref": "#/definitions/VnfResult"
+            }
+          },
+          "404": {
+            "description": "the vnfmid and vnfInstanceId  are wrong"
+          },
+          "500": {
+            "description": "the url is invalid"
+          }
+        }
+      }
+    },
+    "/{vnfmid}/vnfs/{vnfInstanceId}": {
+      "get": {
+        "tags": [
+          "query vnf"
+        ],
+        "summary": "query the vnf",
+        "description": "",
+        "operationId": "query_vnf",
+        "consumes": [
+          "application/json"
+        ],
+        "produces": [
+          "application/json"
+        ],
+        "parameters": [
+          {
+            "name": "vnfmid",
+            "in": "path",
+            "description": "vnfm instance id",
+            "required": true,
+            "type": "string"
+          },
+          {
+            "name": "vnfInstanceId",
+            "in": "path",
+            "description": "vnf instance id",
+            "required": true,
+            "type": "string"
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "successful operation",
+            "schema": {
+              "$ref": "#/definitions/returnVnfInfo"
+            }
+          },
+          "404": {
+            "description": "the vnfmid and vnfInstanceId  are wrong"
+          },
+          "500": {
+            "description": "the url is invalid"
+          }
+        }
+      }
+    },
+    "/{vnfmid}/jobs/{jobid}": {
+      "get": {
+        "tags": [
+          "operation status"
+        ],
+        "summary": "operation status",
+        "description": "",
+        "operationId": "operation_status",
+        "consumes": [
+          "application/json"
+        ],
+        "produces": [
+          "application/json"
+        ],
+        "parameters": [
+          {
+            "name": "vnfmid",
+            "in": "path",
+            "description": "vnfm instance id",
+            "required": true,
+            "type": "string"
+          },
+          {
+            "name": "jobid",
+            "in": "path",
+            "description": "vnf job id",
+            "required": true,
+            "type": "string"
+          },
+          {
+            "name": "responseId",
+            "in": "path",
+            "description": "vnf response id",
+            "required": true,
+            "type": "integer"
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "successful operation",
+            "schema": {
+              "$ref": "#/definitions/OperationStatusInfo"
+            }
+          },
+          "404": {
+            "description": "the vnfmid ,jobid and responseId are wrong"
+          },
+          "500": {
+            "description": "the url is invalid"
+          }
+        }
+      }
+    },
+    "/resource/grant": {
+      "put": {
+        "tags": [
+          "grant vnf"
+        ],
+        "summary": "grant the vnf",
+        "description": "",
+        "operationId": "grant_vnf",
+        "consumes": [
+          "application/json"
+        ],
+        "produces": [
+          "application/json"
+        ],
+        "parameters": [
+          {
+            "name": "body",
+            "in": "body",
+            "description": "request data for grant the vnf",
+            "required": true,
+            "schema": {
+              "$ref": "#/definitions/RequestGrantParams"
+            }
+          }
+        ],
+        "responses": {
+          "201": {
+            "description": "successful grant",
+            "schema": {
+              "$ref": "#/definitions/responseGrantResult"
+            }
+          },
+          "404": {
+            "description": "the request body is wrong"
+          },
+          "500": {
+            "description": "the url is invalid"
+          }
+        }
+      }
+    },
+    "/vnfs/lifecyclechangesnotification": {
+      "post": {
+        "tags": [
+          "life cycle changes notification"
+        ],
+        "summary": "life cycle changes notification",
+        "description": "",
+        "operationId": "lifecyclechangesnotification",
+        "consumes": [
+          "application/json"
+        ],
+        "produces": [
+          "application/json"
+        ],
+        "parameters": [
+          {
+            "name": "body",
+            "in": "body",
+            "description": "request data for grant the vnf",
+            "required": true,
+            "schema": {
+              "$ref": "#/definitions/RequestNotifyParams"
+            }
+          }
+        ],
+        "responses": {
+          "201": {
+            "description": "successful Notify",
+            "schema": {
+              "$ref": "#/definitions/ResponseNotifyResult"
+            }
+          },
+          "404": {
+            "description": "the request body is wrong"
+          },
+          "500": {
+            "description": "the url is invalid"
+          }
+        }
+      }
+    },
+    "/{vnfmid}/vnfs/{nfInstanceId}/scale": {
+      "post": {
+        "tags": [
+          "scale vnf"
+        ],
+        "summary": "scale vnf",
+        "description": "",
+        "operationId": "scale_vnf",
+        "consumes": [
+          "application/json"
+        ],
+        "produces": [
+          "application/json"
+        ],
+        "parameters": [
+          {
+            "name": "vnfmid",
+            "in": "path",
+            "description": "vnfm instance id",
+            "required": true,
+            "type": "string"
+          },
+          {
+            "name": "nfInstanceId",
+            "in": "path",
+            "description": "nf instance id",
+            "required": true,
+            "type": "string"
+          },
+          {
+            "name": "body",
+            "in": "body",
+            "description": "request data for grant the vnf",
+            "required": true,
+            "schema": {
+              "$ref": "#/definitions/RequestScaleParams"
+            }
+          }
+        ],
+        "responses": {
+          "201": {
+            "description": "successful scale",
+            "schema": {
+              "$ref": "#/definitions/ResponseScaleResult"
+            }
+          },
+          "404": {
+            "description": "the request body is wrong"
+          },
+          "500": {
+            "description": "the url is invalid"
+          }
+        }
+      }
+    }
+  },
+  "definitions": {
+    "VnfRequestParams": {
+      "type": "object",
+      "properties": {
+        "vnfInstanceName": {
+          "type": "string"
+        },
+        "vnfPackageId": {
+          "type": "string"
+        },
+        "vnfDescriptorId": {
+          "type": "string"
+        },
+        "additionalParam": {
+          "type": "object",
+          "properties": {
+            "sdncontroller": {
+              "type": "string"
+            },
+            "NatIpRange": {
+              "type": "string"
+            },
+            "m6000_mng_ip": {
+              "type": "string"
+            },
+            "externalPluginManageNetworkName": {
+              "type": "string"
+            },
+            "location": {
+              "type": "string"
+            },
+            "externalManageNetworkName": {
+              "type": "string"
+            },
+            "sfc_data_network": {
+              "type": "string"
+            },
+            "externalDataNetworkName": {
+              "type": "string"
+            },
+            "inputs": {
+              "type": "object"
+            }
+          }
+        }
+      }
+    },
+    "VnfResult": {
+      "type": "object",
+      "properties": {
+        "vnfInstanceId": {
+          "type": "string"
+        },
+        "jobid": {
+          "type": "string"
+        }
+      }
+    },
+    "returnVnfInfo": {
+      "type": "object",
+      "properties": {
+        "vnfInfo": {
+          "type": "object",
+          "properties": {
+            "vnfStatus": {
+              "type": "string"
+            }
+          }
+        }
+      }
+    },
+    "OperationStatusInfo": {
+      "type": "object",
+      "properties": {
+        "responsedescriptor": {
+          "type": "object",
+          "properties": {
+            "status": {
+              "type": "string"
+            },
+            "responsehistorylist": {
+              "type": "string"
+            },
+            "responseid": {
+              "type": "integer"
+            },
+            "errorcode": {
+              "type": "string"
+            },
+            "progress": {
+              "type": "integer"
+            },
+            "statusdescription": {
+              "type": "string"
+            }
+          }
+        },
+        "jobid": {
+          "type": "string"
+        }
+      }
+    },
+    "RequestGrantParams": {
+      "type": "object",
+      "properties": {
+        "vnfmid": {
+          "type": "string"
+        },
+        "nfvoid": {
+          "type": "string"
+        },
+        "vimid": {
+          "type": "string"
+        },
+        "exvimidlist": {
+          "type": "string"
+        },
+        "tenant": {
+          "type": "string"
+        },
+        "vnfistanceid": {
+          "type": "string"
+        },
+        "operationright": {
+          "type": "string"
+        },
+        "vmlist": {
+          "type": "string"
+        }
+      }
+    },
+    "responseGrantResult": {
+      "type": "object",
+      "properties": {
+        "vimid": {
+          "type": "string"
+        },
+        "tenant": {
+          "type": "string"
+        }
+      }
+    },
+    "RequestNotifyParams": {
+      "type": "object",
+      "properties": {
+        "nfvoid": {
+          "type": "string"
+        },
+        "vnfmid": {
+          "type": "string"
+        },
+        "vimid": {
+          "type": "string"
+        },
+        "timestamp": {
+          "type": "string"
+        },
+        "vnfinstanceid": {
+          "type": "string"
+        },
+        "eventtype": {
+          "type": "string"
+        },
+        "vmlist": {
+          "type": "string"
+        }
+      }
+    },
+    "ResponseNotifyResult": {
+      "type": "object"
+    },
+    "RequestScaleParams": {
+      "type": "object",
+      "properties": {
+        "type": {
+          "type": "string"
+        },
+        "aspectId": {
+          "type": "string"
+        },
+        "numberOfSteps": {
+          "type": "string"
+        },
+        "additionalParam": {
+          "type": "object"
+        }
+      }
+    },
+    "ResponseScaleResult": {
+      "type": "object",
+      "properties": {
+        "jobid": {
+          "type": "string"
+        },
+        "nfInstanceId": {
+          "type": "string"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/zte/vmanager/driver/swagger/tests.py b/zte/vmanager/driver/swagger/tests.py
new file mode 100644 (file)
index 0000000..2bc8f8c
--- /dev/null
@@ -0,0 +1,31 @@
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+import json
+from django.test import Client
+from rest_framework import status
+
+
+class SwaggerViewTest(unittest.TestCase):
+    def setUp(self):
+        self.client = Client()
+
+    def tearDown(self):
+        pass
+
+    def test_sample(self):
+        response = self.client.get("/openoapi/ztevmanagerdriver/v1/swagger.json")
+        self.assertEqual(status.HTTP_200_OK, response.status_code, response.content)
+
diff --git a/zte/vmanager/driver/swagger/urls.py b/zte/vmanager/driver/swagger/urls.py
new file mode 100644 (file)
index 0000000..4837870
--- /dev/null
@@ -0,0 +1,20 @@
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from django.conf.urls import url
+from driver.swagger import views
+
+urlpatterns = [
+    url(r'^openoapi/ztevmanagerdriver/v1/swagger.json$', views.SwaggerView.as_view()), 
+]
diff --git a/zte/vmanager/driver/swagger/views.py b/zte/vmanager/driver/swagger/views.py
new file mode 100644 (file)
index 0000000..e9c9604
--- /dev/null
@@ -0,0 +1,29 @@
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import os
+import json
+from rest_framework.views import APIView
+from rest_framework.response import Response
+
+
+class SwaggerView(APIView):
+    """
+    Show rest api swagger.
+    """
+    def get(self, request, format=None):
+        json_file = os.path.join(os.path.dirname(__file__), 'swagger.json')
+        f = open(json_file)
+        json_data = json.JSONDecoder().decode(f.read())
+        f.close()
+        return Response(json_data)
diff --git a/zte/vmanager/driver/urls.py b/zte/vmanager/driver/urls.py
new file mode 100644 (file)
index 0000000..94164d1
--- /dev/null
@@ -0,0 +1,26 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from driver.pub.config.config import REG_TO_MSB_WHEN_START, REG_TO_MSB_REG_URL, REG_TO_MSB_REG_PARAM
+from django.conf.urls import include, url
+urlpatterns = [
+    url(r'^', include('driver.interfaces.urls')), 
+    url(r'^', include('driver.swagger.urls')), 
+]
+
+# regist to MSB when startup
+if REG_TO_MSB_WHEN_START:
+    import json
+    from driver.pub.utils.restcall import req_by_msb
+    req_by_msb(REG_TO_MSB_REG_URL, "POST", json.JSONEncoder().encode(REG_TO_MSB_REG_PARAM))
diff --git a/zte/vmanager/driver/wsgi.py b/zte/vmanager/driver/wsgi.py
new file mode 100644 (file)
index 0000000..68fc46c
--- /dev/null
@@ -0,0 +1,22 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import os
+
+from django.core.wsgi import get_wsgi_application
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "driver.settings")
+
+application = get_wsgi_application()
diff --git a/zte/vmanager/initialize.sh b/zte/vmanager/initialize.sh
new file mode 100644 (file)
index 0000000..8f6a000
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+pip install -r requirements.txt
diff --git a/zte/vmanager/logs/empty.txt b/zte/vmanager/logs/empty.txt
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/zte/vmanager/manage.py b/zte/vmanager/manage.py
new file mode 100644 (file)
index 0000000..401f800
--- /dev/null
@@ -0,0 +1,23 @@
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import sys
+
+os.environ.setdefault("DJANGO_SETTINGS_MODULE", "driver.settings")
+
+# load initial configuration
+if __name__ == "__main__":
+    from django.core.management import execute_from_command_line
+    execute_from_command_line(sys.argv)
diff --git a/zte/vmanager/pom.xml b/zte/vmanager/pom.xml
new file mode 100644 (file)
index 0000000..b61939c
--- /dev/null
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<!--
+    Copyright 2016 ZTE Corporation.
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+            http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.openo.nfvo</groupId>
+        <artifactId>nfvo-root</artifactId>
+        <version>1.1.0-SNAPSHOT</version>
+        <relativePath>../../../../../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.openo.nfvo</groupId>
+    <artifactId>drivers-vnfm-svnfm-zte-vmanager</artifactId>
+    <version>1.1.0-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>nfvo/drivers/vnfm/svnfm/zte/vmanager</name>
+    <description>nfvo drivers-vnfm-svnfm-zte-vmanager</description>
+    <build>
+      <plugins>
+        <plugin>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <configuration>
+                <appendAssemblyId>false</appendAssemblyId>
+                <descriptors>
+                    <descriptor>assembly.xml</descriptor>
+                </descriptors>
+            </configuration>
+            <executions>
+                <execution>
+                    <id>make-assembly</id>
+                    <phase>package</phase>
+                    <goals>
+                        <goal>single</goal>
+                    </goals>
+                </execution>
+            </executions>
+        </plugin>
+      </plugins>
+    </build>
+</project>
diff --git a/zte/vmanager/requirements.txt b/zte/vmanager/requirements.txt
new file mode 100644 (file)
index 0000000..49f0e42
--- /dev/null
@@ -0,0 +1,11 @@
+# rest framework
+Django==1.9.6
+djangorestframework==3.3.3
+
+# for call rest api
+httplib2==0.9.2
+
+# for unit test
+coverage==4.2
+mock==2.0.0
+unittest_xml_reporting==1.12.0
diff --git a/zte/vmanager/run.sh b/zte/vmanager/run.sh
new file mode 100644 (file)
index 0000000..8c0b4fa
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+sip=127.0.0.1
+nohup python manage.py runserver $sip:8410 > /dev/null &
diff --git a/zte/vmanager/stop.sh b/zte/vmanager/stop.sh
new file mode 100644 (file)
index 0000000..528da95
--- /dev/null
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+sip=127.0.0.1
+ps auxww | grep "manage.py runserver $sip:8410" | awk '{print $2}' | xargs kill -9
diff --git a/zte/vmanager/tox.ini b/zte/vmanager/tox.ini
new file mode 100644 (file)
index 0000000..4e62baf
--- /dev/null
@@ -0,0 +1,7 @@
+[tox]
+envlist = py27
+skipsdist = true
+[testenv]
+deps = -r{toxinidir}/requirements.txt
+commands = coverage run --branch manage.py test