Пример #1
0
class Charge(PlCoreBase):
    KIND_CHOICES = (('besteffort', 'besteffort'),
                    ('reservation', 'reservation'), ('monthlyfee',
                                                     'monthlyfee'))
    STATE_CHOICES = (('pending', 'pending'), ('invoiced', 'invoiced'))

    account = models.ForeignKey(Account, related_name="charges")
    slice = models.ForeignKey(Slice,
                              related_name="charges",
                              null=True,
                              blank=True)
    kind = StrippedCharField(max_length=30,
                             choices=KIND_CHOICES,
                             default="besteffort")
    state = StrippedCharField(max_length=30,
                              choices=STATE_CHOICES,
                              default="pending")
    date = models.DateTimeField()
    object = models.ForeignKey(UsableObject)
    amount = models.FloatField(default=0.0)
    coreHours = models.FloatField(default=0.0)
    invoice = models.ForeignKey(Invoice,
                                blank=True,
                                null=True,
                                related_name="charges")
    xos_links = [
        ModelLink(Account, via='account'),
        ModelLink(Slice, via='slice'),
        ModelLink(Invoice, via='invoice')
    ]

    def __unicode__(self):
        return u'%s-%0.2f-%s' % (self.account.site.name, self.amount,
                                 str(self.date))
Пример #2
0
class SiteDeployment(PlCoreBase):
    objects = ControllerLinkManager()
    deleted_objects = ControllerLinkDeletionManager()

    site = models.ForeignKey(Site, related_name='sitedeployments')
    deployment = models.ForeignKey(Deployment, related_name='sitedeployments')
    controller = models.ForeignKey(Controller,
                                   null=True,
                                   blank=True,
                                   related_name='sitedeployments')
    availability_zone = StrippedCharField(
        max_length=200,
        null=True,
        blank=True,
        help_text="OpenStack availability zone")

    xos_links = [
        ModelLink(Site, 'site'),
        ModelLink(Deployment, 'deployment'),
        ModelLink(Controller, 'controller')
    ]

    class Meta:
        unique_together = ('site', 'deployment', 'controller')

    def __unicode__(self):
        return u'%s %s' % (self.deployment, self.site)
Пример #3
0
class SitePrivilege(PlCoreBase):

    user = models.ForeignKey('User', related_name='siteprivileges')
    site = models.ForeignKey('Site', related_name='siteprivileges')
    role = models.ForeignKey('SiteRole', related_name='siteprivileges')

    xos_links = [
        ModelLink(Site, 'site'),
        ModelLink('User', 'user'),
        ModelLink('Role', 'role')
    ]

    def __unicode__(self):
        return u'%s %s %s' % (self.site, self.user, self.role)

    def save(self, *args, **kwds):
        if not self.user.is_active:
            raise PermissionDenied, "Cannot modify role(s) of a disabled user"
        super(SitePrivilege, self).save(*args, **kwds)

    def delete(self, *args, **kwds):
        super(SitePrivilege, self).delete(*args, **kwds)

    def can_update(self, user):
        return user.can_update_site(self, allow=['pi'])

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = SitePrivilege.objects.all()
        else:
            sp_ids = [sp.id for sp in SitePrivilege.objects.filter(user=user)]
            qs = SitePrivilege.objects.filter(id__in=sp_ids)
        return qs
Пример #4
0
class DeploymentPrivilege(PlCoreBase):
    #objects = DeploymentLinkManager()
    #deleted_objects = DeploymentLinkDeletionManager()

    user = models.ForeignKey('User', related_name='deploymentprivileges')
    deployment = models.ForeignKey('Deployment',
                                   related_name='deploymentprivileges')
    role = models.ForeignKey('DeploymentRole',
                             related_name='deploymentprivileges')

    xos_links = [
        ModelLink(Deployment, 'deployment'),
        ModelLink('User', 'user'),
        ModelLink('Role', 'role')
    ]

    class Meta:
        unique_together = ('user', 'deployment', 'role')

    def __unicode__(self):
        return u'%s %s %s' % (self.deployment, self.user, self.role)

    def can_update(self, user):
        return user.can_update_deployment(self)

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = DeploymentPrivilege.objects.all()
        else:
            dpriv_ids = [
                dp.id for dp in DeploymentPrivilege.objects.filter(user=user)
            ]
            qs = DeploymentPrivilege.objects.filter(id__in=dpriv_ids)
        return qs
Пример #5
0
class ControllerSlicePrivilege(PlCoreBase):
    objects = ControllerLinkManager()
    deleted_objects = ControllerLinkDeletionManager()

    controller = models.ForeignKey('Controller', related_name='controllersliceprivileges')
    slice_privilege = models.ForeignKey('SlicePrivilege', related_name='controllersliceprivileges')
    role_id = StrippedCharField(null=True, blank=True, max_length=200, db_index=True, help_text="Keystone id")
    xos_links = [ModelLink(Controller,via='controller'), ModelLink(SlicePrivilege,via='slice_privilege')]


    class Meta:
        unique_together = ('controller', 'slice_privilege')

    def __unicode__(self):  return u'%s %s' % (self.controller, self.slice_privilege)

    def can_update(self, user):
        if user.is_readonly:
            return False
        if user.is_admin:
            return True
        cprivs = ControllerSlicePrivilege.objects.filter(slice_privilege__user=user)
        for cpriv in dprivs:
            if cpriv.role.role == ['admin', 'Admin']:
                return True
        return False

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = ControllerSlicePrivilege.objects.all()
        else:
            cpriv_ids = [cp.id for cp in ControllerSlicePrivilege.objects.filter(slice_privilege__user=user)]
            qs = ControllerSlicePrivilege.objects.filter(id__in=cpriv_ids)
        return qs
Пример #6
0
class ControllerUser(PlCoreBase):
    objects = ControllerLinkManager()
    deleted_objects = ControllerLinkDeletionManager()

    user = models.ForeignKey(User,related_name='controllerusers')
    controller = models.ForeignKey(Controller,related_name='controllersusers')
    kuser_id = StrippedCharField(null=True, blank=True, max_length=200, help_text="Keystone user id")

    xos_links = [ModelLink(Controller,via='controller'), ModelLink(User,via='user')]


    class Meta:
        unique_together = ('user', 'controller')

    def __unicode__(self):  return u'%s %s' % (self.controller, self.user)

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = ControllerUser.objects.all()
        else:
            users = User.select_by_user(user)
            qs = ControllerUser.objects.filter(user__in=users)
        return qs

    def can_update(self, user):
        return user.can_update_root()    
