summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFu Jinhua <fu.jinhua@zte.com.cn>2017-08-16 07:55:16 +0000
committerGerrit Code Review <gerrit@onap.org>2017-08-16 07:55:16 +0000
commitfb4160ad891151d0fbb15cdf887905f06b875009 (patch)
tree14f16e01790e27c8498c1e0445b15e42eafd8664
parent3149f448e1f439e4ca71dd4c4bf9da2aeb443374 (diff)
parent8068f1ca2ce4fba8e6ffd9085e799eb0a78b72f1 (diff)
Merge "Add ns distribute logic"
-rw-r--r--lcm/packages/sdc_ns_package.py88
-rw-r--r--lcm/packages/tests/test_sdc_ns.py417
2 files changed, 480 insertions, 25 deletions
diff --git a/lcm/packages/sdc_ns_package.py b/lcm/packages/sdc_ns_package.py
index aff5c89f..872f7005 100644
--- a/lcm/packages/sdc_ns_package.py
+++ b/lcm/packages/sdc_ns_package.py
@@ -17,11 +17,15 @@ import logging
import traceback
import sys
+import os
-from lcm.pub.database.models import NSDModel, NSInstModel
+from lcm.pub.database.models import NSDModel, NSInstModel, NfPackageModel
from lcm.pub.utils.values import ignore_case_get
from lcm.pub.exceptions import NSLCMException
from lcm.pub.msapi import sdc
+from lcm.pub.config.config import CATALOG_ROOT_PATH
+from lcm.pub.utils import toscaparser
+from lcm.pub.utils import fileutil
logger = logging.getLogger(__name__)
@@ -32,30 +36,41 @@ def fmt_ns_pkg_rsp(status, desc, error_code="500"):
return [0, {"status": status, "statusDescription": desc, "errorCode": error_code}]
-def ns_common_call(fun, csar_id, operation=""):
+def ns_on_distribute(csar_id):
ret = None
try:
- if operation == "":
- ret = fun(csar_id)
- else:
- ret = fun(csar_id, operation)
-
- if ret[0] != 0:
- return fmt_ns_pkg_rsp(STATUS_FAILED, ret[1])
+ ret = SdcNsPackage().on_distribute(csar_id)
except NSLCMException as e:
+ SdcNsPackage().delete_catalog(csar_id)
return fmt_ns_pkg_rsp(STATUS_FAILED, e.message)
except:
logger.error(traceback.format_exc())
+ SdcNsPackage().delete_catalog(csar_id)
return fmt_ns_pkg_rsp(STATUS_FAILED, str(sys.exc_info()))
return fmt_ns_pkg_rsp(STATUS_SUCCESS, ret[1], "")
-def ns_on_distribute(csar_id):
- return ns_common_call(SdcNsPackage().on_distribute, csar_id)
+def ns_delete_csar(csar_id, force_delete):
+ ret = None
+ try:
+ ret = SdcNsPackage().delete_csar(csar_id, force_delete)
+ except NSLCMException as e:
+ return fmt_ns_pkg_rsp(STATUS_FAILED, e.message)
+ except:
+ logger.error(traceback.format_exc())
+ return fmt_ns_pkg_rsp(STATUS_FAILED, str(sys.exc_info()))
+ return fmt_ns_pkg_rsp(STATUS_SUCCESS, ret[1], "")
-def ns_delete_csar(csar_id):
- return ns_common_call(SdcNsPackage().delete_csar, csar_id)
-
+def ns_get_csars():
+ ret = None
+ try:
+ ret = SdcNsPackage().get_csars()
+ except NSLCMException as e:
+ return [1, e.message]
+ except:
+ logger.error(traceback.format_exc())
+ return [1, str(sys.exc_info())]
+ return ret
def ns_get_csar(csar_id):
ret = None
@@ -82,18 +97,36 @@ class SdcNsPackage(object):
def on_distribute(self, csar_id):
if NSDModel.objects.filter(id=csar_id):
raise NSLCMException("NS CSAR(%s) already exists." % csar_id)
+
artifact = sdc.get_artifact(sdc.ASSETTYPE_SERVICES, csar_id)
- download_artifacts(artifact["toscaModelURL"], "TODO:Local Path")
+ local_path = os.path.join(CATALOG_ROOT_PATH, csar_id)
+ local_file_name = sdc.download_artifacts(artifact["toscaModelURL"], local_path)
+
+ nsd_json = toscaparser.parse_nsd(local_file_name)
+ nsd = json.JSONDecoder().decode(nsd_json)
+
+ nsd_id = nsd["metadata"]["id"]
+ if NSDModel.objects.filter(nsd_id=nsd_id):
+ raise NSLCMException("NSD(%s) already exists." % nsd_id)
+
+ for vnf in nsd["vnfs"]:
+ vnfd_id = vnf["properties"]["id"]
+ pkg = NfPackageModel.objects.filter(vnfdid=vnfd_id)
+ if not pkg:
+ raise NSLCMException("VNF package(%s) is not distributed." % vnfd_id)
NSDModel(
id=csar_id,
- nsd_id="TODO",
- name="TODO",
- vendor="TODO",
- description="TODO",
- version="TODO",
- nsd_model="TODO",
- nsd_path="TODO").save()
+ nsd_id=nsd_id,
+ name=nsd["metadata"].get("name", nsd_id),
+ vendor=nsd["metadata"].get("vendor", "undefined"),
+ description=nsd["metadata"].get("description", ""),
+ version=nsd["metadata"].get("version", "undefined"),
+ nsd_path=local_file_name,
+ nsd_model=nsd_json).save()
+
+ return [0, "CSAR(%s) distributed successfully." % csar_id]
+
def delete_csar(self, csar_id, force_delete):
if force_delete:
@@ -105,14 +138,14 @@ class SdcNsPackage(object):
def get_csars(self):
- ret = {"csars": []}
+ csars = {"csars": []}
nss = NSDModel.objects.filter()
for ns in nss:
- ret["csars"].append({
+ csars["csars"].append({
"csarId": ns.id,
"nsdId": ns.nsd_id
})
- return ret
+ return [0, csars]
def get_csar(self, csar_id):
package_info = {}
@@ -131,5 +164,10 @@ class SdcNsPackage(object):
"packageInfo": package_info,
"nsInstanceInfo": ns_instance_info}]
+ def delete_catalog(self, csar_id):
+ local_path = os.path.join(CATALOG_ROOT_PATH, csar_id)
+ fileutil.delete_dirs(local_path)
+
+
\ No newline at end of file
diff --git a/lcm/packages/tests/test_sdc_ns.py b/lcm/packages/tests/test_sdc_ns.py
index c7b6818e..6f9c52d2 100644
--- a/lcm/packages/tests/test_sdc_ns.py
+++ b/lcm/packages/tests/test_sdc_ns.py
@@ -11,3 +11,420 @@
# 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 rest_framework import status
+from django.test import TestCase
+from django.test import Client
+
+from lcm.pub.utils import restcall
+from lcm.pub.database.models import NSDModel, NSInstModel, NfPackageModel
+
+
+class TestSdcNsPackage(TestCase):
+ def setUp(self):
+ self.client = Client()
+ NSDModel.objects.filter().delete()
+ NSInstModel.objects.filter().delete()
+ NfPackageModel.objects.filter().delete()
+ self.nsd_data = {
+ "vnffgs": [
+ {
+ "vnffg_id": "vnffg1",
+ "description": "",
+ "members": [
+ "path1",
+ "path2"
+ ],
+ "properties": {
+ "vendor": "zte",
+ "connection_point": [
+ "m6000_data_in",
+ "m600_tunnel_cp",
+ "m6000_data_out"
+ ],
+ "version": "1.0",
+ "constituent_vnfs": [
+ "VFW",
+ "VNAT"
+ ],
+ "number_of_endpoints": 3,
+ "dependent_virtual_link": [
+ "sfc_data_network",
+ "ext_datanet_net",
+ "ext_mnet_net"
+ ]
+ }
+ }
+ ],
+ "inputs": {
+ "sfc_data_network": {
+ "type": "string",
+ "value": "sfc_data_network"
+ },
+ "externalDataNetworkName": {
+ "type": "string",
+ "value": "vlan_4004_tunnel_net"
+ },
+ "externalManageNetworkName": {
+ "type": "string",
+ "value": "vlan_4008_mng_net"
+ },
+ "NatIpRange": {
+ "type": "string",
+ "value": "192.167.0.10-192.168.0.20"
+ },
+ "externalPluginManageNetworkName": {
+ "type": "string",
+ "value": "vlan_4007_plugin_net"
+ }
+ },
+ "pnfs": [
+ {
+ "pnf_id": "m6000_s",
+ "cps": [],
+ "description": "",
+ "properties": {
+ "vendor": "zte",
+ "request_reclassification": False ,
+ "pnf_type": "m6000s",
+ "version": "1.0",
+ "management_address": "111111",
+ "id": "m6000_s",
+ "nsh_aware": False
+ }
+ }
+ ],
+ "fps": [
+ {
+ "properties": {
+ "symmetric": False ,
+ "policy": {
+ "type": "ACL",
+ "criteria": {
+ "dest_port_range": "1-100",
+ "ip_protocol": "tcp",
+ "source_ip_range": [
+ "119.1.1.1-119.1.1.10"
+ ],
+ "dest_ip_range": [
+ {
+ "get_input": "NatIpRange"
+ }
+ ],
+ "dscp": 0,
+ "source_port_range": "1-100"
+ }
+ }
+ },
+ "forwarder_list": [
+ {
+ "capability": "",
+ "type": "cp",
+ "node_name": "m6000_data_out"
+ },
+ {
+ "capability": "",
+ "type": "cp",
+ "node_name": "m600_tunnel_cp"
+ },
+ {
+ "capability": "vnat_fw_inout",
+ "type": "vnf",
+ "node_name": "VNAT"
+ }
+ ],
+ "description": "",
+ "fp_id": "path2"
+ },
+ {
+ "properties": {
+ "symmetric": True,
+ "policy": {
+ "type": "ACL",
+ "criteria": {
+ "dest_port_range": "1-100",
+ "ip_protocol": "tcp",
+ "source_ip_range": [
+ "1-100"
+ ],
+ "dest_ip_range": [
+ "1-100"
+ ],
+ "dscp": 4,
+ "source_port_range": "1-100"
+ }
+ }
+ },
+ "forwarder_list": [
+ {
+ "capability": "",
+ "type": "cp",
+ "node_name": "m6000_data_in"
+ },
+ {
+ "capability": "",
+ "type": "cp",
+ "node_name": "m600_tunnel_cp"
+ },
+ {
+ "capability": "vfw_fw_inout",
+ "type": "vnf",
+ "node_name": "VFW"
+ },
+ {
+ "capability": "vnat_fw_inout",
+ "type": "vnf",
+ "node_name": "VNAT"
+ },
+ {
+ "capability": "",
+ "type": "cp",
+ "node_name": "m600_tunnel_cp"
+ },
+ {
+ "capability": "",
+ "type": "cp",
+ "node_name": "m6000_data_out"
+ }
+ ],
+ "description": "",
+ "fp_id": "path1"
+ }
+ ],
+ "routers": [],
+ "vnfs": [
+ {
+ "vnf_id": "VFW",
+ "description": "",
+ "properties": {
+ "plugin_info": "vbrasplugin_1.0",
+ "vendor": "zte",
+ "is_shared": False ,
+ "adjust_vnf_capacity": True,
+ "name": "VFW",
+ "vnf_extend_type": "driver",
+ "csarVersion": "v1.0",
+ "csarType": "NFAR",
+ "csarProvider": "ZTE",
+ "version": "1.0",
+ "nsh_aware": True,
+ "cross_dc": False ,
+ "vnf_type": "VFW",
+ "vmnumber_overquota_alarm": True,
+ "vnfd_version": "1.0.0",
+ "externalPluginManageNetworkName": "vlan_4007_plugin_net",
+ "id": "vcpe_vfw_zte_1_0",
+ "request_reclassification": False
+ },
+ "dependencies": [
+ {
+ "key_name": "vfw_ctrl_by_manager_cp",
+ "vl_id": "ext_mnet_net"
+ },
+ {
+ "key_name": "vfw_data_cp",
+ "vl_id": "sfc_data_network"
+ }
+ ],
+ "type": "tosca.nodes.nfv.ext.zte.VNF.VFW",
+ "networks": []
+ },
+ {
+ "vnf_id": "VNAT",
+ "description": "",
+ "properties": {
+ "NatIpRange": "192.167.0.10-192.168.0.20",
+ "plugin_info": "vbrasplugin_1.0",
+ "vendor": "zte",
+ "is_shared": False ,
+ "adjust_vnf_capacity": True,
+ "name": "VNAT",
+ "id": "vcpe_vnat_zte_1",
+ "vnf_extend_type": "driver",
+ "csarVersion": "v1.0",
+ "csarType": "NFAR",
+ "csarProvider": "ZTE",
+ "version": "1.0",
+ "nsh_aware": True,
+ "cross_dc": False ,
+ "vnf_type": "VNAT",
+ "vmnumber_overquota_alarm": True,
+ "vnfd_version": "1.0.0",
+ "externalPluginManageNetworkName": "vlan_4007_plugin_net",
+ "request_reclassification": False
+ },
+ "dependencies": [
+ {
+ "key_name": "vnat_ctrl_by_manager_cp",
+ "vl_id": "ext_mnet_net"
+ },
+ {
+ "key_name": "vnat_data_cp",
+ "vl_id": "sfc_data_network"
+ }
+ ],
+ "type": "tosca.nodes.nfv.ext.zte.VNF.VNAT",
+ "networks": []
+ }
+ ],
+ "ns_exposed": {
+ "external_cps": [],
+ "forward_cps": []
+ },
+ "policies": [
+ {
+ "file_url": "policies/abc.drl",
+ "name": "aaa"
+ }
+ ],
+ "vls": [
+ {
+ "route_id": "",
+ "vl_id": "ext_mnet_net",
+ "route_external": False ,
+ "description": "",
+ "properties": {
+ "name": "vlan_4008_mng_net",
+ "mtu": 1500,
+ "location_info": {
+ "tenant": "admin",
+ "vimid": 2,
+ "availability_zone": "nova"
+ },
+ "ip_version": 4,
+ "dhcp_enabled": True,
+ "network_name": "vlan_4008_mng_net",
+ "network_type": "vlan"
+ }
+ },
+ {
+ "route_id": "",
+ "vl_id": "ext_datanet_net",
+ "route_external": False ,
+ "description": "",
+ "properties": {
+ "name": "vlan_4004_tunnel_net",
+ "mtu": 1500,
+ "location_info": {
+ "tenant": "admin",
+ "vimid": 2,
+ "availability_zone": "nova"
+ },
+ "ip_version": 4,
+ "dhcp_enabled": True,
+ "network_name": "vlan_4004_tunnel_net",
+ "network_type": "vlan"
+ }
+ },
+ {
+ "route_id": "",
+ "vl_id": "sfc_data_network",
+ "route_external": False ,
+ "description": "",
+ "properties": {
+ "name": "sfc_data_network",
+ "dhcp_enabled": True,
+ "is_predefined": False ,
+ "location_info": {
+ "tenant": "admin",
+ "vimid": 2,
+ "availability_zone": "nova"
+ },
+ "ip_version": 4,
+ "mtu": 1500,
+ "network_name": "sfc_data_network",
+ "network_type": "vlan"
+ }
+ }
+ ],
+ "cps": [
+ {
+ "pnf_id": "m6000_s",
+ "vl_id": "path2",
+ "description": "",
+ "cp_id": "m6000_data_out",
+ "properties": {
+ "direction": "bidirectional",
+ "vnic_type": "normal",
+ "bandwidth": 0,
+ "mac_address": "11-22-33-22-11-44",
+ "interface_name": "xgei-0/4/1/5",
+ "ip_address": "176.1.1.2",
+ "order": 0,
+ "sfc_encapsulation": "mac"
+ }
+ },
+ {
+ "pnf_id": "m6000_s",
+ "vl_id": "ext_datanet_net",
+ "description": "",
+ "cp_id": "m600_tunnel_cp",
+ "properties": {
+ "direction": "bidirectional",
+ "vnic_type": "normal",
+ "bandwidth": 0,
+ "mac_address": "00-11-00-22-33-00",
+ "interface_name": "gei-0/4/0/13",
+ "ip_address": "191.167.100.5",
+ "order": 0,
+ "sfc_encapsulation": "mac"
+ }
+ },
+ {
+ "pnf_id": "m6000_s",
+ "vl_id": "path2",
+ "description": "",
+ "cp_id": "m6000_data_in",
+ "properties": {
+ "direction": "bidirectional",
+ "vnic_type": "normal",
+ "bandwidth": 0,
+ "mac_address": "11-22-33-22-11-41",
+ "interface_name": "gei-0/4/0/7",
+ "ip_address": "1.1.1.1",
+ "order": 0,
+ "sfc_encapsulation": "mac",
+ "bond": "none"
+ }
+ },
+ {
+ "pnf_id": "m6000_s",
+ "vl_id": "ext_mnet_net",
+ "description": "",
+ "cp_id": "m600_mnt_cp",
+ "properties": {
+ "direction": "bidirectional",
+ "vnic_type": "normal",
+ "bandwidth": 0,
+ "mac_address": "00-11-00-22-33-11",
+ "interface_name": "gei-0/4/0/1",
+ "ip_address": "10.46.244.51",
+ "order": 0,
+ "sfc_encapsulation": "mac",
+ "bond": "none"
+ }
+ }
+ ],
+ "metadata": {
+ "invariant_id": "vcpe_ns_sff_1",
+ "name": "VCPE_NS",
+ "csarVersion": "v1.0",
+ "csarType": "NSAR",
+ "csarProvider": "ZTE",
+ "version": 1,
+ "vendor": "ZTE",
+ "id": "VCPE_NS",
+ "description": "vcpe_ns"
+ }
+ }
+
+ def tearDown(self):
+ pass
+
+ def test_ns_pkg_distribute_when_ns_exists(self):
+ NSDModel(id="1", nsd_id="2").save()
+ resp = self.client.post("/api/nslcm/v1/nspackage", {"csarId": "1"}, format='json')
+ self.assertEqual(resp.status_code, status.HTTP_202_ACCEPTED)
+ self.assertEqual("failed", resp.data["status"])
+ self.assertEqual("NS CSAR(1) already exists.", resp.data["statusDescription"])