class DashboardView(PlCoreBase): name = StrippedCharField(max_length=200, unique=True, help_text="Name of the View") url = StrippedCharField(max_length=1024, help_text="URL of Dashboard") controllers = models.ManyToManyField(Controller, blank=True, related_name="dashboardviews", through='ControllerDashboardView') enabled = models.BooleanField(default=True) icon = models.CharField(max_length=200, default="default-icon.png", help_text="Icon for Dashboard") icon_active = models.CharField(max_length=200, default="default-icon-active.png", help_text="Icon for active Dashboard") deployments = models.ManyToManyField( Deployment, blank=True, null=True, related_name="dashboardviews", help_text="Deployments that should be included in this view") def __unicode__(self): return u'%s' % (self.name)
class XOS(PlCoreBase): name = StrippedCharField(max_length=200, unique=True, help_text="Name of XOS", default="XOS") ui_port = models.IntegerField(help_text="Port for XOS UI", default=80) bootstrap_ui_port = models.IntegerField(help_text="Port for XOS UI", default=81) db_container_name = StrippedCharField(max_length=200, help_text="name of XOS db container", default="xos_db") docker_project_name = StrippedCharField(max_length=200, help_text="docker project name") db_container_name = StrippedCharField(max_length=200, help_text="database container name") enable_build = models.BooleanField(help_text="True if Onboarding Synchronizer should build XOS as necessary", default=True) frontend_only = models.BooleanField(help_text="If True, XOS will not start synchronizer containers", default=False) source_ui_image = StrippedCharField(max_length=200, default="xosproject/xos") def __unicode__(self): return u'%s' % (self.name) def __init__(self, *args, **kwargs): super(XOS, self).__init__(*args, **kwargs) def save(self, *args, **kwds): super(XOS, self).save(*args, **kwds) # def can_update(self, user): # return user.can_update_site(self.site, allow=['tech']) def rebuild(self): for service_controller in self.service_controllers.all(): for scr in service_controller.service_controller_resources.all(): scr.save() service_controller.save() self.save()
class Flavor(PlCoreBase): name = StrippedCharField( max_length=32, help_text="name of this flavor, as displayed to users") description = StrippedCharField(max_length=1024, blank=True, null=True) flavor = StrippedCharField( max_length=32, help_text="flavor string used to configure deployments") deployments = models.ManyToManyField(Deployment, blank=True, related_name="flavors") order = models.IntegerField( default=0, help_text="used to order flavors when displayed in a list") default = models.BooleanField( default=False, help_text= "make this a default flavor to use when creating new instances") class Meta: app_label = "core" ordering = ('order', 'name') def __init__(self, *args, **kwargs): super(Flavor, self).__init__(*args, **kwargs) self.no_sync = True def __unicode__(self): return u'%s' % (self.name)
class XOSVolume(PlCoreBase): xos = models.ForeignKey(XOS, related_name='volumes', help_text="The XOS object for this Volume") container_path=StrippedCharField(max_length=1024, unique=True, help_text="Path of Volume in Container") host_path=StrippedCharField(max_length=1024, help_text="Path of Volume in Host") read_only=models.BooleanField(default=False, help_text="True if mount read-only") def __unicode__(self): return u'%s' % (self.container_path)
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") def __unicode__(self): return u'%s-%0.2f-%s' % (self.account.site.name, self.amount, str(self.date))
class ServiceController(PlCoreBase): xos = models.ForeignKey(XOS, related_name='service_controllers', help_text="Pointer to XOS", default=get_xos) name = StrippedCharField(max_length=30, help_text="Service Name") base_url = StrippedCharField( max_length=1024, help_text="Base URL, allows use of relative URLs for resources", null=True, blank=True) synchronizer_run = StrippedCharField(max_length=1024, help_text="synchronizer run command", null=True, blank=True) synchronizer_config = StrippedCharField( max_length=1024, help_text="synchronizer config file", null=True, blank=True) def __unicode__(self): return u'%s' % (self.name) def save(self, *args, **kwargs): super(ServiceController, self).save(*args, **kwargs) if self.xos: # force XOS to rebuild # XXX somewhat hackish XXX self.xos.save(update_fields=["updated"])
class TenantRoot(PlCoreBase, AttributeMixin): """ A tenantRoot is one of the things that can sit at the root of a chain of tenancy. This object represents a node. """ KIND = "generic" kind = StrippedCharField(max_length=30, default=KIND) name = StrippedCharField(max_length=255, help_text="name", blank=True, null=True) service_specific_attribute = models.TextField(blank=True, null=True) service_specific_id = StrippedCharField(max_length=30, blank=True, null=True) def __init__(self, *args, **kwargs): # for subclasses, set the default kind appropriately self._meta.get_field("kind").default = self.KIND super(TenantRoot, self).__init__(*args, **kwargs) def __unicode__(self): if not self.name: return u"%s-tenant_root-#%s" % (str(self.kind), str(self.id)) else: return self.name def can_update(self, user): return user.can_update_tenant_root(self, allow=['admin']) def get_subscribed_tenants(self, tenant_class): ids = self.subscribed_tenants.filter(kind=tenant_class.KIND) return tenant_class.objects.filter(id__in=ids) def get_newest_subscribed_tenant(self, kind): st = list(self.get_subscribed_tenants(kind)) if not st: return None return sorted(st, key=attrgetter('id'))[0] @classmethod def get_tenant_objects(cls): return cls.objects.filter(kind=cls.KIND) @classmethod def get_tenant_objects_by_user(cls, user): return cls.select_by_user(user).filter(kind=cls.KIND) @classmethod def select_by_user(cls, user): if user.is_admin: return cls.objects.all() else: tr_ids = [ trp.tenant_root.id for trp in TenantRootPrivilege.objects.filter(user=user) ] return cls.objects.filter(id__in=tr_ids)
class Image(PlCoreBase): name = StrippedCharField(max_length=256, unique=True) disk_format = StrippedCharField(max_length=256) container_format = StrippedCharField(max_length=256) path = StrippedCharField(max_length=256, null=True, blank=True, help_text="Path to image on local disk") deployments = models.ManyToManyField('Deployment', through='ImageDeployments', blank=True, help_text="Select which images should be instantiated on this deployment", related_name='images') def __unicode__(self): return u'%s' % (self.name)
class XOSComponent(LoadableModule): # this will define loadable XOS component in the form of containers image = StrippedCharField(max_length=200, help_text="docker image name") command = StrippedCharField(max_length=1024, help_text="docker run command", null=True, blank=True) ports = StrippedCharField(max_length=200, help_text="port binding", null=True, blank=True) extra = StrippedCharField(max_length=200, help_text="extra information needed by containers", null=True, blank=True) no_start = models.BooleanField(help_text="Do not start the Component", default=False)
class Program(PlCoreBase): KIND_CHOICES = (('tosca', 'Tosca'), ) COMMAND_CHOICES = ( ('run', 'Run'), ('destroy', 'Destroy'), ) name = StrippedCharField(max_length=30, help_text="Service Name") description = models.TextField(max_length=254, null=True, blank=True, help_text="Description of Service") kind = StrippedCharField(max_length=30, help_text="Kind of service", choices=KIND_CHOICES) command = StrippedCharField(blank=True, null=True, max_length=30, help_text="Command to run", choices=COMMAND_CHOICES) owner = models.ForeignKey(User, null=True, related_name="programs") contents = models.TextField(blank=True, null=True, help_text="Contents of Program") output = models.TextField(blank=True, null=True, help_text="Output of Program") messages = models.TextField(blank=True, null=True, help_text="Debug messages") status = models.TextField(blank=True, null=True, max_length=30, help_text="Status of program") @classmethod def select_by_user(cls, user): return cls.objects.all() def __unicode__(self): return u'%s' % (self.name) def can_update(self, user): return True def save(self, *args, **kwargs): # set creator on first save if not self.owner and hasattr(self, 'caller'): self.owner = self.caller if (self.command in ["run", "destroy" ]) and (self.status in ["complete", "exception"]): self.status = "queued" super(Program, self).save(*args, **kwargs)
class Service(PlCoreBase): description = models.TextField(max_length=254,null=True, blank=True,help_text="Description of Service") enabled = models.BooleanField(default=True) name = StrippedCharField(max_length=30, help_text="Service Name") versionNumber = StrippedCharField(max_length=30, help_text="Version of Service Definition") published = models.BooleanField(default=True) view_url = StrippedCharField(blank=True, null=True, max_length=1024) icon_url = StrippedCharField(blank=True, null=True, max_length=1024) def __unicode__(self): return u'%s' % (self.name)
class XOSComponentVolumeContainer(PlCoreBase): component = models.ForeignKey(XOSComponent, related_name='volumecontainers', help_text="The Component object for this VolumeContainer") name = StrippedCharField(max_length=300, help_text="Volume Name") container = StrippedCharField(max_length=300, help_text="Volume Name") def save(self, *args, **kwds): existing = XOSComponentVolumeContainer.objects.filter(name=self.name) if len(existing) > 0: raise XOSValidationError('XOSComponentVolumeContainer for %s:%s already defined' % (self.container_path, self.host_path)) super(XOSComponentVolumeContainer, self).save(*args, **kwds)
class XOSGuiExtension(PlCoreBase): """Persist GUI Extension""" class Meta: app_label = "core" name = StrippedCharField(max_length=200, unique=True, help_text="Name of the GUI Extensions") files = StrippedCharField( max_length=1024, help_text="List of comma separated file composing the view")
class Image(PlCoreBase): KIND_CHOICES = (('vm', 'Virtual Machine'), ('container', 'Container'), ) name = StrippedCharField(max_length=256, unique=True) kind = models.CharField(null=False, blank=False, max_length=30, choices=KIND_CHOICES, default="vm") disk_format = StrippedCharField(max_length=256) container_format = StrippedCharField(max_length=256) path = StrippedCharField(max_length=256, null=True, blank=True, help_text="Path to image on local disk") deployments = models.ManyToManyField('Deployment', through='ImageDeployments', blank=True, help_text="Select which images should be instantiated on this deployment", related_name='images') def __unicode__(self): return u'%s' % (self.name)
class XOSComponentVolume(PlCoreBase): component = models.ForeignKey(XOSComponent, related_name='volumes', help_text="The Component object for this Volume") name = StrippedCharField(max_length=300, help_text="Volume Name") container_path = StrippedCharField(max_length=1024, unique=True, help_text="Path of Volume in Container") host_path = StrippedCharField(max_length=1024, help_text="Path of Volume in Host") read_only = models.BooleanField(default=False, help_text="True if mount read-only") def save(self, *args, **kwds): existing = XOSComponentVolume.objects.filter(container_path=self.container_path, host_path=self.host_path) if len(existing) > 0: raise XOSValidationError('XOSComponentVolume for %s:%s already defined' % (self.container_path, self.host_path)) super(XOSComponentVolume, self).save(*args, **kwds)
class ServiceController(LoadableModule): synchronizer_run = StrippedCharField(max_length=1024, help_text="synchronizer run command", null=True, blank=True) synchronizer_config = StrippedCharField( max_length=1024, help_text="synchronizer config file", null=True, blank=True) no_start = models.BooleanField( help_text="Do not start the XOS UI inside of the UI docker container", default=False)
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") deployment = models.ForeignKey(Deployment,related_name='controllerdeployments') def __unicode__(self): return u'%s %s %s' % (self.name, self.backend_type, self.version) @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
class DeploymentRole(PlCoreBase): #objects = DeploymentLinkManager() #deleted_objects = DeploymentLinkDeletionManager() ROLE_CHOICES = (('admin','Admin'),) role = StrippedCharField(choices=ROLE_CHOICES, unique=True, max_length=30) def __unicode__(self): return u'%s' % (self.role)
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") 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 = Users.select_by_user(user) qs = ControllerUser.objects.filter(user__in=users) return qs def can_update(self, user): return user.can_update_root()
class Project(PlCoreBase): name = StrippedCharField(max_length=200, unique=True, help_text="Name of Project") def __unicode__(self): return u'%s' % (self.name)
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") class Meta: unique_together = ('controller', 'slice') 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)
class TenantRootRole(PlCoreBase): ROLE_CHOICES = (('admin', 'Admin'), ) role = StrippedCharField(choices=ROLE_CHOICES, unique=True, max_length=30) def __unicode__(self): return u'%s' % (self.role)
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
class ServiceAttribute(PlCoreBase): name = models.SlugField(help_text="Attribute Name", max_length=128) value = StrippedCharField(help_text="Attribute Value", max_length=1024) service = models.ForeignKey( Service, related_name='serviceattributes', help_text="The Service this attribute is associated with")
class Tag(PlCoreBase): service = models.ForeignKey( Service, related_name='tags', help_text="The Service this Tag is associated with") name = models.SlugField(help_text="The name of this tag", max_length=128) value = StrippedCharField(help_text="The value of this tag", max_length=1024) # The required fields to do a ObjectType lookup, and object_id assignment content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') def __unicode__(self): return self.name def can_update(self, user): return user.can_update_root() @classmethod def select_by_content_object(cls, obj): return cls.objects.filter( content_type=ContentType.objects.get_for_model(obj), object_id=obj.id) @staticmethod def select_by_user(user): return Tag.objects.all()
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)
class HpcService(Service): class Meta: app_label = "hpc" verbose_name = "HPC Service" cmi_hostname = StrippedCharField(max_length=254, null=True, blank=True) hpc_port80 = models.BooleanField(default=True, help_text="Enable port 80 for HPC") watcher_hpc_network = StrippedCharField( max_length=254, null=True, blank=True, help_text="Network for hpc_watcher to contact hpc sliver") watcher_dnsdemux_network = StrippedCharField( max_length=254, null=True, blank=True, help_text="Network for hpc_watcher to contact dnsdemux sliver") watcher_dnsredir_network = StrippedCharField( max_length=254, null=True, blank=True, help_text="Network for hpc_watcher to contact dnsredir sliver") @property def scale(self): hpc_slices = [x for x in self.slices.all() if "hpc" in x.name] if not hpc_slices: return 0 return hpc_slices[0].slivers.count() @scale.setter def scale(self, value): self.set_scale = value def save(self, *args, **kwargs): super(HpcService, self).save(*args, **kwargs) # scale up/down scale = getattr(self, "set_scale", None) if scale is not None: exclude_slices = [x for x in self.slices.all() if "cmi" in x.name] self.adjust_scale(slice_hint="hpc", scale=scale, exclusive_slices=exclude_slices, max_per_node=1)
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") class Meta: unique_together = ('site', 'controller')
class ControllerDashboardView(PlCoreBase): objects = ControllerLinkManager() deleted_objects = ControllerLinkDeletionManager() controller = models.ForeignKey(Controller, related_name='controllerdashboardviews') dashboardView = models.ForeignKey(DashboardView, related_name='controllerdashboardviews') enabled = models.BooleanField(default=True) url = StrippedCharField(max_length=1024, help_text="URL of Dashboard") xos_links=[ModelLink(Controller,via='controller'),ModelLink(DashboardView,via='dashboardview')]
class SiteRole(PlCoreBase): ROLE_CHOICES = (('admin', 'Admin'), ('pi', 'PI'), ('tech', 'Tech'), ('billing', 'Billing')) role = StrippedCharField(choices=ROLE_CHOICES, unique=True, max_length=30) def __unicode__(self): return u'%s' % (self.role)