Пример #7
0
class UserDashboardView(PlCoreBase):
    user = models.ForeignKey(User, related_name='userdashboardviews')
    dashboardView = models.ForeignKey(
        DashboardView, related_name='userdashboardviews')
    order = models.IntegerField(default=0)

    xos_links = [ModelLink(User, via='user'), ModelLink(DashboardView,via='userdashboardviews')]
Пример #8
0
class SlicePrivilege(PlCoreBase):
    user = models.ForeignKey('User', related_name='sliceprivileges')
    slice = models.ForeignKey('Slice', related_name='sliceprivileges')
    role = models.ForeignKey('SliceRole', related_name='sliceprivileges')

    xos_links = [
        ModelLink(User, via='user'),
        ModelLink(Slice, via='slice'),
        ModelLink(Role, via='role')
    ]

    class Meta:
        unique_together = ('user', 'slice', 'role')

    def __unicode__(self):
        return u'%s %s %s' % (self.slice, self.user, self.role)

    def save(self, *args, **kwds):
        if not self.user.is_active:
            raise PermissionDenied, "Cannot modify role(s) of a disabled user"
        super(SlicePrivilege, self).save(*args, **kwds)

    def can_update(self, user):
        return user.can_update_slice(self.slice)

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = SlicePrivilege.objects.all()
        else:
            # You can see your own SlicePrivileges
            sp_ids = [sp.id for sp in SlicePrivilege.objects.filter(user=user)]

            # A site pi or site admin can see the SlicePrivileges for all slices in his Site
            for priv in SitePrivilege.objects.filter(user=user):
                if priv.role.role in ['pi', 'admin']:
                    sp_ids.extend([
                        sp.id for sp in SlicePrivilege.objects.filter(
                            slice__site=priv.site)
                    ])

            # A slice admin can see the SlicePrivileges for his Slice
            for priv in SlicePrivilege.objects.filter(user=user,
                                                      role__role="admin"):
                sp_ids.extend([
                    sp.id
                    for sp in SlicePrivilege.objects.filter(slice=priv.slice)
                ])

            qs = SlicePrivilege.objects.filter(id__in=sp_ids)
        return qs
Пример #9
0
class ControllerNetwork(PlCoreBase):
    objects = ControllerLinkManager()
    deleted_objects = ControllerLinkDeletionManager()

    # Stores the openstack ids at various controllers
    network = models.ForeignKey(Network, related_name='controllernetworks')
    controller = models.ForeignKey(Controller,
                                   related_name='controllernetworks')
    subnet = models.CharField(max_length=32, blank=True)
    start_ip = models.CharField(max_length=32, blank=True)
    stop_ip = models.CharField(max_length=32, blank=True)
    net_id = models.CharField(null=True,
                              blank=True,
                              max_length=256,
                              help_text="Neutron network")  # feedback state
    router_id = models.CharField(
        null=True, blank=True, max_length=256,
        help_text="Neutron router id")  # feedback state
    subnet_id = models.CharField(
        null=True, blank=True, max_length=256,
        help_text="Neutron subnet id")  # feedback state
    gateway = models.CharField(max_length=32, blank=True,
                               null=True)  # feedback state
    segmentation_id = models.CharField(max_length=32, blank=True,
                                       null=True)  # feedback state
    xos_links = [
        ModelLink(Controller, via='controller'),
        ModelLink(Network, via='network')
    ]

    class Meta:
        unique_together = ('network', 'controller')

    def tologdict(self):
        d = super(ControllerNetwork, self).tologdict()
        try:
            d['network_name'] = self.network.name
            d['controller_name'] = self.controller.name
        except:
            pass
        return d

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = ControllerNetwork.objects.all()
        else:
            slices = Slice.select_by_user(user)
            networks = Network.objects.filter(owner__in=slices)
            qs = ControllerNetwork.objects.filter(network__in=networks)
        return qs
Пример #10
0
class ControllerSlice(PlCoreBase):
    objects = ControllerLinkManager()
    deleted_objects = ControllerLinkDeletionManager()

    controller = models.ForeignKey(Controller, related_name='controllerslices')
    slice = models.ForeignKey(Slice, related_name='controllerslices')
    tenant_id = StrippedCharField(null=True,
                                  blank=True,
                                  max_length=200,
                                  help_text="Keystone tenant id")

    xos_links = [
        ModelLink(Controller, via='controller'),
        ModelLink(Slice, via='slice')
    ]

    class Meta:
        unique_together = ('controller', 'slice')

    def tologdict(self):
        d = super(ControllerSlice, self).tologdict()
        try:
            d['slice_name'] = self.slice.name
            d['controller_name'] = self.controller.name
        except:
            pass
        return d

    def __unicode__(self):
        return u'%s %s' % (self.slice, self.controller)

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = ControllerSlice.objects.all()
        else:
            slices = Slice.select_by_user(user)
            qs = ControllerSlice.objects.filter(slice__in=slices)
        return qs

    def get_cpu_stats(self):
        filter = 'project_id=%s' % self.tenant_id
        return monitor.get_meter('cpu', filter, None)

    def get_bw_stats(self):
        filter = 'project_id=%s' % self.tenant_id
        return monitor.get_meter('network.outgoing.bytes', filter, None)

    def get_node_stats(self):
        return len(self.slice.instances)
Пример #11
0
class NetworkSlice(PlCoreBase):
    # This object exists solely so we can implement the permission check when
    # adding slices to networks. It adds no additional fields to the relation.

    network = models.ForeignKey(Network, related_name='networkslices')
    slice = models.ForeignKey(Slice, related_name='networkslices')

    xos_links = [
        ModelLink(Network, via='network'),
        ModelLink(Slice, via='slice')
    ]

    class Meta:
        unique_together = ('network', 'slice')

    def save(self, *args, **kwds):
        slice = self.slice
        if (slice not in self.network.permitted_slices.all()) and (
                slice !=
                self.network.owner) and (not self.network.permit_all_slices):
            # to add a instance to the network, then one of the following must be true:
            #   1) instance's slice is in network's permittedSlices list,
            #   2) instance's slice is network's owner, or
            #   3) network's permitAllSlices is true
            raise ValueError(
                "Slice %s is not allowed to connect to network %s" %
                (str(slice), str(self.network)))

        super(NetworkSlice, self).save(*args, **kwds)

    def __unicode__(self):
        return u'%s-%s' % (self.network.name, self.slice.name)

    def can_update(self, user):
        return user.can_update_slice(self.slice)

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = NetworkSlice.objects.all()
        else:
            slice_ids = [s.id for s in Slice.select_by_user(user)]
            network_ids = [
                network.id for network in Network.select_by_user(user)
            ]
            qs = NetworkSlice.objects.filter(
                Q(slice__in=slice_ids) | Q(network__in=network_ids))
        return qs
