diff --git a/xos/models.py b/xos/models.py
index 00193bc..05aeebc 100644
--- a/xos/models.py
+++ b/xos/models.py
@@ -1,349 +1,360 @@
-from django.db import models
-from core.models import Service, PlCoreBase, Slice, Instance, Tenant, TenantWithContainer, Node, Image, User, Flavor, NetworkParameter, NetworkParameterType, Port, AddressPool, User
-from core.models.plcorebase import StrippedCharField
-import os
-from django.db import models, transaction
-from django.forms.models import model_to_dict
-from django.db.models import Q
-from operator import itemgetter, attrgetter, methodcaller
-from core.models import Tag
-from core.models.service import LeastLoadedNodeScheduler
-from services.vrouter.models import VRouterService, VRouterTenant
-import traceback
-from xos.exceptions import *
-from xos.config import Config
+from header import *
 
-class ConfigurationError(Exception):
-    pass
 
-VCPE_KIND = "vCPE"
-CORD_SUBSCRIBER_KIND = "CordSubscriberRoot"
 
-# -------------------------------------------
-# VCPE
-# -------------------------------------------
+#from core.models.service import Service
+from core.models import Service
+
+
+
+#from core.models.tenantwithcontainer import TenantWithContainer
+from core.models import TenantWithContainer
+
+
+
+
 
 class VSGService(Service):
-    KIND = VCPE_KIND
 
-    URL_FILTER_KIND_CHOICES = ( (None, "None"), ("safebrowsing", "Safe Browsing"), ("answerx", "AnswerX") )
+  KIND = "vCPE"
 
-    url_filter_kind = StrippedCharField(max_length=30, choices=URL_FILTER_KIND_CHOICES, null=True, blank=True)
-    dns_servers = StrippedCharField(max_length=255, default="8.8.8.8")
-    node_label = StrippedCharField(max_length=30, null=True, blank=True)
-    docker_image_name = StrippedCharField(max_length=255, default="docker.io/xosproject/vsg")
-    docker_insecure_registry = models.BooleanField(default=False)
+  class Meta:
+      app_label = "vsg"
+      name = "vsg"
+      verbose_name = "vSG Service"
 
-    class Meta:
-        app_label = "vsg"
-        verbose_name = "vSG Service"
+  # Primitive Fields (Not Relations)
+  url_filter_kind = StrippedCharField( blank = True, max_length = 30, null = True, db_index = False, choices = ((None, 'None'), ('safebrowsing', 'Safe Browsing'), ('answerx', 'AnswerX')) )
+  dns_servers = StrippedCharField( default = "8.8.8.8", max_length = 255, null = False, db_index = False, blank = False )
+  node_label = StrippedCharField( db_index = False, max_length = 30, null = True, blank = True )
+  docker_image_name = StrippedCharField( default = "docker.io/xosproject/vsg", max_length = 255, null = False, db_index = False, blank = False )
+  docker_insecure_registry = BooleanField( default = False, null = False, blank = True, db_index = False )
+  
+
+  # Relations
+  
+
+  
+  pass
+
+
+
 
 class VSGTenant(TenantWithContainer):
-    KIND = VCPE_KIND
 
-    # it's not clear we still need this field...
-    last_ansible_hash = StrippedCharField(max_length=128, null=True, blank=True)
+  KIND = "vCPE"
 
-    class Meta:
-        app_label = "vsg"
+  class Meta:
+      app_label = "vsg"
+      name = "vsg"
+      verbose_name = "vSG Service"
 
-    sync_attributes = ("wan_container_ip", "wan_container_mac", "wan_container_netbits",
-                       "wan_container_gateway_ip", "wan_container_gateway_mac",
-                       "wan_vm_ip", "wan_vm_mac")
+  # Primitive Fields (Not Relations)
+  last_ansible_hash = StrippedCharField( db_index = False, max_length = 128, null = True, blank = True )
+  
 
-    def __init__(self, *args, **kwargs):
-        super(VSGTenant, self).__init__(*args, **kwargs)
-        self.cached_vrouter=None
+  # Relations
+  
 
