Refactor to /opt/planetstack, final tweaks to make sure planetstack can run in non-openstack mode, adjustments to GUI for model focus changes
diff --git a/planetstack/core/models/__init__.py b/planetstack/core/models/__init__.py
new file mode 100644
index 0000000..4d9387b
--- /dev/null
+++ b/planetstack/core/models/__init__.py
@@ -0,0 +1,14 @@
+from .plcorebase import PlCoreBase
+from .deploymentnetwork import DeploymentNetwork
+from .site import Site
+from .site import SitePrivilege
+from .image import Image
+from .key import Key
+from .user import User
+from .role import Role
+from .node import Node
+from .slice import Slice
+from .slice import SliceMembership
+from .sliver import Sliver
+from .subnet import Subnet
+
diff --git a/planetstack/core/models/deploymentnetwork.py b/planetstack/core/models/deploymentnetwork.py
new file mode 100644
index 0000000..4068ee9
--- /dev/null
+++ b/planetstack/core/models/deploymentnetwork.py
@@ -0,0 +1,11 @@
+import os
+from django.db import models
+from core.models import PlCoreBase
+
+# Create your models here.
+
+class DeploymentNetwork(PlCoreBase):
+ name = models.CharField(max_length=200, unique=True, help_text="Name of the Deployment Network")
+
+ def __unicode__(self): return u'%s' % (self.name)
+
diff --git a/planetstack/core/models/image.py b/planetstack/core/models/image.py
new file mode 100644
index 0000000..b4803e2
--- /dev/null
+++ b/planetstack/core/models/image.py
@@ -0,0 +1,13 @@
+import os
+from django.db import models
+from core.models import PlCoreBase
+
+# Create your models here.
+
+class Image(PlCoreBase):
+ image_id = models.CharField(max_length=256, unique=True)
+ name = models.CharField(max_length=256, unique=True)
+ disk_format = models.CharField(max_length=256)
+ container_format = models.CharField(max_length=256)
+
+ def __unicode__(self): return u'%s' % (self.name)
diff --git a/planetstack/core/models/key.py b/planetstack/core/models/key.py
new file mode 100644
index 0000000..98cfb9b
--- /dev/null
+++ b/planetstack/core/models/key.py
@@ -0,0 +1,23 @@
+import os
+from django.db import models
+from core.models import PlCoreBase
+
+# Create your models here.
+
+class Key(PlCoreBase):
+ name = models.CharField(max_length=256, unique=True)
+ nkey_id = models.CharField(max_length=256, unique=True)
+ key = models.CharField(max_length=512)
+ type = models.CharField(max_length=256)
+ blacklisted = models.BooleanField(default=False)
+
+ def __unicode__(self): return u'%s' % (self.name)
+
+ def save(self, *args, **kwds):
+ self.os_manager.save_key(self)
+ super(Key, self).save(*args, **kwds)
+
+ def delete(self, *args, **kwds):
+ self.os_manager.delete_key(self)
+ super(Key, self).delete(*args, **kwds)
+
diff --git a/planetstack/core/models/node.py b/planetstack/core/models/node.py
new file mode 100644
index 0000000..a249628
--- /dev/null
+++ b/planetstack/core/models/node.py
@@ -0,0 +1,14 @@
+import os
+from django.db import models
+from core.models import PlCoreBase
+from core.models import Site
+from core.models import DeploymentNetwork
+
+# Create your models here.
+
+class Node(PlCoreBase):
+ name = models.CharField(max_length=200, unique=True, help_text="Name of the Node")
+ site = models.ForeignKey(Site, related_name='nodes')
+ deploymentNetwork = models.ForeignKey(DeploymentNetwork, related_name='nodes')
+
+ def __unicode__(self): return u'%s' % (self.name)
diff --git a/planetstack/core/models/plcorebase.py b/planetstack/core/models/plcorebase.py
new file mode 100644
index 0000000..52aa0f7
--- /dev/null
+++ b/planetstack/core/models/plcorebase.py
@@ -0,0 +1,14 @@
+import os
+from django.db import models
+
+class PlCoreBase(models.Model):
+
+ created = models.DateTimeField(auto_now_add=True)
+ updated = models.DateTimeField(auto_now=True)
+
+ class Meta:
+ abstract = True
+ app_label = "core"
+
+
+
diff --git a/planetstack/core/models/role.py b/planetstack/core/models/role.py
new file mode 100644
index 0000000..b3611c1
--- /dev/null
+++ b/planetstack/core/models/role.py
@@ -0,0 +1,22 @@
+import os
+import datetime
+from django.db import models
+from core.models import PlCoreBase
+
+class Role(PlCoreBase):
+
+ #ROLE_CHOICES = (('admin', 'Admin'), ('pi', 'Principle Investigator'), ('user','User'))
+ role_id = models.CharField(max_length=256, unique=True)
+ role_type = models.CharField(max_length=80, unique=True)
+
+ def __unicode__(self): return u'%s' % (self.role_type)
+
+
+ def save(self, *args, **kwds):
+ self.os_manager.save_role(self)
+ super(Role, self).save(*args, **kwds)
+
+ def delete(self, *args, **kwds):
+ self.os_manager.delete_role(self)
+ super(Role, self).delete(*args, **kwds)
+
diff --git a/planetstack/core/models/site.py b/planetstack/core/models/site.py
new file mode 100644
index 0000000..ebf2ab9
--- /dev/null
+++ b/planetstack/core/models/site.py
@@ -0,0 +1,49 @@
+import os
+from django.db import models
+from core.models import PlCoreBase
+from core.models import DeploymentNetwork
+
+
+class Site(PlCoreBase):
+
+ tenant_id = models.CharField(max_length=200, help_text="Keystone tenant id")
+ name = models.CharField(max_length=200, help_text="Name for this Site")
+ site_url = models.URLField(null=True, blank=True, max_length=512, help_text="Site's Home URL Page")
+ enabled = models.BooleanField(default=True, help_text="Status for this Site")
+ longitude = models.FloatField(null=True, blank=True)
+ latitude = models.FloatField(null=True, blank=True)
+ login_base = models.CharField(max_length=50, unique=True, help_text="Prefix for Slices associated with this Site")
+ is_public = models.BooleanField(default=True, help_text="Indicates the visibility of this site to other members")
+ abbreviated_name = models.CharField(max_length=80)
+
+ deployments = models.ManyToManyField(DeploymentNetwork, blank=True, related_name='sites')
+
+ def __unicode__(self): return u'%s' % (self.name)
+
+ def save(self, *args, **kwds):
+ self.os_manager.save_site(self)
+ super(Site, self).save(*args, **kwds)
+
+
+ def delete(self, *args, **kwds):
+ self.os_manager.delete_site(self)
+ super(Site, self).delete(*args, **kwds)
+
+
+class SitePrivilege(PlCoreBase):
+
+ user = models.ForeignKey('User', related_name='site_privileges')
+ site = models.ForeignKey('Site', related_name='site_privileges')
+ role = models.ForeignKey('Role')
+
+ def __unicode__(self): return u'%s %s %s' % (self.site, self.user, self.role)
+
+ def save(self, *args, **kwds):
+ self.os_manager.driver.add_user_role(self.user.kuser_id, self.site.tenant_id, self.role.role_type)
+ super(SitePrivilege, self).save(*args, **kwds)
+
+ def delete(self, *args, **kwds):
+ self.os_manager.driver.delete_user_role(self.user.kuser_id, self.site.tenant_id, self.role.role_type)
+ super(SitePrivilege, self).delete(*args, **kwds)
+
+
diff --git a/planetstack/core/models/slice.py b/planetstack/core/models/slice.py
new file mode 100644
index 0000000..539be24
--- /dev/null
+++ b/planetstack/core/models/slice.py
@@ -0,0 +1,51 @@
+import os
+from django.db import models
+from core.models import PlCoreBase
+from core.models import Site
+from core.models import User
+from core.models import Role
+from core.models import DeploymentNetwork
+
+# Create your models here.
+
+class Slice(PlCoreBase):
+ tenant_id = models.CharField(max_length=200, help_text="Keystone tenant id")
+ name = models.CharField(unique=True, help_text="The Name of the Slice", max_length=80)
+ enabled = models.BooleanField(default=True, help_text="Status for this Slice")
+ SLICE_CHOICES = (('plc', 'PLC'), ('delegated', 'Delegated'), ('controller','Controller'), ('none','None'))
+ instantiation = models.CharField(help_text="The instantiation type of the slice", max_length=80, choices=SLICE_CHOICES)
+ omf_friendly = models.BooleanField()
+ 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 Node belongs too")
+ network_id = models.CharField(max_length=256, help_text="Quantum network")
+ router_id = models.CharField(max_length=256, help_text="Quantum router id")
+
+ SVC_CLASS_CHOICES = (('besteffort', 'Best Effort'), ('silver', 'Silver'), ('gold','Gold'))
+ serviceClass = models.CharField(verbose_name="Service Class",default="besteffort",help_text="The Service Class of this slice", max_length=30, choices=SVC_CLASS_CHOICES)
+
+
+ def __unicode__(self): return u'%s' % (self.name)
+
+ def save(self, *args, **kwds):
+ self.os_manager.save_slice(self)
+ super(Slice, self).save(*args, **kwds)
+
+ def delete(self, *args, **kwds):
+ self.os_manager.delete_slice(self)
+ super(Slice, self).delete(*args, **kwds)
+
+class SliceMembership(PlCoreBase):
+ user = models.ForeignKey('User', related_name='slice_memberships')
+ slice = models.ForeignKey('Slice', related_name='slice_memberships')
+ role = models.ForeignKey('Role')
+
+ def __unicode__(self): return u'%s %s %s' % (self.slice, self.user, self.role)
+
+ def save(self, *args, **kwds):
+ self.os_manager.driver.add_user_role(self.user.kuser_id, self.slice.tenant_id, self.role.role_type)
+ super(SliceMembership, self).save(*args, **kwds)
+
+ def delete(self, *args, **kwds):
+ self.os_manager.driver.delete_user_role(self.user.kuser_id, self.slice.tenant_id, self.role.role_type)
+ super(SliceMembership, self).delete(*args, **kwds)
diff --git a/planetstack/core/models/sliver.py b/planetstack/core/models/sliver.py
new file mode 100644
index 0000000..580c2af
--- /dev/null
+++ b/planetstack/core/models/sliver.py
@@ -0,0 +1,37 @@
+import os
+from django.db import models
+from django.core import exceptions
+from core.models import PlCoreBase
+from core.models import Image
+from core.models import Key
+from core.models import Slice
+from core.models import Node
+from core.models import Site
+from core.models import DeploymentNetwork
+
+# Create your models here.
+class Sliver(PlCoreBase):
+ instance_id = models.CharField(max_length=200, help_text="Nova instance id")
+ name = models.CharField(max_length=200, help_text="Sliver name")
+ instance_name = models.CharField(blank=True, null=True, max_length=200, help_text="OpenStack generated name")
+ ip = models.GenericIPAddressField(help_text="Sliver ip address", blank=True, null=True)
+ image = models.ForeignKey(Image, related_name='slivers')
+ key = models.ForeignKey(Key, related_name='slivers')
+ slice = models.ForeignKey(Slice, related_name='slivers')
+ node = models.ForeignKey(Node, related_name='slivers')
+ deploymentNetwork = models.ForeignKey(DeploymentNetwork, verbose_name='deployment', related_name='sliver_deploymentNetwork')
+ numberCores = models.IntegerField(verbose_name="Number of Cores", help_text="Number of cores for sliver", default=2)
+
+
+ def __unicode__(self): return u'%s' % (self.instance_name)
+
+ def save(self, *args, **kwds):
+ if not self.slice.subnet.exists():
+ raise exceptions.ValidationError, "Slice %s has no subnet" % self.slice.name
+
+ self.os_manager.save_sliver(self)
+ super(Sliver, self).save(*args, **kwds)
+
+ def delete(self, *args, **kwds):
+ self.os_manager.delete_sliver(self)
+ super(Sliver, self).delete(*args, **kwds)
diff --git a/planetstack/core/models/subnet.py b/planetstack/core/models/subnet.py
new file mode 100644
index 0000000..cad9fea
--- /dev/null
+++ b/planetstack/core/models/subnet.py
@@ -0,0 +1,25 @@
+import os
+import commands
+from django.db import models
+from core.models import PlCoreBase
+from core.models import Slice
+
+# Create your models here.
+
+class Subnet(PlCoreBase):
+ subnet_id = models.CharField(max_length=256, unique=True)
+ cidr = models.CharField(max_length=20)
+ ip_version = models.IntegerField()
+ start = models.IPAddressField()
+ end = models.IPAddressField()
+ slice = models.ForeignKey(Slice, related_name='subnet')
+
+ def __unicode__(self): return u'%s' % (self.slice.name)
+
+ def save(self, *args, **kwds):
+ self.os_manager.save_subnet(self)
+ super(Subnet, self).save(*args, **kwds)
+
+ def delete(self, *args, **kwds):
+ self.os_manager.delete_subnet(self)
+ super(Subnet, self).delete(*args, **kwds)
diff --git a/planetstack/core/models/user.py b/planetstack/core/models/user.py
new file mode 100644
index 0000000..6c776b1
--- /dev/null
+++ b/planetstack/core/models/user.py
@@ -0,0 +1,122 @@
+import os
+import datetime
+from django.db import models
+from core.models import PlCoreBase
+from core.models import Site
+from core.models import Key
+from openstack.manager import OpenStackManager
+from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
+
+# Create your models here.
+has_openstack = False
+
+class UserManager(BaseUserManager):
+ def create_user(self, email, firstname, lastname, password=None):
+ """
+ Creates and saves a User with the given email, date of
+ birth and password.
+ """
+ if not email:
+ raise ValueError('Users must have an email address')
+
+ user = self.model(
+ email=UserManager.normalize_email(email),
+ firstname=firstname,
+ lastname=lastname,
+ password=password
+ )
+ #user.set_password(password)
+ user.is_admin = True
+ user.save(using=self._db)
+ return user
+
+ def create_superuser(self, email, firstname, lastname, password):
+ """
+ Creates and saves a superuser with the given email, date of
+ birth and password.
+ """
+ user = self.create_user(email,
+ password=password,
+ firstname=firstname,
+ lastname=lastname
+ )
+ user.is_admin = True
+ user.save(using=self._db)
+ return user
+
+
+class User(AbstractBaseUser):
+
+ class Meta:
+ app_label = "core"
+
+ email = models.EmailField(
+ verbose_name='email address',
+ max_length=255,
+ unique=True,
+ db_index=True,
+ )
+
+ kuser_id = models.CharField(help_text="keystone user id", max_length=200)
+ firstname = models.CharField(help_text="person's given name", max_length=200)
+ lastname = models.CharField(help_text="person's surname", max_length=200)
+
+ phone = models.CharField(null=True, blank=True, help_text="phone number contact", max_length=100)
+ user_url = models.URLField(null=True, blank=True)
+ site = models.ForeignKey(Site, related_name='users', verbose_name="Site this user will be homed too", null=True)
+ key = models.ForeignKey(Key, related_name='user', null=True, blank=True)
+
+ is_active = models.BooleanField(default=True)
+ is_admin = models.BooleanField(default=True)
+ is_staff = models.BooleanField(default=True)
+
+ objects = UserManager()
+
+ USERNAME_FIELD = 'email'
+ REQUIRED_FIELDS = ['firstname', 'lastname']
+
+ def get_full_name(self):
+ # The user is identified by their email address
+ return self.email
+
+ def get_short_name(self):
+ # The user is identified by their email address
+ return self.email
+
+ def __unicode__(self):
+ return self.email
+
+ def has_perm(self, perm, obj=None):
+ "Does the user have a specific permission?"
+ # Simplest possible answer: Yes, always
+ return True
+
+ def has_module_perms(self, app_label):
+ "Does the user have permissions to view the app `app_label`?"
+ # Simplest possible answer: Yes, always
+ return True
+
+ @property
+ def is_staff(self):
+ "Is the user a member of staff?"
+ # Simplest possible answer: All admins are staff
+ return self.is_admin
+
+
+ def save(self, *args, **kwds):
+ if has_openstack:
+ if not hasattr(self, 'os_manager'):
+ setattr(self, 'os_manager', OpenStackManager())
+
+ self.os_manager.save_user(self)
+ if not self.id:
+ self.set_password(self.password)
+ super(User, self).save(*args, **kwds)
+
+ def delete(self, *args, **kwds):
+ if has_openstack:
+ if not hasattr(self, 'os_manager'):
+ setattr(self, 'os_manager', OpenStackManager())
+
+ self.os_manager.delete_user(self)
+ super(User, self).delete(*args, **kwds)