Пример #12
0
class Account(PlCoreBase):
    site = models.ForeignKey(Site,
                             related_name="accounts",
                             help_text="Site for this account")

    xos_links = [ModelLink(Site, via='site')]

    @property
    def total_invoices(self):
        # Since the amount of an invoice is the sum of it's charges, we can
        # compute the sum of the invoices by summing all charges where
        # charge.invoice != Null.
        x = self.charges.filter(invoice__isnull=False).aggregate(
            Sum('amount'))["amount__sum"]
        if (x == None):
            return 0.0
        return x

    @property
    def total_payments(self):
        x = self.payments.all().aggregate(Sum('amount'))["amount__sum"]
        if (x == None):
            return 0.0
        return x

    @property
    def balance_due(self):
        return self.total_invoices - self.total_payments

    def __unicode__(self):
        return u'%s' % (self.site.name)
Пример #13
0
class Payment(PlCoreBase):
    account = models.ForeignKey(Account, related_name="payments")
    amount = models.FloatField(default=0.0)
    date = models.DateTimeField(default=timezone.now)

    xos_links = [ModelLink(Account, via='account')]

    def __unicode__(self):
        return u'%s-%0.2f-%s' % (self.account.site.name, self.amount,
                                 str(self.date))
Пример #14
0
class Invoice(PlCoreBase):
    date = models.DateTimeField()
    account = models.ForeignKey(Account, related_name="invoices")

    xos_links = [ModelLink(Account, via='account')]

    @property
    def amount(self):
        return str(self.charges.all().aggregate(Sum('amount'))["amount__sum"])

    def __unicode__(self):
        return u'%s-%s' % (self.account.site.name, str(self.date))
Пример #15
0
class ControllerSite(PlCoreBase):

    site = models.ForeignKey(Site, related_name='controllersite')
    controller = models.ForeignKey(Controller,
                                   null=True,
                                   blank=True,
                                   related_name='controllersite')
    tenant_id = StrippedCharField(null=True,
                                  blank=True,
                                  max_length=200,
                                  db_index=True,
                                  help_text="Keystone tenant id")

    xos_links = [
        ModelLink(Controller, via='controller'),
        ModelLink(Site, via='site')
    ]

    def delete(self, *args, **kwds):
        super(ControllerSite, self).delete(*args, **kwds)

    class Meta:
        unique_together = ('site', 'controller')
class SyncExampleTenant(SyncInstanceUsingAnsible):

    provides = [ExampleTenant]

    observes = ExampleTenant

    requested_interval = 0

    template_name = "exampletenant_playbook.yaml"

    service_key_name = "/opt/xos/synchronizers/exampleservice/exampleservice_private_key"

    watches = [ModelLink(CoarseTenant,via='coarsetenant')]

    def __init__(self, *args, **kwargs):
        super(SyncExampleTenant, self).__init__(*args, **kwargs)

    def fetch_pending(self, deleted):

        if (not deleted):
            objs = ExampleTenant.get_tenant_objects().filter(
                Q(enacted__lt=F('updated')) | Q(enacted=None), Q(lazy_blocked=False))
        else:
            # If this is a deletion we get all of the deleted tenants..
            objs = ExampleTenant.get_deleted_tenant_objects()

        return objs

    def get_exampleservice(self, o):
        if not o.provider_service:
            return None

        exampleservice = ExampleService.get_service_objects().filter(id=o.provider_service.id)

        if not exampleservice:
            return None

        return exampleservice[0]

    # Gets the attributes that are used by the Ansible template but are not
    # part of the set of default attributes.
    def get_extra_attributes(self, o):
        fields = {}
        fields['tenant_message'] = o.tenant_message
        fields['image_name'] = o.image_name
        return fields
Пример #17
0
class UserCredential(PlCoreBase):
    user = models.ForeignKey(
        User,
        related_name='usercredentials',
        help_text="The User this credential is associated with")

    name = models.SlugField(help_text="The credential type, e.g. ec2",
                            max_length=128)
    key_id = StrippedCharField(help_text="The backend id of this credential",
                               max_length=1024)
    enc_value = EncryptedCharField(
        help_text="The key value of this credential", max_length=1024)

    xos_links = [ModelLink(User, via='user')]

    def __unicode__(self):
        return self.name
Пример #18
0
class ControllerCredential(PlCoreBase):
    objects = ControllerLinkManager()
    deleted_objects = ControllerLinkDeletionManager()
    controller = models.ForeignKey(
        Controller,
        related_name='controllercredentials',
        help_text="The User this credential is associated with")

    name = models.SlugField(help_text="The credential type, e.g. ec2",
                            max_length=128)
    key_id = models.CharField(help_text="The backend id of this credential",
                              max_length=1024)
    enc_value = EncryptedCharField(
        help_text="The key value of this credential", max_length=1024)

    xos_links = [ModelLink(Controller, via='controller')]

    def __unicode__(self):
        return self.name
Пример #19
0
class SliceTag(PlCoreBase):
    slice = models.ForeignKey(Slice, related_name='slicetags')

    NAME_CHOICES = (('privatekey', 'Private Key'), ('publickey', 'Public Key'))
    name = StrippedCharField(help_text="The name of this tag",
                             max_length=30,
                             choices=NAME_CHOICES)
    value = StrippedCharField(help_text="The value of this tag",
                              max_length=1024)

    xos_links = [ModelLink(Slice, via='slice')]

    def can_update(self, user):
        return user.can_update_slice(self.slice)

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = SliceTag.objects.all()
        else:
            slices = Slice.select_by_user(user)
            qs = SliceTag.objects.filter(slice__in=slices)
        return qs
Пример #20
0
class Node(PlCoreBase):
    name = StrippedCharField(max_length=200,
                             unique=True,
                             help_text="Name of the Node")
    site_deployment = models.ForeignKey(SiteDeployment, related_name='nodes')
    site = models.ForeignKey(Site, null=True, blank=True, related_name='nodes')
    tags = GenericRelation(Tag)
    xos_links = [ModelLink(Site, 'site')]

    def __unicode__(self):
        return u'%s' % (self.name)

    def __init__(self, *args, **kwargs):
        super(Node, self).__init__(*args, **kwargs)
        self.no_sync = True

    def save(self, *args, **kwds):
        if self.site is None and self.site_deployment is not None:
            self.site = self.site_deployment.site

        super(Node, self).save(*args, **kwds)

    def can_update(self, user):
        return user.can_update_site(self.site, allow=['tech'])