-    @property
-    def vrouter(self):
-        vrouter = self.get_newest_subscribed_tenant(VRouterTenant)
-        if not vrouter:
-            return None
-
-        # always return the same object when possible
-        if (self.cached_vrouter) and (self.cached_vrouter.id == vrouter.id):
-            return self.cached_vrouter
-
-        vrouter.caller = self.creator
-        self.cached_vrouter = vrouter
-        return vrouter
-
-    @vrouter.setter
-    def vrouter(self, value):
-        raise XOSConfigurationError("VSGTenant.vrouter setter is not implemented")
-
-    @property
-    def volt(self):
-        from services.volt.models import VOLTTenant
-        if not self.subscriber_tenant:
-            return None
-        volts = VOLTTenant.objects.filter(id=self.subscriber_tenant.id)
-        if not volts:
-            return None
-        return volts[0]
-
-    @volt.setter
-    def volt(self, value):
-        raise XOSConfigurationError("VSGTenant.volt setter is not implemented")
-
-    @property
-    def ssh_command(self):
-        if self.instance:
-            return self.instance.get_ssh_command()
-        else:
-            return "no-instance"
-
-    def get_vrouter_field(self, name, default=None):
-        if self.vrouter:
-            return getattr(self.vrouter, name, default)
-        else:
-            return default
-
-    @property
-    def wan_container_ip(self):
-        return self.get_vrouter_field("public_ip", None)
-
-    @property
-    def wan_container_mac(self):
-        return self.get_vrouter_field("public_mac", None)
-
-    @property
-    def wan_container_netbits(self):
-        return self.get_vrouter_field("netbits", None)
-
-    @property
-    def wan_container_gateway_ip(self):
-        return self.get_vrouter_field("gateway_ip", None)
-
-    @property
-    def wan_container_gateway_mac(self):
-        return self.get_vrouter_field("gateway_mac", None)
-
-    @property
-    def wan_vm_ip(self):
-        tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
-        if tags:
-            tenant = VRouterTenant.objects.get(id=tags[0].value)
-            return tenant.public_ip
-        else:
-            raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
-
-    @property
-    def wan_vm_mac(self):
-        tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
-        if tags:
-            tenant = VRouterTenant.objects.get(id=tags[0].value)
-            return tenant.public_mac
-        else:
-            raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
-
-    @property
-    def is_synced(self):
-        return (self.enacted is not None) and (self.enacted >= self.updated)
-
-    @is_synced.setter
-    def is_synced(self, value):
-        pass
-
-    def get_vrouter_service(self):
-        vrouterServices = VRouterService.get_service_objects().all()
-        if not vrouterServices:
-            raise XOSConfigurationError("No VROUTER Services available")
-        return vrouterServices[0]
-
-    def manage_vrouter(self):
-        # Each vCPE object owns exactly one vRouterTenant object
-
-        if self.deleted:
-            return
-
-        if self.vrouter is None:
-            vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_tenant = self)
-            vrouter.caller = self.creator
-            vrouter.save()
-
-    def cleanup_vrouter(self):
-        if self.vrouter:
-            # print "XXX cleanup vrouter", self.vrouter
-            self.vrouter.delete()
-
-    def cleanup_orphans(self):
-        # ensure vCPE only has one vRouter
-        cur_vrouter = self.vrouter
-        for vrouter in list(self.get_subscribed_tenants(VRouterTenant)):
-            if (not cur_vrouter) or (vrouter.id != cur_vrouter.id):
-                # print "XXX clean up orphaned vrouter", vrouter
-                vrouter.delete()
-
-        if self.orig_instance_id and (self.orig_instance_id != self.get_attribute("instance_id")):
-            instances=Instance.objects.filter(id=self.orig_instance_id)
-            if instances:
-                # print "XXX clean up orphaned instance", instances[0]
-                instances[0].delete()
-
-    def get_slice(self):
-        if not self.provider_service.slices.count():
-            print self, "dio porco"
-            raise XOSConfigurationError("The service has no slices")
-        slice = self.provider_service.slices.all()[0]
-        return slice
-
-    def get_vsg_service(self):
-        return VSGService.get_service_objects().get(id=self.provider_service.id)
-
-    def find_instance_for_s_tag(self, s_tag):
-        #s_tags = STagBlock.objects.find(s_s_tag)
-        #if s_tags:
-        #    return s_tags[0].instance
-
-        tags = Tag.objects.filter(name="s_tag", value=s_tag)
-        if tags:
-            return tags[0].content_object
-
-        return None
-
-    def find_or_make_instance_for_s_tag(self, s_tag):
-        instance = self.find_instance_for_s_tag(self.volt.s_tag)
-        if instance:
-            return instance
-
-        flavors = Flavor.objects.filter(name="m1.small")
-        if not flavors:
-            raise XOSConfigurationError("No m1.small flavor")
-
-        slice = self.provider_service.slices.all()[0]
-
-        if slice.default_isolation == "container_vm":
-            (node, parent) = ContainerVmScheduler(slice).pick()
-        else:
-            (node, parent) = LeastLoadedNodeScheduler(slice, label=self.get_vsg_service().node_label).pick()
-
-        instance = Instance(slice = slice,
-                        node = node,
-                        image = self.image,
-                        creator = self.creator,
-                        deployment = node.site_deployment.deployment,
-                        flavor = flavors[0],
-                        isolation = slice.default_isolation,
-                        parent = parent)
-
-        self.save_instance(instance)
-
-        return instance
-
-    def manage_container(self):
-        from core.models import Instance, Flavor
-
-        if self.deleted:
-            return
-
-        # For container or container_vm isolation, use what TenantWithCotnainer
-        # provides us
-        slice = self.get_slice()
-        if slice.default_isolation in ["container_vm", "container"]:
-            super(VSGTenant,self).manage_container()
-            return
-
-        if not self.volt:
-            raise XOSConfigurationError("This vCPE container has no volt")
-
-        if self.instance:
-            # We're good.
-            return
-
-        instance = self.find_or_make_instance_for_s_tag(self.volt.s_tag)
-        self.instance = instance
-        super(TenantWithContainer, self).save()
-
-    def cleanup_container(self):
-        if self.get_slice().default_isolation in ["container_vm", "container"]:
-            super(VSGTenant,self).cleanup_container()
-
-        # To-do: cleanup unused instances
-        pass
-
-    def find_or_make_port(self, instance, network, **kwargs):
-        port = Port.objects.filter(instance=instance, network=network)
-        if port:
-            port = port[0]
-        else:
-            port = Port(instance=instance, network=network, **kwargs)
-            port.save()
-        return port
-
-    def get_lan_network(self, instance):
-        slice = self.provider_service.slices.all()[0]
-        # there should only be one network private network, and its template should not be the management template
-        lan_networks = [x for x in slice.networks.all() if x.template.visibility=="private" and (not "management" in x.template.name)]
-        if len(lan_networks)>1:
-            raise XOSProgrammingError("The vSG slice should only have one non-management private network")
-        if not lan_networks:
-            raise XOSProgrammingError("No lan_network")
-        return lan_networks[0]
-
-    def save_instance(self, instance):
-        with transaction.atomic():
-            instance.volumes = "/etc/dnsmasq.d,/etc/ufw"
-            super(VSGTenant, self).save_instance(instance)
-
-            if instance.isolation in ["container", "container_vm"]:
-                lan_network = self.get_lan_network(instance)
-                port = self.find_or_make_port(instance, lan_network, ip="192.168.0.1", port_id="unmanaged")
-                port.set_parameter("c_tag", self.volt.c_tag)
-                port.set_parameter("s_tag", self.volt.s_tag)
-                port.set_parameter("device", "eth1")
-                port.set_parameter("bridge", "br-lan")
-
-                wan_networks = [x for x in instance.slice.networks.all() if "wan" in x.name]
-                if not wan_networks:
-                    raise XOSProgrammingError("No wan_network")
-                port = self.find_or_make_port(instance, wan_networks[0])
-                port.set_parameter("next_hop", value="10.0.1.253")   # FIX ME
-                port.set_parameter("device", "eth0")
-
-            if instance.isolation in ["vm"]:
-                lan_network = self.get_lan_network(instance)
-                port = self.find_or_make_port(instance, lan_network)
-                port.set_parameter("c_tag", self.volt.c_tag)
-                port.set_parameter("s_tag", self.volt.s_tag)
-                port.set_parameter("neutron_port_name", "stag-%s" % self.volt.s_tag)
-                port.save()
-
-            # tag the instance with the s-tag, so we can easily find the
-            # instance later
-            if self.volt and self.volt.s_tag:
-                tags = Tag.objects.filter(name="s_tag", value=self.volt.s_tag)
-                if not tags:
-                    tag = Tag(service=self.provider_service, content_object=instance, name="s_tag", value=self.volt.s_tag)
-                    tag.save()
-
-            # VTN-CORD needs a WAN address for the VM, so that the VM can
-            # be configured.
-            tags = Tag.select_by_content_object(instance).filter(name="vm_vrouter_tenant")
-            if not tags:
-                vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_service = self.provider_service)
-                vrouter.set_attribute("tenant_for_instance_id", instance.id)
-                vrouter.save()
-                tag = Tag(service=self.provider_service, content_object=instance, name="vm_vrouter_tenant", value="%d" % vrouter.id)
-                tag.save()
-
-    def save(self, *args, **kwargs):
-        if not self.creator:
-            if not getattr(self, "caller", None):
-                # caller must be set when creating a vCPE since it creates a slice
-                raise XOSProgrammingError("VSGTenant's self.caller was not set")
-            self.creator = self.caller
-            if not self.creator:
-                raise XOSProgrammingError("VSGTenant's self.creator was not set")
-
-        super(VSGTenant, self).save(*args, **kwargs)
-        model_policy_vcpe(self.pk)
-
-    def delete(self, *args, **kwargs):
-        self.cleanup_vrouter()
-        self.cleanup_container()
-        super(VSGTenant, self).delete(*args, **kwargs)
+  sync_attributes = ("wan_container_ip", "wan_container_mac", "wan_container_netbits",
+                     "wan_container_gateway_ip", "wan_container_gateway_mac",
+                     "wan_vm_ip", "wan_vm_mac")
+  
+  def __init__(self, *args, **kwargs):
+      super(VSGTenant, self).__init__(*args, **kwargs)
+      self.cached_vrouter=None
+  
+  @property
+  def vrouter(self):
+      vrouter = self.get_newest_subscribed_tenant(VRouterTenant)
+      if not vrouter:
+          return None
+  
+      # always return the same object when possible
+      if (self.cached_vrouter) and (self.cached_vrouter.id == vrouter.id):
+          return self.cached_vrouter
+  
+      vrouter.caller = self.creator
+      self.cached_vrouter = vrouter
+      return vrouter
+  
+  @vrouter.setter
+  def vrouter(self, value):
+      raise XOSConfigurationError("VSGTenant.vrouter setter is not implemented")
+  
+  @property
+  def volt(self):
+      from services.volt.models import VOLTTenant
+      if not self.subscriber_tenant:
+          return None
+      volts = VOLTTenant.objects.filter(id=self.subscriber_tenant.id)
+      if not volts:
+          return None
+      return volts[0]
+  
+  @volt.setter
+  def volt(self, value):
+      raise XOSConfigurationError("VSGTenant.volt setter is not implemented")
+  
+  @property
+  def ssh_command(self):
+      if self.instance:
+          return self.instance.get_ssh_command()
+      else:
+          return "no-instance"
+  
+  def get_vrouter_field(self, name, default=None):
+      if self.vrouter:
+          return getattr(self.vrouter, name, default)
+      else:
+          return default
+  
+  @property
+  def wan_container_ip(self):
+      return self.get_vrouter_field("public_ip", None)
+  
+  @property
+  def wan_container_mac(self):
+      return self.get_vrouter_field("public_mac", None)
+  
+  @property
+  def wan_container_netbits(self):
+      return self.get_vrouter_field("netbits", None)
+  
+  @property
+  def wan_container_gateway_ip(self):
+      return self.get_vrouter_field("gateway_ip", None)
+  
+  @property
+  def wan_container_gateway_mac(self):
+      return self.get_vrouter_field("gateway_mac", None)
+  
+  @property
+  def wan_vm_ip(self):
+      tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
+      if tags:
+          tenant = VRouterTenant.objects.get(id=tags[0].value)
+          return tenant.public_ip
+      else:
+          raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
+  
+  @property
+  def wan_vm_mac(self):
+      tags = Tag.select_by_content_object(self.instance).filter(name="vm_vrouter_tenant")
+      if tags:
+          tenant = VRouterTenant.objects.get(id=tags[0].value)
+          return tenant.public_mac
+      else:
+          raise Exception("no vm_vrouter_tenant tag for instance %s" % o.instance)
+  
+  @property
+  def is_synced(self):
+      return (self.enacted is not None) and (self.enacted >= self.updated)
+  
+  @is_synced.setter
+  def is_synced(self, value):
+      pass
+  
+  def get_vrouter_service(self):
+      vrouterServices = VRouterService.get_service_objects().all()
+      if not vrouterServices:
+          raise XOSConfigurationError("No VROUTER Services available")
+      return vrouterServices[0]
+  
+  def manage_vrouter(self):
+      # Each vCPE object owns exactly one vRouterTenant object
+  
+      if self.deleted:
+          return
+  
+      if self.vrouter is None:
+          vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_tenant = self)
+          vrouter.caller = self.creator
+          vrouter.save()
+  
+  def cleanup_vrouter(self):
+      if self.vrouter:
+          # print "XXX cleanup vrouter", self.vrouter
+          self.vrouter.delete()
+  
+  def cleanup_orphans(self):
+      # ensure vCPE only has one vRouter
+      cur_vrouter = self.vrouter
+      for vrouter in list(self.get_subscribed_tenants(VRouterTenant)):
+          if (not cur_vrouter) or (vrouter.id != cur_vrouter.id):
+              # print "XXX clean up orphaned vrouter", vrouter
+              vrouter.delete()
+  
+      if self.orig_instance_id and (self.orig_instance_id != self.get_attribute("instance_id")):
+          instances=Instance.objects.filter(id=self.orig_instance_id)
+          if instances:
+              # print "XXX clean up orphaned instance", instances[0]
+              instances[0].delete()
+  
+  def get_slice(self):
+      if not self.provider_service.slices.count():
+          print self, "dio porco"
+          raise XOSConfigurationError("The service has no slices")
+      slice = self.provider_service.slices.all()[0]
+      return slice
+  
+  def get_vsg_service(self):
+      return VSGService.get_service_objects().get(id=self.provider_service.id)
+  
+  def find_instance_for_s_tag(self, s_tag):
+      #s_tags = STagBlock.objects.find(s_s_tag)
+      #if s_tags:
+      #    return s_tags[0].instance
+  
+      tags = Tag.objects.filter(name="s_tag", value=s_tag)
+      if tags:
+          return tags[0].content_object
+  
+      return None
+  
+  def find_or_make_instance_for_s_tag(self, s_tag):
+      instance = self.find_instance_for_s_tag(self.volt.s_tag)
+      if instance:
+          return instance
+  
+      flavors = Flavor.objects.filter(name="m1.small")
+      if not flavors:
+          raise XOSConfigurationError("No m1.small flavor")
+  
+      slice = self.provider_service.slices.all()[0]
+  
+      if slice.default_isolation == "container_vm":
+          (node, parent) = ContainerVmScheduler(slice).pick()
+      else:
+          (node, parent) = LeastLoadedNodeScheduler(slice, label=self.get_vsg_service().node_label).pick()
+  
+      instance = Instance(slice = slice,
+                      node = node,
+                      image = self.image,
+                      creator = self.creator,
+                      deployment = node.site_deployment.deployment,
+                      flavor = flavors[0],
+                      isolation = slice.default_isolation,
+                      parent = parent)
+  
+      self.save_instance(instance)
+  
+      return instance
+  
+  def manage_container(self):
+      from core.models import Instance, Flavor
+  
+      if self.deleted:
+          return
+  
+      # For container or container_vm isolation, use what TenantWithCotnainer
+      # provides us
+      slice = self.get_slice()
+      if slice.default_isolation in ["container_vm", "container"]:
+          super(VSGTenant,self).manage_container()
+          return
+  
+      if not self.volt:
+          raise XOSConfigurationError("This vCPE container has no volt")
+  
+      if self.instance:
+          # We're good.
+          return
+  
+      instance = self.find_or_make_instance_for_s_tag(self.volt.s_tag)
+      self.instance = instance
+      super(TenantWithContainer, self).save()
+  
+  def cleanup_container(self):
+      if self.get_slice().default_isolation in ["container_vm", "container"]:
+          super(VSGTenant,self).cleanup_container()
+  
+      # To-do: cleanup unused instances
+      pass
+  
+  def find_or_make_port(self, instance, network, **kwargs):
+      port = Port.objects.filter(instance=instance, network=network)
+      if port:
+          port = port[0]
+      else:
+          port = Port(instance=instance, network=network, **kwargs)
+          port.save()
+      return port
+  
+  def get_lan_network(self, instance):
+      slice = self.provider_service.slices.all()[0]
+      # there should only be one network private network, and its template should not be the management template
+      lan_networks = [x for x in slice.networks.all() if x.template.visibility=="private" and (not "management" in x.template.name)]
+      if len(lan_networks)>1:
+          raise XOSProgrammingError("The vSG slice should only have one non-management private network")
+      if not lan_networks:
+          raise XOSProgrammingError("No lan_network")
+      return lan_networks[0]
+  
+  def save_instance(self, instance):
+      with transaction.atomic():
+          instance.volumes = "/etc/dnsmasq.d,/etc/ufw"
+          super(VSGTenant, self).save_instance(instance)
+  
+          if instance.isolation in ["container", "container_vm"]:
+              lan_network = self.get_lan_network(instance)
+              port = self.find_or_make_port(instance, lan_network, ip="192.168.0.1", port_id="unmanaged")
+              port.set_parameter("c_tag", self.volt.c_tag)
+              port.set_parameter("s_tag", self.volt.s_tag)
+              port.set_parameter("device", "eth1")
+              port.set_parameter("bridge", "br-lan")
+  
+              wan_networks = [x for x in instance.slice.networks.all() if "wan" in x.name]
+              if not wan_networks:
+                  raise XOSProgrammingError("No wan_network")
+              port = self.find_or_make_port(instance, wan_networks[0])
+              port.set_parameter("next_hop", value="10.0.1.253")   # FIX ME
+              port.set_parameter("device", "eth0")
+  
+          if instance.isolation in ["vm"]:
+              lan_network = self.get_lan_network(instance)
+              port = self.find_or_make_port(instance, lan_network)
+              port.set_parameter("c_tag", self.volt.c_tag)
+              port.set_parameter("s_tag", self.volt.s_tag)
+              port.set_parameter("neutron_port_name", "stag-%s" % self.volt.s_tag)
+              port.save()
+  
+          # tag the instance with the s-tag, so we can easily find the
+          # instance later
+          if self.volt and self.volt.s_tag:
+              tags = Tag.objects.filter(name="s_tag", value=self.volt.s_tag)
+              if not tags:
+                  tag = Tag(service=self.provider_service, content_object=instance, name="s_tag", value=self.volt.s_tag)
+                  tag.save()
+  
+          # VTN-CORD needs a WAN address for the VM, so that the VM can
+          # be configured.
+          tags = Tag.select_by_content_object(instance).filter(name="vm_vrouter_tenant")
+          if not tags:
+              vrouter = self.get_vrouter_service().get_tenant(address_pool_name="addresses_vsg", subscriber_service = self.provider_service)
+              vrouter.set_attribute("tenant_for_instance_id", instance.id)
+              vrouter.save()
+              tag = Tag(service=self.provider_service, content_object=instance, name="vm_vrouter_tenant", value="%d" % vrouter.id)
+              tag.save()
+  
+  def save(self, *args, **kwargs):
+      if not self.creator:
+          if not getattr(self, "caller", None):
+              # caller must be set when creating a vCPE since it creates a slice
+              raise XOSProgrammingError("VSGTenant's self.caller was not set")
+          self.creator = self.caller
+          if not self.creator:
+              raise XOSProgrammingError("VSGTenant's self.creator was not set")
+  
+      super(VSGTenant, self).save(*args, **kwargs)
+      model_policy_vcpe(self.pk)
+  
+  def delete(self, *args, **kwargs):
+      self.cleanup_vrouter()
+      self.cleanup_container()
+      super(VSGTenant, self).delete(*args, **kwargs)
+  
+  pass
 
 def model_policy_vcpe(pk):
     # TODO: this should be made in to a real model_policy
