+# 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.
+
*.pyc
.cache
.eggs
*egg-info
*.gz
-osm_im
osm_im_trees
dists
pool
osm-im-*.post*
osm-imdocs-*.post*
osm-imdocs_*.post*
+osm_im/nsd.py
+osm_im/vnfd.py
+osm_im/nst.py
+osm_im/nsi.py
+osm_im/osm.yaml
#Pyang and other tools' folders
pyangbind
--- /dev/null
+# -*- 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.
+
+recursive-include models *.yang
\ No newline at end of file
openapi_schemas: $(OPENAPI_SCHEMAS)
-$(OUT_DIR):
- $(Q)mkdir -p $(OUT_DIR)
- $(Q)touch $(OUT_DIR)/__init__.py
-
$(TREES_DIR):
$(Q)mkdir -p $(TREES_DIR)
-%.py: $(OUT_DIR) yang-ietf
+%.py: yang-ietf
$(Q)echo generating $@ from $*.yang
$(Q)pyang $(PYANG_OPTIONS) --path $(MODEL_DIR) --plugindir $(PYBINDPLUGIN) -f pybind -o $(OUT_DIR)/$@ $(MODEL_DIR)/$*.yang
$(Q)sed -r -i 's|<a href=\"http://www.tail-f.com">|<a href="http://osm.etsi.org">|g' $(TREES_DIR)/$@
$(Q)mv $(TREES_DIR)/$@ $(TREES_DIR)/$*.html
-osm.yaml: $(OUT_DIR) yang-ietf yang2swagger
+osm.yaml: yang-ietf yang2swagger
$(Q)echo generating $@
$(Q)$(JAVA) -jar ${HOME}/.m2/repository/com/mrv/yangtools/swagger-generator-cli/1.1.11/swagger-generator-cli-1.1.11-executable.jar -yang-dir $(MODEL_DIR) -output $(OUT_DIR)/$@
$(Q)cp -n ~/.m2/settings.xml{,.orig} ; wget -q -O - https://raw.githubusercontent.com/opendaylight/odlparent/master/settings.xml > ~/.m2/settings.xml
clean:
- $(Q)rm -rf dist osm_im.egg-info deb deb_dist *.gz yang2swagger $(OUT_DIR) $(TREES_DIR)
+ $(Q)rm -rf dist osm_im.egg-info deb deb_dist *.gz osm-imdocs* yang2swagger $(TREES_DIR)
description
"Name of the configuration primitive.";
type string;
- mandatory "true";
+ mandatory true;
}
leaf user-defined-script {
}
- grouping vca-relationships {
- container vca-relationships {
- list relation {
- description "List of relations between VCA componets.";
+ grouping vca-relations {
+ list relation {
+ description "List of relations between elements in this descriptor.";
+ key "name";
+
+ leaf name {
+ description
+ "Name of the relation.";
- key "requires provides";
+ type string;
+ }
+
+ list entities {
+ description
+ "List of two elements to be related.
+ Elements to be related are identified by a pair (id, endpoint).
+ The relation will relate (id1, endpoint1) to (id2, endpoint2).";
+ key "id";
- leaf requires {
+ leaf id {
description
- "Name of the required relation.";
+ "A string, reference to the element id in the descriptor.
+ It could be a vnfd-id or a vdu-id in a VNFD,
+ or a nsd-id or member-vnf-index in a NSD.";
type string;
}
- leaf provides {
+ leaf endpoint {
description
- "Name of the provided relation.";
+ "Endpoint name defining the relation.";
type string;
}
}
type boolean;
default true;
}
- uses manotypes:vca-relationships;
}
}
}
"Information about NS configuration.";
uses manotypes:vca-configuration;
+ uses manotypes:vca-relations;
}
uses manotypes:input-parameter-xpath;
description
"Name of the primitive.";
type string;
- mandatory "true";
+ mandatory true;
}
leaf user-defined-script {
container vnf-configuration {
uses manotypes:vca-configuration;
+ uses manotypes:vca-relations;
uses manotypes:vca-config-access;
}
leaf mac-address {
description
- "MAC address of the interface.
- Some VNFs require a specific MAC address to be configured
- in the interface. While this is not recommended at all in
- NFV environments, this parameter exists to allow those
- scenarios.
- This parameter will be likely deprecated in the future.";
+ "MAC address of the interface.
+ Some VNFs require a specific MAC address to be configured
+ in the interface. While this is not recommended at all in
+ NFV environments, this parameter exists to allow those
+ scenarios.
+ This parameter will be likely deprecated in the future.";
type string;
}
case internal {
leaf internal-connection-point-ref {
description
- "Leaf Ref to the particular internal connection point";
+ "Leaf Ref to the particular internal connection point";
type leafref {
- path "../../internal-connection-point/id";
- }
+ path "../../internal-connection-point/id";
+ }
}
}
case external {
leaf external-connection-point-ref {
description
- "Leaf Ref to the particular external connection point";
+ "Leaf Ref to the particular external connection point";
type leafref {
- path "../../../connection-point/name";
- }
+ path "../../../connection-point/name";
+ }
}
}
}
}
}
+ list kdu {
+ description "List of K8s Deployment Units";
+ key "name";
+
+ leaf name {
+ description "Unique name for the KDU";
+ type string;
+ }
+
+ leaf description {
+ description "Description of the KDU.";
+ type string;
+ }
+
+ container kdu-configuration {
+ uses manotypes:vca-configuration;
+ uses manotypes:vca-config-access;
+
+ leaf-list blacklist-config-primitive {
+ description
+ "List of blacklisted config primitives from the list of
+ default kdu config primitives";
+
+ type enumeration {
+ enum upgrade;
+ enum rollback;
+ }
+
+ }
+
+ }
+
+ choice kdu-model {
+ description
+ "Indicates the KDU model, either as a helm-chart or as a juju-bundle.";
+
+ case helm-chart {
+ leaf helm-chart {
+ description
+ "Helm chart that models the KDU, in any of the following ways:
+ - <helm-repo>/<helm-chart>
+ - <helm-chart folder under k8s_models folder in the package>
+ - <helm-chart tgz file (w/ or w/o extension) under k8s_models folder in the package>
+ - <URL_where_to_fetch_chart>
+ ";
+ type string;
+ }
+ }
+
+ case juju-bundle {
+ leaf juju-bundle {
+ description
+ "Juju bundle that models the KDU, in any of the following ways:
+ - <juju-repo>/<juju-bundle>
+ - <juju-bundle folder under k8s_models folder in the package>
+ - <juju-bundle tgz file (w/ or w/o extension) under k8s_models folder in the package>
+ - <URL_where_to_fetch_juju_bundle>
+ ";
+ type string;
+ }
+ }
+ }
+
+ }
+
+ container k8s-cluster {
+ leaf-list version {
+ description
+ "List of supported K8s versions.
+ The cluster where the KDUs will be deployed will have to match
+ one of these versions.";
+
+ type string;
+ }
+
+ leaf-list cni {
+ description
+ "List of supported CNI plugins.
+ The cluster where the KDUs will be deployed will have to use
+ one of these CNI plugins.";
+
+ type enumeration {
+ enum calico;
+ enum flannel;
+ enum multus;
+ }
+ }
+
+ list nets {
+ description
+ "List of required networks in the K8s cluster.
+ The cluster where the KDUs will be deployed will have to use
+ one of these CNI plugins.";
+
+ key "id";
+
+ leaf id {
+ description "Internal identifier for the K8s cluster network in this VNF";
+ type string;
+ }
+
+ leaf external-connection-point-ref {
+ description
+ "Leaf Ref to the particular external connection point";
+ type leafref {
+ path "../../../connection-point/name";
+ }
+ }
+
+ }
+ }
+
list vdu-dependency {
description
"List of VDU dependencies.";
--- /dev/null
+##
+# 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.
+##
--- /dev/null
+# -*- 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 json
+# import logging
+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 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()
+ 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"
+ 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)
+
+#!/usr/bin/env python3
+# -*- 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 subprocess
+import sys
+import os
from setuptools import setup, find_packages
+from setuptools.command.install import install
+
+
+class Install_osm_im(install):
+ """Generation of .py files from yang models"""
+ model_dir = "models/yang"
+ im_dir = "osm_im"
+
+ def pipinstall(self, package):
+ """pip install for executable dependencies"""
+ subprocess.call([sys.executable, "-m", "pip", "install", package])
+
+ def run(self):
+ self.pipinstall('pyang')
+ self.pipinstall('pyangbind')
+ import pyangbind
+ print("Using dir {}/{} for python artifacts".format(os.getcwd(), self.im_dir))
+ path = "{}/{}".format(os.getcwd(), self.im_dir)
+ for files_item in ['vnfd', 'nsd', 'nst']:
+ protoc_command = ["pyang",
+ "-Werror",
+ "--plugindir",
+ "{}/plugin".format(os.path.dirname(pyangbind.__file__)),
+ "--path",
+ self.model_dir,
+ "-f", "pybind",
+ "-o",
+ "{}/{}.py".format(self.im_dir, files_item),
+ "{}/{}.yang".format(self.model_dir, files_item)]
+ print("Generating {}.py from {}.yang".format(files_item, files_item))
+ if subprocess.call(protoc_command) != 0:
+ sys.exit(-1)
+ # To ensure generated files are copied to the python installation folder
+ self.copy_tree(self.im_dir, "{}{}".format(self.install_lib, self.im_dir))
+ install.run(self)
+
setup(
name='osm_im',
description='OSM Information Model',
- long_description = open('README.rst').read(),
+ long_description=open('README.rst').read(),
version_command=('git describe --tags --long --dirty --match v*', 'pep440-git-full'),
author='Mike Marchetti',
author_email='mmarchetti@sandvine.com',
packages=find_packages(),
include_package_data=True,
setup_requires=['setuptools-version-command'],
+ install_requires=['pyang', 'pyangbind'],
test_suite='nose.collector',
+ url='https://osm.etsi.org/gitweb/?p=osm/IM.git;a=summary',
+ license='Apache 2.0',
+ cmdclass={'install': Install_osm_im},
)
+# -*- 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.
+
[DEFAULT]
Suite: xenial
+Build-Depends: dh-python
Maintainer: Gerardo Garcia <gerardo.garciadeblas@telefonica.com>
Depends: osm-imdocs
Depends3: osm-imdocs