Пример #21
0
class SyncONOSNetcfg(SyncStep):
    provides = [VTNService]
    observes = VTNService
    watches = [
        ModelLink(Node, via='node'),
        ModelLink(AddressPool, via='addresspool')
    ]
    requested_interval = 0

    def __init__(self, **args):
        SyncStep.__init__(self, **args)

    def handle_watched_object(self, o):
        logger.info("handle_watched_object is invoked for object %s" %
                    (str(o)),
                    extra=o.tologdict())
        if (type(o) is Node):  # For Node add/delete/modify
            self.call()
        if (type(o) is AddressPool):  # For public gateways
            self.call()

    def get_node_tag(self, node, tagname):
        tags = Tag.select_by_content_object(node).filter(name=tagname)
        return tags[0].value

    def get_tenants_who_want_config(self):
        tenants = []
        # attribute is comma-separated list
        for ta in TenantAttribute.objects.filter(name="autogenerate"):
            if ta.value:
                for config in ta.value.split(','):
                    if config == "vtn-network-cfg":
                        tenants.append(ta.tenant)
        return tenants

    def save_tenant_attribute(self, tenant, name, value):
        tas = TenantAttribute.objects.filter(tenant=tenant, name=name)
        if tas:
            ta = tas[0]
            if ta.value != value:
                logger.info("updating %s with attribute" % name)
                ta.value = value
                ta.save()
        else:
            logger.info("saving autogenerated config %s" % name)
            ta = TenantAttribute(tenant=tenant, name=name, value=value)
            ta.save()

    # This function currently assumes a single Deployment and Site
    def get_onos_netcfg(self, vtn):
        privateGatewayMac = vtn.privateGatewayMac
        localManagementIp = vtn.localManagementIp
        ovsdbPort = vtn.ovsdbPort
        sshPort = vtn.sshPort
        sshUser = vtn.sshUser
        sshKeyFile = vtn.sshKeyFile
        mgmtSubnetBits = vtn.mgmtSubnetBits
        xosEndpoint = vtn.xosEndpoint
        xosUser = vtn.xosUser
        xosPassword = vtn.xosPassword

        controllerPort = vtn.controllerPort
        if ":" in controllerPort:
            (c_hostname, c_port) = controllerPort.split(":", 1)
            controllerPort = socket.gethostbyname(c_hostname) + ":" + c_port
        else:
            controllerPort = ":" + controllerPort

        data = {
            "apps": {
                "org.opencord.vtn": {
                    "cordvtn": {
                        "privateGatewayMac": privateGatewayMac,
                        "localManagementIp": localManagementIp,
                        "ovsdbPort": ovsdbPort,
                        "ssh": {
                            "sshPort": sshPort,
                            "sshUser": sshUser,
                            "sshKeyFile": sshKeyFile
                        },
                        "xos": {
                            "endpoint": xosEndpoint,
                            "user": xosUser,
                            "password": xosPassword
                        },
                        "publicGateways": [],
                        "nodes": [],
                        "controllers": [controllerPort]
                    }
                }
            }
        }

        # Generate apps->org.opencord.vtn->cordvtn->openstack
        controllers = Controller.objects.all()
        if controllers:
            controller = controllers[0]
            keystone_server = controller.auth_url
            user_name = controller.admin_user
            tenant_name = controller.admin_tenant
            password = controller.admin_password
            openstack = {
                "endpoint": keystone_server,
                "tenant": tenant_name,
                "user": user_name,
                "password": password
            }
            data["apps"]["org.opencord.vtn"]["cordvtn"][
                "openstack"] = openstack

        # Generate apps->org.opencord.vtn->cordvtn->nodes
        nodes = Node.objects.all()
        for node in nodes:
            nodeip = socket.gethostbyname(node.name)

            try:
                bridgeId = self.get_node_tag(node, "bridgeId")
                dataPlaneIntf = self.get_node_tag(node, "dataPlaneIntf")
                dataPlaneIp = self.get_node_tag(node, "dataPlaneIp")
            except:
                logger.error("not adding node %s to the VTN configuration" %
                             node.name)
                continue

            node_dict = {
                "hostname": node.name,
                "hostManagementIp": "%s/%s" % (nodeip, mgmtSubnetBits),
                "bridgeId": bridgeId,
                "dataPlaneIntf": dataPlaneIntf,
                "dataPlaneIp": dataPlaneIp
            }

            # this one is optional
            try:
                node_dict["hostManagementIface"] = self.get_node_tag(
                    node, "hostManagementIface")
            except IndexError:
                pass

            data["apps"]["org.opencord.vtn"]["cordvtn"]["nodes"].append(
                node_dict)

        # Generate apps->org.onosproject.cordvtn->cordvtn->publicGateways
        # Pull the gateway information from vRouter
        try:
            from services.vrouter.models import VRouterService

            vrouters = VRouterService.get_service_objects().all()
            if vrouters:
                for gateway in vrouters[0].get_gateways():
                    gatewayIp = gateway['gateway_ip'].split('/', 1)[0]
                    gatewayMac = gateway['gateway_mac']
                    gateway_dict = {
                        "gatewayIp": gatewayIp,
                        "gatewayMac": gatewayMac
                    }
                    data["apps"]["org.opencord.vtn"]["cordvtn"][
                        "publicGateways"].append(gateway_dict)
        except:
            logger.info(
                "No VRouter service present, not adding publicGateways to config"
            )

        return json.dumps(data, indent=4, sort_keys=True)

    def call(self, **args):
        vtn_service = VTNService.get_service_objects().all()
        if not vtn_service:
            raise Exception("No VTN Service")

        vtn_service = vtn_service[0]

        # Check for autogenerate attribute
        netcfg = self.get_onos_netcfg(vtn_service)

        tenants = self.get_tenants_who_want_config()
        for tenant in tenants:
            self.save_tenant_attribute(tenant,
                                       "rest_onos/v1/network/configuration/",
                                       netcfg)
