Merge remote-tracking branch 'origin/master' into domain_auth
diff --git a/xos/cord/models.py b/xos/cord/models.py
index 68bd2ba..d55ff2d 100644
--- a/xos/cord/models.py
+++ b/xos/cord/models.py
@@ -477,66 +477,6 @@
     def __init__(self, *args, **kwargs):
         super(VCPETenant, self).__init__(*args, **kwargs)
         self.cached_vbng=None
-        self.cached_instance=None
-        self.orig_instance_id = self.get_initial_attribute("instance_id")
-
-    @property
-    def image(self):
-        LOOK_FOR_IMAGES=["ubuntu-vcpe4",        # ONOS demo machine -- preferred vcpe image
-                         "Ubuntu 14.04 LTS",    # portal
-                         "Ubuntu-14.04-LTS",    # ONOS demo machine
-                        ]
-        for image_name in LOOK_FOR_IMAGES:
-            images = Image.objects.filter(name = image_name)
-            if images:
-                return images[0]
-
-        raise XOSProgrammingError("No VPCE image (looked for %s)" % str(LOOK_FOR_IMAGES))
-
-    @property
-    def instance(self):
-        if getattr(self, "cached_instance", None):
-            return self.cached_instance
-        instance_id=self.get_attribute("instance_id")
-        if not instance_id:
-            return None
-        instances=Instance.objects.filter(id=instance_id)
-        if not instances:
-            return None
-        instance=instances[0]
-        instance.caller = self.creator
-        self.cached_instance = instance
-        return instance
-
-    @instance.setter
-    def instance(self, value):
-        if value:
-            value = value.id
-        if (value != self.get_attribute("instance_id", None)):
-            self.cached_instance=None
-        self.set_attribute("instance_id", value)
-
-    @property
-    def creator(self):
-        if getattr(self, "cached_creator", None):
-            return self.cached_creator
-        creator_id=self.get_attribute("creator_id")
-        if not creator_id:
-            return None
-        users=User.objects.filter(id=creator_id)
-        if not users:
-            return None
-        user=users[0]
-        self.cached_creator = users[0]
-        return user
-
-    @creator.setter
-    def creator(self, value):
-        if value:
-            value = value.id
-        if (value != self.get_attribute("creator_id", None)):
-            self.cached_creator=None
-        self.set_attribute("creator_id", value)
 
     @property
     def vbng(self):
@@ -659,53 +599,6 @@
     def is_synced(self, value):
         pass
 
-    def pick_node(self):
-        nodes = list(Node.objects.all())
-        # TODO: logic to filter nodes by which nodes are up, and which
-        #   nodes the slice can instantiate on.
-        nodes = sorted(nodes, key=lambda node: node.instances.all().count())
-        return nodes[0]
-
-    def manage_instance(self):
-        # Each VCPE object owns exactly one instance.
-
-        if self.deleted:
-            return
-
-        if (self.instance is not None) and (self.instance.image != self.image):
-            self.instance.delete()
-            self.instance = None
-
-        if self.instance is None:
-            if not self.provider_service.slices.count():
-                raise XOSConfigurationError("The VCPE service has no slices")
-
-            flavors = Flavor.objects.filter(name="m1.small")
-            if not flavors:
-                raise XOSConfigurationError("No m1.small flavor")
-
-            node =self.pick_node()
-            instance = Instance(slice = self.provider_service.slices.all()[0],
-                            node = node,
-                            image = self.image,
-                            creator = self.creator,
-                            deployment = node.site_deployment.deployment,
-                            flavor = flavors[0])
-            instance.save()
-
-            try:
-                self.instance = instance
-                super(VCPETenant, self).save()
-            except:
-                instance.delete()
-                raise
-
-    def cleanup_instance(self):
-        if self.instance:
-            # print "XXX cleanup instance", self.instance
-            self.instance.delete()
-            self.instance = None
-
     def manage_vbng(self):
         # Each vCPE object owns exactly one vBNG object
 
diff --git a/xos/core/admin.py b/xos/core/admin.py
index d5ec4bd..93486a2 100644
--- a/xos/core/admin.py
+++ b/xos/core/admin.py
@@ -402,39 +402,6 @@
     def queryset(self, request):
         return Tag.select_by_user(request.user)
 
-class NetworkLookerUpper:
-    """ This is a callable that looks up a network name in a instance and returns
-        the ip address for that network.
-    """
-
-    byNetworkName = {}    # class variable
-
-    def __init__(self, name):
-        self.short_description = name
-        self.__name__ = name
-        self.network_name = name
-
-    def __call__(self, obj):
-        if obj is not None:
-            for nbs in obj.networkinstance_set.all():
-                if (nbs.network.name == self.network_name):
-                    return nbs.ip
-        return ""
-
-    def __str__(self):
-        return self.network_name
-
-    @staticmethod
-    def get(network_name):
-        """ We want to make sure we alwars return the same NetworkLookerUpper
-            because sometimes django will cause them to be instantiated multiple
-            times (and we don't want different ones in form.fields vs
-            InstanceInline.readonly_fields).
-        """
-        if network_name not in NetworkLookerUpper.byNetworkName:
-            NetworkLookerUpper.byNetworkName[network_name] = NetworkLookerUpper(network_name)
-        return NetworkLookerUpper.byNetworkName[network_name]
-
 class InstanceInline(XOSTabularInline):
     model = Instance
     fields = ['backend_status_icon', 'all_ips_string', 'instance_id', 'instance_name', 'slice', 'deployment', 'flavor', 'image', 'node', 'no_sync']
