def __init__(self, *args, **kwargs):
    volt_services = VOLTService.get_service_objects().all()
    if volt_services:
        self._meta.get_field("provider_service").default = volt_services[0].id
    super(VOLTTenant, self).__init__(*args, **kwargs)
    self.cached_vcpe = None

@property
def vcpe(self):
    from services.vsg.models import VSGTenant
    vcpe = self.get_newest_subscribed_tenant(VSGTenant)
    if not vcpe:
        return None

    # always return the same object when possible
    if (self.cached_vcpe) and (self.cached_vcpe.id == vcpe.id):
        return self.cached_vcpe

    vcpe.caller = self.creator
    self.cached_vcpe = vcpe
    return vcpe

@vcpe.setter
def vcpe(self, value):
    raise XOSConfigurationError("vOLT.vCPE cannot be set this way -- create a new vCPE object and set its subscriber_tenant instead")

@property
def subscriber(self):
    if not self.subscriber_root:
        return None
    subs = CordSubscriberRoot.objects.filter(id=self.subscriber_root.id)
    if not subs:
        return None
    return subs[0]

def manage_vcpe(self):
    # Each VOLT object owns exactly one VCPE object

    if self.deleted:
        return

    # Check to see if the wrong s-tag is set. This can only happen if the
    # user changed the s-tag after the VoltTenant object was created.
    if self.vcpe and self.vcpe.instance:
        s_tags = Tag.select_by_content_object(self.vcpe.instance).filter(name="s_tag")
        if s_tags and (s_tags[0].value != str(self.s_tag)):
            self.vcpe.delete()

    if self.vcpe is None:
        from services.vsg.models import VSGService, VSGTenant
        vsgServices = VSGService.get_service_objects().all()
        if not vsgServices:
            raise XOSConfigurationError("No VSG Services available")

        vcpe = VSGTenant(provider_service = vsgServices[0],
                          subscriber_tenant = self)
        vcpe.caller = self.creator
        vcpe.save()

def manage_subscriber(self):
    if (self.subscriber_root is None):
        # The vOLT is not connected to a Subscriber, so either find an
        # existing subscriber with the same SSID, or autogenerate a new
        # subscriber.
        #
        # TODO: This probably goes away when we rethink the ONOS-to-XOS
        # vOLT API.

        subs = CordSubscriberRoot.get_tenant_objects().filter(service_specific_id = self.service_specific_id)
        if subs:
            sub = subs[0]
        else:
            sub = CordSubscriberRoot(service_specific_id = self.service_specific_id,
                                     name = "autogenerated-for-vOLT-%s" % self.id)
            sub.save()
        self.subscriber_root = sub
        self.save()

def cleanup_vcpe(self):
    if self.vcpe:
        # print "XXX cleanup vcpe", self.vcpe
        self.vcpe.delete()

def cleanup_orphans(self):
    from services.vsg.models import VSGTenant
    # ensure vOLT only has one vCPE
    cur_vcpe = self.vcpe
    for vcpe in list(self.get_subscribed_tenants(VSGTenant)):
        if (not cur_vcpe) or (vcpe.id != cur_vcpe.id):
            # print "XXX clean up orphaned vcpe", vcpe
            vcpe.delete()

def save(self, *args, **kwargs):
    # VOLTTenant probably doesn't need a SSID anymore; that will be handled
    # by CORDSubscriberRoot...
    # self.validate_unique_service_specific_id()

    if (self.subscriber_root is not None):
        subs = self.subscriber_root.get_subscribed_tenants(VOLTTenant)
        if (subs) and (self not in subs):
            raise XOSDuplicateKey("Subscriber should only be linked to one vOLT")

    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("VOLTTenant's self.caller was not set")
        self.creator = self.caller
        if not self.creator:
            raise XOSProgrammingError("VOLTTenant's self.creator was not set")

    super(VOLTTenant, self).save(*args, **kwargs)
    model_policy_volt(self.pk)

def delete(self, *args, **kwargs):
    self.cleanup_vcpe()
    super(VOLTTenant, self).delete(*args, **kwargs)