Пример #22
0
class Instance(PlCoreBase):
    ISOLATION_CHOICES = (('vm', 'Virtual Machine'), ('container', 'Container'),
                         ('container_vm', 'Container In VM'))

    objects = InstanceManager()
    deleted_objects = InstanceDeletionManager()
    instance_id = StrippedCharField(null=True,
                                    blank=True,
                                    max_length=200,
                                    help_text="Nova instance id")
    instance_uuid = StrippedCharField(null=True,
                                      blank=True,
                                      max_length=200,
                                      help_text="Nova instance uuid")
    name = StrippedCharField(max_length=200, help_text="Instance name")
    instance_name = StrippedCharField(blank=True,
                                      null=True,
                                      max_length=200,
                                      help_text="OpenStack generated name")
    ip = models.GenericIPAddressField(help_text="Instance ip address",
                                      blank=True,
                                      null=True)
    image = models.ForeignKey(Image, related_name='instances')
    creator = models.ForeignKey(User,
                                related_name='instances',
                                blank=True,
                                null=True)
    slice = models.ForeignKey(Slice, related_name='instances')
    deployment = models.ForeignKey(Deployment,
                                   verbose_name='deployment',
                                   related_name='instance_deployment')
    node = models.ForeignKey(Node, related_name='instances')
    numberCores = models.IntegerField(verbose_name="Number of Cores",
                                      help_text="Number of cores for instance",
                                      default=0)
    flavor = models.ForeignKey(Flavor,
                               help_text="Flavor of this instance",
                               default=get_default_flavor)
    tags = GenericRelation(Tag)
    userData = models.TextField(
        blank=True,
        null=True,
        help_text="user_data passed to instance during creation")
    isolation = models.CharField(null=False,
                                 blank=False,
                                 max_length=30,
                                 choices=ISOLATION_CHOICES,
                                 default="vm")
    volumes = models.TextField(
        null=True,
        blank=True,
        help_text=
        "Comma-separated list of directories to expose to parent context")
    parent = models.ForeignKey(
        "Instance",
        null=True,
        blank=True,
        help_text="Parent Instance for containers nested inside of VMs")

    xos_links = [
        ModelLink(dest=Slice, via='slice'),
        ModelLink(dest=Image, via='image')
    ]

    def get_controller(self):
        return self.node.site_deployment.controller

    def tologdict(self):
        d = super(Instance, self).tologdict()
        try:
            d['slice_name'] = self.slice.name
            d['controller_name'] = self.get_controller().name
        except:
            pass
        return d

    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
            #   deleting the slice before the instance.
            return u'%s' % self.name
        elif self.instance_name:
            return u'%s' % (self.instance_name)
        elif self.id:
            return u'uninstantiated-%s' % str(self.id)
        elif self.slice:
            return u'unsaved-instance on %s' % self.slice.name
        else:
            return u'unsaved-instance'

    def save(self, *args, **kwds):
        if not self.name:
            self.name = self.slice.name
        if not self.creator and hasattr(self, 'caller'):
            self.creator = self.caller
        if not self.creator:
            raise ValidationError('instance has no creator')

        if (self.isolation == "container") or (self.isolation
                                               == "container_vm"):
            if (self.image.kind != "container"):
                raise ValidationError(
                    "Container instance must use container image")
        elif (self.isolation == "vm"):
            if (self.image.kind != "vm"):
                raise ValidationError("VM instance must use VM image")

        if (self.isolation == "container_vm") and (not self.parent):
            raise ValidationError("Container-vm instance must have a parent")

        if (self.parent) and (self.isolation != "container_vm"):
            raise ValidationError(
                "Parent field can only be set on Container-vm instances")

        if (self.slice.creator != self.creator):
            # Check to make sure there's a slice_privilege for the user. If there
            # isn't, then keystone will throw an exception inside the observer.
            slice_privs = SlicePrivilege.objects.filter(slice=self.slice,
                                                        user=self.creator)
            if not slice_privs:
                raise ValidationError(
                    'instance creator has no privileges on slice')


# XXX smbaker - disabled for now, was causing fault in tenant view create slice
#        if not self.controllerNetwork.test_acl(slice=self.slice):
#            raise exceptions.ValidationError("Deployment %s's ACL does not allow any of this slice %s's users" % (self.controllerNetwork.name, self.slice.name))

        super(Instance, self).save(*args, **kwds)

    def can_update(self, user):
        return user.can_update_slice(self.slice)

    def all_ips(self):
        ips = {}
        for ns in self.ports.all():
            if ns.ip:
                ips[ns.network.name] = ns.ip
        return ips

    def all_ips_string(self):
        result = []
        ips = self.all_ips()
        for key in sorted(ips.keys()):
            #result.append("%s = %s" % (key, ips[key]))
            result.append(ips[key])
        return ", ".join(result)

    all_ips_string.short_description = "addresses"

    def get_public_ip(self):
        for ns in self.ports.all():
            if (ns.ip) and (ns.network.template.visibility
                            == "public") and (ns.network.template.translation
                                              == "none"):
                return ns.ip
        return None

    # return an address on nat-net
    def get_network_ip(self, pattern):
        for ns in self.ports.all():
            if pattern in ns.network.name.lower():
                return ns.ip
        return None

    # return an address that the synchronizer can use to SSH to the instance
    def get_ssh_ip(self):
        # first look specifically for a management_local network
        for ns in self.ports.all():
            if ns.network.template and ns.network.template.vtn_kind == "MANAGEMENT_LOCAL":
                return ns.ip

        # for compatibility, now look for any management network
        management = self.get_network_ip("management")
        if management:
            return management

        # if all else fails, look for nat-net (for OpenCloud?)
        return self.get_network_ip("nat")

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = Instance.objects.all()
        else:
            slices = Slice.select_by_user(user)
            qs = Instance.objects.filter(slice__in=slices)
        return qs

    def get_cpu_stats(self):
        filter = 'instance_id=%s' % self.instance_id
        return monitor.get_meter('cpu', filter, None)

    def get_bw_stats(self):
        filter = 'instance_id=%s' % self.instance_id
        return monitor.get_meter('network.outgoing.bytes', filter, None)

    def get_node_stats(self):
        # Note sure what should go back here
        return 1

    def get_ssh_command(self):
        if (not self.instance_id) or (not self.node) or (
                not self.instance_name):
            return None
        else:
            return 'ssh -o "ProxyCommand ssh -q %s@%s" ubuntu@%s' % (
                self.instance_id, self.node.name, self.instance_name)

    def get_public_keys(self):
        slice_memberships = SlicePrivilege.objects.filter(slice=self.slice)
        pubkeys = set([
            sm.user.public_key for sm in slice_memberships
            if sm.user.public_key
        ])

        if self.creator.public_key:
            pubkeys.add(self.creator.public_key)

        if self.slice.creator.public_key:
            pubkeys.add(self.slice.creator.public_key)

        if self.slice.service and self.slice.service.public_key:
            pubkeys.add(self.slice.service.public_key)

        return pubkeys