diff --git a/xos/core/models/__init__.py b/xos/core/models/__init__.py
index 0efe37b..ad271a4 100644
--- a/xos/core/models/__init__.py
+++ b/xos/core/models/__init__.py
@@ -26,7 +26,7 @@
 from .instance import Instance
 from .reservation import ReservedResource
 from .reservation import Reservation
-from .network import Network, NetworkParameterType, NetworkParameter, NetworkInstance, Port, NetworkTemplate, Router, NetworkSlice, ControllerNetwork
+from .network import Network, NetworkParameterType, NetworkParameter, Port, NetworkTemplate, Router, NetworkSlice, ControllerNetwork
 from .billing import Account, Invoice, Charge, UsableObject, Payment
 from .program import Program
 
diff --git a/xos/core/models/instance.py b/xos/core/models/instance.py
index adb9395..6240c34 100644
--- a/xos/core/models/instance.py
+++ b/xos/core/models/instance.py
@@ -98,11 +98,6 @@
     tags = generic.GenericRelation(Tag)
     userData = models.TextField(blank=True, null=True, help_text="user_data passed to instance during creation")
 
-    # TODO: Remove when NetworkInstance->Port rename is complete
-    @property
-    def ports(self):
-        return self.networkinstances
-
     def __unicode__(self):
         if self.name and Slice.objects.filter(id=self.slice_id) and (self.name != self.slice.name):
             # NOTE: The weird check on self.slice_id was due to a problem when
diff --git a/xos/core/models/network.py b/xos/core/models/network.py
index 63d617c..1258d76 100644
--- a/xos/core/models/network.py
+++ b/xos/core/models/network.py
@@ -108,7 +108,7 @@
     permit_all_slices = models.BooleanField(default=False)
     permitted_slices = models.ManyToManyField(Slice, blank=True, related_name="availableNetworks")
     slices = models.ManyToManyField(Slice, blank=True, related_name="networks", through="NetworkSlice")
-    instances = models.ManyToManyField(Instance, blank=True, related_name="networks", through="NetworkInstance")
+    instances = models.ManyToManyField(Instance, blank=True, related_name="networks", through="Port")
 
     topology_parameters = models.TextField(null=True, blank=True)
     controller_url = models.CharField(null=True, blank=True, max_length=1024)
@@ -123,11 +123,6 @@
 
     def __unicode__(self):  return u'%s' % (self.name)
 
-    # TODO: Remove when NetworkInstance->Port rename is complete
-    @property
-    def links(self):
-        return self.networkinstances
-
     def save(self, *args, **kwds):
         if (not self.subnet) and (NO_OBSERVER):
             from util.network_subnet_allocator import find_unused_subnet
@@ -211,12 +206,12 @@
             qs = NetworkSlice.objects.filter(id__in=slice_ids)
         return qs
 
-class NetworkInstance(PlCoreBase):
+class Port(PlCoreBase):
     # Please use "Port" instead of "NetworkInstance". NetworkInstance will soon be
     # removed.
 
-    network = models.ForeignKey(Network,related_name='networkinstances')
-    instance = models.ForeignKey(Instance, null=True, blank=True, related_name='networkinstances')
+    network = models.ForeignKey(Network,related_name='links')
+    instance = models.ForeignKey(Instance, null=True, blank=True, related_name='ports')
     ip = models.GenericIPAddressField(help_text="Instance ip address", blank=True, null=True)
     port_id = models.CharField(null=True, blank=True, max_length=256, help_text="Quantum port id")
     mac = models.CharField(null=True, blank=True, max_length=256, help_text="MAC address associated with this port")
@@ -234,11 +229,7 @@
                 #   3) network's permitAllSlices is true
                 raise ValueError("Slice %s is not allowed to connect to network %s" % (str(slice), str(self.network)))
 
-        if (not self.ip) and (NO_OBSERVER):
-            from util.network_subnet_allocator import find_unused_address
-            self.ip = find_unused_address(self.network.subnet,
-                                          [x.ip for x in self.network.networkinstance_set.all()])
-        super(NetworkInstance, self).save(*args, **kwds)
+        super(Port, self).save(*args, **kwds)
 
     def __unicode__(self):
         if self.instance:
@@ -256,17 +247,12 @@
     @staticmethod
     def select_by_user(user):
         if user.is_admin:
-            qs = NetworkInstance.objects.all()
+            qs = Port.objects.all()
         else:
-            instance_ids = [s.id for s in NetworkInstance.select_by_user(user)]
-            qs = NetworkInstance.objects.filter(id__in=instance_ids)
+            instance_ids = [s.id for s in Port.select_by_user(user)]
+            qs = Port.objects.filter(id__in=instance_ids)
         return qs
 
-class Port(NetworkInstance):
-    # Rename in progress: NetworkInstance->Port
-    class Meta:
-        proxy = True
-
 class Router(PlCoreBase):
     name = models.CharField(max_length=32)
     owner = models.ForeignKey(Slice, related_name="routers")
diff --git a/xos/xos/xosapi.py b/xos/xos/xosapi.py
index 9948313..bec3ea2 100644
--- a/xos/xos/xosapi.py
+++ b/xos/xos/xosapi.py
@@ -1,4 +1,3 @@
-
 from rest_framework.decorators import api_view
 from rest_framework.response import Response
 from rest_framework.reverse import reverse
@@ -75,12 +74,12 @@
         url(r'xos/slice_privileges/$', SlicePrivilegeList.as_view(), name='sliceprivilege-list'),
         url(r'xos/slice_privileges/(?P<pk>[a-zA-Z0-9\-]+)/$', SlicePrivilegeDetail.as_view(), name ='sliceprivilege-detail'),
     
-        url(r'xos/networkinstances/$', NetworkInstanceList.as_view(), name='networkinstance-list'),
-        url(r'xos/networkinstances/(?P<pk>[a-zA-Z0-9\-]+)/$', NetworkInstanceDetail.as_view(), name ='networkinstance-detail'),
-    
         url(r'xos/flavors/$', FlavorList.as_view(), name='flavor-list'),
         url(r'xos/flavors/(?P<pk>[a-zA-Z0-9\-]+)/$', FlavorDetail.as_view(), name ='flavor-detail'),
     
+        url(r'xos/ports/$', PortList.as_view(), name='port-list'),
+        url(r'xos/ports/(?P<pk>[a-zA-Z0-9\-]+)/$', PortDetail.as_view(), name ='port-detail'),
+    
         url(r'xos/controllersites/$', ControllerSiteList.as_view(), name='controllersite-list'),
         url(r'xos/controllersites/(?P<pk>[a-zA-Z0-9\-]+)/$', ControllerSiteDetail.as_view(), name ='controllersite-detail'),
     
@@ -105,6 +104,9 @@
         url(r'xos/subscribers/$', SubscriberList.as_view(), name='subscriber-list'),
         url(r'xos/subscribers/(?P<pk>[a-zA-Z0-9\-]+)/$', SubscriberDetail.as_view(), name ='subscriber-detail'),
     
+        url(r'xos/instances/$', InstanceList.as_view(), name='instance-list'),
+        url(r'xos/instances/(?P<pk>[a-zA-Z0-9\-]+)/$', InstanceDetail.as_view(), name ='instance-detail'),
+    
         url(r'xos/charges/$', ChargeList.as_view(), name='charge-list'),
         url(r'xos/charges/(?P<pk>[a-zA-Z0-9\-]+)/$', ChargeDetail.as_view(), name ='charge-detail'),
     
@@ -123,9 +125,6 @@
         url(r'xos/slicecredentials/$', SliceCredentialList.as_view(), name='slicecredential-list'),
         url(r'xos/slicecredentials/(?P<pk>[a-zA-Z0-9\-]+)/$', SliceCredentialDetail.as_view(), name ='slicecredential-detail'),
     
-        url(r'xos/instances/$', InstanceList.as_view(), name='instance-list'),
-        url(r'xos/instances/(?P<pk>[a-zA-Z0-9\-]+)/$', InstanceDetail.as_view(), name ='instance-detail'),
-    
         url(r'xos/nodes/$', NodeList.as_view(), name='node-list'),
         url(r'xos/nodes/(?P<pk>[a-zA-Z0-9\-]+)/$', NodeDetail.as_view(), name ='node-detail'),
     
@@ -156,9 +155,6 @@
         url(r'xos/controllers/$', ControllerList.as_view(), name='controller-list'),
         url(r'xos/controllers/(?P<pk>[a-zA-Z0-9\-]+)/$', ControllerDetail.as_view(), name ='controller-detail'),
     
-        url(r'xos/ports/$', PortList.as_view(), name='port-list'),
-        url(r'xos/ports/(?P<pk>[a-zA-Z0-9\-]+)/$', PortDetail.as_view(), name ='port-detail'),
-    
         url(r'xos/users/$', UserList.as_view(), name='user-list'),
         url(r'xos/users/(?P<pk>[a-zA-Z0-9\-]+)/$', UserDetail.as_view(), name ='user-detail'),
     
