CORD-2964 Allow ports to be created without instances

Change-Id: Ieb8571258b9a2cffcc3c5bf5b600f46656721e12
diff --git a/xos/core/models/core.xproto b/xos/core/models/core.xproto
index acafa7e..0c8da6f 100644
--- a/xos/core/models/core.xproto
+++ b/xos/core/models/core.xproto
@@ -381,11 +381,9 @@
      required manytomany node->Node/NodeLabel_node:nodelabels = 2 [db_index = False, blank = True];
 }
 
-policy port_validator < (obj.instance.slice in obj.network.permitted_slices.all()) | (obj.instance.slice = obj.network.owner) | obj.network.permit_all_slices >
 policy port_policy < *instance_policy(instance) & *network_policy(network) >
 
 message Port::port_policy (XOSBase) {
-     option validators = "port_validator:Slice is not allowed to connect to network";
      required manytoone network->Network:links = 1 [db_index = True, null = False, blank = False, unique_with = "instance"];
      optional manytoone instance->Instance:ports = 2 [db_index = True, null = True, blank = True];
      optional string ip = 3 [max_length = 39, content_type = "ip", blank = True, help_text = "Instance ip address", null = True, db_index = False];
diff --git a/xos/core/models/port.py b/xos/core/models/port.py
index bbee8a7..83ba7f8 100644
--- a/xos/core/models/port.py
+++ b/xos/core/models/port.py
@@ -19,3 +19,12 @@
 class Port(Port_decl):
     class Meta:
         proxy = True
+
+    def save(self, *args, **kwargs):
+        if self.instance:
+            if (self.instance.slice not in self.network.permitted_slices.all()) and \
+                (self.instance.slice != self.network.owner) and \
+                (not self.network.permit_all_slices):
+                raise XOSValidationError("Slice is not allowed to connect to network")
+
+        super(Port, self).save(*args, **kwargs)