Пример #23
0
class SyncVSGTenant(SyncInstanceUsingAnsible):
    provides = [VSGTenant]
    observes = VSGTenant
    requested_interval = 0
    template_name = "sync_vcpetenant.yaml"
    watches = [
        ModelLink(CoarseTenant, via='coarsetenant'),
        ModelLink(ServiceMonitoringAgentInfo, via='monitoringagentinfo')
    ]

    def __init__(self, *args, **kwargs):
        super(SyncVSGTenant, self).__init__(*args, **kwargs)

    def fetch_pending(self, deleted):
        if (not deleted):
            objs = VSGTenant.get_tenant_objects().filter(
                Q(enacted__lt=F('updated')) | Q(enacted=None),
                Q(lazy_blocked=False))
        else:
            objs = VSGTenant.get_deleted_tenant_objects()

        return objs

    def get_vcpe_service(self, o):
        if not o.provider_service:
            return None

        vcpes = VSGService.get_service_objects().filter(
            id=o.provider_service.id)
        if not vcpes:
            return None

        return vcpes[0]

    def get_extra_attributes(self, o):
        # This is a place to include extra attributes that aren't part of the
        # object itself. In the case of vCPE, we need to know:
        #   1) the addresses of dnsdemux, to setup dnsmasq in the vCPE
        #   2) CDN prefixes, so we know what URLs to send to dnsdemux
        #   3) BroadBandShield server addresses, for parental filtering
        #   4) vlan_ids, for setting up networking in the vCPE VM

        vcpe_service = self.get_vcpe_service(o)

        dnsdemux_ip = None
        cdn_prefixes = []

        cdn_config_fn = "/opt/xos/synchronizers/vsg/cdn_config"
        if os.path.exists(cdn_config_fn):
            # manual CDN configuration
            #   the first line is the address of dnsredir
            #   the remaining lines are domain names, one per line
            lines = file(cdn_config_fn).readlines()
            if len(lines) >= 2:
                dnsdemux_ip = lines[0].strip()
                cdn_prefixes = [x.strip() for x in lines[1:] if x.strip()]
        elif hpc_service_onboarded:
            # automatic CDN configuiration
            #    it learns everything from CDN objects in XOS
            #    not tested on pod.
            if vcpe_service.backend_network_label:
                # Connect to dnsdemux using the network specified by
                #     vcpe_service.backend_network_label
                for service in HpcService.objects.all():
                    for slice in service.slices.all():
                        if "dnsdemux" in slice.name:
                            for instance in slice.instances.all():
                                for ns in instance.ports.all():
                                    if ns.ip and ns.network.labels and (
                                            vcpe_service.backend_network_label
                                            in ns.network.labels):
                                        dnsdemux_ip = ns.ip
                if not dnsdemux_ip:
                    logger.info("failed to find a dnsdemux on network %s" %
                                vcpe_service.backend_network_label,
                                extra=o.tologdict())
            else:
                # Connect to dnsdemux using the instance's public address
                for service in HpcService.objects.all():
                    for slice in service.slices.all():
                        if "dnsdemux" in slice.name:
                            for instance in slice.instances.all():
                                if dnsdemux_ip == "none":
                                    try:
                                        dnsdemux_ip = socket.gethostbyname(
                                            instance.node.name)
                                    except:
                                        pass
                if not dnsdemux_ip:
                    logger.info(
                        "failed to find a dnsdemux with a public address",
                        extra=o.tologdict())

            for prefix in CDNPrefix.objects.all():
                cdn_prefixes.append(prefix.prefix)

        dnsdemux_ip = dnsdemux_ip or "none"

        # Broadbandshield can either be set up internally, using vcpe_service.bbs_slice,
        # or it can be setup externally using vcpe_service.bbs_server.

        bbs_addrs = []
        if vcpe_service.bbs_slice:
            if vcpe_service.backend_network_label:
                for bbs_instance in vcpe_service.bbs_slice.instances.all():
                    for ns in bbs_instance.ports.all():
                        if ns.ip and ns.network.labels and (
                                vcpe_service.backend_network_label
                                in ns.network.labels):
                            bbs_addrs.append(ns.ip)
            else:
                logger.info(
                    "unsupported configuration -- bbs_slice is set, but backend_network_label is not",
                    extra=o.tologdict())
            if not bbs_addrs:
                logger.info("failed to find any usable addresses on bbs_slice",
                            extra=o.tologdict())
        elif vcpe_service.bbs_server:
            bbs_addrs.append(vcpe_service.bbs_server)
        else:
            logger.info(
                "neither bbs_slice nor bbs_server is configured in the vCPE",
                extra=o.tologdict())

        s_tags = []
        c_tags = []
        if o.volt:
            s_tags.append(o.volt.s_tag)
            c_tags.append(o.volt.c_tag)

        try:
            full_setup = Config().observer_full_setup
        except:
            full_setup = True

        safe_macs = []
        if vcpe_service.url_filter_kind == "safebrowsing":
            if o.volt and o.volt.subscriber:
                for user in o.volt.subscriber.devices:
                    level = user.get("level", None)
                    mac = user.get("mac", None)
                    if level in ["G", "PG"]:
                        if mac:
                            safe_macs.append(mac)

        docker_opts = []
        if vcpe_service.docker_insecure_registry:
            reg_name = vcpe_service.docker_image_name.split("/", 1)[0]
            docker_opts.append("--insecure-registry " + reg_name)

        fields = {
            "s_tags": s_tags,
            "c_tags": c_tags,
            "docker_remote_image_name": vcpe_service.docker_image_name,
            "docker_local_image_name": vcpe_service.
            docker_image_name,  # vcpe_service.docker_image_name.split("/",1)[1].split(":",1)[0],
            "docker_opts": " ".join(docker_opts),
            "dnsdemux_ip": dnsdemux_ip,
            "cdn_prefixes": cdn_prefixes,
            "bbs_addrs": bbs_addrs,
            "full_setup": full_setup,
            "isolation": o.instance.isolation,
            "safe_browsing_macs": safe_macs,
            "container_name": "vcpe-%s-%s" % (s_tags[0], c_tags[0]),
            "dns_servers":
            [x.strip() for x in vcpe_service.dns_servers.split(",")],
            "url_filter_kind": vcpe_service.url_filter_kind
        }

        # add in the sync_attributes that come from the SubscriberRoot object

        if o.volt and o.volt.subscriber and hasattr(o.volt.subscriber,
                                                    "sync_attributes"):
            for attribute_name in o.volt.subscriber.sync_attributes:
                fields[attribute_name] = getattr(o.volt.subscriber,
                                                 attribute_name)

        return fields

    def sync_fields(self, o, fields):
        # the super causes the playbook to be run

        super(SyncVSGTenant, self).sync_fields(o, fields)

        # now do all of our broadbandshield stuff...

        service = self.get_vcpe_service(o)
        if not service:
            # Ansible uses the service's keypair in order to SSH into the
            # instance. It would be bad if the slice had no service.

            raise Exception("Slice %s is not associated with a service" %
                            instance.slice.name)

        # Make sure the slice is configured properly
        if (service != o.instance.slice.service):
            raise Exception(
                "Slice %s is associated with some service that is not %s" %
                (str(instance.slice), str(service)))

        # only enable filtering if we have a subscriber object (see below)
        url_filter_enable = False

        # for attributes that come from CordSubscriberRoot
        if o.volt and o.volt.subscriber:
            url_filter_enable = o.volt.subscriber.url_filter_enable
            url_filter_level = o.volt.subscriber.url_filter_level
            url_filter_users = o.volt.subscriber.devices

        if service.url_filter_kind == "broadbandshield":
            # disable url_filter if there are no bbs_addrs
            if url_filter_enable and (not fields.get("bbs_addrs", [])):
                logger.info(
                    "disabling url_filter because there are no bbs_addrs",
                    extra=o.tologdict())
                url_filter_enable = False

            if url_filter_enable:
                bbs_hostname = None
                if service.bbs_api_hostname and service.bbs_api_port:
                    bbs_hostname = service.bbs_api_hostname
                else:
                    # TODO: extract from slice
                    bbs_hostname = "cordcompute01.onlab.us"

                if service.bbs_api_port:
                    bbs_port = service.bbs_api_port
                else:
                    bbs_port = 8018

                if not bbs_hostname:
                    logger.info("broadbandshield is not configured",
                                extra=o.tologdict())
                else:
                    tStart = time.time()
                    bbs = BBS(o.bbs_account, "123", bbs_hostname, bbs_port)
                    bbs.sync(url_filter_level, url_filter_users)

                    if o.hpc_client_ip:
                        logger.info("associate account %s with ip %s" %
                                    (o.bbs_account, o.hpc_client_ip),
                                    extra=o.tologdict())
                        bbs.associate(o.hpc_client_ip)
                    else:
                        logger.info("no hpc_client_ip to associate",
                                    extra=o.tologdict())

                    logger.info("bbs update time %d" %
                                int(time.time() - tStart),
                                extra=o.tologdict())

    def run_playbook(self, o, fields):
        ansible_hash = hashlib.md5(repr(sorted(fields.items()))).hexdigest()
        quick_update = (o.last_ansible_hash == ansible_hash)

        if ENABLE_QUICK_UPDATE and quick_update:
            logger.info("quick_update triggered; skipping ansible recipe",
                        extra=o.tologdict())
        else:
            if o.instance.isolation in ["container", "container_vm"]:
                super(SyncVSGTenant,
                      self).run_playbook(o, fields, "sync_vcpetenant_new.yaml")
            else:
                if CORD_USE_VTN:
                    super(SyncVSGTenant, self).run_playbook(
                        o, fields, template_name="sync_vcpetenant_vtn.yaml")
                else:
                    super(SyncVSGTenant, self).run_playbook(o, fields)

        o.last_ansible_hash = ansible_hash

    def delete_record(self, m):
        pass

    def handle_service_monitoringagentinfo_watch_notification(
            self, monitoring_agent_info):
        if not monitoring_agent_info.service:
            logger.info(
                "handle watch notifications for service monitoring agent info...ignoring because service attribute in monitoring agent info:%s is null"
                % (monitoring_agent_info))
            return

        if not monitoring_agent_info.target_uri:
            logger.info(
                "handle watch notifications for service monitoring agent info...ignoring because target_uri attribute in monitoring agent info:%s is null"
                % (monitoring_agent_info))
            return

        objs = VSGTenant.get_tenant_objects().all()
        for obj in objs:
            if obj.provider_service.id != monitoring_agent_info.service.id:
                logger.info(
                    "handle watch notifications for service monitoring agent info...ignoring because service attribute in monitoring agent info:%s is not matching"
                    % (monitoring_agent_info))
                return

            instance = self.get_instance(obj)
            if not instance:
                logger.warn(
                    "handle watch notifications for service monitoring agent info...: No valid instance found for object %s"
                    % (str(obj)))
                return

            logger.info(
                "handling watch notification for monitoring agent info:%s for VSGTenant object:%s"
                % (monitoring_agent_info, obj))

            #Run ansible playbook to update the routing table entries in the instance
            fields = self.get_ansible_fields(instance)
            fields["ansible_tag"] = obj.__class__.__name__ + "_" + str(
                obj.id) + "_service_monitoring"

            #Parse the monitoring agent target_uri
            url = urlparse(monitoring_agent_info.target_uri)

            #Assuming target_uri is rabbitmq URI
            fields["rabbit_user"] = url.username
            fields["rabbit_password"] = url.password
            fields["rabbit_host"] = url.hostname

            template_name = "sync_monitoring_agent.yaml"
            super(SyncVSGTenant, self).run_playbook(obj, fields, template_name)
        pass