@@ -204,6 +200,9 @@
         url(r'xos/sitedeployments/$', SiteDeploymentList.as_view(), name='sitedeployment-list'),
         url(r'xos/sitedeployments/(?P<pk>[a-zA-Z0-9\-]+)/$', SiteDeploymentDetail.as_view(), name ='sitedeployment-detail'),
     
+        url(r'xos/tenantwithcontainers/$', TenantWithContainerList.as_view(), name='tenantwithcontainer-list'),
+        url(r'xos/tenantwithcontainers/(?P<pk>[a-zA-Z0-9\-]+)/$', TenantWithContainerDetail.as_view(), name ='tenantwithcontainer-detail'),
+    
         url(r'xos/deploymentroles/$', DeploymentRoleList.as_view(), name='deploymentrole-list'),
         url(r'xos/deploymentroles/(?P<pk>[a-zA-Z0-9\-]+)/$', DeploymentRoleDetail.as_view(), name ='deploymentrole-detail'),
     
@@ -245,8 +244,8 @@
         'tags': reverse('tag-list', request=request, format=format),
         'invoices': reverse('invoice-list', request=request, format=format),
         'sliceprivileges': reverse('sliceprivilege-list', request=request, format=format),
-        'networkinstances': reverse('networkinstance-list', request=request, format=format),
         'flavors': reverse('flavor-list', request=request, format=format),
+        'ports': reverse('port-list', request=request, format=format),
         'controllersites': reverse('controllersite-list', request=request, format=format),
         'projects': reverse('project-list', request=request, format=format),
         'slices': reverse('slice-list', request=request, format=format),
@@ -255,13 +254,13 @@
         'serviceclasses': reverse('serviceclass-list', request=request, format=format),
         'payments': reverse('payment-list', request=request, format=format),
         'subscribers': reverse('subscriber-list', request=request, format=format),
+        'instances': reverse('instance-list', request=request, format=format),
         'charges': reverse('charge-list', request=request, format=format),
         'programs': reverse('program-list', request=request, format=format),
         'roles': reverse('role-list', request=request, format=format),
         'usableobjects': reverse('usableobject-list', request=request, format=format),
         'providers': reverse('provider-list', request=request, format=format),
         'slicecredentials': reverse('slicecredential-list', request=request, format=format),
-        'instances': reverse('instance-list', request=request, format=format),
         'nodes': reverse('node-list', request=request, format=format),
         'dashboardviews': reverse('dashboardview-list', request=request, format=format),
         'controllernetworks': reverse('controllernetwork-list', request=request, format=format),
@@ -272,7 +271,6 @@
         'networkslices': reverse('networkslice-list', request=request, format=format),
         'userdashboardviews': reverse('userdashboardview-list', request=request, format=format),
         'controllers': reverse('controller-list', request=request, format=format),
-        'ports': reverse('port-list', request=request, format=format),
         'users': reverse('user-list', request=request, format=format),
         'deployments': reverse('deployment-list', request=request, format=format),
         'reservations': reverse('reservation-list', request=request, format=format),
@@ -288,6 +286,7 @@
         'deploymentprivileges': reverse('deploymentprivilege-list', request=request, format=format),
         'controllersliceprivileges': reverse('controllersliceprivilege-list', request=request, format=format),
         'sitedeployments': reverse('sitedeployment-list', request=request, format=format),
+        'tenantwithcontainers': reverse('tenantwithcontainer-list', request=request, format=format),
         'deploymentroles': reverse('deploymentrole-list', request=request, format=format),
         'usercredentials': reverse('usercredential-list', request=request, format=format),
         'tenantrootprivileges': reverse('tenantrootprivilege-list', request=request, format=format),
@@ -791,41 +790,6 @@
 
 
 
-class NetworkInstanceSerializer(serializers.HyperlinkedModelSerializer):
-    id = IdField()
-    
-    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
-    validators = serializers.SerializerMethodField("getValidators")
-    def getHumanReadableName(self, obj):
-        return str(obj)
-    def getValidators(self, obj):
-        try:
-            return obj.getValidators()
-        except:
-            return None
-    class Meta:
-        model = NetworkInstance
-        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','network','instance','ip','port_id',)
-
-class NetworkInstanceIdSerializer(XOSModelSerializer):
-    id = IdField()
-    
-    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
-    validators = serializers.SerializerMethodField("getValidators")
-    def getHumanReadableName(self, obj):
-        return str(obj)
-    def getValidators(self, obj):
-        try:
-            return obj.getValidators()
-        except:
-            return None
-    class Meta:
-        model = NetworkInstance
-        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','network','instance','ip','port_id',)
-
-
-
-
 class FlavorSerializer(serializers.HyperlinkedModelSerializer):
     id = IdField()
     
@@ -869,6 +833,41 @@
 
 
 
