RIFT OSM R1 Initial Submission
[osm/SO.git] / common / python / rift / mano / tosca_translator / rwmano / tosca / tosca_network_port.py
diff --git a/common/python/rift/mano/tosca_translator/rwmano/tosca/tosca_network_port.py b/common/python/rift/mano/tosca_translator/rwmano/tosca/tosca_network_port.py
new file mode 100644 (file)
index 0000000..04e3a59
--- /dev/null
@@ -0,0 +1,145 @@
+#
+# 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.
+#
+# Copyright 2016 RIFT.io Inc
+
+
+from rift.mano.tosca_translator.common.utils import _
+from rift.mano.tosca_translator.rwmano.syntax.mano_resource import ManoResource
+
+from toscaparser.common.exception import ValidationError
+
+
+# Name used to dynamically load appropriate map class.
+TARGET_CLASS_NAME = 'ToscaNetworkPort'
+TOSCA_LINKS_TO = 'tosca.relationships.network.LinksTo'
+TOSCA_BINDS_TO = 'tosca.relationships.network.BindsTo'
+
+
+class ToscaNetworkPort(ManoResource):
+    '''Translate TOSCA node type tosca.nodes.network.Port.'''
+
+    toscatype = 'tosca.nodes.network.Port'
+
+    VALID_TYPES = ['VIRTIO', 'VPORT']
+
+    def __init__(self, log, nodetemplate, metadata=None):
+        super(ToscaNetworkPort, self).__init__(log,
+                                               nodetemplate,
+                                               type_='port',
+                                               metadata=metadata)
+        # Default order
+        self.order = 0
+        pass
+
+    def handle_properties(self):
+        tosca_props = self.get_tosca_props()
+        self.log.debug(_("Port {0} with tosca properties: {1}").
+                       format(self.name, tosca_props))
+        port_props = {}
+        for key, value in tosca_props.items():
+            port_props[key] = value
+
+        if 'cp_type' not in port_props:
+            port_props['cp_type'] = 'VPORT'
+        else:
+            if not port_props['cp_type'] in ToscaNetworkPort.VALID_TYPES:
+                err_msg = _("Invalid port type, {0}, specified for {1}"). \
+                          format(port_props['cp_type'], self.name)
+                self.log.warn(err_msg)
+                raise ValidationError(message=err_msg)
+
+        if 'vdu_intf_type' not in port_props:
+            port_props['vdu_intf_type'] = 'VIRTIO'
+        else:
+            if not port_props['vdu_intf_type'] in ToscaNetworkPort.VALID_TYPES:
+                err_msg = _("Invalid port type, {0}, specified for {1}"). \
+                          format(port_props['vdu_intf_type'], self.name)
+                self.log.warn(err_msg)
+                raise ValidationError(message=err_msg)
+
+        self.properties = port_props
+
+    def handle_requirements(self, nodes):
+        tosca_reqs = self.get_tosca_reqs()
+        self.log.debug("VNF {0} requirements: {1}".
+                       format(self.name, tosca_reqs))
+
+        vnf = None  # Need vnf ref to generate cp refs in vld
+        vld = None
+        if len(tosca_reqs) != 2:
+            err_msg = _("Invalid configuration as incorrect number of "
+                        "requirements for CP {0} are specified"). \
+                        format(self)
+            self.log.error(err_msg)
+            raise ValidationError(message=err_msg)
+
+        for req in tosca_reqs:
+            if 'virtualBinding' in req:
+                target = req['virtualBinding']['target']
+                node = self.get_node_with_name(target, nodes)
+                if node:
+                    vnf = node.vnf
+                    if not vnf:
+                        err_msg = _("No vnfs linked to a VDU {0}"). \
+                                    format(node)
+                        self.log.error(err_msg)
+                        raise ValidationError(message=err_msg)
+                    cp = {}
+                    cp['name'] = self.properties['name']
+                    cp['type'] = self.properties['cp_type']
+                    self.log.debug(_("Connection Point entry for VNF {0}:{1}").
+                                   format(vnf, cp))
+                    if 'connection-point' not in vnf.properties:
+                        vnf.properties['connection-point'] = []
+                    vnf.properties['connection-point'].append(cp)
+                    ext_intf = {}
+                    ext_intf['name'] = self.properties['vdu_intf_name']
+                    ext_intf['virtual-interface'] = \
+                                    {'type': self.properties['vdu_intf_type']}
+                    ext_intf['vnfd-connection-point-ref'] = \
+                                    self.properties['name']
+                    if 'external-interface' not in node.properties:
+                        node.properties['external-interface'] = []
+                    node.properties['external-interface'].append(ext_intf)
+                else:
+                    err_msg = _("Connection point {0}, VDU {1} "
+                                "specified not found"). \
+                                format(self.name, target)
+                    self.log.error(err_msg)
+                    raise ValidationError(message=err_msg)
+            elif 'virtualLink' in req:
+                target = req['virtualLink']['target']
+                node = self.get_node_with_name(target, nodes)
+                if node:
+                    vld = node
+                else:
+                    err_msg = _("CP {0}, VL {1} specified not found"). \
+                              format(self, target)
+                    self.log.error(err_msg)
+                    raise ValidationError(message=err_msg)
+
+        if vnf and vld:
+            cp_ref = {}
+            cp_ref['vnfd-connection-point-ref'] = self.properties['name']
+            cp_ref['vnfd-id-ref'] = vnf.properties['id']
+            cp_ref['member-vnf-index-ref'] = \
+                            vnf._const_vnfd['member-vnf-index']
+            if 'vnfd-connection-point-ref' not in vld.properties:
+                vld.properties['vnfd-connection-point-ref'] = []
+            vld.properties['vnfd-connection-point-ref'].append(cp_ref)
+        else:
+            err_msg = _("CP {0}, VNF {1} or VL {2} not found"). \
+                      format(self, vnf, vld)
+            self.log.error(err_msg)
+            raise ValidationError(message=err_msg)