Пример #24
0
class Port(PlCoreBase, ParameterMixin):
    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="Neutron port id")
    mac = models.CharField(null=True,
                           blank=True,
                           max_length=256,
                           help_text="MAC address associated with this port")
    xos_created = models.BooleanField(
        default=False
    )  # True if XOS created this port in Neutron, False if port created by Neutron and observed by XOS

    xos_links = [
        ModelLink(Network, via='network'),
        ModelLink('Instance', via='instance')
    ]

    class Meta:
        unique_together = ('network', 'instance')

    def save(self, *args, **kwds):
        if self.instance:
            slice = self.instance.slice
            if (slice not in self.network.permitted_slices.all()) and (
                    slice != self.network.owner) and (
                        not self.network.permit_all_slices):
                # to add a instance to the network, then one of the following must be true:
                #   1) instance's slice is in network's permittedSlices list,
                #   2) instance's slice is network's owner, or
                #   3) network's permitAllSlices is true
                raise ValueError(
                    "Slice %s is not allowed to connect to network %s" %
                    (str(slice), str(self.network)))

        super(Port, self).save(*args, **kwds)

    def __unicode__(self):
        if self.instance:
            return u'%s-%s' % (self.network.name, self.instance.instance_name)
        else:
            return u'%s-unboundport-%s' % (self.network.name, self.id)

    def can_update(self, user):
        if self.instance:
            return user.can_update_slice(self.instance.slice)
        if self.network:
            return user.can_update_slice(self.network.owner)
        return False

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = Port.objects.all()
        else:
            instances = Instance.select_by_user(user)
            instance_ids = [instance.id for instance in instances]
            networks = Network.select_by_user(user)
            network_ids = [network.id for network in networks]
            qs = Port.objects.filter(
                Q(instance__in=instance_ids) | Q(network__in=network_ids))
        return qs

    def get_parameters(self):
        # returns parameters from the network, updated by self.
        p = {}
        if self.network:
            p = self.network.get_parameters()
        p.update(ParameterMixin.get_parameters(self))
        return p