+class PortSerializer(serializers.HyperlinkedModelSerializer):
+    id = IdField()
+    
+    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
+    validators = serializers.SerializerMethodField("getValidators")
+    def getHumanReadableName(self, obj):
+        return str(obj)
+    def getValidators(self, obj):
+        try:
+            return obj.getValidators()
+        except:
+            return None
+    class Meta:
+        model = Port
+        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','network','instance','ip','port_id','mac',)
+
+class PortIdSerializer(XOSModelSerializer):
+    id = IdField()
+    
+    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
+    validators = serializers.SerializerMethodField("getValidators")
+    def getHumanReadableName(self, obj):
+        return str(obj)
+    def getValidators(self, obj):
+        try:
+            return obj.getValidators()
+        except:
+            return None
+    class Meta:
+        model = Port
+        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','network','instance','ip','port_id','mac',)
+
+
+
+
 class ControllerSiteSerializer(serializers.HyperlinkedModelSerializer):
     id = IdField()
     
@@ -961,7 +960,7 @@
             return None
     class Meta:
         model = Slice
-        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','name','enabled','omf_friendly','description','slice_url','site','max_instance','service','network','serviceClass','creator','default_flavor','default_image','mount_data_sets','networks','networks',)
+        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','name','enabled','omf_friendly','description','slice_url','site','max_instances','service','network','serviceClass','creator','default_flavor','default_image','mount_data_sets','networks','networks',)
 
 class SliceIdSerializer(XOSModelSerializer):
     id = IdField()
@@ -989,6 +988,7 @@
 
 
 
+
 class NetworkSerializer(serializers.HyperlinkedModelSerializer):
     id = IdField()
     
@@ -1204,6 +1204,49 @@
 
 
 
+class InstanceSerializer(serializers.HyperlinkedModelSerializer):
+    id = IdField()
+    
+    
+    networks = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='network-detail')
+    
+    
+    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
+    validators = serializers.SerializerMethodField("getValidators")
+    def getHumanReadableName(self, obj):
+        return str(obj)
+    def getValidators(self, obj):
+        try:
+            return obj.getValidators()
+        except:
+            return None
+    class Meta:
+        model = Instance
+        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','instance_id','instance_uuid','name','instance_name','ip','image','creator','slice','deployment','node','numberCores','flavor','userData','networks',)
+
+class InstanceIdSerializer(XOSModelSerializer):
+    id = IdField()
+    
+    
+    networks = serializers.PrimaryKeyRelatedField(many=True,  queryset = Network.objects.all())
+    
+    
+    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
+    validators = serializers.SerializerMethodField("getValidators")
+    def getHumanReadableName(self, obj):
+        return str(obj)
+    def getValidators(self, obj):
+        try:
+            return obj.getValidators()
+        except:
+            return None
+    class Meta:
+        model = Instance
+        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','instance_id','instance_uuid','name','instance_name','ip','image','creator','slice','deployment','node','numberCores','flavor','userData','networks',)
+
+
+
+
 class ChargeSerializer(serializers.HyperlinkedModelSerializer):
     id = IdField()
     
@@ -1414,59 +1457,6 @@
 
 
 
-class InstanceSerializer(serializers.HyperlinkedModelSerializer):
-    id = IdField()
-    
-    
-    networks = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='network-detail')
-    
-    
-    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
-    validators = serializers.SerializerMethodField("getValidators")
-    def getHumanReadableName(self, obj):
-        return str(obj)
-    def getValidators(self, obj):
-        try:
-            return obj.getValidators()
-        except:
-            return None
-    class Meta:
-<<<<<<< HEAD
-        model = Instance
-        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','instance_id','instance_uuid','name','instance_name','ip','image','creator','slice','deployment','node','numberCores','flavor','userData','networks',)
-=======
-        model = Instance
-        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','instance_id','instance_uuid','name','instance_name','ip','image','creator','slice','deployment','node','numberCores','flavor','userData','networks',)
->>>>>>> origin/master
-
-class InstanceIdSerializer(XOSModelSerializer):
-    id = IdField()
-    
-    
-    networks = serializers.PrimaryKeyRelatedField(many=True,  queryset = Network.objects.all())
-    
-    
-    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
-    validators = serializers.SerializerMethodField("getValidators")
-    def getHumanReadableName(self, obj):
-        return str(obj)
-    def getValidators(self, obj):
-        try:
-            return obj.getValidators()
-        except:
-            return None
-    class Meta:
-<<<<<<< HEAD
-        model = Instance
-        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','instance_id','instance_uuid','name','instance_name','ip','image','creator','slice','deployment','node','numberCores','flavor','userData','networks',)
-=======
-        model = Instance
-        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','instance_id','instance_uuid','name','instance_name','ip','image','creator','slice','deployment','node','numberCores','flavor','userData','networks',)
->>>>>>> origin/master
-
-
-
-
 class NodeSerializer(serializers.HyperlinkedModelSerializer):
     id = IdField()
     
@@ -1724,7 +1714,6 @@
     class Meta:
         model = NetworkTemplate
         fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','name','description','guaranteed_bandwidth','visibility','translation','shared_network_name','shared_network_id','topology_kind','controller_kind',)
