CORD-1033 Move vtnnetport.py

Change-Id: Ic79cc59fa869c6713015245e5e442457656fe351
diff --git a/xos/synchronizer/Dockerfile.synchronizer b/xos/synchronizer/Dockerfile.synchronizer
index 28c32ab..7785df4 100644
--- a/xos/synchronizer/Dockerfile.synchronizer
+++ b/xos/synchronizer/Dockerfile.synchronizer
@@ -4,7 +4,7 @@
 
 ADD __init__.py /opt/xos/services/__init__.py
 ADD __init__.py /opt/xos/services/vtn/__init__.py
-ADD tmp.vtnnetport.py /opt/xos/services/vtn/vtnnetport.py
+ADD vtnnetport.py /opt/xos/services/vtn/vtnnetport.py
 
 ENTRYPOINT []
 
diff --git a/xos/synchronizer/vtnnetport.py b/xos/synchronizer/vtnnetport.py
new file mode 100644
index 0000000..e1c15bb
--- /dev/null
+++ b/xos/synchronizer/vtnnetport.py
@@ -0,0 +1,248 @@
+# This library can be used in two different contexts:
+#    1) From the VTN synchronizer
+#    2) From the handcrafted VTN API endpoint
+#
+# If (1) then the modelaccessor module can provide us with models from the API
+# or django as appropriate. If (2) then we must use django, until we can
+# reconcile what to do about handcrafted API endpoints
+
+import __main__ as main_program
+
+if "synchronizer" in main_program.__file__:
+    from synchronizers.new_base.modelaccessor import *
+    in_synchronizer = True
+else:
+    from core.models import *
+    in_synchronizer = False
+
+VTN_SERVCOMP_KINDS=["PRIVATE","VSG"]
+
+class VTNNetwork(object):
+    def __init__(self, xos_network=None):
+        self.xos_network = xos_network
+
+    def get_controller_network(self):
+        for cn in self.xos_network.controllernetworks.all():
+            # TODO: find the right one
+            return cn
+        return None
+
+    def get_cn_field(self, fieldname):
+        cn=self.get_controller_network()
+        if not cn:
+            return None
+        return getattr(cn, fieldname)
+
+    @property
+    def id(self):
+        return self.get_cn_field("net_id")
+
+    @property
+    def name(self):
+        return self.xos_network.name
+
+    @property
+    def subnet(self):
+        return self.get_cn_field("subnet")
+
+    @property
+    def gateway(self):
+        return self.get_cn_field("gateway")
+
+    @property
+    def segmentation_id(self):
+        return self.get_cn_field("segmentation_id")
+
+    @property
+    def type(self):
+        return self.xos_network.template.vtn_kind
+
+    @property
+    def providerNetworks(self):
+        slice = self.xos_network.owner
+        service = slice.service
+        if not service:
+            return []
+
+        nets=[]
+        for tenant in service.subscribed_tenants.all():
+            if tenant.provider_service:
+                bidirectional = tenant.connect_method!="private-unidirectional"
+                for net in tenant.provider_service.get_composable_networks():
+                    if not net.controllernetworks.exists():
+                        continue
+
+                    cn = net.controllernetworks.all()[0]
+
+                    if not cn.net_id:
+                        continue
+
+                    nets.append({"id": cn.net_id,
+                                 "name": net.name,
+                                 "bidirectional": bidirectional})
+        return nets
+
+    @property
+    def subscriberNetworks(self):
+        slice = self.xos_network.owner
+        service = slice.service
+        if not service:
+            return []
+
+        nets=[]
+        for tenant in service.provided_tenants.all():
+            if tenant.subscriber_service:
+                bidirectional = tenant.connect_method!="private-unidirectional"
+                for net in tenant.subscriber_service.get_composable_networks():
+                    if not net.controllernetworks.exists():
+                        continue
+
+                    cn = net.controllernetworks.all()[0]
+
+                    if not cn.net_id:
+                        continue
+
+                    nets.append({"id": cn.net_id,
+                                 "name": net.name,
+                                 "bidirectional": bidirectional})
+        return nets
+
+    @property
+    def ownerSliceName(self):
+        if self.xos_network.owner:
+            return self.xos_network.owner.name
+        return None
+
+    @property
+    def ownerServiceName(self):
+        if self.xos_network.owner and self.xos_network.owner.service:
+            return self.xos_network.owner.service.name
+        return None
+
+    def to_dict(self):
+        return {"id": self.id,
+                "name": self.name,
+                "subnet": self.subnet,
+                "gateway": self.gateway,
+                "segmentation_id": self.segmentation_id,
+                "type": self.type,
+                "providerNetworks": self.providerNetworks,
+                "subscriberNetworks": self.subscriberNetworks,
+                "ownerSliceName": self.ownerSliceName,
+                "ownerServiceName": self.ownerServiceName}
+
+    def __eq__(self, other):
+        return self.to_dict() == other.to_dict()
+
+class VTNPort(object):
+    def __init__(self, xos_port=None):
+        self.xos_port = xos_port
+
+    def get_controller_network(self):
+        for cn in self.xos_port.network.controllernetworks.all():
+            # TODO: find the right one
+            return cn
+        return None
+
+    def get_vsg_tenants(self):
+        # If the VSG service isn't onboarded, then return an empty list.
+        if (in_synchronizer):
+            if not model_accessor.has_model_class("VSGTenant"):
+                 print "VSGTenant model does not exist. Returning no tenants"
+                 return []
+            VSGTenant = model_accessor.get_model_class("VSGTenant")   # suppress undefined local variable error
+        else:
+            try:
+                from services.vsg.models import VSGTenant
+            except ImportError:
+                # TODO: Set up logging for this library...
+                print "Failed to import VSG, returning no tenants"
+                return []
+
+        vsg_tenants=[]
+        for tenant in VSGTenant.objects.all():
+            if tenant.instance.id == self.xos_port.instance.id:
+                vsg_tenants.append(tenant)
+        return vsg_tenants
+
+    @property
+    def vlan_id(self):
+        if not self.xos_port.instance:
+            return None
+
+        # Only some kinds of networks can have s-tags associated with them.
+        # Currently, only VSG access networks qualify.
+        if not self.xos_port.network.template.vtn_kind in ["VSG",]:
+            return None
+
+        if (in_synchronizer):
+            tags = Tag.objects.filter(content_type=model_accessor.get_content_type_id(self.xos_port.instance),
+                                      object_id=self.xos_port.instance.id,
+                                      name="s_tag")
+        else:
+            tags = Tag.select_by_content_object(self.xos_port.instance).filter(name="s_tag")
+
+        if not tags:
+            return None
+
+        return tags[0].value
+
+    @property
+    def floating_address_pairs(self):
+        # Floating_address_pairs is the set of WAN addresses that should be
+        # applied to this port.
+
+        address_pairs = []
+
+        # only look apply the VSG addresses if the Network is of the VSG vtn_kind
+        if self.xos_port.network.template.vtn_kind in ["VSG", ]:
+            for vsg in self.get_vsg_tenants():
+                if vsg.wan_container_ip and vsg.wan_container_mac:
+                    address_pairs.append({"ip_address": vsg.wan_container_ip,
+                                          "mac_address": vsg.wan_container_mac})
+
+                if vsg.wan_vm_ip and vsg.wan_vm_mac:
+                    address_pairs.append({"ip_address": vsg.wan_vm_ip,
+                                          "mac_address": vsg.wan_vm_mac})
+
+        return address_pairs
+
+    @property
+    def id(self):
+        return self.xos_port.port_id
+
+    @property
+    def name(self):
+        return "port-%s" % self.xos_port.id
+
+    @property
+    def network_id(self):
+        cn = self.get_controller_network()
+        if not cn:
+            return None
+        return cn.net_id
+
+    @property
+    def network_name(self):
+        return self.xos_port.network.name
+
+    @property
+    def mac_address(self):
+        return self.xos_port.mac
+
+    @property
+    def ip_address(self):
+        return self.xos_port.ip
+
+    def to_dict(self):
+        return {"id": self.id,
+                "name": self.name,
+                "network_id": self.network_id,
+                "mac_address": self.mac_address,
+                "ip_address": self.ip_address,
+                "floating_address_pairs": self.floating_address_pairs,
+                "vlan_id": self.vlan_id}
+
+    def __eq__(self, other):
+        return self.to_dict() == other.to_dict()
+