Пример #25
0
class Slice(PlCoreBase):
    ISOLATION_CHOICES = (('vm', 'Virtual Machine'), ('container', 'Container'),
                         ('container_vm', 'Container In VM'))
    NETWORK_CHOICES = ((None, 'Default'), ('host', 'Host'),
                       ('bridged', 'Bridged'), ('noauto',
                                                'No Automatic Networks'))

    name = StrippedCharField(unique=True,
                             help_text="The Name of the Slice",
                             max_length=80)
    enabled = models.BooleanField(default=True,
                                  help_text="Status for this Slice")
    omf_friendly = models.BooleanField(default=False)
    description = models.TextField(
        blank=True,
        help_text="High level description of the slice and expected activities",
        max_length=1024)
    slice_url = models.URLField(blank=True, max_length=512)
    site = models.ForeignKey(Site,
                             related_name='slices',
                             help_text="The Site this Slice belongs to")
    max_instances = models.IntegerField(default=10)
    service = models.ForeignKey(Service,
                                related_name='slices',
                                null=True,
                                blank=True)
    network = models.CharField(null=True,
                               blank=True,
                               max_length=256,
                               choices=NETWORK_CHOICES)
    exposed_ports = models.CharField(null=True, blank=True, max_length=256)
    tags = GenericRelation(Tag)
    serviceClass = models.ForeignKey(ServiceClass,
                                     related_name="slices",
                                     null=True,
                                     blank=True)  # DEPRECATED
    creator = models.ForeignKey(User,
                                related_name='slices',
                                blank=True,
                                null=True)

    # for tenant view
    default_flavor = models.ForeignKey(Flavor,
                                       related_name="slices",
                                       null=True,
                                       blank=True)
    default_image = models.ForeignKey(Image,
                                      related_name="slices",
                                      null=True,
                                      blank=True)
    default_node = models.ForeignKey(Node,
                                     related_name="slices",
                                     null=True,
                                     blank=True)
    mount_data_sets = StrippedCharField(default="GenBank",
                                        null=True,
                                        blank=True,
                                        max_length=256)

    default_isolation = models.CharField(null=False,
                                         blank=False,
                                         max_length=30,
                                         choices=ISOLATION_CHOICES,
                                         default="vm")
    xos_links = [ModelLink(Site, 'site'), ModelLink(User, 'user')]

    def __unicode__(self):
        return u'%s' % (self.name)

    @property
    def slicename(self):
        return "%s_%s" % (self.site.login_base, self.name)

    def save(self, *args, **kwds):
        site = Site.objects.get(id=self.site.id)
        # allow preexisting slices to keep their original name for now
        if not self.id and not self.name.startswith(site.login_base):
            raise XOSValidationError('slice name must begin with %s' %
                                     site.login_base)

        if self.name == site.login_base + "_":
            raise XOSValidationError('slice name is too short')

        if " " in self.name:
            raise XOSValidationError('slice name must not contain spaces')

        # set creator on first save
        if not self.creator and hasattr(self, 'caller'):
            self.creator = self.caller

        # only admins change a slice's creator
        if 'creator' in self.changed_fields and \
            (not hasattr(self, 'caller') or not self.caller.is_admin):

            if (self._initial["creator"] == None) and (self.creator == getattr(
                    self, "caller", None)):
                # it's okay if the creator is being set by the caller to
                # himeself on a new slice object.
                pass
            else:
                raise PermissionDenied(
                    "Insufficient privileges to change slice creator")

        if not self.creator:
            raise XOSValidationError('slice has no creator')

        if self.network == "Private Only":
            # "Private Only" was the default from the old Tenant View
            self.network = None
        self.enforce_choices(self.network, self.NETWORK_CHOICES)

        super(Slice, self).save(*args, **kwds)

    def can_update(self, user):
        return user.can_update_slice(self)

    @staticmethod
    def select_by_user(user):
        if user.is_admin:
            qs = Slice.objects.all()
        else:
            # users can see slices they belong to
            slice_ids = [
                sp.slice.id for sp in SlicePrivilege.objects.filter(user=user)
            ]
            # pis and admins can see slices at their sites
            sites = [sp.site for sp in SitePrivilege.objects.filter(user=user)\
                        if (sp.role.role == 'pi') or (sp.role.role == 'admin')]
            slice_ids.extend(
                [s.id for s in Slice.objects.filter(site__in=sites)])
            qs = Slice.objects.filter(id__in=slice_ids)
        return qs

    """
Пример #26
0
class Controller(PlCoreBase):

    objects = ControllerManager()
    deleted_objects = ControllerDeletionManager()

    name = StrippedCharField(max_length=200,
                             unique=True,
                             help_text="Name of the Controller")
    backend_type = StrippedCharField(
        max_length=200,
        help_text=
        "Type of compute controller, e.g. EC2, OpenStack, or OpenStack version"
    )
    version = StrippedCharField(max_length=200, help_text="Controller version")
    auth_url = StrippedCharField(
        max_length=200,
        null=True,
        blank=True,
        help_text="Auth url for the compute controller")
    admin_user = StrippedCharField(
        max_length=200,
        null=True,
        blank=True,
        help_text="Username of an admin user at this controller")
    admin_password = StrippedCharField(
        max_length=200,
        null=True,
        blank=True,
        help_text="Password of theadmin user at this controller")
    admin_tenant = StrippedCharField(
        max_length=200,
        null=True,
        blank=True,
        help_text="Name of the tenant the admin user belongs to")
    domain = StrippedCharField(
        max_length=200,
        null=True,
        blank=True,
        help_text="Name of the domain this controller belongs to")
    rabbit_host = StrippedCharField(
        max_length=200,
        null=True,
        blank=True,
        help_text="IP address of rabbitmq server at this controller")
    rabbit_user = StrippedCharField(
        max_length=200,
        null=True,
        blank=True,
        help_text="Username of rabbitmq server at this controller")
    rabbit_password = StrippedCharField(
        max_length=200,
        null=True,
        blank=True,
        help_text="Password of rabbitmq server at this controller")
    deployment = models.ForeignKey(Deployment,
                                   related_name='controllerdeployments')

    xos_links = [ModelLink(Deployment, via='deployment')]

    def __init__(self, *args, **kwargs):
        super(Controller, self).__init__(*args, **kwargs)
        self.no_sync = True

    def __unicode__(self):
        return u'%s %s %s' % (self.name, self.backend_type, self.version)

    @property
    def auth_url_v3(self):
        if self.auth_url and self.auth_url[-1] == '/':
            return '{}/v3/'.format('/'.join(self.auth_url.split('/')[:-2]))
        else:
            return '{}/v3/'.format('/'.join(self.auth_url.split('/')[:-1]))

    @staticmethod
    def select_by_user(user):

        if user.is_admin:
            qs = Controller.objects.all()
        else:
            deployments = [
                dp.deployment for dp in DeploymentPrivilege.objects.filter(
                    user=user, role__role__in=['Admin', 'admin'])
            ]
            qs = Controller.objects.filter(deployment__in=deployments)
        return qs