->>>>>>> origin/master
 
 
 
@@ -1842,41 +1831,6 @@
 
 
 
-class PortSerializer(serializers.HyperlinkedModelSerializer):
-    id = IdField()
-    
-    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
-    validators = serializers.SerializerMethodField("getValidators")
-    def getHumanReadableName(self, obj):
-        return str(obj)
-    def getValidators(self, obj):
-        try:
-            return obj.getValidators()
-        except:
-            return None
-    class Meta:
-        model = Port
-        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','network','instance','ip','port_id',)
-
-class PortIdSerializer(XOSModelSerializer):
-    id = IdField()
-    
-    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
-    validators = serializers.SerializerMethodField("getValidators")
-    def getHumanReadableName(self, obj):
-        return str(obj)
-    def getValidators(self, obj):
-        try:
-            return obj.getValidators()
-        except:
-            return None
-    class Meta:
-        model = Port
-        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','network','instance','ip','port_id',)
-
-
-
-
 class UserSerializer(serializers.HyperlinkedModelSerializer):
     id = IdField()
     
@@ -2434,6 +2388,41 @@
 
 
 
+class TenantWithContainerSerializer(serializers.HyperlinkedModelSerializer):
+    id = IdField()
+    
+    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
+    validators = serializers.SerializerMethodField("getValidators")
+    def getHumanReadableName(self, obj):
+        return str(obj)
+    def getValidators(self, obj):
+        try:
+            return obj.getValidators()
+        except:
+            return None
+    class Meta:
+        model = TenantWithContainer
+        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','kind','provider_service','subscriber_service','subscriber_tenant','subscriber_user','subscriber_root','service_specific_id','service_specific_attribute','connect_method',)
+
+class TenantWithContainerIdSerializer(XOSModelSerializer):
+    id = IdField()
+    
+    humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
+    validators = serializers.SerializerMethodField("getValidators")
+    def getHumanReadableName(self, obj):
+        return str(obj)
+    def getValidators(self, obj):
+        try:
+            return obj.getValidators()
+        except:
+            return None
+    class Meta:
+        model = TenantWithContainer
+        fields = ('humanReadableName', 'validators', 'id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','kind','provider_service','subscriber_service','subscriber_tenant','subscriber_user','subscriber_root','service_specific_id','service_specific_attribute','connect_method',)
+
+
+
+
 class DeploymentRoleSerializer(serializers.HyperlinkedModelSerializer):
     id = IdField()
     
@@ -2756,10 +2745,10 @@
 
                  SlicePrivilege: SlicePrivilegeSerializer,
 
-                 NetworkInstance: NetworkInstanceSerializer,
-
                  Flavor: FlavorSerializer,
 
+                 Port: PortSerializer,
+
                  ControllerSite: ControllerSiteSerializer,
 
                  Project: ProjectSerializer,
@@ -2776,6 +2765,8 @@
 
                  Subscriber: SubscriberSerializer,
 
+                 Instance: InstanceSerializer,
+
                  Charge: ChargeSerializer,
 
                  Program: ProgramSerializer,
@@ -2788,8 +2779,6 @@
 
                  SliceCredential: SliceCredentialSerializer,
 
-                 Instance: InstanceSerializer,
-
                  Node: NodeSerializer,
 
                  DashboardView: DashboardViewSerializer,
@@ -2810,8 +2799,6 @@
 
                  Controller: ControllerSerializer,
 
-                 Port: PortSerializer,
-
                  User: UserSerializer,
 
                  Deployment: DeploymentSerializer,
@@ -2842,6 +2829,8 @@
 
                  SiteDeployment: SiteDeploymentSerializer,
 
+                 TenantWithContainer: TenantWithContainerSerializer,
+
                  DeploymentRole: DeploymentRoleSerializer,
 
                  UserCredential: UserCredentialSerializer,
@@ -3428,53 +3417,6 @@
 
 
 
-class NetworkInstanceList(XOSListCreateAPIView):
-    queryset = NetworkInstance.objects.select_related().all()
-    serializer_class = NetworkInstanceSerializer
-    id_serializer_class = NetworkInstanceIdSerializer
-    filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','network','instance','ip','port_id',)
-
-    def get_serializer_class(self):
-        no_hyperlinks=False
-        if hasattr(self.request,"QUERY_PARAMS"):
-            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-
-    def get_queryset(self):
-        if (not self.request.user.is_authenticated()):
-            raise XOSNotAuthenticated()
-        return NetworkInstance.select_by_user(self.request.user)
-
-
-class NetworkInstanceDetail(XOSRetrieveUpdateDestroyAPIView):
-    queryset = NetworkInstance.objects.select_related().all()
-    serializer_class = NetworkInstanceSerializer
-    id_serializer_class = NetworkInstanceIdSerializer
-
-    def get_serializer_class(self):
-        no_hyperlinks=False
-        if hasattr(self.request,"QUERY_PARAMS"):
-            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-
-    def get_queryset(self):
-        if (not self.request.user.is_authenticated()):
-            raise XOSNotAuthenticated()
-        return NetworkInstance.select_by_user(self.request.user)
-
-    # update() is handled by XOSRetrieveUpdateDestroyAPIView
-
-    # destroy() is handled by XOSRetrieveUpdateDestroyAPIView
-
-
-
 class FlavorList(XOSListCreateAPIView):
     queryset = Flavor.objects.select_related().all()
     serializer_class = FlavorSerializer
