blob: 7eff67e159fbff41d2a59a0540a0e7b8d16f371e [file] [log] [blame]
# -*- coding: utf-8 -*-
# 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 yaml
import importlib
from osm_im.vnfd import vnfd as vnfd_im
from osm_im.nsd import nsd as nsd_im
from osm_im.nst import nst as nst_im
from osm_im import etsi_nfv_vnfd, etsi_nfv_nsd
from pyangbind.lib.serialise import pybindJSONDecoder
import pyangbind.lib.pybindJSON as pybindJSON
class ValidationException(Exception):
pass
class Validation:
def pyangbind_validation(self, item, data, force=False):
'''
item: vnfd, nst, nsd
data: dict object loaded from the descriptor file
force: True to skip unknown fields in the descriptor
'''
if item == "vnfd":
myobj = vnfd_im()
elif item == "nsd":
myobj = nsd_im()
elif item == "nst":
myobj = nst_im()
elif item == "etsi_nfv_vnfd":
myobj = etsi_nfv_vnfd.etsi_nfv_vnfd()
elif item == "etsi_nfv_nsd":
myobj = etsi_nfv_nsd.etsi_nfv_nsd()
else:
raise ValidationException("Not possible to validate '{}' item".format(item))
try:
pybindJSONDecoder.load_ietf_json(data, None, None, obj=myobj,
path_helper=True, skip_unknown=force)
out = pybindJSON.dumps(myobj, mode="ietf")
desc_out = yaml.safe_load(out)
return desc_out
except Exception as e:
raise ValidationException("Error in pyangbind validation: {}".format(str(e)))
def yaml_validation(self, descriptor):
try:
data = yaml.safe_load(descriptor)
except Exception as e:
raise ValidationException("Error in YAML validation. Not a proper YAML file: {}".format(e))
if 'vnfd:vnfd-catalog' in data or 'vnfd-catalog' in data:
item = "vnfd"
elif 'nsd:nsd-catalog' in data or 'nsd-catalog' in data:
item = "nsd"
elif 'nst' in data:
item = "nst"
elif 'vnfd' in data:
item = "etsi_nfv_vnfd"
elif 'nsd' in data:
item = "etsi_nfv_nsd"
else:
raise ValidationException("Error in YAML validation. Not possible to determine the type of descriptor in the first line. Expected values: vnfd:vnfd-catalog, vnfd-catalog, nsd:nsd-catalog, nsd-catalog, nst")
return item, data
def descriptor_validation(self, descriptor):
item, data = self.yaml_validation(descriptor)
self.pyangbind_validation(item, data)
def validate_instantiation_level_descriptor(self, indata):
all_vdu_ids = set()
for vdu in indata.get("vdu", ()):
all_vdu_ids.add(vdu.get("id"))
for df in indata.get("df", ()):
for il in df.get("instantiation-level", ()):
for vl in il.get("vdu-level", ()):
vl_vdu_id = vl.get("vdu-id")
if vl_vdu_id and vl_vdu_id not in all_vdu_ids:
raise ValidationException(
"df[id='{}']:instantiation-level[id='{}']:vdu-level"
"vdu-id='{}' not defined in vdu".format(
df["id"],
il["id"],
vl_vdu_id,
)
)
def validate_vdu_profile_in_descriptor(self, indata):
all_vdu_ids = set()
for df in indata.get("df", ()):
if "vdu-profile" in df:
if not df.get("vdu-profile"):
if indata.get("vdu"):
raise ValidationException(
"no profiles are defined under vdu-profile section"
)
for vp in df["vdu-profile"]:
missing = None
if not vp.get("id"):
missing = "id"
if df.get("scaling-aspect"):
if not vp.get("min-number-of-instances"):
missing = "min-number-of-instances"
if "min-number-of-instances" in vp:
if not vp.get("min-number-of-instances"):
missing = "min-number-of-instances"
if "max-number-of-instances" in vp:
if not vp.get("max-number-of-instances"):
missing = "max-number-of-instances"
if missing:
raise ValidationException(
"{} key-value pair is missing in vdu-profile".format(
missing
)
)
for df in indata.get("df", ()):
for il in df.get("instantiation-level", ()):
for vl in il.get("vdu-level", ()):
all_vdu_ids.add(vl.get("vdu-id"))
for df in indata.get("df", ()):
for vp in df.get("vdu-profile", ()):
vp_vdu_id = vp.get("id")
if vp_vdu_id and vp_vdu_id not in all_vdu_ids:
raise ValidationException(
"df[id='{}']:vdu-profile:vdu-id='{}' not defined in vdu".format(
df["id"],
vp_vdu_id,
)
)