@@ -3522,6 +3464,53 @@
 
 
 
+class PortList(XOSListCreateAPIView):
+    queryset = Port.objects.select_related().all()
+    serializer_class = PortSerializer
+    id_serializer_class = PortIdSerializer
+    filter_backends = (filters.DjangoFilterBackend,)
+    filter_fields = ('id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','network','instance','ip','port_id','mac',)
+
+    def get_serializer_class(self):
+        no_hyperlinks=False
+        if hasattr(self.request,"QUERY_PARAMS"):
+            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
+        if (no_hyperlinks):
+            return self.id_serializer_class
+        else:
+            return self.serializer_class
+
+    def get_queryset(self):
+        if (not self.request.user.is_authenticated()):
+            raise XOSNotAuthenticated()
+        return Port.select_by_user(self.request.user)
+
+
+class PortDetail(XOSRetrieveUpdateDestroyAPIView):
+    queryset = Port.objects.select_related().all()
+    serializer_class = PortSerializer
+    id_serializer_class = PortIdSerializer
+
+    def get_serializer_class(self):
+        no_hyperlinks=False
+        if hasattr(self.request,"QUERY_PARAMS"):
+            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
+        if (no_hyperlinks):
+            return self.id_serializer_class
+        else:
+            return self.serializer_class
+
+    def get_queryset(self):
+        if (not self.request.user.is_authenticated()):
+            raise XOSNotAuthenticated()
+        return Port.select_by_user(self.request.user)
+
+    # update() is handled by XOSRetrieveUpdateDestroyAPIView
+
+    # destroy() is handled by XOSRetrieveUpdateDestroyAPIView
+
+
+
 class ControllerSiteList(XOSListCreateAPIView):
     queryset = ControllerSite.objects.select_related().all()
     serializer_class = ControllerSiteSerializer
@@ -3898,6 +3887,53 @@
 
 
 
+class InstanceList(XOSListCreateAPIView):
+    queryset = Instance.objects.select_related().all()
+    serializer_class = InstanceSerializer
+    id_serializer_class = InstanceIdSerializer
+    filter_backends = (filters.DjangoFilterBackend,)
+    filter_fields = ('id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','instance_id','instance_uuid','name','instance_name','ip','image','creator','slice','deployment','node','numberCores','flavor','userData','networks',)
+
+    def get_serializer_class(self):
+        no_hyperlinks=False
+        if hasattr(self.request,"QUERY_PARAMS"):
+            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
+        if (no_hyperlinks):
+            return self.id_serializer_class
+        else:
+            return self.serializer_class
+
+    def get_queryset(self):
+        if (not self.request.user.is_authenticated()):
+            raise XOSNotAuthenticated()
+        return Instance.select_by_user(self.request.user)
+
+
+class InstanceDetail(XOSRetrieveUpdateDestroyAPIView):
+    queryset = Instance.objects.select_related().all()
+    serializer_class = InstanceSerializer
+    id_serializer_class = InstanceIdSerializer
+
+    def get_serializer_class(self):
+        no_hyperlinks=False
+        if hasattr(self.request,"QUERY_PARAMS"):
+            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
+        if (no_hyperlinks):
+            return self.id_serializer_class
+        else:
+            return self.serializer_class
+
+    def get_queryset(self):
+        if (not self.request.user.is_authenticated()):
+            raise XOSNotAuthenticated()
+        return Instance.select_by_user(self.request.user)
+
+    # update() is handled by XOSRetrieveUpdateDestroyAPIView
+
+    # destroy() is handled by XOSRetrieveUpdateDestroyAPIView
+
+
+
 class ChargeList(XOSListCreateAPIView):
     queryset = Charge.objects.select_related().all()
     serializer_class = ChargeSerializer
@@ -4180,53 +4216,6 @@
 
 
 
-class InstanceList(XOSListCreateAPIView):
-    queryset = Instance.objects.select_related().all()
-    serializer_class = InstanceSerializer
-    id_serializer_class = InstanceIdSerializer
-    filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','instance_id','instance_uuid','name','instance_name','ip','image','creator','slice','deployment','node','numberCores','flavor','userData','networks',)
-
-    def get_serializer_class(self):
-        no_hyperlinks=False
-        if hasattr(self.request,"QUERY_PARAMS"):
-            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-
-    def get_queryset(self):
-        if (not self.request.user.is_authenticated()):
-            raise XOSNotAuthenticated()
-        return Instance.select_by_user(self.request.user)
-
-
-class InstanceDetail(XOSRetrieveUpdateDestroyAPIView):
-    queryset = Instance.objects.select_related().all()
-    serializer_class = InstanceSerializer
-    id_serializer_class = InstanceIdSerializer
-
-    def get_serializer_class(self):
-        no_hyperlinks=False
-        if hasattr(self.request,"QUERY_PARAMS"):
-            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-
-    def get_queryset(self):
-        if (not self.request.user.is_authenticated()):
-            raise XOSNotAuthenticated()
-        return Instance.select_by_user(self.request.user)
-
-    # update() is handled by XOSRetrieveUpdateDestroyAPIView
-
-    # destroy() is handled by XOSRetrieveUpdateDestroyAPIView
-
-
-
 class NodeList(XOSListCreateAPIView):
     queryset = Node.objects.select_related().all()
     serializer_class = NodeSerializer
@@ -4697,53 +4686,6 @@
 
 
 
-class PortList(XOSListCreateAPIView):
-    queryset = Port.objects.select_related().all()
-    serializer_class = PortSerializer
-    id_serializer_class = PortIdSerializer
-    filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','network','instance','ip','port_id',)
-
-    def get_serializer_class(self):
-        no_hyperlinks=False
-        if hasattr(self.request,"QUERY_PARAMS"):
-            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-
-    def get_queryset(self):
-        if (not self.request.user.is_authenticated()):
-            raise XOSNotAuthenticated()
-        return Port.select_by_user(self.request.user)
-
-
-class PortDetail(XOSRetrieveUpdateDestroyAPIView):
-    queryset = Port.objects.select_related().all()
-    serializer_class = PortSerializer
-    id_serializer_class = PortIdSerializer
-
-    def get_serializer_class(self):
-        no_hyperlinks=False
-        if hasattr(self.request,"QUERY_PARAMS"):
-            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-
-    def get_queryset(self):
-        if (not self.request.user.is_authenticated()):
-            raise XOSNotAuthenticated()
-        return Port.select_by_user(self.request.user)
-
-    # update() is handled by XOSRetrieveUpdateDestroyAPIView
-
-    # destroy() is handled by XOSRetrieveUpdateDestroyAPIView
-
-
-
 class UserList(XOSListCreateAPIView):
     queryset = User.objects.select_related().all()
     serializer_class = UserSerializer
@@ -5449,6 +5391,53 @@
 
 
 
+class TenantWithContainerList(XOSListCreateAPIView):
+    queryset = TenantWithContainer.objects.select_related().all()
+    serializer_class = TenantWithContainerSerializer
+    id_serializer_class = TenantWithContainerIdSerializer
+    filter_backends = (filters.DjangoFilterBackend,)
+    filter_fields = ('id','created','updated','enacted','policed','backend_register','backend_status','deleted','write_protect','lazy_blocked','no_sync','kind','provider_service','subscriber_service','subscriber_tenant','subscriber_user','subscriber_root','service_specific_id','service_specific_attribute','connect_method',)
+
+    def get_serializer_class(self):
+        no_hyperlinks=False
+        if hasattr(self.request,"QUERY_PARAMS"):
+            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
+        if (no_hyperlinks):
+            return self.id_serializer_class
+        else:
+            return self.serializer_class
+
+    def get_queryset(self):
+        if (not self.request.user.is_authenticated()):
+            raise XOSNotAuthenticated()
+        return TenantWithContainer.select_by_user(self.request.user)
+
+
+class TenantWithContainerDetail(XOSRetrieveUpdateDestroyAPIView):
+    queryset = TenantWithContainer.objects.select_related().all()
+    serializer_class = TenantWithContainerSerializer
+    id_serializer_class = TenantWithContainerIdSerializer
+
+    def get_serializer_class(self):
+        no_hyperlinks=False
+        if hasattr(self.request,"QUERY_PARAMS"):
+            no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
+        if (no_hyperlinks):
+            return self.id_serializer_class
+        else:
+            return self.serializer_class
+
+    def get_queryset(self):
+        if (not self.request.user.is_authenticated()):
+            raise XOSNotAuthenticated()
+        return TenantWithContainer.select_by_user(self.request.user)
+
+    # update() is handled by XOSRetrieveUpdateDestroyAPIView
+
+    # destroy() is handled by XOSRetrieveUpdateDestroyAPIView
+
+
+
 class DeploymentRoleList(XOSListCreateAPIView):
     queryset = DeploymentRole.objects.select_related().all()
     serializer_class = DeploymentRoleSerializer
@@ -5822,3 +5811,6 @@
     # update() is handled by XOSRetrieveUpdateDestroyAPIView
 
     # destroy() is handled by XOSRetrieveUpdateDestroyAPIView
+
+
+