Merge branch 'master' of ssh://git.planet-lab.org/git/plstackapi
authorSapan Bhatia <sapanbhatia@nat-oitwireless-inside-vapornet100-c-32154.Princeton.EDU>
Wed, 19 Nov 2014 20:26:27 +0000 (15:26 -0500)
committerSapan Bhatia <sapanbhatia@nat-oitwireless-inside-vapornet100-c-32154.Princeton.EDU>
Wed, 19 Nov 2014 20:26:27 +0000 (15:26 -0500)
50 files changed:
planetstack/core/admin.py
planetstack/core/migrations/0006_auto_20141111_2314.py [deleted file]
planetstack/core/migrations/0007_network_ports.py [new file with mode: 0644]
planetstack/core/migrations/0008_network_sdn.py [new file with mode: 0644]
planetstack/core/migrations/0009_auto_20141119_1515.py [moved from planetstack/core/migrations/0005_auto_20141111_2311.py with 78% similarity]
planetstack/core/models/__init__.py
planetstack/core/models/image.py
planetstack/core/models/network.py
planetstack/core/models/site.py
planetstack/core/models/slice.py
planetstack/core/models/userdeployments.py
planetstack/core/static/uploadTextarea.js [new file with mode: 0644]
planetstack/core/xoslib/dashboards/xosAdminDashboard.html
planetstack/core/xoslib/static/css/xosAdminSite.css
planetstack/core/xoslib/static/js/xosAdminSite.js
planetstack/core/xoslib/static/js/xoslib/xos-backbone.js
planetstack/core/xoslib/static/js/xoslib/xosHelper.js
planetstack/core/xoslib/templates/xosAdmin.html
planetstack/ec2_observer/deleters/site_deleter.py
planetstack/ec2_observer/deleters/site_deployment_deleter.py
planetstack/ec2_observer/deleters/slice_deleter.py
planetstack/ec2_observer/deleters/slice_deployment_deleter.py
planetstack/ec2_observer/deleters/sliver_deleter.py
planetstack/ec2_observer/deleters/user_deleter.py
planetstack/ec2_observer/deleters/user_deployment_deleter.py
planetstack/ec2_observer/steps/sync_nodes.py
planetstack/ec2_observer/steps/sync_site_deployments.py
planetstack/ec2_observer/steps/sync_sites.py
planetstack/ec2_observer/steps/sync_slivers.py
planetstack/genapi.py
planetstack/model_policies/model_policy_Network.py
planetstack/model_policies/model_policy_Slice.py
planetstack/model_policies/model_policy_User.py
planetstack/openstack_observer/steps/__init__.py
planetstack/openstack_observer/steps/sync_image_deployments.py
planetstack/openstack_observer/steps/sync_site_deployments.py
planetstack/openstack_observer/steps/sync_site_privileges.py
planetstack/openstack_observer/steps/sync_sites.py
planetstack/openstack_observer/steps/sync_slice_deployments.py
planetstack/openstack_observer/steps/sync_slice_memberships.py
planetstack/openstack_observer/steps/sync_slices.py
planetstack/openstack_observer/steps/sync_slivers.py
planetstack/openstack_observer/steps/sync_user_deployments.py
planetstack/openstack_observer/steps/sync_users.py
planetstack/servcomp/migrations/0001_initial.py [new file with mode: 0644]
planetstack/servcomp/migrations/__init__.py [new file with mode: 0644]
planetstack/syndicate_observer/syndicatelib_config/config.py [changed from symlink to file mode: 0644]
planetstack/templates/admin/base.html
planetstack/urlfilter/migrations/0001_initial.py [new file with mode: 0644]
planetstack/urlfilter/migrations/__init__.py [new file with mode: 0644]

index cd0e5dd..5590144 100644 (file)
@@ -7,7 +7,7 @@ from django.contrib.auth.models import Group
 from django import forms
 from django.utils.safestring import mark_safe
 from django.contrib.auth.admin import UserAdmin
-from django.contrib.admin.widgets import FilteredSelectMultiple
+from django.contrib.admin.widgets import FilteredSelectMultiple, AdminTextareaWidget
 from django.contrib.auth.forms import ReadOnlyPasswordHashField, AdminPasswordChangeForm
 from django.contrib.auth.signals import user_logged_in
 from django.utils import timezone
@@ -15,6 +15,9 @@ from django.contrib.contenttypes import generic
 from suit.widgets import LinkedSelect
 from django.core.exceptions import PermissionDenied
 from django.core.urlresolvers import reverse, NoReverseMatch
+from django.utils.encoding import force_text, python_2_unicode_compatible
+from django.utils.html import conditional_escape, format_html
+from django.forms.utils import flatatt, to_current_timezone
 from cgi import escape as html_escape
 
 import django_evolution
@@ -40,6 +43,17 @@ def backend_text(obj):
     else:
         return "%s %s" % (icon, html_escape(obj.backend_status, quote=True))
 
+class UploadTextareaWidget(AdminTextareaWidget):
+    def render(self, name, value, attrs=None):
+        if value is None:
+            value = ''\r
+        final_attrs = self.build_attrs(attrs, name=name)\r
+        return format_html('<input type="file" style="width: 0; height: 0" id="btn_upload_%s" onChange="uploadTextarea(event,\'%s\');">' \\r
+                           '<button onClick="$(\'#btn_upload_%s\').click(); return false;">Upload</button>' \\r
+                           '<br><textarea{0}>\r\n{1}</textarea>' % (attrs["id"], attrs["id"], attrs["id"]),\r
+                           flatatt(final_attrs),\r
+                           force_text(value))
+
 class PlainTextWidget(forms.HiddenInput):
     input_type = 'hidden'
 
@@ -408,8 +422,8 @@ class SitePrivilegeInline(PlStackTabularInline):
     def queryset(self, request):
         return SitePrivilege.select_by_user(request.user)
 
-class SiteDeploymentInline(PlStackTabularInline):
-    model = SiteDeployment
+class SiteDeploymentsInline(PlStackTabularInline):
+    model = SiteDeployments
     extra = 0
     suit_classes = 'suit-tab suit-tab-deployments'
     fields = ['backend_status_icon', 'deployment','site']
@@ -421,10 +435,10 @@ class SiteDeploymentInline(PlStackTabularInline):
 
         if db_field.name == 'deployment':
             kwargs['queryset'] = Deployment.select_by_user(request.user)
-        return super(SiteDeploymentInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
+        return super(SiteDeploymentsInline, self).formfield_for_foreignkey(db_field, request, **kwargs)
 
     def queryset(self, request):
-        return SiteDeployment.select_by_user(request.user)
+        return SiteDeployments.select_by_user(request.user)
 
 
 class SlicePrivilegeInline(PlStackTabularInline):
@@ -455,8 +469,8 @@ class SliceNetworkInline(PlStackTabularInline):
     fields = ['backend_status_icon', 'network']
     readonly_fields = ('backend_status_icon', )
 
-class ImageDeploymentInline(PlStackTabularInline):
-    model = ImageDeployment
+class ImageDeploymentsInline(PlStackTabularInline):
+    model = ImageDeployments
     extra = 0
     verbose_name = "Image Deployments"
     verbose_name_plural = "Image Deployments"
@@ -508,8 +522,8 @@ class DeploymentAdminForm(forms.ModelForm):
       self.fields['accessControl'].initial = "allow site " + request.user.site.name
 
       if self.instance and self.instance.pk:
-        self.fields['sites'].initial = [x.site for x in self.instance.sitedeployments_set.all()]
-        self.fields['images'].initial = [x.image for x in self.instance.imagedeployments_set.all()]
+        self.fields['sites'].initial = [x.site for x in self.instance.sitedeployments.all()]
+        self.fields['images'].initial = [x.image for x in self.instance.imagedeployments.all()]
         self.fields['flavors'].initial = self.instance.flavors.all()
 
     def manipulate_m2m_objs(self, this_obj, selected_objs, all_relations, relation_class, local_attrname, foreign_attrname):
@@ -560,8 +574,8 @@ class DeploymentAdminForm(forms.ModelForm):
         #    create/destroy the through models ourselves. There has to be
         #    a better way...
 
-        self.manipulate_m2m_objs(deployment, self.cleaned_data['sites'], deployment.sitedeployments_set.all(), SiteDeployment, "deployment", "site")
-        self.manipulate_m2m_objs(deployment, self.cleaned_data['images'], deployment.imagedeployments_set.all(), ImageDeployment, "deployment", "image")
+        self.manipulate_m2m_objs(deployment, self.cleaned_data['sites'], deployment.sitedeployments.all(), SiteDeployments, "deployment", "site")
+        self.manipulate_m2m_objs(deployment, self.cleaned_data['images'], deployment.imagedeployments.all(), ImageDeployments, "deployment", "image")
 
       self.save_m2m()
 
@@ -580,7 +594,7 @@ class DeploymentAdmin(PlanetStackBaseAdmin):
     model = Deployment
     fieldList = ['backend_status_text', 'name', 'availability_zone', 'sites', 'images', 'flavors', 'accessControl']
     fieldsets = [(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-sites']})]
-    inlines = [DeploymentPrivilegeInline,NodeInline,TagInline] # ,ImageDeploymentInline]
+    inlines = [DeploymentPrivilegeInline,NodeInline,TagInline] # ,ImageDeploymentsInline]
     list_display = ['backend_status_icon', 'name']
     list_display_links = ('backend_status_icon', 'name', )
     readonly_fields = ('backend_status_text', )
@@ -647,7 +661,7 @@ class SiteAdmin(PlanetStackBaseAdmin):
     list_display = ('backend_status_icon', 'name', 'login_base','site_url', 'enabled')
     list_display_links = ('backend_status_icon', 'name', )
     filter_horizontal = ('deployments',)
-    inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline, SiteDeploymentInline]
+    inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline, SiteDeploymentsInline]
     search_fields = ['name']
 
     def queryset(self, request):
@@ -748,8 +762,8 @@ class SliceForm(forms.ModelForm):
             raise forms.ValidationError('slice name must begin with %s' % site.login_base)
         return cleaned_data
 
-class SliceDeploymentInline(PlStackTabularInline):
-    model = SliceDeployment
+class SliceDeploymentsInline(PlStackTabularInline):
+    model = SliceDeployments
     extra = 0
     verbose_name = "Slice Deployment"
     verbose_name_plural = "Slice Deployments"
@@ -765,7 +779,7 @@ class SliceAdmin(PlanetStackBaseAdmin):
     list_display = ('backend_status_icon', 'name', 'site','serviceClass', 'slice_url', 'max_slivers')
     list_display_links = ('backend_status_icon', 'name', )
     inlines = [SlicePrivilegeInline,SliverInline, TagInline, ReservationInline,SliceNetworkInline]
-    admin_inlines = [SliceDeploymentInline]
+    admin_inlines = [SliceDeploymentsInline]
 
     user_readonly_fields = fieldList
 
@@ -892,7 +906,7 @@ class ImageAdmin(PlanetStackBaseAdmin):
 
     suit_form_tabs =(('general','Image Details'),('slivers','Slivers'),('imagedeployments','Deployments'))
 
-    inlines = [SliverInline, ImageDeploymentInline]
+    inlines = [SliverInline, ImageDeploymentsInline]
 
     user_readonly_fields = ['name', 'disk_format', 'container_format']
 
@@ -1041,6 +1055,7 @@ class UserChangeForm(forms.ModelForm):
 
     class Meta:
         model = User
+        widgets = { 'public_key': UploadTextareaWidget, }
 
     def clean_password(self):
         # Regardless of what the user provides, return the initial value.
@@ -1333,6 +1348,14 @@ class NetworkDeploymentsInline(PlStackTabularInline):
     fields = ['backend_status_icon', 'deployment','net_id','subnet_id']
     readonly_fields = ('backend_status_icon', )
 
+class NetworkForm(forms.ModelForm):
+    class Meta:
+        model = Network
+        widgets = {
+            'topologyParameters': UploadTextareaWidget,
+            'controllerParameters': UploadTextareaWidget,
+        }
+
 class NetworkAdmin(PlanetStackBaseAdmin):
     list_display = ("backend_status_icon", "name", "subnet", "ports", "labels")
     list_display_links = ('backend_status_icon', 'name', )
@@ -1341,8 +1364,14 @@ class NetworkAdmin(PlanetStackBaseAdmin):
     inlines = [NetworkParameterInline, NetworkSliversInline, NetworkSlicesInline, RouterInline]
     admin_inlines = [NetworkDeploymentsInline]
 
+    form=NetworkForm
+
     fieldsets = [
-        (None, {'fields': ['backend_status_text', 'name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet'], 'classes':['suit-tab suit-tab-general']}),]
+        (None, {'fields': ['backend_status_text', 'name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet'],
+                'classes':['suit-tab suit-tab-general']}),
+        (None, {'fields': ['topologyParameters', 'controllerUrl', 'controllerParameters'],
+                'classes':['suit-tab suit-tab-sdn']}),
+                ]
 
     readonly_fields = ('backend_status_text', )
     user_readonly_fields = ['name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet']
@@ -1350,6 +1379,7 @@ class NetworkAdmin(PlanetStackBaseAdmin):
     @property
     def suit_form_tabs(self):
         tabs=[('general','Network Details'),
+            ('sdn', 'SDN Configuration'),
             ('netparams', 'Parameters'),
             ('networkslivers','Slivers'),
             ('networkslices','Slices'),
@@ -1368,6 +1398,10 @@ class NetworkTemplateAdmin(PlanetStackBaseAdmin):
     list_display_links = ('backend_status_icon', 'name', )
     user_readonly_fields = ["name", "guaranteedBandwidth", "visibility"]
     user_readonly_inlines = []
+    fieldsets = [
+        (None, {'fields': ['name', 'description', 'guaranteedBandwidth', 'visibility', 'translation', 'sharedNetworkName', 'sharedNetworkId', 'topologyKind', 'controllerKind'],
+                'classes':['suit-tab suit-tab-general']}),]
+    suit_form_tabs = (('general','Network Template Details'), )
 
 class FlavorAdmin(PlanetStackBaseAdmin):
     list_display = ("backend_status_icon", "name", "flavor", "order", "default")
diff --git a/planetstack/core/migrations/0006_auto_20141111_2314.py b/planetstack/core/migrations/0006_auto_20141111_2314.py
deleted file mode 100644 (file)
index 37a197d..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import unicode_literals
-
-from django.db import models, migrations
-
-
-class Migration(migrations.Migration):
-
-    dependencies = [
-        ('core', '0005_auto_20141111_2311'),
-    ]
-
-    operations = [
-        migrations.DeleteModel(
-            name='ImageDeployments',
-        ),
-        migrations.DeleteModel(
-            name='SiteDeployments',
-        ),
-        migrations.DeleteModel(
-            name='SliceDeployments',
-        ),
-        migrations.DeleteModel(
-            name='UserDeployments',
-        ),
-    ]
diff --git a/planetstack/core/migrations/0007_network_ports.py b/planetstack/core/migrations/0007_network_ports.py
new file mode 100644 (file)
index 0000000..b99c840
--- /dev/null
@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import core.models.network
+import timezones.fields
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0004_auto_20141006_1719'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='network',
+            name='ports',
+            field=models.CharField(blank=True, max_length=1024, null=True, validators=[core.models.network.ValidateNatList]),
+        ),
+    ]
diff --git a/planetstack/core/migrations/0008_network_sdn.py b/planetstack/core/migrations/0008_network_sdn.py
new file mode 100644 (file)
index 0000000..4a1443e
--- /dev/null
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0007_network_ports'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='network',
+            name='controllerParameters',
+            field=models.TextField(null=True, blank=True),
+            preserve_default=True,
+        ),
+        migrations.AddField(
+            model_name='network',
+            name='topologyParameters',
+            field=models.TextField(null=True, blank=True),
+            preserve_default=True,
+        ),
+        migrations.AddField(
+            model_name='networktemplate',
+            name='controllerKind',
+            field=models.CharField(default=None, max_length=30, null=True, blank=True, choices=[(None, b'None'), (b'onos', b'ONOS'), (b'custom', b'Custom')]),
+            preserve_default=True,
+        ),
+        migrations.AddField(
+            model_name='networktemplate',
+            name='topologyKind',
+            field=models.CharField(default=b'BigSwitch', max_length=30, choices=[(b'bigswitch', b'BigSwitch'), (b'physical', b'Physical'), (b'custom', b'Custom')]),
+            preserve_default=True,
+        ),
+        migrations.AddField(
+            model_name='network',
+            name='controllerUrl',
+            field=models.CharField(max_length=1024, null=True, blank=True),
+            preserve_default=True,
+        ),
+    ]
@@ -2,8 +2,6 @@
 from __future__ import unicode_literals
 
 from django.db import models, migrations
-import core.models.network
-import django.utils.timezone
 from django.conf import settings
 import timezones.fields
 
@@ -11,117 +9,10 @@ import timezones.fields
 class Migration(migrations.Migration):
 
     dependencies = [
-        ('core', '0004_auto_20141006_1719'),
+        ('core', '0008_network_sdn'),
     ]
 
     operations = [
-        migrations.CreateModel(
-            name='ImageDeployment',
-            fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('created', models.DateTimeField(default=django.utils.timezone.now, auto_now_add=True)),
-                ('updated', models.DateTimeField(default=django.utils.timezone.now, auto_now=True)),
-                ('enacted', models.DateTimeField(default=None, null=True)),
-                ('backend_status', models.CharField(default=b'Provisioning in progress', max_length=140)),
-                ('deleted', models.BooleanField(default=False)),
-                ('glance_image_id', models.CharField(help_text=b'Glance image id', max_length=200, null=True, blank=True)),
-                ('deployment', models.ForeignKey(related_name=b'imagedeployments', to='core.Deployment')),
-                ('image', models.ForeignKey(related_name=b'imagedeployments', to='core.Image')),
-            ],
-            options={
-                'abstract': False,
-            },
-            bases=(models.Model,),
-        ),
-        migrations.CreateModel(
-            name='SiteDeployment',
-            fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('created', models.DateTimeField(default=django.utils.timezone.now, auto_now_add=True)),
-                ('updated', models.DateTimeField(default=django.utils.timezone.now, auto_now=True)),
-                ('enacted', models.DateTimeField(default=None, null=True)),
-                ('backend_status', models.CharField(default=b'Provisioning in progress', max_length=140)),
-                ('deleted', models.BooleanField(default=False)),
-                ('tenant_id', models.CharField(help_text=b'Keystone tenant id', max_length=200, null=True, blank=True)),
-                ('deployment', models.ForeignKey(related_name=b'sitedeployments', to='core.Deployment')),
-                ('site', models.ForeignKey(related_name=b'sitedeployments', to='core.Site')),
-            ],
-            options={
-                'abstract': False,
-            },
-            bases=(models.Model,),
-        ),
-        migrations.CreateModel(
-            name='SliceDeployment',
-            fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('created', models.DateTimeField(default=django.utils.timezone.now, auto_now_add=True)),
-                ('updated', models.DateTimeField(default=django.utils.timezone.now, auto_now=True)),
-                ('enacted', models.DateTimeField(default=None, null=True)),
-                ('backend_status', models.CharField(default=b'Provisioning in progress', max_length=140)),
-                ('deleted', models.BooleanField(default=False)),
-                ('tenant_id', models.CharField(help_text=b'Keystone tenant id', max_length=200, null=True, blank=True)),
-                ('network_id', models.CharField(help_text=b'Quantum network', max_length=256, null=True, blank=True)),
-                ('router_id', models.CharField(help_text=b'Quantum router id', max_length=256, null=True, blank=True)),
-                ('subnet_id', models.CharField(help_text=b'Quantum subnet id', max_length=256, null=True, blank=True)),
-                ('deployment', models.ForeignKey(related_name=b'slicedeployments', to='core.Deployment')),
-                ('slice', models.ForeignKey(related_name=b'slicedeployments', to='core.Slice')),
-            ],
-            options={
-                'abstract': False,
-            },
-            bases=(models.Model,),
-        ),
-        migrations.CreateModel(
-            name='UserDeployment',
-            fields=[
-                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
-                ('created', models.DateTimeField(default=django.utils.timezone.now, auto_now_add=True)),
-                ('updated', models.DateTimeField(default=django.utils.timezone.now, auto_now=True)),
-                ('enacted', models.DateTimeField(default=None, null=True)),
-                ('backend_status', models.CharField(default=b'Provisioning in progress', max_length=140)),
-                ('deleted', models.BooleanField(default=False)),
-                ('kuser_id', models.CharField(help_text=b'Keystone user id', max_length=200, null=True, blank=True)),
-                ('deployment', models.ForeignKey(related_name=b'userdeployments', to='core.Deployment')),
-                ('user', models.ForeignKey(related_name=b'userdeployments', to=settings.AUTH_USER_MODEL)),
-            ],
-            options={
-                'abstract': False,
-            },
-            bases=(models.Model,),
-        ),
-        migrations.RemoveField(
-            model_name='imagedeployments',
-            name='deployment',
-        ),
-        migrations.RemoveField(
-            model_name='imagedeployments',
-            name='image',
-        ),
-        migrations.RemoveField(
-            model_name='sitedeployments',
-            name='deployment',
-        ),
-        migrations.RemoveField(
-            model_name='sitedeployments',
-            name='site',
-        ),
-        migrations.RemoveField(
-            model_name='slicedeployments',
-            name='deployment',
-        ),
-        migrations.RemoveField(
-            model_name='slicedeployments',
-            name='slice',
-        ),
-        migrations.RemoveField(
-            model_name='userdeployments',
-            name='deployment',
-        ),
-        migrations.RemoveField(
-            model_name='userdeployments',
-            name='user',
-        ),
         migrations.AlterField(
             model_name='deploymentcredential',
             name='deployment',
@@ -143,9 +34,14 @@ class Migration(migrations.Migration):
             field=models.ForeignKey(related_name=b'deploymentprivileges', to=settings.AUTH_USER_MODEL),
         ),
         migrations.AlterField(
-            model_name='network',
-            name='ports',
-            field=models.CharField(blank=True, max_length=1024, null=True, validators=[core.models.network.ValidateNatList]),
+            model_name='imagedeployments',
+            name='deployment',
+            field=models.ForeignKey(related_name=b'imagedeployments', to='core.Deployment'),
+        ),
+        migrations.AlterField(
+            model_name='imagedeployments',
+            name='image',
+            field=models.ForeignKey(related_name=b'imagedeployments', to='core.Image'),
         ),
         migrations.AlterField(
             model_name='networkdeployments',
@@ -212,16 +108,21 @@ class Migration(migrations.Migration):
             name='serviceClass',
             field=models.ForeignKey(related_name=b'serviceresources', to='core.ServiceClass'),
         ),
-        migrations.AlterField(
-            model_name='site',
-            name='deployments',
-            field=models.ManyToManyField(help_text=b'Select which sites are allowed to host nodes in this deployment', related_name=b'sites', through='core.SiteDeployment', to=b'core.Deployment', blank=True),
-        ),
         migrations.AlterField(
             model_name='sitecredential',
             name='site',
             field=models.ForeignKey(related_name=b'sitecredentials', to='core.Site', help_text=b'The User this credential is associated with'),
         ),
+        migrations.AlterField(
+            model_name='sitedeployments',
+            name='deployment',
+            field=models.ForeignKey(related_name=b'sitedeployments', to='core.Deployment'),
+        ),
+        migrations.AlterField(
+            model_name='sitedeployments',
+            name='site',
+            field=models.ForeignKey(related_name=b'sitedeployments', to='core.Site'),
+        ),
         migrations.AlterField(
             model_name='siteprivilege',
             name='role',
@@ -242,6 +143,16 @@ class Migration(migrations.Migration):
             name='slice',
             field=models.ForeignKey(related_name=b'slicecredentials', to='core.Slice', help_text=b'The User this credential is associated with'),
         ),
+        migrations.AlterField(
+            model_name='slicedeployments',
+            name='deployment',
+            field=models.ForeignKey(related_name=b'slicedeployments', to='core.Deployment'),
+        ),
+        migrations.AlterField(
+            model_name='slicedeployments',
+            name='slice',
+            field=models.ForeignKey(related_name=b'slicedeployments', to='core.Slice'),
+        ),
         migrations.AlterField(
             model_name='sliceprivilege',
             name='role',
@@ -260,7 +171,7 @@ class Migration(migrations.Migration):
         migrations.AlterField(
             model_name='user',
             name='timezone',
-            field=timezones.fields.TimeZoneField(default=b'America/New_York', max_length=100, choices=[(b'Pacific/Midway', b'(GMT-1100) Pacific/Midway'), (b'Pacific/Niue', b'(GMT-1100) Pacific/Niue'), (b'Pacific/Pago_Pago', b'(GMT-1100) Pacific/Pago_Pago'), (b'America/Adak', b'(GMT-1000) America/Adak'), (b'Pacific/Honolulu', b'(GMT-1000) Pacific/Honolulu'), (b'Pacific/Johnston', b'(GMT-1000) Pacific/Johnston'), (b'Pacific/Rarotonga', b'(GMT-1000) Pacific/Rarotonga'), (b'Pacific/Tahiti', b'(GMT-1000) Pacific/Tahiti'), (b'US/Hawaii', b'(GMT-1000) US/Hawaii'), (b'Pacific/Marquesas', b'(GMT-0930) Pacific/Marquesas'), (b'America/Anchorage', b'(GMT-0900) America/Anchorage'), (b'America/Juneau', b'(GMT-0900) America/Juneau'), (b'America/Nome', b'(GMT-0900) America/Nome'), (b'America/Sitka', b'(GMT-0900) America/Sitka'), (b'America/Yakutat', b'(GMT-0900) America/Yakutat'), (b'Pacific/Gambier', b'(GMT-0900) Pacific/Gambier'), (b'US/Alaska', b'(GMT-0900) US/Alaska'), (b'America/Dawson', b'(GMT-0800) America/Dawson'), (b'America/Los_Angeles', b'(GMT-0800) America/Los_Angeles'), (b'America/Metlakatla', b'(GMT-0800) America/Metlakatla'), (b'America/Santa_Isabel', b'(GMT-0800) America/Santa_Isabel'), (b'America/Tijuana', b'(GMT-0800) America/Tijuana'), (b'America/Vancouver', b'(GMT-0800) America/Vancouver'), (b'America/Whitehorse', b'(GMT-0800) America/Whitehorse'), (b'Pacific/Pitcairn', b'(GMT-0800) Pacific/Pitcairn'), (b'US/Pacific', b'(GMT-0800) US/Pacific'), (b'America/Boise', b'(GMT-0700) America/Boise'), (b'America/Cambridge_Bay', b'(GMT-0700) America/Cambridge_Bay'), (b'America/Chihuahua', b'(GMT-0700) America/Chihuahua'), (b'America/Creston', b'(GMT-0700) America/Creston'), (b'America/Dawson_Creek', b'(GMT-0700) America/Dawson_Creek'), (b'America/Denver', b'(GMT-0700) America/Denver'), (b'America/Edmonton', b'(GMT-0700) America/Edmonton'), (b'America/Hermosillo', b'(GMT-0700) America/Hermosillo'), (b'America/Inuvik', b'(GMT-0700) America/Inuvik'), (b'America/Mazatlan', b'(GMT-0700) America/Mazatlan'), (b'America/Ojinaga', b'(GMT-0700) America/Ojinaga'), (b'America/Phoenix', b'(GMT-0700) America/Phoenix'), (b'America/Yellowknife', b'(GMT-0700) America/Yellowknife'), (b'US/Arizona', b'(GMT-0700) US/Arizona'), (b'US/Mountain', b'(GMT-0700) US/Mountain'), (b'America/Bahia_Banderas', b'(GMT-0600) America/Bahia_Banderas'), (b'America/Belize', b'(GMT-0600) America/Belize'), (b'America/Cancun', b'(GMT-0600) America/Cancun'), (b'America/Chicago', b'(GMT-0600) America/Chicago'), (b'America/Costa_Rica', b'(GMT-0600) America/Costa_Rica'), (b'America/El_Salvador', b'(GMT-0600) America/El_Salvador'), (b'America/Guatemala', b'(GMT-0600) America/Guatemala'), (b'America/Indiana/Knox', b'(GMT-0600) America/Indiana/Knox'), (b'America/Indiana/Tell_City', b'(GMT-0600) America/Indiana/Tell_City'), (b'America/Managua', b'(GMT-0600) America/Managua'), (b'America/Matamoros', b'(GMT-0600) America/Matamoros'), (b'America/Menominee', b'(GMT-0600) America/Menominee'), (b'America/Merida', b'(GMT-0600) America/Merida'), (b'America/Mexico_City', b'(GMT-0600) America/Mexico_City'), (b'America/Monterrey', b'(GMT-0600) America/Monterrey'), (b'America/North_Dakota/Beulah', b'(GMT-0600) America/North_Dakota/Beulah'), (b'America/North_Dakota/Center', b'(GMT-0600) America/North_Dakota/Center'), (b'America/North_Dakota/New_Salem', b'(GMT-0600) America/North_Dakota/New_Salem'), (b'America/Rainy_River', b'(GMT-0600) America/Rainy_River'), (b'America/Rankin_Inlet', b'(GMT-0600) America/Rankin_Inlet'), (b'America/Regina', b'(GMT-0600) America/Regina'), (b'America/Resolute', b'(GMT-0600) America/Resolute'), (b'America/Swift_Current', b'(GMT-0600) America/Swift_Current'), (b'America/Tegucigalpa', b'(GMT-0600) America/Tegucigalpa'), (b'America/Winnipeg', b'(GMT-0600) America/Winnipeg'), (b'Pacific/Galapagos', b'(GMT-0600) Pacific/Galapagos'), (b'US/Central', b'(GMT-0600) US/Central'), (b'America/Atikokan', b'(GMT-0500) America/Atikokan'), (b'America/Bogota', b'(GMT-0500) America/Bogota'), (b'America/Cayman', b'(GMT-0500) America/Cayman'), (b'America/Detroit', b'(GMT-0500) America/Detroit'), (b'America/Eirunepe', b'(GMT-0500) America/Eirunepe'), (b'America/Guayaquil', b'(GMT-0500) America/Guayaquil'), (b'America/Havana', b'(GMT-0500) America/Havana'), (b'America/Indiana/Indianapolis', b'(GMT-0500) America/Indiana/Indianapolis'), (b'America/Indiana/Marengo', b'(GMT-0500) America/Indiana/Marengo'), (b'America/Indiana/Petersburg', b'(GMT-0500) America/Indiana/Petersburg'), (b'America/Indiana/Vevay', b'(GMT-0500) America/Indiana/Vevay'), (b'America/Indiana/Vincennes', b'(GMT-0500) America/Indiana/Vincennes'), (b'America/Indiana/Winamac', b'(GMT-0500) America/Indiana/Winamac'), (b'America/Iqaluit', b'(GMT-0500) America/Iqaluit'), (b'America/Jamaica', b'(GMT-0500) America/Jamaica'), (b'America/Kentucky/Louisville', b'(GMT-0500) America/Kentucky/Louisville'), (b'America/Kentucky/Monticello', b'(GMT-0500) America/Kentucky/Monticello'), (b'America/Lima', b'(GMT-0500) America/Lima'), (b'America/Nassau', b'(GMT-0500) America/Nassau'), (b'America/New_York', b'(GMT-0500) America/New_York'), (b'America/Nipigon', b'(GMT-0500) America/Nipigon'), (b'America/Panama', b'(GMT-0500) America/Panama'), (b'America/Pangnirtung', b'(GMT-0500) America/Pangnirtung'), (b'America/Port-au-Prince', b'(GMT-0500) America/Port-au-Prince'), (b'America/Rio_Branco', b'(GMT-0500) America/Rio_Branco'), (b'America/Thunder_Bay', b'(GMT-0500) America/Thunder_Bay'), (b'America/Toronto', b'(GMT-0500) America/Toronto'), (b'Pacific/Easter', b'(GMT-0500) Pacific/Easter'), (b'US/Eastern', b'(GMT-0500) US/Eastern'), (b'America/Caracas', b'(GMT-0430) America/Caracas'), (b'America/Anguilla', b'(GMT-0400) America/Anguilla'), (b'America/Antigua', b'(GMT-0400) America/Antigua'), (b'America/Aruba', b'(GMT-0400) America/Aruba'), (b'America/Barbados', b'(GMT-0400) America/Barbados'), (b'America/Blanc-Sablon', b'(GMT-0400) America/Blanc-Sablon'), (b'America/Boa_Vista', b'(GMT-0400) America/Boa_Vista'), (b'America/Curacao', b'(GMT-0400) America/Curacao'), (b'America/Dominica', b'(GMT-0400) America/Dominica'), (b'America/Glace_Bay', b'(GMT-0400) America/Glace_Bay'), (b'America/Goose_Bay', b'(GMT-0400) America/Goose_Bay'), (b'America/Grand_Turk', b'(GMT-0400) America/Grand_Turk'), (b'America/Grenada', b'(GMT-0400) America/Grenada'), (b'America/Guadeloupe', b'(GMT-0400) America/Guadeloupe'), (b'America/Guyana', b'(GMT-0400) America/Guyana'), (b'America/Halifax', b'(GMT-0400) America/Halifax'), (b'America/Kralendijk', b'(GMT-0400) America/Kralendijk'), (b'America/La_Paz', b'(GMT-0400) America/La_Paz'), (b'America/Lower_Princes', b'(GMT-0400) America/Lower_Princes'), (b'America/Manaus', b'(GMT-0400) America/Manaus'), (b'America/Marigot', b'(GMT-0400) America/Marigot'), (b'America/Martinique', b'(GMT-0400) America/Martinique'), (b'America/Moncton', b'(GMT-0400) America/Moncton'), (b'America/Montserrat', b'(GMT-0400) America/Montserrat'), (b'America/Port_of_Spain', b'(GMT-0400) America/Port_of_Spain'), (b'America/Porto_Velho', b'(GMT-0400) America/Porto_Velho'), (b'America/Puerto_Rico', b'(GMT-0400) America/Puerto_Rico'), (b'America/Santo_Domingo', b'(GMT-0400) America/Santo_Domingo'), (b'America/St_Barthelemy', b'(GMT-0400) America/St_Barthelemy'), (b'America/St_Kitts', b'(GMT-0400) America/St_Kitts'), (b'America/St_Lucia', b'(GMT-0400) America/St_Lucia'), (b'America/St_Thomas', b'(GMT-0400) America/St_Thomas'), (b'America/St_Vincent', b'(GMT-0400) America/St_Vincent'), (b'America/Thule', b'(GMT-0400) America/Thule'), (b'America/Tortola', b'(GMT-0400) America/Tortola'), (b'Atlantic/Bermuda', b'(GMT-0400) Atlantic/Bermuda'), (b'America/St_Johns', b'(GMT-0330) America/St_Johns'), (b'America/Araguaina', b'(GMT-0300) America/Araguaina'), (b'America/Argentina/Buenos_Aires', b'(GMT-0300) America/Argentina/Buenos_Aires'), (b'America/Argentina/Catamarca', b'(GMT-0300) America/Argentina/Catamarca'), (b'America/Argentina/Cordoba', b'(GMT-0300) America/Argentina/Cordoba'), (b'America/Argentina/Jujuy', b'(GMT-0300) America/Argentina/Jujuy'), (b'America/Argentina/La_Rioja', b'(GMT-0300) America/Argentina/La_Rioja'), (b'America/Argentina/Mendoza', b'(GMT-0300) America/Argentina/Mendoza'), (b'America/Argentina/Rio_Gallegos', b'(GMT-0300) America/Argentina/Rio_Gallegos'), (b'America/Argentina/Salta', b'(GMT-0300) America/Argentina/Salta'), (b'America/Argentina/San_Juan', b'(GMT-0300) America/Argentina/San_Juan'), (b'America/Argentina/San_Luis', b'(GMT-0300) America/Argentina/San_Luis'), (b'America/Argentina/Tucuman', b'(GMT-0300) America/Argentina/Tucuman'), (b'America/Argentina/Ushuaia', b'(GMT-0300) America/Argentina/Ushuaia'), (b'America/Asuncion', b'(GMT-0300) America/Asuncion'), (b'America/Bahia', b'(GMT-0300) America/Bahia'), (b'America/Belem', b'(GMT-0300) America/Belem'), (b'America/Campo_Grande', b'(GMT-0300) America/Campo_Grande'), (b'America/Cayenne', b'(GMT-0300) America/Cayenne'), (b'America/Cuiaba', b'(GMT-0300) America/Cuiaba'), (b'America/Fortaleza', b'(GMT-0300) America/Fortaleza'), (b'America/Godthab', b'(GMT-0300) America/Godthab'), (b'America/Maceio', b'(GMT-0300) America/Maceio'), (b'America/Miquelon', b'(GMT-0300) America/Miquelon'), (b'America/Paramaribo', b'(GMT-0300) America/Paramaribo'), (b'America/Recife', b'(GMT-0300) America/Recife'), (b'America/Santarem', b'(GMT-0300) America/Santarem'), (b'America/Santiago', b'(GMT-0300) America/Santiago'), (b'Antarctica/Palmer', b'(GMT-0300) Antarctica/Palmer'), (b'Antarctica/Rothera', b'(GMT-0300) Antarctica/Rothera'), (b'Atlantic/Stanley', b'(GMT-0300) Atlantic/Stanley'), (b'America/Montevideo', b'(GMT-0200) America/Montevideo'), (b'America/Noronha', b'(GMT-0200) America/Noronha'), (b'America/Sao_Paulo', b'(GMT-0200) America/Sao_Paulo'), (b'Atlantic/South_Georgia', b'(GMT-0200) Atlantic/South_Georgia'), (b'America/Scoresbysund', b'(GMT-0100) America/Scoresbysund'), (b'Atlantic/Azores', b'(GMT-0100) Atlantic/Azores'), (b'Atlantic/Cape_Verde', b'(GMT-0100) Atlantic/Cape_Verde'), (b'Africa/Abidjan', b'(GMT+0000) Africa/Abidjan'), (b'Africa/Accra', b'(GMT+0000) Africa/Accra'), (b'Africa/Bamako', b'(GMT+0000) Africa/Bamako'), (b'Africa/Banjul', b'(GMT+0000) Africa/Banjul'), (b'Africa/Bissau', b'(GMT+0000) Africa/Bissau'), (b'Africa/Casablanca', b'(GMT+0000) Africa/Casablanca'), (b'Africa/Conakry', b'(GMT+0000) Africa/Conakry'), (b'Africa/Dakar', b'(GMT+0000) Africa/Dakar'), (b'Africa/El_Aaiun', b'(GMT+0000) Africa/El_Aaiun'), (b'Africa/Freetown', b'(GMT+0000) Africa/Freetown'), (b'Africa/Lome', b'(GMT+0000) Africa/Lome'), (b'Africa/Monrovia', b'(GMT+0000) Africa/Monrovia'), (b'Africa/Nouakchott', b'(GMT+0000) Africa/Nouakchott'), (b'Africa/Ouagadougou', b'(GMT+0000) Africa/Ouagadougou'), (b'Africa/Sao_Tome', b'(GMT+0000) Africa/Sao_Tome'), (b'America/Danmarkshavn', b'(GMT+0000) America/Danmarkshavn'), (b'Antarctica/Troll', b'(GMT+0000) Antarctica/Troll'), (b'Atlantic/Canary', b'(GMT+0000) Atlantic/Canary'), (b'Atlantic/Faroe', b'(GMT+0000) Atlantic/Faroe'), (b'Atlantic/Madeira', b'(GMT+0000) Atlantic/Madeira'), (b'Atlantic/Reykjavik', b'(GMT+0000) Atlantic/Reykjavik'), (b'Atlantic/St_Helena', b'(GMT+0000) Atlantic/St_Helena'), (b'Europe/Dublin', b'(GMT+0000) Europe/Dublin'), (b'Europe/Guernsey', b'(GMT+0000) Europe/Guernsey'), (b'Europe/Isle_of_Man', b'(GMT+0000) Europe/Isle_of_Man'), (b'Europe/Jersey', b'(GMT+0000) Europe/Jersey'), (b'Europe/Lisbon', b'(GMT+0000) Europe/Lisbon'), (b'Europe/London', b'(GMT+0000) Europe/London'), (b'GMT', b'(GMT+0000) GMT'), (b'UTC', b'(GMT+0000) UTC'), (b'Africa/Algiers', b'(GMT+0100) Africa/Algiers'), (b'Africa/Bangui', b'(GMT+0100) Africa/Bangui'), (b'Africa/Brazzaville', b'(GMT+0100) Africa/Brazzaville'), (b'Africa/Ceuta', b'(GMT+0100) Africa/Ceuta'), (b'Africa/Douala', b'(GMT+0100) Africa/Douala'), (b'Africa/Kinshasa', b'(GMT+0100) Africa/Kinshasa'), (b'Africa/Lagos', b'(GMT+0100) Africa/Lagos'), (b'Africa/Libreville', b'(GMT+0100) Africa/Libreville'), (b'Africa/Luanda', b'(GMT+0100) Africa/Luanda'), (b'Africa/Malabo', b'(GMT+0100) Africa/Malabo'), (b'Africa/Ndjamena', b'(GMT+0100) Africa/Ndjamena'), (b'Africa/Niamey', b'(GMT+0100) Africa/Niamey'), (b'Africa/Porto-Novo', b'(GMT+0100) Africa/Porto-Novo'), (b'Africa/Tunis', b'(GMT+0100) Africa/Tunis'), (b'Arctic/Longyearbyen', b'(GMT+0100) Arctic/Longyearbyen'), (b'Europe/Amsterdam', b'(GMT+0100) Europe/Amsterdam'), (b'Europe/Andorra', b'(GMT+0100) Europe/Andorra'), (b'Europe/Belgrade', b'(GMT+0100) Europe/Belgrade'), (b'Europe/Berlin', b'(GMT+0100) Europe/Berlin'), (b'Europe/Bratislava', b'(GMT+0100) Europe/Bratislava'), (b'Europe/Brussels', b'(GMT+0100) Europe/Brussels'), (b'Europe/Budapest', b'(GMT+0100) Europe/Budapest'), (b'Europe/Busingen', b'(GMT+0100) Europe/Busingen'), (b'Europe/Copenhagen', b'(GMT+0100) Europe/Copenhagen'), (b'Europe/Gibraltar', b'(GMT+0100) Europe/Gibraltar'), (b'Europe/Ljubljana', b'(GMT+0100) Europe/Ljubljana'), (b'Europe/Luxembourg', b'(GMT+0100) Europe/Luxembourg'), (b'Europe/Madrid', b'(GMT+0100) Europe/Madrid'), (b'Europe/Malta', b'(GMT+0100) Europe/Malta'), (b'Europe/Monaco', b'(GMT+0100) Europe/Monaco'), (b'Europe/Oslo', b'(GMT+0100) Europe/Oslo'), (b'Europe/Paris', b'(GMT+0100) Europe/Paris'), (b'Europe/Podgorica', b'(GMT+0100) Europe/Podgorica'), (b'Europe/Prague', b'(GMT+0100) Europe/Prague'), (b'Europe/Rome', b'(GMT+0100) Europe/Rome'), (b'Europe/San_Marino', b'(GMT+0100) Europe/San_Marino'), (b'Europe/Sarajevo', b'(GMT+0100) Europe/Sarajevo'), (b'Europe/Skopje', b'(GMT+0100) Europe/Skopje'), (b'Europe/Stockholm', b'(GMT+0100) Europe/Stockholm'), (b'Europe/Tirane', b'(GMT+0100) Europe/Tirane'), (b'Europe/Vaduz', b'(GMT+0100) Europe/Vaduz'), (b'Europe/Vatican', b'(GMT+0100) Europe/Vatican'), (b'Europe/Vienna', b'(GMT+0100) Europe/Vienna'), (b'Europe/Warsaw', b'(GMT+0100) Europe/Warsaw'), (b'Europe/Zagreb', b'(GMT+0100) Europe/Zagreb'), (b'Europe/Zurich', b'(GMT+0100) Europe/Zurich'), (b'Africa/Blantyre', b'(GMT+0200) Africa/Blantyre'), (b'Africa/Bujumbura', b'(GMT+0200) Africa/Bujumbura'), (b'Africa/Cairo', b'(GMT+0200) Africa/Cairo'), (b'Africa/Gaborone', b'(GMT+0200) Africa/Gaborone'), (b'Africa/Harare', b'(GMT+0200) Africa/Harare'), (b'Africa/Johannesburg', b'(GMT+0200) Africa/Johannesburg'), (b'Africa/Kigali', b'(GMT+0200) Africa/Kigali'), (b'Africa/Lubumbashi', b'(GMT+0200) Africa/Lubumbashi'), (b'Africa/Lusaka', b'(GMT+0200) Africa/Lusaka'), (b'Africa/Maputo', b'(GMT+0200) Africa/Maputo'), (b'Africa/Maseru', b'(GMT+0200) Africa/Maseru'), (b'Africa/Mbabane', b'(GMT+0200) Africa/Mbabane'), (b'Africa/Tripoli', b'(GMT+0200) Africa/Tripoli'), (b'Africa/Windhoek', b'(GMT+0200) Africa/Windhoek'), (b'Asia/Amman', b'(GMT+0200) Asia/Amman'), (b'Asia/Beirut', b'(GMT+0200) Asia/Beirut'), (b'Asia/Damascus', b'(GMT+0200) Asia/Damascus'), (b'Asia/Gaza', b'(GMT+0200) Asia/Gaza'), (b'Asia/Hebron', b'(GMT+0200) Asia/Hebron'), (b'Asia/Jerusalem', b'(GMT+0200) Asia/Jerusalem'), (b'Asia/Nicosia', b'(GMT+0200) Asia/Nicosia'), (b'Europe/Athens', b'(GMT+0200) Europe/Athens'), (b'Europe/Bucharest', b'(GMT+0200) Europe/Bucharest'), (b'Europe/Chisinau', b'(GMT+0200) Europe/Chisinau'), (b'Europe/Helsinki', b'(GMT+0200) Europe/Helsinki'), (b'Europe/Istanbul', b'(GMT+0200) Europe/Istanbul'), (b'Europe/Kaliningrad', b'(GMT+0200) Europe/Kaliningrad'), (b'Europe/Kiev', b'(GMT+0200) Europe/Kiev'), (b'Europe/Mariehamn', b'(GMT+0200) Europe/Mariehamn'), (b'Europe/Riga', b'(GMT+0200) Europe/Riga'), (b'Europe/Sofia', b'(GMT+0200) Europe/Sofia'), (b'Europe/Tallinn', b'(GMT+0200) Europe/Tallinn'), (b'Europe/Uzhgorod', b'(GMT+0200) Europe/Uzhgorod'), (b'Europe/Vilnius', b'(GMT+0200) Europe/Vilnius'), (b'Europe/Zaporozhye', b'(GMT+0200) Europe/Zaporozhye'), (b'Africa/Addis_Ababa', b'(GMT+0300) Africa/Addis_Ababa'), (b'Africa/Asmara', b'(GMT+0300) Africa/Asmara'), (b'Africa/Dar_es_Salaam', b'(GMT+0300) Africa/Dar_es_Salaam'), (b'Africa/Djibouti', b'(GMT+0300) Africa/Djibouti'), (b'Africa/Juba', b'(GMT+0300) Africa/Juba'), (b'Africa/Kampala', b'(GMT+0300) Africa/Kampala'), (b'Africa/Khartoum', b'(GMT+0300) Africa/Khartoum'), (b'Africa/Mogadishu', b'(GMT+0300) Africa/Mogadishu'), (b'Africa/Nairobi', b'(GMT+0300) Africa/Nairobi'), (b'Antarctica/Syowa', b'(GMT+0300) Antarctica/Syowa'), (b'Asia/Aden', b'(GMT+0300) Asia/Aden'), (b'Asia/Baghdad', b'(GMT+0300) Asia/Baghdad'), (b'Asia/Bahrain', b'(GMT+0300) Asia/Bahrain'), (b'Asia/Kuwait', b'(GMT+0300) Asia/Kuwait'), (b'Asia/Qatar', b'(GMT+0300) Asia/Qatar'), (b'Asia/Riyadh', b'(GMT+0300) Asia/Riyadh'), (b'Europe/Minsk', b'(GMT+0300) Europe/Minsk'), (b'Europe/Moscow', b'(GMT+0300) Europe/Moscow'), (b'Europe/Simferopol', b'(GMT+0300) Europe/Simferopol'), (b'Europe/Volgograd', b'(GMT+0300) Europe/Volgograd'), (b'Indian/Antananarivo', b'(GMT+0300) Indian/Antananarivo'), (b'Indian/Comoro', b'(GMT+0300) Indian/Comoro'), (b'Indian/Mayotte', b'(GMT+0300) Indian/Mayotte'), (b'Asia/Tehran', b'(GMT+0330) Asia/Tehran'), (b'Asia/Baku', b'(GMT+0400) Asia/Baku'), (b'Asia/Dubai', b'(GMT+0400) Asia/Dubai'), (b'Asia/Muscat', b'(GMT+0400) Asia/Muscat'), (b'Asia/Tbilisi', b'(GMT+0400) Asia/Tbilisi'), (b'Asia/Yerevan', b'(GMT+0400) Asia/Yerevan'), (b'Europe/Samara', b'(GMT+0400) Europe/Samara'), (b'Indian/Mahe', b'(GMT+0400) Indian/Mahe'), (b'Indian/Mauritius', b'(GMT+0400) Indian/Mauritius'), (b'Indian/Reunion', b'(GMT+0400) Indian/Reunion'), (b'Asia/Kabul', b'(GMT+0430) Asia/Kabul'), (b'Antarctica/Mawson', b'(GMT+0500) Antarctica/Mawson'), (b'Asia/Aqtau', b'(GMT+0500) Asia/Aqtau'), (b'Asia/Aqtobe', b'(GMT+0500) Asia/Aqtobe'), (b'Asia/Ashgabat', b'(GMT+0500) Asia/Ashgabat'), (b'Asia/Dushanbe', b'(GMT+0500) Asia/Dushanbe'), (b'Asia/Karachi', b'(GMT+0500) Asia/Karachi'), (b'Asia/Oral', b'(GMT+0500) Asia/Oral'), (b'Asia/Samarkand', b'(GMT+0500) Asia/Samarkand'), (b'Asia/Tashkent', b'(GMT+0500) Asia/Tashkent'), (b'Asia/Yekaterinburg', b'(GMT+0500) Asia/Yekaterinburg'), (b'Indian/Kerguelen', b'(GMT+0500) Indian/Kerguelen'), (b'Indian/Maldives', b'(GMT+0500) Indian/Maldives'), (b'Asia/Colombo', b'(GMT+0530) Asia/Colombo'), (b'Asia/Kolkata', b'(GMT+0530) Asia/Kolkata'), (b'Asia/Kathmandu', b'(GMT+0545) Asia/Kathmandu'), (b'Antarctica/Vostok', b'(GMT+0600) Antarctica/Vostok'), (b'Asia/Almaty', b'(GMT+0600) Asia/Almaty'), (b'Asia/Bishkek', b'(GMT+0600) Asia/Bishkek'), (b'Asia/Dhaka', b'(GMT+0600) Asia/Dhaka'), (b'Asia/Novosibirsk', b'(GMT+0600) Asia/Novosibirsk'), (b'Asia/Omsk', b'(GMT+0600) Asia/Omsk'), (b'Asia/Qyzylorda', b'(GMT+0600) Asia/Qyzylorda'), (b'Asia/Thimphu', b'(GMT+0600) Asia/Thimphu'), (b'Asia/Urumqi', b'(GMT+0600) Asia/Urumqi'), (b'Indian/Chagos', b'(GMT+0600) Indian/Chagos'), (b'Asia/Rangoon', b'(GMT+0630) Asia/Rangoon'), (b'Indian/Cocos', b'(GMT+0630) Indian/Cocos'), (b'Antarctica/Davis', b'(GMT+0700) Antarctica/Davis'), (b'Asia/Bangkok', b'(GMT+0700) Asia/Bangkok'), (b'Asia/Ho_Chi_Minh', b'(GMT+0700) Asia/Ho_Chi_Minh'), (b'Asia/Hovd', b'(GMT+0700) Asia/Hovd'), (b'Asia/Jakarta', b'(GMT+0700) Asia/Jakarta'), (b'Asia/Krasnoyarsk', b'(GMT+0700) Asia/Krasnoyarsk'), (b'Asia/Novokuznetsk', b'(GMT+0700) Asia/Novokuznetsk'), (b'Asia/Phnom_Penh', b'(GMT+0700) Asia/Phnom_Penh'), (b'Asia/Pontianak', b'(GMT+0700) Asia/Pontianak'), (b'Asia/Vientiane', b'(GMT+0700) Asia/Vientiane'), (b'Indian/Christmas', b'(GMT+0700) Indian/Christmas'), (b'Antarctica/Casey', b'(GMT+0800) Antarctica/Casey'), (b'Asia/Brunei', b'(GMT+0800) Asia/Brunei'), (b'Asia/Chita', b'(GMT+0800) Asia/Chita'), (b'Asia/Choibalsan', b'(GMT+0800) Asia/Choibalsan'), (b'Asia/Hong_Kong', b'(GMT+0800) Asia/Hong_Kong'), (b'Asia/Irkutsk', b'(GMT+0800) Asia/Irkutsk'), (b'Asia/Kuala_Lumpur', b'(GMT+0800) Asia/Kuala_Lumpur'), (b'Asia/Kuching', b'(GMT+0800) Asia/Kuching'), (b'Asia/Macau', b'(GMT+0800) Asia/Macau'), (b'Asia/Makassar', b'(GMT+0800) Asia/Makassar'), (b'Asia/Manila', b'(GMT+0800) Asia/Manila'), (b'Asia/Shanghai', b'(GMT+0800) Asia/Shanghai'), (b'Asia/Singapore', b'(GMT+0800) Asia/Singapore'), (b'Asia/Taipei', b'(GMT+0800) Asia/Taipei'), (b'Asia/Ulaanbaatar', b'(GMT+0800) Asia/Ulaanbaatar'), (b'Australia/Perth', b'(GMT+0800) Australia/Perth'), (b'Australia/Eucla', b'(GMT+0845) Australia/Eucla'), (b'Asia/Dili', b'(GMT+0900) Asia/Dili'), (b'Asia/Jayapura', b'(GMT+0900) Asia/Jayapura'), (b'Asia/Khandyga', b'(GMT+0900) Asia/Khandyga'), (b'Asia/Pyongyang', b'(GMT+0900) Asia/Pyongyang'), (b'Asia/Seoul', b'(GMT+0900) Asia/Seoul'), (b'Asia/Tokyo', b'(GMT+0900) Asia/Tokyo'), (b'Asia/Yakutsk', b'(GMT+0900) Asia/Yakutsk'), (b'Pacific/Palau', b'(GMT+0900) Pacific/Palau'), (b'Australia/Darwin', b'(GMT+0930) Australia/Darwin'), (b'Antarctica/DumontDUrville', b'(GMT+1000) Antarctica/DumontDUrville'), (b'Asia/Magadan', b'(GMT+1000) Asia/Magadan'), (b'Asia/Sakhalin', b'(GMT+1000) Asia/Sakhalin'), (b'Asia/Ust-Nera', b'(GMT+1000) Asia/Ust-Nera'), (b'Asia/Vladivostok', b'(GMT+1000) Asia/Vladivostok'), (b'Australia/Brisbane', b'(GMT+1000) Australia/Brisbane'), (b'Australia/Lindeman', b'(GMT+1000) Australia/Lindeman'), (b'Pacific/Chuuk', b'(GMT+1000) Pacific/Chuuk'), (b'Pacific/Guam', b'(GMT+1000) Pacific/Guam'), (b'Pacific/Port_Moresby', b'(GMT+1000) Pacific/Port_Moresby'), (b'Pacific/Saipan', b'(GMT+1000) Pacific/Saipan'), (b'Australia/Adelaide', b'(GMT+1030) Australia/Adelaide'), (b'Australia/Broken_Hill', b'(GMT+1030) Australia/Broken_Hill'), (b'Antarctica/Macquarie', b'(GMT+1100) Antarctica/Macquarie'), (b'Asia/Srednekolymsk', b'(GMT+1100) Asia/Srednekolymsk'), (b'Australia/Currie', b'(GMT+1100) Australia/Currie'), (b'Australia/Hobart', b'(GMT+1100) Australia/Hobart'), (b'Australia/Lord_Howe', b'(GMT+1100) Australia/Lord_Howe'), (b'Australia/Melbourne', b'(GMT+1100) Australia/Melbourne'), (b'Australia/Sydney', b'(GMT+1100) Australia/Sydney'), (b'Pacific/Efate', b'(GMT+1100) Pacific/Efate'), (b'Pacific/Guadalcanal', b'(GMT+1100) Pacific/Guadalcanal'), (b'Pacific/Kosrae', b'(GMT+1100) Pacific/Kosrae'), (b'Pacific/Noumea', b'(GMT+1100) Pacific/Noumea'), (b'Pacific/Pohnpei', b'(GMT+1100) Pacific/Pohnpei'), (b'Pacific/Norfolk', b'(GMT+1130) Pacific/Norfolk'), (b'Asia/Anadyr', b'(GMT+1200) Asia/Anadyr'), (b'Asia/Kamchatka', b'(GMT+1200) Asia/Kamchatka'), (b'Pacific/Funafuti', b'(GMT+1200) Pacific/Funafuti'), (b'Pacific/Kwajalein', b'(GMT+1200) Pacific/Kwajalein'), (b'Pacific/Majuro', b'(GMT+1200) Pacific/Majuro'), (b'Pacific/Nauru', b'(GMT+1200) Pacific/Nauru'), (b'Pacific/Tarawa', b'(GMT+1200) Pacific/Tarawa'), (b'Pacific/Wake', b'(GMT+1200) Pacific/Wake'), (b'Pacific/Wallis', b'(GMT+1200) Pacific/Wallis'), (b'Antarctica/McMurdo', b'(GMT+1300) Antarctica/McMurdo'), (b'Pacific/Auckland', b'(GMT+1300) Pacific/Auckland'), (b'Pacific/Enderbury', b'(GMT+1300) Pacific/Enderbury'), (b'Pacific/Fakaofo', b'(GMT+1300) Pacific/Fakaofo'), (b'Pacific/Fiji', b'(GMT+1300) Pacific/Fiji'), (b'Pacific/Tongatapu', b'(GMT+1300) Pacific/Tongatapu'), (b'Pacific/Chatham', b'(GMT+1345) Pacific/Chatham'), (b'Pacific/Apia', b'(GMT+1400) Pacific/Apia'), (b'Pacific/Kiritimati', b'(GMT+1400) Pacific/Kiritimati')]),
+            field=timezones.fields.TimeZoneField(default=b'America/New_York', max_length=100, choices=[(b'Pacific/Midway', b'(GMT-1100) Pacific/Midway'), (b'Pacific/Niue', b'(GMT-1100) Pacific/Niue'), (b'Pacific/Pago_Pago', b'(GMT-1100) Pacific/Pago_Pago'), (b'America/Adak', b'(GMT-1000) America/Adak'), (b'Pacific/Honolulu', b'(GMT-1000) Pacific/Honolulu'), (b'Pacific/Johnston', b'(GMT-1000) Pacific/Johnston'), (b'Pacific/Rarotonga', b'(GMT-1000) Pacific/Rarotonga'), (b'Pacific/Tahiti', b'(GMT-1000) Pacific/Tahiti'), (b'US/Hawaii', b'(GMT-1000) US/Hawaii'), (b'Pacific/Marquesas', b'(GMT-0930) Pacific/Marquesas'), (b'America/Anchorage', b'(GMT-0900) America/Anchorage'), (b'America/Juneau', b'(GMT-0900) America/Juneau'), (b'America/Nome', b'(GMT-0900) America/Nome'), (b'America/Sitka', b'(GMT-0900) America/Sitka'), (b'America/Yakutat', b'(GMT-0900) America/Yakutat'), (b'Pacific/Gambier', b'(GMT-0900) Pacific/Gambier'), (b'US/Alaska', b'(GMT-0900) US/Alaska'), (b'America/Dawson', b'(GMT-0800) America/Dawson'), (b'America/Los_Angeles', b'(GMT-0800) America/Los_Angeles'), (b'America/Metlakatla', b'(GMT-0800) America/Metlakatla'), (b'America/Santa_Isabel', b'(GMT-0800) America/Santa_Isabel'), (b'America/Tijuana', b'(GMT-0800) America/Tijuana'), (b'America/Vancouver', b'(GMT-0800) America/Vancouver'), (b'America/Whitehorse', b'(GMT-0800) America/Whitehorse'), (b'Pacific/Pitcairn', b'(GMT-0800) Pacific/Pitcairn'), (b'US/Pacific', b'(GMT-0800) US/Pacific'), (b'America/Boise', b'(GMT-0700) America/Boise'), (b'America/Cambridge_Bay', b'(GMT-0700) America/Cambridge_Bay'), (b'America/Chihuahua', b'(GMT-0700) America/Chihuahua'), (b'America/Creston', b'(GMT-0700) America/Creston'), (b'America/Dawson_Creek', b'(GMT-0700) America/Dawson_Creek'), (b'America/Denver', b'(GMT-0700) America/Denver'), (b'America/Edmonton', b'(GMT-0700) America/Edmonton'), (b'America/Hermosillo', b'(GMT-0700) America/Hermosillo'), (b'America/Inuvik', b'(GMT-0700) America/Inuvik'), (b'America/Mazatlan', b'(GMT-0700) America/Mazatlan'), (b'America/Ojinaga', b'(GMT-0700) America/Ojinaga'), (b'America/Phoenix', b'(GMT-0700) America/Phoenix'), (b'America/Yellowknife', b'(GMT-0700) America/Yellowknife'), (b'US/Arizona', b'(GMT-0700) US/Arizona'), (b'US/Mountain', b'(GMT-0700) US/Mountain'), (b'America/Bahia_Banderas', b'(GMT-0600) America/Bahia_Banderas'), (b'America/Belize', b'(GMT-0600) America/Belize'), (b'America/Cancun', b'(GMT-0600) America/Cancun'), (b'America/Chicago', b'(GMT-0600) America/Chicago'), (b'America/Costa_Rica', b'(GMT-0600) America/Costa_Rica'), (b'America/El_Salvador', b'(GMT-0600) America/El_Salvador'), (b'America/Guatemala', b'(GMT-0600) America/Guatemala'), (b'America/Indiana/Knox', b'(GMT-0600) America/Indiana/Knox'), (b'America/Indiana/Tell_City', b'(GMT-0600) America/Indiana/Tell_City'), (b'America/Managua', b'(GMT-0600) America/Managua'), (b'America/Matamoros', b'(GMT-0600) America/Matamoros'), (b'America/Menominee', b'(GMT-0600) America/Menominee'), (b'America/Merida', b'(GMT-0600) America/Merida'), (b'America/Mexico_City', b'(GMT-0600) America/Mexico_City'), (b'America/Monterrey', b'(GMT-0600) America/Monterrey'), (b'America/North_Dakota/Beulah', b'(GMT-0600) America/North_Dakota/Beulah'), (b'America/North_Dakota/Center', b'(GMT-0600) America/North_Dakota/Center'), (b'America/North_Dakota/New_Salem', b'(GMT-0600) America/North_Dakota/New_Salem'), (b'America/Rainy_River', b'(GMT-0600) America/Rainy_River'), (b'America/Rankin_Inlet', b'(GMT-0600) America/Rankin_Inlet'), (b'America/Regina', b'(GMT-0600) America/Regina'), (b'America/Resolute', b'(GMT-0600) America/Resolute'), (b'America/Swift_Current', b'(GMT-0600) America/Swift_Current'), (b'America/Tegucigalpa', b'(GMT-0600) America/Tegucigalpa'), (b'America/Winnipeg', b'(GMT-0600) America/Winnipeg'), (b'Pacific/Galapagos', b'(GMT-0600) Pacific/Galapagos'), (b'US/Central', b'(GMT-0600) US/Central'), (b'America/Atikokan', b'(GMT-0500) America/Atikokan'), (b'America/Bogota', b'(GMT-0500) America/Bogota'), (b'America/Cayman', b'(GMT-0500) America/Cayman'), (b'America/Detroit', b'(GMT-0500) America/Detroit'), (b'America/Eirunepe', b'(GMT-0500) America/Eirunepe'), (b'America/Guayaquil', b'(GMT-0500) America/Guayaquil'), (b'America/Havana', b'(GMT-0500) America/Havana'), (b'America/Indiana/Indianapolis', b'(GMT-0500) America/Indiana/Indianapolis'), (b'America/Indiana/Marengo', b'(GMT-0500) America/Indiana/Marengo'), (b'America/Indiana/Petersburg', b'(GMT-0500) America/Indiana/Petersburg'), (b'America/Indiana/Vevay', b'(GMT-0500) America/Indiana/Vevay'), (b'America/Indiana/Vincennes', b'(GMT-0500) America/Indiana/Vincennes'), (b'America/Indiana/Winamac', b'(GMT-0500) America/Indiana/Winamac'), (b'America/Iqaluit', b'(GMT-0500) America/Iqaluit'), (b'America/Jamaica', b'(GMT-0500) America/Jamaica'), (b'America/Kentucky/Louisville', b'(GMT-0500) America/Kentucky/Louisville'), (b'America/Kentucky/Monticello', b'(GMT-0500) America/Kentucky/Monticello'), (b'America/Lima', b'(GMT-0500) America/Lima'), (b'America/Nassau', b'(GMT-0500) America/Nassau'), (b'America/New_York', b'(GMT-0500) America/New_York'), (b'America/Nipigon', b'(GMT-0500) America/Nipigon'), (b'America/Panama', b'(GMT-0500) America/Panama'), (b'America/Pangnirtung', b'(GMT-0500) America/Pangnirtung'), (b'America/Port-au-Prince', b'(GMT-0500) America/Port-au-Prince'), (b'America/Rio_Branco', b'(GMT-0500) America/Rio_Branco'), (b'America/Thunder_Bay', b'(GMT-0500) America/Thunder_Bay'), (b'America/Toronto', b'(GMT-0500) America/Toronto'), (b'Pacific/Easter', b'(GMT-0500) Pacific/Easter'), (b'US/Eastern', b'(GMT-0500) US/Eastern'), (b'America/Caracas', b'(GMT-0430) America/Caracas'), (b'America/Anguilla', b'(GMT-0400) America/Anguilla'), (b'America/Antigua', b'(GMT-0400) America/Antigua'), (b'America/Aruba', b'(GMT-0400) America/Aruba'), (b'America/Barbados', b'(GMT-0400) America/Barbados'), (b'America/Blanc-Sablon', b'(GMT-0400) America/Blanc-Sablon'), (b'America/Boa_Vista', b'(GMT-0400) America/Boa_Vista'), (b'America/Curacao', b'(GMT-0400) America/Curacao'), (b'America/Dominica', b'(GMT-0400) America/Dominica'), (b'America/Glace_Bay', b'(GMT-0400) America/Glace_Bay'), (b'America/Goose_Bay', b'(GMT-0400) America/Goose_Bay'), (b'America/Grand_Turk', b'(GMT-0400) America/Grand_Turk'), (b'America/Grenada', b'(GMT-0400) America/Grenada'), (b'America/Guadeloupe', b'(GMT-0400) America/Guadeloupe'), (b'America/Guyana', b'(GMT-0400) America/Guyana'), (b'America/Halifax', b'(GMT-0400) America/Halifax'), (b'America/Kralendijk', b'(GMT-0400) America/Kralendijk'), (b'America/La_Paz', b'(GMT-0400) America/La_Paz'), (b'America/Lower_Princes', b'(GMT-0400) America/Lower_Princes'), (b'America/Manaus', b'(GMT-0400) America/Manaus'), (b'America/Marigot', b'(GMT-0400) America/Marigot'), (b'America/Martinique', b'(GMT-0400) America/Martinique'), (b'America/Moncton', b'(GMT-0400) America/Moncton'), (b'America/Montserrat', b'(GMT-0400) America/Montserrat'), (b'America/Port_of_Spain', b'(GMT-0400) America/Port_of_Spain'), (b'America/Porto_Velho', b'(GMT-0400) America/Porto_Velho'), (b'America/Puerto_Rico', b'(GMT-0400) America/Puerto_Rico'), (b'America/Santo_Domingo', b'(GMT-0400) America/Santo_Domingo'), (b'America/St_Barthelemy', b'(GMT-0400) America/St_Barthelemy'), (b'America/St_Kitts', b'(GMT-0400) America/St_Kitts'), (b'America/St_Lucia', b'(GMT-0400) America/St_Lucia'), (b'America/St_Thomas', b'(GMT-0400) America/St_Thomas'), (b'America/St_Vincent', b'(GMT-0400) America/St_Vincent'), (b'America/Thule', b'(GMT-0400) America/Thule'), (b'America/Tortola', b'(GMT-0400) America/Tortola'), (b'Atlantic/Bermuda', b'(GMT-0400) Atlantic/Bermuda'), (b'America/St_Johns', b'(GMT-0330) America/St_Johns'), (b'America/Araguaina', b'(GMT-0300) America/Araguaina'), (b'America/Argentina/Buenos_Aires', b'(GMT-0300) America/Argentina/Buenos_Aires'), (b'America/Argentina/Catamarca', b'(GMT-0300) America/Argentina/Catamarca'), (b'America/Argentina/Cordoba', b'(GMT-0300) America/Argentina/Cordoba'), (b'America/Argentina/Jujuy', b'(GMT-0300) America/Argentina/Jujuy'), (b'America/Argentina/La_Rioja', b'(GMT-0300) America/Argentina/La_Rioja'), (b'America/Argentina/Mendoza', b'(GMT-0300) America/Argentina/Mendoza'), (b'America/Argentina/Rio_Gallegos', b'(GMT-0300) America/Argentina/Rio_Gallegos'), (b'America/Argentina/Salta', b'(GMT-0300) America/Argentina/Salta'), (b'America/Argentina/San_Juan', b'(GMT-0300) America/Argentina/San_Juan'), (b'America/Argentina/San_Luis', b'(GMT-0300) America/Argentina/San_Luis'), (b'America/Argentina/Tucuman', b'(GMT-0300) America/Argentina/Tucuman'), (b'America/Argentina/Ushuaia', b'(GMT-0300) America/Argentina/Ushuaia'), (b'America/Asuncion', b'(GMT-0300) America/Asuncion'), (b'America/Bahia', b'(GMT-0300) America/Bahia'), (b'America/Belem', b'(GMT-0300) America/Belem'), (b'America/Campo_Grande', b'(GMT-0300) America/Campo_Grande'), (b'America/Cayenne', b'(GMT-0300) America/Cayenne'), (b'America/Cuiaba', b'(GMT-0300) America/Cuiaba'), (b'America/Fortaleza', b'(GMT-0300) America/Fortaleza'), (b'America/Godthab', b'(GMT-0300) America/Godthab'), (b'America/Maceio', b'(GMT-0300) America/Maceio'), (b'America/Miquelon', b'(GMT-0300) America/Miquelon'), (b'America/Paramaribo', b'(GMT-0300) America/Paramaribo'), (b'America/Recife', b'(GMT-0300) America/Recife'), (b'America/Santarem', b'(GMT-0300) America/Santarem'), (b'America/Santiago', b'(GMT-0300) America/Santiago'), (b'Antarctica/Palmer', b'(GMT-0300) Antarctica/Palmer'), (b'Antarctica/Rothera', b'(GMT-0300) Antarctica/Rothera'), (b'Atlantic/Stanley', b'(GMT-0300) Atlantic/Stanley'), (b'America/Montevideo', b'(GMT-0200) America/Montevideo'), (b'America/Noronha', b'(GMT-0200) America/Noronha'), (b'America/Sao_Paulo', b'(GMT-0200) America/Sao_Paulo'), (b'Atlantic/South_Georgia', b'(GMT-0200) Atlantic/South_Georgia'), (b'America/Scoresbysund', b'(GMT-0100) America/Scoresbysund'), (b'Atlantic/Azores', b'(GMT-0100) Atlantic/Azores'), (b'Atlantic/Cape_Verde', b'(GMT-0100) Atlantic/Cape_Verde'), (b'Africa/Abidjan', b'(GMT+0000) Africa/Abidjan'), (b'Africa/Accra', b'(GMT+0000) Africa/Accra'), (b'Africa/Bamako', b'(GMT+0000) Africa/Bamako'), (b'Africa/Banjul', b'(GMT+0000) Africa/Banjul'), (b'Africa/Bissau', b'(GMT+0000) Africa/Bissau'), (b'Africa/Casablanca', b'(GMT+0000) Africa/Casablanca'), (b'Africa/Conakry', b'(GMT+0000) Africa/Conakry'), (b'Africa/Dakar', b'(GMT+0000) Africa/Dakar'), (b'Africa/El_Aaiun', b'(GMT+0000) Africa/El_Aaiun'), (b'Africa/Freetown', b'(GMT+0000) Africa/Freetown'), (b'Africa/Lome', b'(GMT+0000) Africa/Lome'), (b'Africa/Monrovia', b'(GMT+0000) Africa/Monrovia'), (b'Africa/Nouakchott', b'(GMT+0000) Africa/Nouakchott'), (b'Africa/Ouagadougou', b'(GMT+0000) Africa/Ouagadougou'), (b'Africa/Sao_Tome', b'(GMT+0000) Africa/Sao_Tome'), (b'America/Danmarkshavn', b'(GMT+0000) America/Danmarkshavn'), (b'Antarctica/Troll', b'(GMT+0000) Antarctica/Troll'), (b'Atlantic/Canary', b'(GMT+0000) Atlantic/Canary'), (b'Atlantic/Faroe', b'(GMT+0000) Atlantic/Faroe'), (b'Atlantic/Madeira', b'(GMT+0000) Atlantic/Madeira'), (b'Atlantic/Reykjavik', b'(GMT+0000) Atlantic/Reykjavik'), (b'Atlantic/St_Helena', b'(GMT+0000) Atlantic/St_Helena'), (b'Europe/Dublin', b'(GMT+0000) Europe/Dublin'), (b'Europe/Guernsey', b'(GMT+0000) Europe/Guernsey'), (b'Europe/Isle_of_Man', b'(GMT+0000) Europe/Isle_of_Man'), (b'Europe/Jersey', b'(GMT+0000) Europe/Jersey'), (b'Europe/Lisbon', b'(GMT+0000) Europe/Lisbon'), (b'Europe/London', b'(GMT+0000) Europe/London'), (b'GMT', b'(GMT+0000) GMT'), (b'UTC', b'(GMT+0000) UTC'), (b'Africa/Algiers', b'(GMT+0100) Africa/Algiers'), (b'Africa/Bangui', b'(GMT+0100) Africa/Bangui'), (b'Africa/Brazzaville', b'(GMT+0100) Africa/Brazzaville'), (b'Africa/Ceuta', b'(GMT+0100) Africa/Ceuta'), (b'Africa/Douala', b'(GMT+0100) Africa/Douala'), (b'Africa/Kinshasa', b'(GMT+0100) Africa/Kinshasa'), (b'Africa/Lagos', b'(GMT+0100) Africa/Lagos'), (b'Africa/Libreville', b'(GMT+0100) Africa/Libreville'), (b'Africa/Luanda', b'(GMT+0100) Africa/Luanda'), (b'Africa/Malabo', b'(GMT+0100) Africa/Malabo'), (b'Africa/Ndjamena', b'(GMT+0100) Africa/Ndjamena'), (b'Africa/Niamey', b'(GMT+0100) Africa/Niamey'), (b'Africa/Porto-Novo', b'(GMT+0100) Africa/Porto-Novo'), (b'Africa/Tunis', b'(GMT+0100) Africa/Tunis'), (b'Arctic/Longyearbyen', b'(GMT+0100) Arctic/Longyearbyen'), (b'Europe/Amsterdam', b'(GMT+0100) Europe/Amsterdam'), (b'Europe/Andorra', b'(GMT+0100) Europe/Andorra'), (b'Europe/Belgrade', b'(GMT+0100) Europe/Belgrade'), (b'Europe/Berlin', b'(GMT+0100) Europe/Berlin'), (b'Europe/Bratislava', b'(GMT+0100) Europe/Bratislava'), (b'Europe/Brussels', b'(GMT+0100) Europe/Brussels'), (b'Europe/Budapest', b'(GMT+0100) Europe/Budapest'), (b'Europe/Busingen', b'(GMT+0100) Europe/Busingen'), (b'Europe/Copenhagen', b'(GMT+0100) Europe/Copenhagen'), (b'Europe/Gibraltar', b'(GMT+0100) Europe/Gibraltar'), (b'Europe/Ljubljana', b'(GMT+0100) Europe/Ljubljana'), (b'Europe/Luxembourg', b'(GMT+0100) Europe/Luxembourg'), (b'Europe/Madrid', b'(GMT+0100) Europe/Madrid'), (b'Europe/Malta', b'(GMT+0100) Europe/Malta'), (b'Europe/Monaco', b'(GMT+0100) Europe/Monaco'), (b'Europe/Oslo', b'(GMT+0100) Europe/Oslo'), (b'Europe/Paris', b'(GMT+0100) Europe/Paris'), (b'Europe/Podgorica', b'(GMT+0100) Europe/Podgorica'), (b'Europe/Prague', b'(GMT+0100) Europe/Prague'), (b'Europe/Rome', b'(GMT+0100) Europe/Rome'), (b'Europe/San_Marino', b'(GMT+0100) Europe/San_Marino'), (b'Europe/Sarajevo', b'(GMT+0100) Europe/Sarajevo'), (b'Europe/Skopje', b'(GMT+0100) Europe/Skopje'), (b'Europe/Stockholm', b'(GMT+0100) Europe/Stockholm'), (b'Europe/Tirane', b'(GMT+0100) Europe/Tirane'), (b'Europe/Vaduz', b'(GMT+0100) Europe/Vaduz'), (b'Europe/Vatican', b'(GMT+0100) Europe/Vatican'), (b'Europe/Vienna', b'(GMT+0100) Europe/Vienna'), (b'Europe/Warsaw', b'(GMT+0100) Europe/Warsaw'), (b'Europe/Zagreb', b'(GMT+0100) Europe/Zagreb'), (b'Europe/Zurich', b'(GMT+0100) Europe/Zurich'), (b'Africa/Blantyre', b'(GMT+0200) Africa/Blantyre'), (b'Africa/Bujumbura', b'(GMT+0200) Africa/Bujumbura'), (b'Africa/Cairo', b'(GMT+0200) Africa/Cairo'), (b'Africa/Gaborone', b'(GMT+0200) Africa/Gaborone'), (b'Africa/Harare', b'(GMT+0200) Africa/Harare'), (b'Africa/Johannesburg', b'(GMT+0200) Africa/Johannesburg'), (b'Africa/Kigali', b'(GMT+0200) Africa/Kigali'), (b'Africa/Lubumbashi', b'(GMT+0200) Africa/Lubumbashi'), (b'Africa/Lusaka', b'(GMT+0200) Africa/Lusaka'), (b'Africa/Maputo', b'(GMT+0200) Africa/Maputo'), (b'Africa/Maseru', b'(GMT+0200) Africa/Maseru'), (b'Africa/Mbabane', b'(GMT+0200) Africa/Mbabane'), (b'Africa/Tripoli', b'(GMT+0200) Africa/Tripoli'), (b'Africa/Windhoek', b'(GMT+0200) Africa/Windhoek'), (b'Asia/Amman', b'(GMT+0200) Asia/Amman'), (b'Asia/Beirut', b'(GMT+0200) Asia/Beirut'), (b'Asia/Damascus', b'(GMT+0200) Asia/Damascus'), (b'Asia/Gaza', b'(GMT+0200) Asia/Gaza'), (b'Asia/Hebron', b'(GMT+0200) Asia/Hebron'), (b'Asia/Jerusalem', b'(GMT+0200) Asia/Jerusalem'), (b'Asia/Nicosia', b'(GMT+0200) Asia/Nicosia'), (b'Europe/Athens', b'(GMT+0200) Europe/Athens'), (b'Europe/Bucharest', b'(GMT+0200) Europe/Bucharest'), (b'Europe/Chisinau', b'(GMT+0200) Europe/Chisinau'), (b'Europe/Helsinki', b'(GMT+0200) Europe/Helsinki'), (b'Europe/Istanbul', b'(GMT+0200) Europe/Istanbul'), (b'Europe/Kaliningrad', b'(GMT+0200) Europe/Kaliningrad'), (b'Europe/Kiev', b'(GMT+0200) Europe/Kiev'), (b'Europe/Mariehamn', b'(GMT+0200) Europe/Mariehamn'), (b'Europe/Riga', b'(GMT+0200) Europe/Riga'), (b'Europe/Sofia', b'(GMT+0200) Europe/Sofia'), (b'Europe/Tallinn', b'(GMT+0200) Europe/Tallinn'), (b'Europe/Uzhgorod', b'(GMT+0200) Europe/Uzhgorod'), (b'Europe/Vilnius', b'(GMT+0200) Europe/Vilnius'), (b'Europe/Zaporozhye', b'(GMT+0200) Europe/Zaporozhye'), (b'Africa/Addis_Ababa', b'(GMT+0300) Africa/Addis_Ababa'), (b'Africa/Asmara', b'(GMT+0300) Africa/Asmara'), (b'Africa/Dar_es_Salaam', b'(GMT+0300) Africa/Dar_es_Salaam'), (b'Africa/Djibouti', b'(GMT+0300) Africa/Djibouti'), (b'Africa/Juba', b'(GMT+0300) Africa/Juba'), (b'Africa/Kampala', b'(GMT+0300) Africa/Kampala'), (b'Africa/Khartoum', b'(GMT+0300) Africa/Khartoum'), (b'Africa/Mogadishu', b'(GMT+0300) Africa/Mogadishu'), (b'Africa/Nairobi', b'(GMT+0300) Africa/Nairobi'), (b'Antarctica/Syowa', b'(GMT+0300) Antarctica/Syowa'), (b'Asia/Aden', b'(GMT+0300) Asia/Aden'), (b'Asia/Baghdad', b'(GMT+0300) Asia/Baghdad'), (b'Asia/Bahrain', b'(GMT+0300) Asia/Bahrain'), (b'Asia/Kuwait', b'(GMT+0300) Asia/Kuwait'), (b'Asia/Qatar', b'(GMT+0300) Asia/Qatar'), (b'Asia/Riyadh', b'(GMT+0300) Asia/Riyadh'), (b'Europe/Minsk', b'(GMT+0300) Europe/Minsk'), (b'Europe/Moscow', b'(GMT+0300) Europe/Moscow'), (b'Europe/Simferopol', b'(GMT+0300) Europe/Simferopol'), (b'Europe/Volgograd', b'(GMT+0300) Europe/Volgograd'), (b'Indian/Antananarivo', b'(GMT+0300) Indian/Antananarivo'), (b'Indian/Comoro', b'(GMT+0300) Indian/Comoro'), (b'Indian/Mayotte', b'(GMT+0300) Indian/Mayotte'), (b'Asia/Tehran', b'(GMT+0330) Asia/Tehran'), (b'Asia/Baku', b'(GMT+0400) Asia/Baku'), (b'Asia/Dubai', b'(GMT+0400) Asia/Dubai'), (b'Asia/Muscat', b'(GMT+0400) Asia/Muscat'), (b'Asia/Tbilisi', b'(GMT+0400) Asia/Tbilisi'), (b'Asia/Yerevan', b'(GMT+0400) Asia/Yerevan'), (b'Europe/Samara', b'(GMT+0400) Europe/Samara'), (b'Indian/Mahe', b'(GMT+0400) Indian/Mahe'), (b'Indian/Mauritius', b'(GMT+0400) Indian/Mauritius'), (b'Indian/Reunion', b'(GMT+0400) Indian/Reunion'), (b'Asia/Kabul', b'(GMT+0430) Asia/Kabul'), (b'Antarctica/Mawson', b'(GMT+0500) Antarctica/Mawson'), (b'Asia/Aqtau', b'(GMT+0500) Asia/Aqtau'), (b'Asia/Aqtobe', b'(GMT+0500) Asia/Aqtobe'), (b'Asia/Ashgabat', b'(GMT+0500) Asia/Ashgabat'), (b'Asia/Dushanbe', b'(GMT+0500) Asia/Dushanbe'), (b'Asia/Karachi', b'(GMT+0500) Asia/Karachi'), (b'Asia/Oral', b'(GMT+0500) Asia/Oral'), (b'Asia/Samarkand', b'(GMT+0500) Asia/Samarkand'), (b'Asia/Tashkent', b'(GMT+0500) Asia/Tashkent'), (b'Asia/Yekaterinburg', b'(GMT+0500) Asia/Yekaterinburg'), (b'Indian/Kerguelen', b'(GMT+0500) Indian/Kerguelen'), (b'Indian/Maldives', b'(GMT+0500) Indian/Maldives'), (b'Asia/Colombo', b'(GMT+0530) Asia/Colombo'), (b'Asia/Kolkata', b'(GMT+0530) Asia/Kolkata'), (b'Asia/Kathmandu', b'(GMT+0545) Asia/Kathmandu'), (b'Antarctica/Vostok', b'(GMT+0600) Antarctica/Vostok'), (b'Asia/Almaty', b'(GMT+0600) Asia/Almaty'), (b'Asia/Bishkek', b'(GMT+0600) Asia/Bishkek'), (b'Asia/Dhaka', b'(GMT+0600) Asia/Dhaka'), (b'Asia/Novosibirsk', b'(GMT+0600) Asia/Novosibirsk'), (b'Asia/Omsk', b'(GMT+0600) Asia/Omsk'), (b'Asia/Qyzylorda', b'(GMT+0600) Asia/Qyzylorda'), (b'Asia/Thimphu', b'(GMT+0600) Asia/Thimphu'), (b'Asia/Urumqi', b'(GMT+0600) Asia/Urumqi'), (b'Indian/Chagos', b'(GMT+0600) Indian/Chagos'), (b'Asia/Rangoon', b'(GMT+0630) Asia/Rangoon'), (b'Indian/Cocos', b'(GMT+0630) Indian/Cocos'), (b'Antarctica/Davis', b'(GMT+0700) Antarctica/Davis'), (b'Asia/Bangkok', b'(GMT+0700) Asia/Bangkok'), (b'Asia/Ho_Chi_Minh', b'(GMT+0700) Asia/Ho_Chi_Minh'), (b'Asia/Hovd', b'(GMT+0700) Asia/Hovd'), (b'Asia/Jakarta', b'(GMT+0700) Asia/Jakarta'), (b'Asia/Krasnoyarsk', b'(GMT+0700) Asia/Krasnoyarsk'), (b'Asia/Novokuznetsk', b'(GMT+0700) Asia/Novokuznetsk'), (b'Asia/Phnom_Penh', b'(GMT+0700) Asia/Phnom_Penh'), (b'Asia/Pontianak', b'(GMT+0700) Asia/Pontianak'), (b'Asia/Vientiane', b'(GMT+0700) Asia/Vientiane'), (b'Indian/Christmas', b'(GMT+0700) Indian/Christmas'), (b'Antarctica/Casey', b'(GMT+0800) Antarctica/Casey'), (b'Asia/Brunei', b'(GMT+0800) Asia/Brunei'), (b'Asia/Chita', b'(GMT+0800) Asia/Chita'), (b'Asia/Choibalsan', b'(GMT+0800) Asia/Choibalsan'), (b'Asia/Hong_Kong', b'(GMT+0800) Asia/Hong_Kong'), (b'Asia/Irkutsk', b'(GMT+0800) Asia/Irkutsk'), (b'Asia/Kuala_Lumpur', b'(GMT+0800) Asia/Kuala_Lumpur'), (b'Asia/Kuching', b'(GMT+0800) Asia/Kuching'), (b'Asia/Macau', b'(GMT+0800) Asia/Macau'), (b'Asia/Makassar', b'(GMT+0800) Asia/Makassar'), (b'Asia/Manila', b'(GMT+0800) Asia/Manila'), (b'Asia/Shanghai', b'(GMT+0800) Asia/Shanghai'), (b'Asia/Singapore', b'(GMT+0800) Asia/Singapore'), (b'Asia/Taipei', b'(GMT+0800) Asia/Taipei'), (b'Asia/Ulaanbaatar', b'(GMT+0800) Asia/Ulaanbaatar'), (b'Australia/Perth', b'(GMT+0800) Australia/Perth'), (b'Australia/Eucla', b'(GMT+0845) Australia/Eucla'), (b'Asia/Dili', b'(GMT+0900) Asia/Dili'), (b'Asia/Jayapura', b'(GMT+0900) Asia/Jayapura'), (b'Asia/Khandyga', b'(GMT+0900) Asia/Khandyga'), (b'Asia/Pyongyang', b'(GMT+0900) Asia/Pyongyang'), (b'Asia/Seoul', b'(GMT+0900) Asia/Seoul'), (b'Asia/Tokyo', b'(GMT+0900) Asia/Tokyo'), (b'Asia/Yakutsk', b'(GMT+0900) Asia/Yakutsk'), (b'Pacific/Palau', b'(GMT+0900) Pacific/Palau'), (b'Australia/Darwin', b'(GMT+0930) Australia/Darwin'), (b'Antarctica/DumontDUrville', b'(GMT+1000) Antarctica/DumontDUrville'), (b'Asia/Magadan', b'(GMT+1000) Asia/Magadan'), (b'Asia/Sakhalin', b'(GMT+1000) Asia/Sakhalin'), (b'Asia/Ust-Nera', b'(GMT+1000) Asia/Ust-Nera'), (b'Asia/Vladivostok', b'(GMT+1000) Asia/Vladivostok'), (b'Australia/Brisbane', b'(GMT+1000) Australia/Brisbane'), (b'Australia/Lindeman', b'(GMT+1000) Australia/Lindeman'), (b'Pacific/Bougainville', b'(GMT+1000) Pacific/Bougainville'), (b'Pacific/Chuuk', b'(GMT+1000) Pacific/Chuuk'), (b'Pacific/Guam', b'(GMT+1000) Pacific/Guam'), (b'Pacific/Port_Moresby', b'(GMT+1000) Pacific/Port_Moresby'), (b'Pacific/Saipan', b'(GMT+1000) Pacific/Saipan'), (b'Australia/Adelaide', b'(GMT+1030) Australia/Adelaide'), (b'Australia/Broken_Hill', b'(GMT+1030) Australia/Broken_Hill'), (b'Antarctica/Macquarie', b'(GMT+1100) Antarctica/Macquarie'), (b'Asia/Srednekolymsk', b'(GMT+1100) Asia/Srednekolymsk'), (b'Australia/Currie', b'(GMT+1100) Australia/Currie'), (b'Australia/Hobart', b'(GMT+1100) Australia/Hobart'), (b'Australia/Lord_Howe', b'(GMT+1100) Australia/Lord_Howe'), (b'Australia/Melbourne', b'(GMT+1100) Australia/Melbourne'), (b'Australia/Sydney', b'(GMT+1100) Australia/Sydney'), (b'Pacific/Efate', b'(GMT+1100) Pacific/Efate'), (b'Pacific/Guadalcanal', b'(GMT+1100) Pacific/Guadalcanal'), (b'Pacific/Kosrae', b'(GMT+1100) Pacific/Kosrae'), (b'Pacific/Noumea', b'(GMT+1100) Pacific/Noumea'), (b'Pacific/Pohnpei', b'(GMT+1100) Pacific/Pohnpei'), (b'Pacific/Norfolk', b'(GMT+1130) Pacific/Norfolk'), (b'Asia/Anadyr', b'(GMT+1200) Asia/Anadyr'), (b'Asia/Kamchatka', b'(GMT+1200) Asia/Kamchatka'), (b'Pacific/Funafuti', b'(GMT+1200) Pacific/Funafuti'), (b'Pacific/Kwajalein', b'(GMT+1200) Pacific/Kwajalein'), (b'Pacific/Majuro', b'(GMT+1200) Pacific/Majuro'), (b'Pacific/Nauru', b'(GMT+1200) Pacific/Nauru'), (b'Pacific/Tarawa', b'(GMT+1200) Pacific/Tarawa'), (b'Pacific/Wake', b'(GMT+1200) Pacific/Wake'), (b'Pacific/Wallis', b'(GMT+1200) Pacific/Wallis'), (b'Antarctica/McMurdo', b'(GMT+1300) Antarctica/McMurdo'), (b'Pacific/Auckland', b'(GMT+1300) Pacific/Auckland'), (b'Pacific/Enderbury', b'(GMT+1300) Pacific/Enderbury'), (b'Pacific/Fakaofo', b'(GMT+1300) Pacific/Fakaofo'), (b'Pacific/Fiji', b'(GMT+1300) Pacific/Fiji'), (b'Pacific/Tongatapu', b'(GMT+1300) Pacific/Tongatapu'), (b'Pacific/Chatham', b'(GMT+1345) Pacific/Chatham'), (b'Pacific/Apia', b'(GMT+1400) Pacific/Apia'), (b'Pacific/Kiritimati', b'(GMT+1400) Pacific/Kiritimati')]),
         ),
         migrations.AlterField(
             model_name='usercredential',
@@ -277,4 +188,14 @@ class Migration(migrations.Migration):
             name='user',
             field=models.ForeignKey(related_name=b'userdashboardviews', to=settings.AUTH_USER_MODEL),
         ),
+        migrations.AlterField(
+            model_name='userdeployments',
+            name='deployment',
+            field=models.ForeignKey(related_name=b'userdeployments', to='core.Deployment'),
+        ),
+        migrations.AlterField(
+            model_name='userdeployments',
+            name='user',
+            field=models.ForeignKey(related_name=b'userdeployments', to=settings.AUTH_USER_MODEL),
+        ),
     ]
index 821939e..2070e16 100644 (file)
@@ -5,15 +5,15 @@ from .service import Service
 from .service import ServiceAttribute
 from .tag import Tag
 from .role import Role
-from .site import Site,Deployment, DeploymentRole, DeploymentPrivilege, SiteDeployment
+from .site import Site,Deployment, DeploymentRole, DeploymentPrivilege, SiteDeployments
 from .dashboard import DashboardView
 from .user import User, UserDashboardView
 from .serviceclass import ServiceClass
 from .site import DeploymentLinkManager,DeploymentLinkDeletionManager
-from .slice import Slice, SliceDeployment
-from .site import SitePrivilege, SiteDeployment
-from .userdeployments import UserDeployment
-from .image import Image, ImageDeployment
+from .slice import Slice, SliceDeployments
+from .site import SitePrivilege, SiteDeployments
+from .userdeployments import UserDeployments
+from .image import Image, ImageDeployments
 from .node import Node
 from .serviceresource import ServiceResource
 from .slice import SliceRole
index 1bca1b9..fdeb2cc 100644 (file)
@@ -14,7 +14,7 @@ class Image(PlCoreBase):
 
     def __unicode__(self):  return u'%s' % (self.name)
 
-class ImageDeployment(PlCoreBase):
+class ImageDeployments(PlCoreBase):
     objects = DeploymentLinkManager()
     deleted_objects = DeploymentLinkDeletionManager()
     image = models.ForeignKey(Image,related_name='imagedeployments')
index 3c5a19b..0b3400a 100644 (file)
@@ -65,6 +65,8 @@ def ValidateNatList(ports):
 class NetworkTemplate(PlCoreBase):
     VISIBILITY_CHOICES = (('public', 'public'), ('private', 'private'))
     TRANSLATION_CHOICES = (('none', 'none'), ('NAT', 'NAT'))
+    TOPOLOGY_CHOICES = (('bigswitch', 'BigSwitch'), ('physical', 'Physical'), ('custom', 'Custom'))
+    CONTROLLER_CHOICES = ((None, 'None'), ('onos', 'ONOS'), ('custom', 'Custom'))
 
     name = models.CharField(max_length=32)
     description = models.CharField(max_length=1024, blank=True, null=True)
@@ -73,6 +75,8 @@ class NetworkTemplate(PlCoreBase):
     translation = models.CharField(max_length=30, choices=TRANSLATION_CHOICES, default="none")
     sharedNetworkName = models.CharField(max_length=30, blank=True, null=True)
     sharedNetworkId = models.CharField(null=True, blank=True, max_length=256, help_text="Quantum network")
+    topologyKind = models.CharField(null=False, blank=False, max_length=30, choices=TOPOLOGY_CHOICES, default="BigSwitch")
+    controllerKind = models.CharField(null=True, blank=True, max_length=30, choices=CONTROLLER_CHOICES, default=None)
 
     def __unicode__(self):  return u'%s' % (self.name)
 
@@ -90,6 +94,10 @@ class Network(PlCoreBase):
     slices = models.ManyToManyField(Slice, blank=True, related_name="networks", through="NetworkSlice")
     slivers = models.ManyToManyField(Sliver, blank=True, related_name="networks", through="NetworkSliver")
 
+    topologyParameters = models.TextField(null=True, blank=True)
+    controllerUrl = models.CharField(null=True, blank=True, max_length=1024)
+    controllerParameters = models.TextField(null=True, blank=True)
+
     # for observer/manager
     network_id = models.CharField(null=True, blank=True, max_length=256, help_text="Quantum network")
     router_id = models.CharField(null=True, blank=True, max_length=256, help_text="Quantum router id")
index 09eb786..2404e34 100644 (file)
@@ -105,7 +105,7 @@ class Site(PlCoreBase):
     abbreviated_name = models.CharField(max_length=80)
 
     #deployments = models.ManyToManyField('Deployment', blank=True, related_name='sites')
-    deployments = models.ManyToManyField('Deployment', through='SiteDeployment', blank=True, help_text="Select which sites are allowed to host nodes in this deployment", related_name='sites')
+    deployments = models.ManyToManyField('Deployment', through='SiteDeployments', blank=True, help_text="Select which sites are allowed to host nodes in this deployment", related_name='sites')
     tags = generic.GenericRelation(Tag)
 
     def __unicode__(self):  return u'%s' % (self.name)
@@ -255,7 +255,7 @@ class DeploymentPrivilege(PlCoreBase):
             qs = DeploymentPrivilege.objects.filter(id__in=dpriv_ids)
         return qs 
 
-class SiteDeployment(PlCoreBase):
+class SiteDeployments(PlCoreBase):
     objects = DeploymentLinkManager()
     deleted_objects = DeploymentLinkDeletionManager()
 
index 24d02aa..128d605 100644 (file)
@@ -93,7 +93,7 @@ class Slice(PlCoreBase):
         nets = Network.objects.filter(slices=self)
         nets.delete() 
         # delete slice deployments
-        slice_deployments = SliceDeployments.objects.filter(slice=self)
+        slice_deployments = SliceDeploymentss.objects.filter(slice=self)
         slice_deployments.delete()
         # delete slice privilege
         slice_privileges = SlicePrivilege.objects.filter(slice=self)
@@ -128,7 +128,7 @@ class SlicePrivilege(PlCoreBase):
             qs = SlicePrivilege.objects.filter(id__in=sp_ids)
         return qs
 
-class SliceDeployment(PlCoreBase):
+class SliceDeployments(PlCoreBase):
     objects = DeploymentLinkManager()
     deleted_objects = DeploymentLinkDeletionManager()
 
@@ -144,8 +144,8 @@ class SliceDeployment(PlCoreBase):
     @staticmethod
     def select_by_user(user):
         if user.is_admin:
-            qs = SliceDeployment.objects.all()
+            qs = SliceDeployments.objects.all()
         else:
             slices = Slice.select_by_user(user)
-            qs = SliceDeployment.objects.filter(slice__in=slices)
+            qs = SliceDeployments.objects.filter(slice__in=slices)
         return qs    
index d0337ba..d8051bf 100644 (file)
@@ -6,7 +6,7 @@ from django.db.models import F, Q
 from core.models import PlCoreBase,Site,User,Deployment
 from core.models import Deployment,DeploymentLinkManager,DeploymentLinkDeletionManager
 
-class UserDeployment(PlCoreBase):
+class UserDeployments(PlCoreBase):
     objects = DeploymentLinkManager()
     deleted_objects = DeploymentLinkDeletionManager()
 
@@ -19,7 +19,7 @@ class UserDeployment(PlCoreBase):
     @staticmethod
     def select_by_user(user):
         if user.is_admin:
-            qs = UserDeployment.objects.all()
+            qs = UserDeployments.objects.all()
         else:
             users = Users.select_by_user(user)
             qs = Usereployments.objects.filter(user__in=slices)
diff --git a/planetstack/core/static/uploadTextarea.js b/planetstack/core/static/uploadTextarea.js
new file mode 100644 (file)
index 0000000..a7f76bf
--- /dev/null
@@ -0,0 +1,19 @@
+function uploadTextarea(event,textarea_id) {
+    var input = event.target;
+
+    var reader = new FileReader();
+    //reader.onloadstart = function() {
+    // reader.abort();
+    //};
+
+    reader.onloadend = function() {
+        if (reader.error) {
+           alert(reader.error.message);
+        } else {
+            $("#" + textarea_id).val(this.result);
+           //console.log(this.result);
+        }
+    };
+
+    reader.readAsText(input.files[0]);
+};
index 6d60535..b5dacc9 100644 (file)
   </tr>
 </script>
 
+<div id="xos-confirm-dialog" title="Confirmation Required">
+  Are you sure about this?\r
+</div>
+
 <div id="contentPanel">
 <div id="contentTitle">
 </div>
 <button class="btn btn-high btn-info btn-xos-contentButtonPanel" onclick="$('button.btn-xos-save-leave').click()">Save</button>
 <button class="btn btn-high btn-xos-contentButtonPanel" onclick="$('button.btn-xos-save-continue').click()">Save and continue editing</button>
 <button class="btn btn-high btn-xos-contentButtonPanel" onclick="$('button.btn-xos-save-another').click()">Save and add another</button>
+<button class="btn btn-danger btn-xos-contentButtonPanel" onclick="$('button.btn-xos-delete').click()">Delete</button>
 </div>
 <div class="box save-box" id="xos-listview-button-box">
+<button class="btn btn-high btn-primary btn-xos-contentButtonPanel" onclick="$('button.btn-xos-refresh').click()">Refresh</button>
 <button class="btn btn-high btn-success btn-xos-contentButtonPanel" onclick="$('button.btn-xos-add').click()">Add</button>
 </div>
 <div class="box" id="logPanel">
index d1b4275..f09bbcf 100644 (file)
@@ -66,6 +66,8 @@
     text-decoration:none;
 }
 
+/* these are for the inline list and detail titles */
+
 .xos-list-title {
     display: none;
 }
     display: none;
 }
 
+/* this one goes with contenttitle */
+
+#xos-list-title-spinner {
+    display: none;
+}
+
 /* undo what planetstack.css does to the progressbar */
 #xos-startup-progress .ui-progressbar-value {
     background-color: rgb(204,204,204) !important;
@@ -91,4 +99,6 @@
     display: none;
 }
 
-
+#xos-confirm-dialog {
+    display: none;
+}
index b5d0f6c..ceb2589 100644 (file)
@@ -26,6 +26,17 @@ XOSAdminApp.navigateToModel = function(app, detailClass, detailNavLink, model) {
      XOSAdminApp.Router.navigate(detailNavLink + "/" + model.id, {trigger: true});
 };\r
 \r
+XOSAdminApp.navigate = function(what, modelName, modelId) {\r
+    collection_name = modelName + "s";\r
+    if (what=="list") {\r
+        XOSAdminApp.Router.navigate(collection_name, {trigger: true})\r
+    } else if (what=="detail") {\r
+        XOSAdminApp.Router.navigate(collection_name + "/" + modelId, {trigger: true})\r
+    } else if (what=="add") {\r
+        XOSAdminApp.Router.navigate("add" + firstCharUpper(modelName), {trigger: true})\r
+    }\r
+}\r
+\r
 ICON_CLASSES = {home: "icon-home", deployments: "icon-deployment", sites: "icon-site", slices: "icon-slice", users: "icon-user"};\r
 \r
 XOSAdminApp.updateNavigationPanel = function() {\r
@@ -56,12 +67,10 @@ XOSAdminApp.buildViews = function() {
          collection_name = name + "s";
          region_name = name + "List";
          detailNavLink = collection_name;
-         listNavLink = collection_name;
 
          detailClass = XOSDetailView.extend({
             template: detail_template,\r
             app: XOSAdminApp,\r
-            listNavLink: listNavLink,\r
          });\r
          XOSAdminApp[collection_name + "DetailView"] = detailClass;\r
 
index 36df6eb..f615c30 100644 (file)
@@ -116,21 +116,27 @@ if (! window.XOSLIB_LOADED ) {
         },\r
 \r
         fetchSuccess: function(collection, response, options) {\r
+            //console.log("fetch succeeded " + collection.modelName);\r
             this.failedLoad = false;\r
+            this.fetching = false;\r
             if (!this.isLoaded) {\r
                 this.isLoaded = true;\r
                 Backbone.trigger("xoslib:collectionLoadChange", this);\r
             }\r
+            this.trigger("fetchStateChange");\r
             if (options["orig_success"]) {\r
                 options["orig_success"](collection, response, options);\r
             }\r
         },\r
 \r
         fetchFailure: function(collection, response, options) {\r
+            //console.log("fetch failed " + collection.modelName);\r
+            this.fetching = false;\r
             if ((!this.isLoaded) && (!this.failedLoad)) {\r
                 this.failedLoad=true;\r
                 Backbone.trigger("xoslib:collectionLoadChange", this);\r
             }\r
+            this.trigger("fetchStateChange");\r
             if (options["orig_failure"]) {\r
                 options["orig_failure"](collection, response, options);\r
             }\r
@@ -138,10 +144,13 @@ if (! window.XOSLIB_LOADED ) {
 \r
         fetch: function(options) {\r
             var self=this;\r
+            this.fetching=true;\r
+            //console.log("fetch " + this.modelName);\r
             if (!this.startedLoad) {\r
                 this.startedLoad=true;\r
                 Backbone.trigger("xoslib:collectionLoadChange", this);\r
             }\r
+            this.trigger("fetchStateChange");\r
             if (options == undefined) {\r
                 options = {};\r
             }\r
@@ -161,6 +170,20 @@ if (! window.XOSLIB_LOADED ) {
             }
         },
 
+        refresh: function(refreshRelated) {
+            if (!this.fetching) {
+                this.fetch();
+            }
+            if (refreshRelated) {
+                for (related in this.relatedCollections) {
+                    related = xos[related];
+                    if (!related.fetching) {
+                        related.fetch();
+                    }
+                }
+            }
+        },
+
         maybeFetch: function(options){
                 // Helper function to fetch only if this collection has not been fetched before.
             if(this._fetched){
index 89d0d3b..98dfb88 100644 (file)
@@ -28,6 +28,23 @@ XOSApplication = Marionette.Application.extend({
     successTemplate: "#xos-success-template",
     logMessageCount: 0,
 
+    confirmDialog: function(view, event) {
+        $("#xos-confirm-dialog").dialog({
+           autoOpen: false,\r
+           modal: true,\r
+           buttons : {\r
+                "Confirm" : function() {\r
+                  $(this).dialog("close");\r
+                  view.trigger(event);\r
+                },\r
+                "Cancel" : function() {\r
+                  $(this).dialog("close");\r
+                }\r
+              }\r
+            });
+        $("#xos-confirm-dialog").dialog("open");
+    },
+
     hideError: function() {
         if (this.logWindowId) {
         } else {
@@ -128,7 +145,7 @@ XOSApplication = Marionette.Application.extend({
         return function() {\r
             model = new xos[collection_name].model();\r
             detailViewClass = app[detailName];\r
-            detailView = new detailViewClass({model: model});\r
+            detailView = new detailViewClass({model: model, collection:xos[collection_name]});\r
             app[regionName].show(detailView);\r
             $("#xos-detail-button-box").show();\r
             $("#xos-listview-button-box").hide();\r
@@ -169,8 +186,13 @@ XOSDetailView = Marionette.ItemView.extend({
             events: {"click button.btn-xos-save-continue": "submitContinueClicked",
                      "click button.btn-xos-save-leave": "submitLeaveClicked",
                      "click button.btn-xos-save-another": "submitAddAnotherClicked",
+                     "click button.btn-xos-delete": "deleteClicked",
                      "change input": "inputChanged"},
 
+            initialize: function() {
+                this.on('deleteConfirmed', this.deleteConfirmed);
+            },
+
             /* inputChanged is watching the onChange events of the input controls. We
                do this to track when this view is 'dirty', so we can throw up a warning\r
                if the user tries to change his slices without saving first.\r
@@ -193,6 +215,19 @@ XOSDetailView = Marionette.ItemView.extend({
                 this.app.showSuccess(result);\r
             },
 
+            destroyError: function(model, result, xhr, infoMsgId) {
+                result["what"] = "destroy " + model.__proto__.modelName;\r
+                result["infoMsgId"] = infoMsgId;\r
+                this.app.showError(result);\r
+            },\r
+\r
+            destroySuccess: function(model, result, xhr, infoMsgId) {\r
+                result = {status: xhr.xhr.status, statusText: xhr.xhr.statusText};\r
+                result["what"] = "destroy " + model.__proto__.modelName;\r
+                result["infoMsgId"] = infoMsgId;\r
+                this.app.showSuccess(result);\r
+            },
+
             submitContinueClicked: function(e) {
                 console.log("saveContinue");
                 e.preventDefault();
@@ -203,14 +238,14 @@ XOSDetailView = Marionette.ItemView.extend({
                 console.log("saveLeave");
                 e.preventDefault();
                 this.save();
-                this.app.Router.navigate(this.listNavLink, {trigger: true});
-                console.log("route to " + this.listNavLink);
+                this.app.navigate("list", this.model.modelName);
             },
 
             submitAddAnotherClicked: function(e) {
                 console.log("saveAnother");
                 e.preventDefault();
                 this.save();
+                this.app.navigate("add", this.model.modelName);
             },
 
             save: function() {
@@ -218,11 +253,36 @@ XOSDetailView = Marionette.ItemView.extend({
                 var infoMsgId = this.app.showInformational( {what: "save " + this.model.__proto__.modelName, status: "", statusText: "in progress..."} );\r
                 var data = Backbone.Syphon.serialize(this);\r
                 var that = this;\r
+                var isNew = !this.model.id;\r
                 this.model.save(data, {error: function(model, result, xhr) { that.saveError(model,result,xhr,infoMsgId);},\r
                                        success: function(model, result, xhr) { that.saveSuccess(model,result,xhr,infoMsgId);}});\r
+                if (isNew) {\r
+                    console.log(this.model);\r
+                    this.collection.add(this.model);\r
+                    this.collection.sort();\r
+                }\r
                 this.dirty = false;\r
             },
 
+            destroyModel: function() {
+                 this.app.hideError();
+                 var infoMsgId = this.app.showInformational( {what: "destroy " + this.model.__proto__.modelName, status: "", statusText: "in progress..."} );
+                 var that = this;
+                 this.model.destroy({error: function(model, result, xhr) { that.destroyError(model,result,xhr,infoMsgId);},
+                                     success: function(model, result, xhr) { that.destroySuccess(model,result,xhr,infoMsgId);}});
+            },
+
+             deleteClicked: function(e) {
+                 e.preventDefault();
+\r                 this.app.confirmDialog(this, "deleteConfirmed");
+\r             },
+\r
+\r             deleteConfirmed: function() {
+\r                 modelName = this.model.modelName;
+\r                 this.destroyModel();
+\r                 this.app.navigate("list", modelName);
+\r             },
+\r
             tabClick: function(tabId, regionName) {
                     region = this.app[regionName];\r
                     if (this.currentTabRegion != undefined) {\r
@@ -320,16 +380,30 @@ XOSListView = Marionette.CompositeView.extend({
              childViewContainer: 'tbody',\r
 \r
              events: {"click button.btn-xos-add": "addClicked",\r
-                     },
-
+                      "click button.btn-xos-refresh": "refreshClicked",\r
+                     },\r
+\r
+             _fetchStateChange: function() {\r
+                 if (this.collection.fetching) {\r
+                    $("#xos-list-title-spinner").show();\r
+                 } else {\r
+                    $("#xos-list-title-spinner").hide();\r
+                 }\r
+             },\r
+\r
              addClicked: function(e) {
-                console.log("add");
                 e.preventDefault();
                 this.app.Router.navigate("add" + firstCharUpper(this.collection.modelName), {trigger: true});
              },
 \r
-             initialize: function() {\r
-                 this.listenTo(this.collection, 'change', this._renderChildren)
+\r             refreshClicked: function(e) {
+\r                 e.preventDefault();
+\r                 this.collection.refresh(refreshRelated=true);
+\r             },
+\r
+\r             initialize: function() {
+\r                 this.listenTo(this.collection, 'change', this._renderChildren)
+                 this.listenTo(this.collection, 'fetchStateChange', this._fetchStateChange);
 
                  // Because many of the templates use idToName(), we need to
                  // listen to the collections that hold the names for the ids
index d543502..bc6ac02 100644 (file)
@@ -35,7 +35,7 @@
 </script>
 
 <script type="text/template" id="xos-title-list">
-  <h3><%= title %></h3>
+  <h3><img src="/static/img/brokencircle.gif" height=16 width=16 id="xos-list-title-spinner"> <%= title %></h3>
 </script>
 
 <script type="text/template" id="xos-title-detail">
        <td colspan=2><button class="btn js-submit btn-xos-detail btn-xos-save-leave">Save</button>
            <button class="btn js-submit btn-xos-detail btn-xos-save-continue">Save and Continue Editing</button>
            <button class="btn js-submit btn-xos-detail btn-xos-save-another">Save and Add Another</button>
+           <button class="btn js-submit btn-xos-detail btn-xos-delete">Delete</button>
        </td>
     </tr>
 </script>
 
 <script type="text/template" id="xos-inline-list-buttons-template">
            <button class="btn js-submit btn-xos-list btn-xos-add">Add</button>
+           <button class="btn js-submit btn-xos-list btn-xos-refresh">Refresh</button>
        </td>
     </tr>
 </script>
@@ -89,7 +91,7 @@
   <td class="objectLink"><%= name %></td>
   <td><%= backend_type %></td>
   <td><%= admin_tenant %></td>
-  <td><%= sites.length %></td>
+  <td><%= typeof sites != 'undefined' && sites.length || 0 %></td>
 </script>
 
 <script type="text/template" id="xosAdmin-deployment-detail-template">
index 88a4008..b8ca6a1 100644 (file)
@@ -1,14 +1,14 @@
-from core.models import Site, SiteDeployment
+from core.models import Site, SiteDeployments
 from observer.deleter import Deleter
-from observer.deleters.site_deployment_deleter import SiteDeploymentDeleter
+from observer.deleters.site_deployment_deleter import SiteDeploymentsDeleter
 
 class SiteDeleter(Deleter):
     model='Site'
     
     def call(self, pk):
         site = Site.objects.get(pk=pk)
-        site_deployments = SiteDeployment.objects.filter(site=site)
-        site_deployment_deleter = SiteDeploymentDeleter()
+        site_deployments = SiteDeployments.objects.filter(site=site)
+        site_deployment_deleter = SiteDeploymentsDeleter()
         for site_deployment in site_deployments:
             site_deployment_deleter(site_deployment.id)
         site.delete() 
index db344cd..cc71d43 100644 (file)
@@ -1,11 +1,11 @@
-from core.models import Site, SiteDeployment
+from core.models import Site, SiteDeployments
 from observer.deleter import Deleter
 
-class SiteDeploymentDeleter(Deleter):
-    model='SiteDeployment'
+class SiteDeploymentsDeleter(Deleter):
+    model='SiteDeployments'
 
     def call(self, pk):
-        site_deployment = SiteDeployment.objects.get(pk=pk)
+        site_deployment = SiteDeployments.objects.get(pk=pk)
         if site_deployment.tenant_id:
             driver = self.driver.admin_driver(deployment=site_deployment.deployment.name)
             driver.delete_tenant(site_deployment.tenant_id)
index e7c54e6..7e9dfd4 100644 (file)
@@ -1,6 +1,6 @@
-from core.models import Slice, SliceDeployment, User
+from core.models import Slice, SliceDeployments, User
 from observer.deleter import Deleter
-from observer.deleters.slice_deployment_deleter import SliceDeploymentDeleter
+from observer.deleters.slice_deployment_deleter import SliceDeploymentsDeleter
 from util.logger import Logger, logging
 
 logger = Logger(level=logging.INFO)
@@ -10,8 +10,8 @@ class SliceDeleter(Deleter):
 
     def call(self, pk):
         slice = Slice.objects.get(pk=pk)
-        slice_deployment_deleter = SliceDeploymentDeleter()
-        for slice_deployment in SliceDeployment.objects.filter(slice=slice):
+        slice_deployment_deleter = SliceDeploymentsDeleter()
+        for slice_deployment in SliceDeployments.objects.filter(slice=slice):
             try:
                 slice_deployment_deleter(slice_deployment.id)
             except:
index 31d26fb..6f1aec0 100644 (file)
@@ -1,12 +1,12 @@
-from core.models import Slice, SliceDeployment, User
+from core.models import Slice, SliceDeployments, User
 from observer.deleter import Deleter
 from openstack.driver import OpenStackDriver
 
-class SliceDeploymentDeleter(Deleter):
-    model='SliceDeployment'
+class SliceDeploymentsDeleter(Deleter):
+    model='SliceDeployments'
 
     def call(self, pk):
-        slice_deployment = SliceDeployment.objects.get(pk=pk)
+        slice_deployment = SliceDeployments.objects.get(pk=pk)
         user = User.objects.get(id=slice_deployment.slice.creator.id)
         driver = OpenStackDriver().admin_driver(deployment=slice_deployment.deployment.name)
         client_driver = driver.client_driver(caller=user,
index 732e535..097f0f7 100644 (file)
@@ -1,4 +1,4 @@
-from core.models import Sliver, SliceDeployment
+from core.models import Sliver, SliceDeployments
 from observer.deleter import Deleter
 
 class SliverDeleter(Deleter):
index 3f93060..3930eb0 100644 (file)
@@ -1,13 +1,13 @@
-from core.models import User, UserDeployment
+from core.models import User, UserDeployments
 from observer.deleter import Deleter
-from observer.deleters.user_deployment_deleter import UserDeploymentDeleter
+from observer.deleters.user_deployment_deleter import UserDeploymentsDeleter
 
 class UserDeleter(Deleter):
     model='User'
 
     def call(self, pk):
         user = User.objects.get(pk=pk)
-        user_deployment_deleter = UserDeploymentDeleter()
-        for user_deployment in UserDeployment.objects.filter(user=user):
+        user_deployment_deleter = UserDeploymentsDeleter()
+        for user_deployment in UserDeployments.objects.filter(user=user):
             user_deployment_deleter(user_deployment.id)
         user.delete()
index 6d3825c..4bc7619 100644 (file)
@@ -1,11 +1,11 @@
-from core.models import User, UserDeployment
+from core.models import User, UserDeployments
 from observer.deleter import Deleter
 
-class UserDeploymentDeleter(Deleter):
-    model='UserDeployment'
+class UserDeploymentsDeleter(Deleter):
+    model='UserDeployments'
 
     def call(self, pk):
-        user_deployment = UserDeployment.objects.get(pk=pk)
+        user_deployment = UserDeployments.objects.get(pk=pk)
         if user_deployment.user.kuser_id:
             driver = self.driver.admin_driver(deployment=user_deployment.deployment.name)
             driver.delete_user(user_deployment.user.kuser_id)
index 0fa8b61..9f032ed 100644 (file)
@@ -20,7 +20,7 @@ class SyncNodes(SyncStep):
             return []
 
         deployment = Deployment.objects.filter(Q(name="Amazon EC2"))[0]
-        current_site_deployments = SiteDeployment.objects.filter(Q(deployment=deployment))
+        current_site_deployments = SiteDeployments.objects.filter(Q(deployment=deployment))
 
         zone_ret = aws_run('ec2 describe-availability-zones')
         zones = zone_ret['AvailabilityZones']
index 5adccb7..7c24f68 100644 (file)
@@ -7,9 +7,9 @@ from core.models.site import *
 from ec2_observer.awslib import *
 import pdb
 
-class SyncSiteDeployment(SyncStep):
+class SyncSiteDeployments(SyncStep):
     requested_interval=86400
-    provides=[SiteDeployment]
+    provides=[SiteDeployments]
 
     def fetch_pending(self, deletion):
         if (deletion):
@@ -29,7 +29,7 @@ class SyncSiteDeployment(SyncStep):
         # The syncstep should catch it
         # At any rate, we should not run if there are no deployments
         deployment = Deployment.objects.filter(Q(name="Amazon EC2"))[0]
-        current_site_deployments = SiteDeployment.objects.filter(Q(deployment=deployment))
+        current_site_deployments = SiteDeployments.objects.filter(Q(deployment=deployment))
         site_dict = {}
 
         for sd in current_site_deployments:
@@ -40,7 +40,7 @@ class SyncSiteDeployment(SyncStep):
             try:
                 site_record = site_dict[site]
             except KeyError:
-                sd = SiteDeployment(site=site,deployment=deployment,tenant_id=base64.urlsafe_b64encode(os.urandom(12)))
+                sd = SiteDeployments(site=site,deployment=deployment,tenant_id=base64.urlsafe_b64encode(os.urandom(12)))
                 updated_site_deployments.append(sd)
 
         return updated_site_deployments
index 0959c71..0c1c7cf 100644 (file)
@@ -16,7 +16,7 @@ class SyncSites(SyncStep):
             return []
 
         deployment = Deployment.objects.filter(Q(name="Amazon EC2"))[0]
-        current_site_deployments = SiteDeployment.objects.filter(Q(deployment=deployment))
+        current_site_deployments = SiteDeployments.objects.filter(Q(deployment=deployment))
 
         zone_ret = aws_run('ec2 describe-availability-zones')
         zones = zone_ret['AvailabilityZones']
index ed75438..15cd5eb 100644 (file)
@@ -5,7 +5,7 @@ from django.db.models import F, Q
 from planetstack.config import Config
 from ec2_observer.syncstep import SyncStep
 from core.models.sliver import Sliver
-from core.models.slice import SlicePrivilege, SliceDeployment
+from core.models.slice import SlicePrivilege, SliceDeployments
 from core.models.network import Network, NetworkSlice, NetworkDeployments
 from util.logger import Logger, logging
 from ec2_observer.awslib import *
@@ -30,7 +30,7 @@ class SyncSlivers(SyncStep):
         my_slivers = [] 
 
         for sliver in all_slivers:
-            sd = SliceDeployment.objects.filter(Q(slice=sliver.slice))
+            sd = SliceDeployments.objects.filter(Q(slice=sliver.slice))
             if (sd):
                 if (sd.deployment.name=='Amazon EC2'):
                     my_slivers.append(sliver)
index 1e1fa9f..1503431 100644 (file)
@@ -96,9 +96,9 @@ def get_REST_patterns():
         url(r'plstackapi/serviceclasses/(?P<pk>[a-zA-Z0-9\-]+)/$', ServiceClassDetail.as_view(), name ='serviceclass-detail'),
 #        url(r'plstackapi/serviceclasses/!new/$', ServiceClassNew.as_view(), name ='serviceclass-new'),
     
-        url(r'plstackapi/payments/$', PaymentList.as_view(), name='payment-list'),
-        url(r'plstackapi/payments/(?P<pk>[a-zA-Z0-9\-]+)/$', PaymentDetail.as_view(), name ='payment-detail'),
-#        url(r'plstackapi/payments/!new/$', PaymentNew.as_view(), name ='payment-new'),
+        url(r'plstackapi/planetstacks/$', PlanetStackList.as_view(), name='planetstack-list'),
+        url(r'plstackapi/planetstacks/(?P<pk>[a-zA-Z0-9\-]+)/$', PlanetStackDetail.as_view(), name ='planetstack-detail'),
+#        url(r'plstackapi/planetstacks/!new/$', PlanetStackNew.as_view(), name ='planetstack-new'),
     
         url(r'plstackapi/charges/$', ChargeList.as_view(), name='charge-list'),
         url(r'plstackapi/charges/(?P<pk>[a-zA-Z0-9\-]+)/$', ChargeDetail.as_view(), name ='charge-detail'),
@@ -132,14 +132,14 @@ def get_REST_patterns():
         url(r'plstackapi/dashboardviews/(?P<pk>[a-zA-Z0-9\-]+)/$', DashboardViewDetail.as_view(), name ='dashboardview-detail'),
 #        url(r'plstackapi/dashboardviews/!new/$', DashboardViewNew.as_view(), name ='dashboardview-new'),
     
-        url(r'plstackapi/imagedeployments/$', ImageDeploymentsList.as_view(), name='imagedeployments-list'),
-        url(r'plstackapi/imagedeployments/(?P<pk>[a-zA-Z0-9\-]+)/$', ImageDeploymentsDetail.as_view(), name ='imagedeployments-detail'),
-#        url(r'plstackapi/imagedeployments/!new/$', ImageDeploymentsNew.as_view(), name ='imagedeployments-new'),
-    
         url(r'plstackapi/reservedresources/$', ReservedResourceList.as_view(), name='reservedresource-list'),
         url(r'plstackapi/reservedresources/(?P<pk>[a-zA-Z0-9\-]+)/$', ReservedResourceDetail.as_view(), name ='reservedresource-detail'),
 #        url(r'plstackapi/reservedresources/!new/$', ReservedResourceNew.as_view(), name ='reservedresource-new'),
     
+        url(r'plstackapi/payments/$', PaymentList.as_view(), name='payment-list'),
+        url(r'plstackapi/payments/(?P<pk>[a-zA-Z0-9\-]+)/$', PaymentDetail.as_view(), name ='payment-detail'),
+#        url(r'plstackapi/payments/!new/$', PaymentNew.as_view(), name ='payment-new'),
+    
         url(r'plstackapi/networkslices/$', NetworkSliceList.as_view(), name='networkslice-list'),
         url(r'plstackapi/networkslices/(?P<pk>[a-zA-Z0-9\-]+)/$', NetworkSliceDetail.as_view(), name ='networkslice-detail'),
 #        url(r'plstackapi/networkslices/!new/$', NetworkSliceNew.as_view(), name ='networkslice-new'),
@@ -148,6 +148,10 @@ def get_REST_patterns():
         url(r'plstackapi/userdashboardviews/(?P<pk>[a-zA-Z0-9\-]+)/$', UserDashboardViewDetail.as_view(), name ='userdashboardview-detail'),
 #        url(r'plstackapi/userdashboardviews/!new/$', UserDashboardViewNew.as_view(), name ='userdashboardview-new'),
     
+        url(r'plstackapi/sitedeployments/$', SiteDeploymentsList.as_view(), name='sitedeployment-list'),
+        url(r'plstackapi/sitedeployments/(?P<pk>[a-zA-Z0-9\-]+)/$', SiteDeploymentsDetail.as_view(), name ='sitedeployment-detail'),
+#        url(r'plstackapi/sitedeployments/!new/$', SiteDeploymentsNew.as_view(), name ='sitedeployment-new'),
+    
         url(r'plstackapi/planetstackprivileges/$', PlanetStackPrivilegeList.as_view(), name='planetstackprivilege-list'),
         url(r'plstackapi/planetstackprivileges/(?P<pk>[a-zA-Z0-9\-]+)/$', PlanetStackPrivilegeDetail.as_view(), name ='planetstackprivilege-detail'),
 #        url(r'plstackapi/planetstackprivileges/!new/$', PlanetStackPrivilegeNew.as_view(), name ='planetstackprivilege-new'),
@@ -164,21 +168,17 @@ def get_REST_patterns():
         url(r'plstackapi/reservations/(?P<pk>[a-zA-Z0-9\-]+)/$', ReservationDetail.as_view(), name ='reservation-detail'),
 #        url(r'plstackapi/reservations/!new/$', ReservationNew.as_view(), name ='reservation-new'),
     
-        url(r'plstackapi/slice_deployments/$', SliceDeploymentsList.as_view(), name='slicedeployments-list'),
-        url(r'plstackapi/slice_deployments/(?P<pk>[a-zA-Z0-9\-]+)/$', SliceDeploymentsDetail.as_view(), name ='slicedeployments-detail'),
-#        url(r'plstackapi/slice_deployments/!new/$', SliceDeploymentsNew.as_view(), name ='slicedeployments-new'),
-    
         url(r'plstackapi/siteprivileges/$', SitePrivilegeList.as_view(), name='siteprivilege-list'),
         url(r'plstackapi/siteprivileges/(?P<pk>[a-zA-Z0-9\-]+)/$', SitePrivilegeDetail.as_view(), name ='siteprivilege-detail'),
 #        url(r'plstackapi/siteprivileges/!new/$', SitePrivilegeNew.as_view(), name ='siteprivilege-new'),
     
-        url(r'plstackapi/planetstacks/$', PlanetStackList.as_view(), name='planetstack-list'),
-        url(r'plstackapi/planetstacks/(?P<pk>[a-zA-Z0-9\-]+)/$', PlanetStackDetail.as_view(), name ='planetstack-detail'),
-#        url(r'plstackapi/planetstacks/!new/$', PlanetStackNew.as_view(), name ='planetstack-new'),
+        url(r'plstackapi/slicedeployments/$', SliceDeploymentsList.as_view(), name='slicedeployment-list'),
+        url(r'plstackapi/slicedeployments/(?P<pk>[a-zA-Z0-9\-]+)/$', SliceDeploymentsDetail.as_view(), name ='slicedeployment-detail'),
+#        url(r'plstackapi/slicedeployments/!new/$', SliceDeploymentsNew.as_view(), name ='slicedeployment-new'),
     
-        url(r'plstackapi/user_deployments/$', UserDeploymentsList.as_view(), name='userdeployments-list'),
-        url(r'plstackapi/user_deployments/(?P<pk>[a-zA-Z0-9\-]+)/$', UserDeploymentsDetail.as_view(), name ='userdeployments-detail'),
-#        url(r'plstackapi/user_deployments/!new/$', UserDeploymentsNew.as_view(), name ='userdeployments-new'),
+        url(r'plstackapi/userdeployments/$', UserDeploymentsList.as_view(), name='userdeployment-list'),
+        url(r'plstackapi/userdeployments/(?P<pk>[a-zA-Z0-9\-]+)/$', UserDeploymentsDetail.as_view(), name ='userdeployment-detail'),
+#        url(r'plstackapi/userdeployments/!new/$', UserDeploymentsNew.as_view(), name ='userdeployment-new'),
     
         url(r'plstackapi/accounts/$', AccountList.as_view(), name='account-list'),
         url(r'plstackapi/accounts/(?P<pk>[a-zA-Z0-9\-]+)/$', AccountDetail.as_view(), name ='account-detail'),
@@ -196,6 +196,10 @@ def get_REST_patterns():
         url(r'plstackapi/deploymentprivileges/(?P<pk>[a-zA-Z0-9\-]+)/$', DeploymentPrivilegeDetail.as_view(), name ='deploymentprivilege-detail'),
 #        url(r'plstackapi/deploymentprivileges/!new/$', DeploymentPrivilegeNew.as_view(), name ='deploymentprivilege-new'),
     
+        url(r'plstackapi/imagedeployments/$', ImageDeploymentsList.as_view(), name='imagedeployment-list'),
+        url(r'plstackapi/imagedeployments/(?P<pk>[a-zA-Z0-9\-]+)/$', ImageDeploymentsDetail.as_view(), name ='imagedeployment-detail'),
+#        url(r'plstackapi/imagedeployments/!new/$', ImageDeploymentsNew.as_view(), name ='imagedeployment-new'),
+    
         url(r'plstackapi/deploymentroles/$', DeploymentRoleList.as_view(), name='deploymentrole-list'),
         url(r'plstackapi/deploymentroles/(?P<pk>[a-zA-Z0-9\-]+)/$', DeploymentRoleDetail.as_view(), name ='deploymentrole-detail'),
 #        url(r'plstackapi/deploymentroles/!new/$', DeploymentRoleNew.as_view(), name ='deploymentrole-new'),
@@ -204,10 +208,6 @@ def get_REST_patterns():
         url(r'plstackapi/usercredentials/(?P<pk>[a-zA-Z0-9\-]+)/$', UserCredentialDetail.as_view(), name ='usercredential-detail'),
 #        url(r'plstackapi/usercredentials/!new/$', UserCredentialNew.as_view(), name ='usercredential-new'),
     
-        url(r'plstackapi/sitedeployments/$', SiteDeploymentsList.as_view(), name='sitedeployments-list'),
-        url(r'plstackapi/sitedeployments/(?P<pk>[a-zA-Z0-9\-]+)/$', SiteDeploymentsDetail.as_view(), name ='sitedeployments-detail'),
-#        url(r'plstackapi/sitedeployments/!new/$', SiteDeploymentsNew.as_view(), name ='sitedeployments-new'),
-    
         url(r'plstackapi/slicetags/$', SliceTagList.as_view(), name='slicetag-list'),
         url(r'plstackapi/slicetags/(?P<pk>[a-zA-Z0-9\-]+)/$', SliceTagDetail.as_view(), name ='slicetag-detail'),
 #        url(r'plstackapi/slicetags/!new/$', SliceTagNew.as_view(), name ='slicetag-new'),
@@ -246,7 +246,7 @@ def api_root(request, format=None):
         'networks': reverse('network-list', request=request, format=format),
         'services': reverse('service-list', request=request, format=format),
         'serviceclasses': reverse('serviceclass-list', request=request, format=format),
-        'payments': reverse('payment-list', request=request, format=format),
+        'planetstacks': reverse('planetstack-list', request=request, format=format),
         'charges': reverse('charge-list', request=request, format=format),
         'roles': reverse('role-list', request=request, format=format),
         'usableobjects': reverse('usableobject-list', request=request, format=format),
@@ -255,25 +255,25 @@ def api_root(request, format=None):
         'slivers': reverse('sliver-list', request=request, format=format),
         'nodes': reverse('node-list', request=request, format=format),
         'dashboardviews': reverse('dashboardview-list', request=request, format=format),
-        'imagedeploymentses': reverse('imagedeployments-list', request=request, format=format),
         'reservedresources': reverse('reservedresource-list', request=request, format=format),
+        'payments': reverse('payment-list', request=request, format=format),
         'networkslices': reverse('networkslice-list', request=request, format=format),
         'userdashboardviews': reverse('userdashboardview-list', request=request, format=format),
+        'sitedeployments': reverse('sitedeployment-list', request=request, format=format),
         'planetstackprivileges': reverse('planetstackprivilege-list', request=request, format=format),
         'users': reverse('user-list', request=request, format=format),
         'deployments': reverse('deployment-list', request=request, format=format),
         'reservations': reverse('reservation-list', request=request, format=format),
-        'slicedeploymentses': reverse('slicedeployments-list', request=request, format=format),
         'siteprivileges': reverse('siteprivilege-list', request=request, format=format),
-        'planetstacks': reverse('planetstack-list', request=request, format=format),
-        'userdeploymentses': reverse('userdeployments-list', request=request, format=format),
+        'slicedeployments': reverse('slicedeployment-list', request=request, format=format),
+        'userdeployments': reverse('userdeployment-list', request=request, format=format),
         'accounts': reverse('account-list', request=request, format=format),
         'networkparametertypes': reverse('networkparametertype-list', request=request, format=format),
         'sitecredentials': reverse('sitecredential-list', request=request, format=format),
         'deploymentprivileges': reverse('deploymentprivilege-list', request=request, format=format),
+        'imagedeployments': reverse('imagedeployment-list', request=request, format=format),
         'deploymentroles': reverse('deploymentrole-list', request=request, format=format),
         'usercredentials': reverse('usercredential-list', request=request, format=format),
-        'sitedeploymentses': reverse('sitedeployments-list', request=request, format=format),
         'slicetags': reverse('slicetag-list', request=request, format=format),
         'networktemplates': reverse('networktemplate-list', request=request, format=format),
         'routers': reverse('router-list', request=request, format=format),
@@ -576,7 +576,7 @@ class NetworkSerializer(serializers.HyperlinkedModelSerializer):
     
     class Meta:
         model = Network
-        fields = ('id','created','updated','enacted','backend_status','deleted','name','template','subnet','ports','labels','owner','guaranteedBandwidth','permitAllSlices','network_id','router_id','subnet_id','routers','availableRouters','routers','routers',)
+        fields = ('id','created','updated','enacted','backend_status','deleted','name','template','subnet','ports','labels','owner','guaranteedBandwidth','permitAllSlices','topologyParameters','controllerUrl','controllerParameters','network_id','router_id','subnet_id','routers','availableRouters','routers','routers',)
 
 class NetworkIdSerializer(serializers.ModelSerializer):
     id = serializers.Field()
@@ -599,7 +599,7 @@ class NetworkIdSerializer(serializers.ModelSerializer):
     
     class Meta:
         model = Network
-        fields = ('id','created','updated','enacted','backend_status','deleted','name','template','subnet','ports','labels','owner','guaranteedBandwidth','permitAllSlices','network_id','router_id','subnet_id','routers','availableRouters','routers','routers',)
+        fields = ('id','created','updated','enacted','backend_status','deleted','name','template','subnet','ports','labels','owner','guaranteedBandwidth','permitAllSlices','topologyParameters','controllerUrl','controllerParameters','network_id','router_id','subnet_id','routers','availableRouters','routers','routers',)
 
 
 
@@ -638,19 +638,19 @@ class ServiceClassIdSerializer(serializers.ModelSerializer):
 
 
 
-class PaymentSerializer(serializers.HyperlinkedModelSerializer):
+class PlanetStackSerializer(serializers.HyperlinkedModelSerializer):
     id = serializers.Field()
     
     class Meta:
-        model = Payment
-        fields = ('id','created','updated','enacted','backend_status','deleted','account','amount','date',)
+        model = PlanetStack
+        fields = ('id','created','updated','enacted','backend_status','deleted','description',)
 
-class PaymentIdSerializer(serializers.ModelSerializer):
+class PlanetStackIdSerializer(serializers.ModelSerializer):
     id = serializers.Field()
     
     class Meta:
-        model = Payment
-        fields = ('id','created','updated','enacted','backend_status','deleted','account','amount','date',)
+        model = PlanetStack
+        fields = ('id','created','updated','enacted','backend_status','deleted','description',)
 
 
 
@@ -807,36 +807,36 @@ class DashboardViewIdSerializer(serializers.ModelSerializer):
 
 
 
-class ImageDeploymentsSerializer(serializers.HyperlinkedModelSerializer):
+class ReservedResourceSerializer(serializers.HyperlinkedModelSerializer):
     id = serializers.Field()
     
     class Meta:
-        model = ImageDeployments
-        fields = ('id','created','updated','enacted','backend_status','deleted','image','deployment','glance_image_id',)
+        model = ReservedResource
+        fields = ('id','created','updated','enacted','backend_status','deleted','sliver','resource','quantity','reservationSet',)
 
-class ImageDeploymentsIdSerializer(serializers.ModelSerializer):
+class ReservedResourceIdSerializer(serializers.ModelSerializer):
     id = serializers.Field()
     
     class Meta:
-        model = ImageDeployments
-        fields = ('id','created','updated','enacted','backend_status','deleted','image','deployment','glance_image_id',)
+        model = ReservedResource
+        fields = ('id','created','updated','enacted','backend_status','deleted','sliver','resource','quantity','reservationSet',)
 
 
 
 
-class ReservedResourceSerializer(serializers.HyperlinkedModelSerializer):
+class PaymentSerializer(serializers.HyperlinkedModelSerializer):
     id = serializers.Field()
     
     class Meta:
-        model = ReservedResource
-        fields = ('id','created','updated','enacted','backend_status','deleted','sliver','resource','quantity','reservationSet',)
+        model = Payment
+        fields = ('id','created','updated','enacted','backend_status','deleted','account','amount','date',)
 
-class ReservedResourceIdSerializer(serializers.ModelSerializer):
+class PaymentIdSerializer(serializers.ModelSerializer):
     id = serializers.Field()
     
     class Meta:
-        model = ReservedResource
-        fields = ('id','created','updated','enacted','backend_status','deleted','sliver','resource','quantity','reservationSet',)
+        model = Payment
+        fields = ('id','created','updated','enacted','backend_status','deleted','account','amount','date',)
 
 
 
@@ -875,6 +875,23 @@ class UserDashboardViewIdSerializer(serializers.ModelSerializer):
 
 
 
+class SiteDeploymentsSerializer(serializers.HyperlinkedModelSerializer):
+    id = serializers.Field()
+    
+    class Meta:
+        model = SiteDeployments
+        fields = ('id','created','updated','enacted','backend_status','deleted','site','deployment','tenant_id',)
+
+class SiteDeploymentsIdSerializer(serializers.ModelSerializer):
+    id = serializers.Field()
+    
+    class Meta:
+        model = SiteDeployments
+        fields = ('id','created','updated','enacted','backend_status','deleted','site','deployment','tenant_id',)
+
+
+
+
 class PlanetStackPrivilegeSerializer(serializers.HyperlinkedModelSerializer):
     id = serializers.Field()
     
@@ -975,23 +992,6 @@ class ReservationIdSerializer(serializers.ModelSerializer):
 
 
 
-class SliceDeploymentsSerializer(serializers.HyperlinkedModelSerializer):
-    id = serializers.Field()
-    
-    class Meta:
-        model = SliceDeployments
-        fields = ('id','created','updated','enacted','backend_status','deleted','slice','deployment','tenant_id','network_id','router_id','subnet_id',)
-
-class SliceDeploymentsIdSerializer(serializers.ModelSerializer):
-    id = serializers.Field()
-    
-    class Meta:
-        model = SliceDeployments
-        fields = ('id','created','updated','enacted','backend_status','deleted','slice','deployment','tenant_id','network_id','router_id','subnet_id',)
-
-
-
-
 class SitePrivilegeSerializer(serializers.HyperlinkedModelSerializer):
     id = serializers.Field()
     
@@ -1009,19 +1009,19 @@ class SitePrivilegeIdSerializer(serializers.ModelSerializer):
 
 
 
-class PlanetStackSerializer(serializers.HyperlinkedModelSerializer):
+class SliceDeploymentsSerializer(serializers.HyperlinkedModelSerializer):
     id = serializers.Field()
     
     class Meta:
-        model = PlanetStack
-        fields = ('id','created','updated','enacted','backend_status','deleted','description',)
+        model = SliceDeployments
+        fields = ('id','created','updated','enacted','backend_status','deleted','slice','deployment','tenant_id','network_id','router_id','subnet_id',)
 
-class PlanetStackIdSerializer(serializers.ModelSerializer):
+class SliceDeploymentsIdSerializer(serializers.ModelSerializer):
     id = serializers.Field()
     
     class Meta:
-        model = PlanetStack
-        fields = ('id','created','updated','enacted','backend_status','deleted','description',)
+        model = SliceDeployments
+        fields = ('id','created','updated','enacted','backend_status','deleted','slice','deployment','tenant_id','network_id','router_id','subnet_id',)
 
 
 
@@ -1111,6 +1111,23 @@ class DeploymentPrivilegeIdSerializer(serializers.ModelSerializer):
 
 
 
+class ImageDeploymentsSerializer(serializers.HyperlinkedModelSerializer):
+    id = serializers.Field()
+    
+    class Meta:
+        model = ImageDeployments
+        fields = ('id','created','updated','enacted','backend_status','deleted','image','deployment','glance_image_id',)
+
+class ImageDeploymentsIdSerializer(serializers.ModelSerializer):
+    id = serializers.Field()
+    
+    class Meta:
+        model = ImageDeployments
+        fields = ('id','created','updated','enacted','backend_status','deleted','image','deployment','glance_image_id',)
+
+
+
+
 class DeploymentRoleSerializer(serializers.HyperlinkedModelSerializer):
     id = serializers.Field()
     
@@ -1145,23 +1162,6 @@ class UserCredentialIdSerializer(serializers.ModelSerializer):
 
 
 
-class SiteDeploymentsSerializer(serializers.HyperlinkedModelSerializer):
-    id = serializers.Field()
-    
-    class Meta:
-        model = SiteDeployments
-        fields = ('id','created','updated','enacted','backend_status','deleted','site','deployment','tenant_id',)
-
-class SiteDeploymentsIdSerializer(serializers.ModelSerializer):
-    id = serializers.Field()
-    
-    class Meta:
-        model = SiteDeployments
-        fields = ('id','created','updated','enacted','backend_status','deleted','site','deployment','tenant_id',)
-
-
-
-
 class SliceTagSerializer(serializers.HyperlinkedModelSerializer):
     id = serializers.Field()
     
@@ -1184,14 +1184,14 @@ class NetworkTemplateSerializer(serializers.HyperlinkedModelSerializer):
     
     class Meta:
         model = NetworkTemplate
-        fields = ('id','created','updated','enacted','backend_status','deleted','name','description','guaranteedBandwidth','visibility','translation','sharedNetworkName','sharedNetworkId',)
+        fields = ('id','created','updated','enacted','backend_status','deleted','name','description','guaranteedBandwidth','visibility','translation','sharedNetworkName','sharedNetworkId','topologyKind','controllerKind',)
 
 class NetworkTemplateIdSerializer(serializers.ModelSerializer):
     id = serializers.Field()
     
     class Meta:
         model = NetworkTemplate
-        fields = ('id','created','updated','enacted','backend_status','deleted','name','description','guaranteedBandwidth','visibility','translation','sharedNetworkName','sharedNetworkId',)
+        fields = ('id','created','updated','enacted','backend_status','deleted','name','description','guaranteedBandwidth','visibility','translation','sharedNetworkName','sharedNetworkId','topologyKind','controllerKind',)
 
 
 
@@ -1266,7 +1266,7 @@ serializerLookUp = {
 
                  ServiceClass: ServiceClassSerializer,
 
-                 Payment: PaymentSerializer,
+                 PlanetStack: PlanetStackSerializer,
 
                  Charge: ChargeSerializer,
 
@@ -1284,14 +1284,16 @@ serializerLookUp = {
 
                  DashboardView: DashboardViewSerializer,
 
-                 ImageDeployments: ImageDeploymentsSerializer,
-
                  ReservedResource: ReservedResourceSerializer,
 
+                 Payment: PaymentSerializer,
+
                  NetworkSlice: NetworkSliceSerializer,
 
                  UserDashboardView: UserDashboardViewSerializer,
 
+                 SiteDeployments: SiteDeploymentsSerializer,
+
                  PlanetStackPrivilege: PlanetStackPrivilegeSerializer,
 
                  User: UserSerializer,
@@ -1300,11 +1302,9 @@ serializerLookUp = {
 
                  Reservation: ReservationSerializer,
 
-                 SliceDeployments: SliceDeploymentsSerializer,
-
                  SitePrivilege: SitePrivilegeSerializer,
 
-                 PlanetStack: PlanetStackSerializer,
+                 SliceDeployments: SliceDeploymentsSerializer,
 
                  UserDeployments: UserDeploymentsSerializer,
 
@@ -1316,12 +1316,12 @@ serializerLookUp = {
 
                  DeploymentPrivilege: DeploymentPrivilegeSerializer,
 
+                 ImageDeployments: ImageDeploymentsSerializer,
+
                  DeploymentRole: DeploymentRoleSerializer,
 
                  UserCredential: UserCredentialSerializer,
 
-                 SiteDeployments: SiteDeploymentsSerializer,
-
                  SliceTag: SliceTagSerializer,
 
                  NetworkTemplate: NetworkTemplateSerializer,
@@ -2520,7 +2520,7 @@ class NetworkList(generics.ListCreateAPIView):
     serializer_class = NetworkSerializer
     id_serializer_class = NetworkIdSerializer
     filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','backend_status','deleted','name','template','subnet','ports','labels','owner','guaranteedBandwidth','permitAllSlices','network_id','router_id','subnet_id','routers','availableRouters','routers','routers',)
+    filter_fields = ('id','created','updated','enacted','backend_status','deleted','name','template','subnet','ports','labels','owner','guaranteedBandwidth','permitAllSlices','topologyParameters','controllerUrl','controllerParameters','network_id','router_id','subnet_id','routers','availableRouters','routers','routers',)
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -2758,12 +2758,12 @@ class ServiceClassNew(GenericAPIView):
 
 
 
-class PaymentList(generics.ListCreateAPIView):
-    queryset = Payment.objects.select_related().all()
-    serializer_class = PaymentSerializer
-    id_serializer_class = PaymentIdSerializer
+class PlanetStackList(generics.ListCreateAPIView):
+    queryset = PlanetStack.objects.select_related().all()
+    serializer_class = PlanetStackSerializer
+    id_serializer_class = PlanetStackIdSerializer
     filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','backend_status','deleted','account','amount','date',)
+    filter_fields = ('id','created','updated','enacted','backend_status','deleted','description',)
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -2773,7 +2773,7 @@ class PaymentList(generics.ListCreateAPIView):
             return self.serializer_class
 
     def get_queryset(self):
-        return Payment.select_by_user(self.request.user)
+        return PlanetStack.select_by_user(self.request.user)
 
     def create(self, request, *args, **kwargs):
         serializer = self.get_serializer(data=request.DATA, files=request.FILES)
@@ -2782,21 +2782,21 @@ class PaymentList(generics.ListCreateAPIView):
         obj = serializer.object
         obj.caller = request.user
         if obj.can_update(request.user):
-            return super(PaymentList, self).create(request, *args, **kwargs)
+            return super(PlanetStackList, self).create(request, *args, **kwargs)
         else:
             raise Exception("failed obj.can_update")
 
-        ret = super(PaymentList, self).create(request, *args, **kwargs)
+        ret = super(PlanetStackList, self).create(request, *args, **kwargs)
         if (ret.status_code%100 != 200):
             raise Exception(ret.data)
 
         return ret
 
 
-class PaymentDetail(PlanetStackRetrieveUpdateDestroyAPIView):
-    queryset = Payment.objects.select_related().all()
-    serializer_class = PaymentSerializer
-    id_serializer_class = PaymentIdSerializer
+class PlanetStackDetail(PlanetStackRetrieveUpdateDestroyAPIView):
+    queryset = PlanetStack.objects.select_related().all()
+    serializer_class = PlanetStackSerializer
+    id_serializer_class = PlanetStackIdSerializer
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -2806,7 +2806,7 @@ class PaymentDetail(PlanetStackRetrieveUpdateDestroyAPIView):
             return self.serializer_class
     
     def get_queryset(self):
-        return Payment.select_by_user(self.request.user)
+        return PlanetStack.select_by_user(self.request.user)
 
     # update() is handled by PlanetStackRetrieveUpdateDestroyAPIView
 
@@ -2817,9 +2817,9 @@ class PaymentDetail(PlanetStackRetrieveUpdateDestroyAPIView):
     filled with defaults. I solved it another way, so this code may soon be
     abandoned.
 
-class PaymentNew(GenericAPIView):
-    serializer_class = PaymentSerializer
-    id_serializer_class = PaymentIdSerializer
+class PlanetStackNew(GenericAPIView):
+    serializer_class = PlanetStackSerializer
+    id_serializer_class = PlanetStackIdSerializer
 
     def get(self, request, *args, **kwargs):
         return self.makenew(request, *args, **kwargs)
@@ -2832,7 +2832,7 @@ class PaymentNew(GenericAPIView):
             return self.serializer_class
 
     def makenew(self, request, *args, **kwargs):
-        obj = Payment()
+        obj = PlanetStack()
         serializer = self.get_serializer(obj)
         return Response(serializer.data)
 """
@@ -3487,12 +3487,12 @@ class DashboardViewNew(GenericAPIView):
 
 
 
-class ImageDeploymentsList(generics.ListCreateAPIView):
-    queryset = ImageDeployments.objects.select_related().all()
-    serializer_class = ImageDeploymentsSerializer
-    id_serializer_class = ImageDeploymentsIdSerializer
+class ReservedResourceList(generics.ListCreateAPIView):
+    queryset = ReservedResource.objects.select_related().all()
+    serializer_class = ReservedResourceSerializer
+    id_serializer_class = ReservedResourceIdSerializer
     filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','backend_status','deleted','image','deployment','glance_image_id',)
+    filter_fields = ('id','created','updated','enacted','backend_status','deleted','sliver','resource','quantity','reservationSet',)
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -3502,7 +3502,7 @@ class ImageDeploymentsList(generics.ListCreateAPIView):
             return self.serializer_class
 
     def get_queryset(self):
-        return ImageDeployments.select_by_user(self.request.user)
+        return ReservedResource.select_by_user(self.request.user)
 
     def create(self, request, *args, **kwargs):
         serializer = self.get_serializer(data=request.DATA, files=request.FILES)
@@ -3511,21 +3511,21 @@ class ImageDeploymentsList(generics.ListCreateAPIView):
         obj = serializer.object
         obj.caller = request.user
         if obj.can_update(request.user):
-            return super(ImageDeploymentsList, self).create(request, *args, **kwargs)
+            return super(ReservedResourceList, self).create(request, *args, **kwargs)
         else:
             raise Exception("failed obj.can_update")
 
-        ret = super(ImageDeploymentsList, self).create(request, *args, **kwargs)
+        ret = super(ReservedResourceList, self).create(request, *args, **kwargs)
         if (ret.status_code%100 != 200):
             raise Exception(ret.data)
 
         return ret
 
 
-class ImageDeploymentsDetail(PlanetStackRetrieveUpdateDestroyAPIView):
-    queryset = ImageDeployments.objects.select_related().all()
-    serializer_class = ImageDeploymentsSerializer
-    id_serializer_class = ImageDeploymentsIdSerializer
+class ReservedResourceDetail(PlanetStackRetrieveUpdateDestroyAPIView):
+    queryset = ReservedResource.objects.select_related().all()
+    serializer_class = ReservedResourceSerializer
+    id_serializer_class = ReservedResourceIdSerializer
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -3535,7 +3535,7 @@ class ImageDeploymentsDetail(PlanetStackRetrieveUpdateDestroyAPIView):
             return self.serializer_class
     
     def get_queryset(self):
-        return ImageDeployments.select_by_user(self.request.user)
+        return ReservedResource.select_by_user(self.request.user)
 
     # update() is handled by PlanetStackRetrieveUpdateDestroyAPIView
 
@@ -3546,9 +3546,9 @@ class ImageDeploymentsDetail(PlanetStackRetrieveUpdateDestroyAPIView):
     filled with defaults. I solved it another way, so this code may soon be
     abandoned.
 
-class ImageDeploymentsNew(GenericAPIView):
-    serializer_class = ImageDeploymentsSerializer
-    id_serializer_class = ImageDeploymentsIdSerializer
+class ReservedResourceNew(GenericAPIView):
+    serializer_class = ReservedResourceSerializer
+    id_serializer_class = ReservedResourceIdSerializer
 
     def get(self, request, *args, **kwargs):
         return self.makenew(request, *args, **kwargs)
@@ -3561,19 +3561,19 @@ class ImageDeploymentsNew(GenericAPIView):
             return self.serializer_class
 
     def makenew(self, request, *args, **kwargs):
-        obj = ImageDeployments()
+        obj = ReservedResource()
         serializer = self.get_serializer(obj)
         return Response(serializer.data)
 """
 
 
 
-class ReservedResourceList(generics.ListCreateAPIView):
-    queryset = ReservedResource.objects.select_related().all()
-    serializer_class = ReservedResourceSerializer
-    id_serializer_class = ReservedResourceIdSerializer
+class PaymentList(generics.ListCreateAPIView):
+    queryset = Payment.objects.select_related().all()
+    serializer_class = PaymentSerializer
+    id_serializer_class = PaymentIdSerializer
     filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','backend_status','deleted','sliver','resource','quantity','reservationSet',)
+    filter_fields = ('id','created','updated','enacted','backend_status','deleted','account','amount','date',)
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -3583,7 +3583,7 @@ class ReservedResourceList(generics.ListCreateAPIView):
             return self.serializer_class
 
     def get_queryset(self):
-        return ReservedResource.select_by_user(self.request.user)
+        return Payment.select_by_user(self.request.user)
 
     def create(self, request, *args, **kwargs):
         serializer = self.get_serializer(data=request.DATA, files=request.FILES)
@@ -3592,21 +3592,21 @@ class ReservedResourceList(generics.ListCreateAPIView):
         obj = serializer.object
         obj.caller = request.user
         if obj.can_update(request.user):
-            return super(ReservedResourceList, self).create(request, *args, **kwargs)
+            return super(PaymentList, self).create(request, *args, **kwargs)
         else:
             raise Exception("failed obj.can_update")
 
-        ret = super(ReservedResourceList, self).create(request, *args, **kwargs)
+        ret = super(PaymentList, self).create(request, *args, **kwargs)
         if (ret.status_code%100 != 200):
             raise Exception(ret.data)
 
         return ret
 
 
-class ReservedResourceDetail(PlanetStackRetrieveUpdateDestroyAPIView):
-    queryset = ReservedResource.objects.select_related().all()
-    serializer_class = ReservedResourceSerializer
-    id_serializer_class = ReservedResourceIdSerializer
+class PaymentDetail(PlanetStackRetrieveUpdateDestroyAPIView):
+    queryset = Payment.objects.select_related().all()
+    serializer_class = PaymentSerializer
+    id_serializer_class = PaymentIdSerializer
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -3616,7 +3616,7 @@ class ReservedResourceDetail(PlanetStackRetrieveUpdateDestroyAPIView):
             return self.serializer_class
     
     def get_queryset(self):
-        return ReservedResource.select_by_user(self.request.user)
+        return Payment.select_by_user(self.request.user)
 
     # update() is handled by PlanetStackRetrieveUpdateDestroyAPIView
 
@@ -3627,9 +3627,9 @@ class ReservedResourceDetail(PlanetStackRetrieveUpdateDestroyAPIView):
     filled with defaults. I solved it another way, so this code may soon be
     abandoned.
 
-class ReservedResourceNew(GenericAPIView):
-    serializer_class = ReservedResourceSerializer
-    id_serializer_class = ReservedResourceIdSerializer
+class PaymentNew(GenericAPIView):
+    serializer_class = PaymentSerializer
+    id_serializer_class = PaymentIdSerializer
 
     def get(self, request, *args, **kwargs):
         return self.makenew(request, *args, **kwargs)
@@ -3642,7 +3642,7 @@ class ReservedResourceNew(GenericAPIView):
             return self.serializer_class
 
     def makenew(self, request, *args, **kwargs):
-        obj = ReservedResource()
+        obj = Payment()
         serializer = self.get_serializer(obj)
         return Response(serializer.data)
 """
@@ -3811,6 +3811,87 @@ class UserDashboardViewNew(GenericAPIView):
 
 
 
+class SiteDeploymentsList(generics.ListCreateAPIView):
+    queryset = SiteDeployments.objects.select_related().all()
+    serializer_class = SiteDeploymentsSerializer
+    id_serializer_class = SiteDeploymentsIdSerializer
+    filter_backends = (filters.DjangoFilterBackend,)
+    filter_fields = ('id','created','updated','enacted','backend_status','deleted','site','deployment','tenant_id',)
+
+    def get_serializer_class(self):
+        no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
+        if (no_hyperlinks):
+            return self.id_serializer_class
+        else:
+            return self.serializer_class
+
+    def get_queryset(self):
+        return SiteDeployments.select_by_user(self.request.user)
+
+    def create(self, request, *args, **kwargs):
+        serializer = self.get_serializer(data=request.DATA, files=request.FILES)
+        if not (serializer.is_valid()):
+            raise Exception("failed serializer.is_valid: " + str(serializer.errors))
+        obj = serializer.object
+        obj.caller = request.user
+        if obj.can_update(request.user):
+            return super(SiteDeploymentsList, self).create(request, *args, **kwargs)
+        else:
+            raise Exception("failed obj.can_update")
+
+        ret = super(SiteDeploymentsList, self).create(request, *args, **kwargs)
+        if (ret.status_code%100 != 200):
+            raise Exception(ret.data)
+
+        return ret
+
+
+class SiteDeploymentsDetail(PlanetStackRetrieveUpdateDestroyAPIView):
+    queryset = SiteDeployments.objects.select_related().all()
+    serializer_class = SiteDeploymentsSerializer
+    id_serializer_class = SiteDeploymentsIdSerializer
+
+    def get_serializer_class(self):
+        no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
+        if (no_hyperlinks):
+            return self.id_serializer_class
+        else:
+            return self.serializer_class
+    
+    def get_queryset(self):
+        return SiteDeployments.select_by_user(self.request.user)
+
+    # update() is handled by PlanetStackRetrieveUpdateDestroyAPIView
+
+    # destroy() is handled by PlanetStackRetrieveUpdateDestroyAPIView
+
+"""
+    XXX smbaker: my intent was to create a view that would return 'new' objects
+    filled with defaults. I solved it another way, so this code may soon be
+    abandoned.
+
+class SiteDeploymentsNew(GenericAPIView):
+    serializer_class = SiteDeploymentsSerializer
+    id_serializer_class = SiteDeploymentsIdSerializer
+
+    def get(self, request, *args, **kwargs):
+        return self.makenew(request, *args, **kwargs)
+
+    def get_serializer_class(self):
+        no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
+        if (no_hyperlinks):
+            return self.id_serializer_class
+        else:
+            return self.serializer_class
+
+    def makenew(self, request, *args, **kwargs):
+        obj = SiteDeployments()
+        serializer = self.get_serializer(obj)
+        return Response(serializer.data)
+"""
+
+
+
 class PlanetStackPrivilegeList(generics.ListCreateAPIView):
     queryset = PlanetStackPrivilege.objects.select_related().all()
     serializer_class = PlanetStackPrivilegeSerializer
@@ -4135,87 +4216,6 @@ class ReservationNew(GenericAPIView):
 
 
 
-class SliceDeploymentsList(generics.ListCreateAPIView):
-    queryset = SliceDeployments.objects.select_related().all()
-    serializer_class = SliceDeploymentsSerializer
-    id_serializer_class = SliceDeploymentsIdSerializer
-    filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','backend_status','deleted','slice','deployment','tenant_id','network_id','router_id','subnet_id',)
-
-    def get_serializer_class(self):
-        no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-
-    def get_queryset(self):
-        return SliceDeployments.select_by_user(self.request.user)
-
-    def create(self, request, *args, **kwargs):
-        serializer = self.get_serializer(data=request.DATA, files=request.FILES)
-        if not (serializer.is_valid()):
-            raise Exception("failed serializer.is_valid: " + str(serializer.errors))
-        obj = serializer.object
-        obj.caller = request.user
-        if obj.can_update(request.user):
-            return super(SliceDeploymentsList, self).create(request, *args, **kwargs)
-        else:
-            raise Exception("failed obj.can_update")
-
-        ret = super(SliceDeploymentsList, self).create(request, *args, **kwargs)
-        if (ret.status_code%100 != 200):
-            raise Exception(ret.data)
-
-        return ret
-
-
-class SliceDeploymentsDetail(PlanetStackRetrieveUpdateDestroyAPIView):
-    queryset = SliceDeployments.objects.select_related().all()
-    serializer_class = SliceDeploymentsSerializer
-    id_serializer_class = SliceDeploymentsIdSerializer
-
-    def get_serializer_class(self):
-        no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-    
-    def get_queryset(self):
-        return SliceDeployments.select_by_user(self.request.user)
-
-    # update() is handled by PlanetStackRetrieveUpdateDestroyAPIView
-
-    # destroy() is handled by PlanetStackRetrieveUpdateDestroyAPIView
-
-"""
-    XXX smbaker: my intent was to create a view that would return 'new' objects
-    filled with defaults. I solved it another way, so this code may soon be
-    abandoned.
-
-class SliceDeploymentsNew(GenericAPIView):
-    serializer_class = SliceDeploymentsSerializer
-    id_serializer_class = SliceDeploymentsIdSerializer
-
-    def get(self, request, *args, **kwargs):
-        return self.makenew(request, *args, **kwargs)
-
-    def get_serializer_class(self):
-        no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
-        if (no_hyperlinks):
-            return self.id_serializer_class
-        else:
-            return self.serializer_class
-
-    def makenew(self, request, *args, **kwargs):
-        obj = SliceDeployments()
-        serializer = self.get_serializer(obj)
-        return Response(serializer.data)
-"""
-
-
-
 class SitePrivilegeList(generics.ListCreateAPIView):
     queryset = SitePrivilege.objects.select_related().all()
     serializer_class = SitePrivilegeSerializer
@@ -4297,12 +4297,12 @@ class SitePrivilegeNew(GenericAPIView):
 
 
 
-class PlanetStackList(generics.ListCreateAPIView):
-    queryset = PlanetStack.objects.select_related().all()
-    serializer_class = PlanetStackSerializer
-    id_serializer_class = PlanetStackIdSerializer
+class SliceDeploymentsList(generics.ListCreateAPIView):
+    queryset = SliceDeployments.objects.select_related().all()
+    serializer_class = SliceDeploymentsSerializer
+    id_serializer_class = SliceDeploymentsIdSerializer
     filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','backend_status','deleted','description',)
+    filter_fields = ('id','created','updated','enacted','backend_status','deleted','slice','deployment','tenant_id','network_id','router_id','subnet_id',)
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -4312,7 +4312,7 @@ class PlanetStackList(generics.ListCreateAPIView):
             return self.serializer_class
 
     def get_queryset(self):
-        return PlanetStack.select_by_user(self.request.user)
+        return SliceDeployments.select_by_user(self.request.user)
 
     def create(self, request, *args, **kwargs):
         serializer = self.get_serializer(data=request.DATA, files=request.FILES)
@@ -4321,21 +4321,21 @@ class PlanetStackList(generics.ListCreateAPIView):
         obj = serializer.object
         obj.caller = request.user
         if obj.can_update(request.user):
-            return super(PlanetStackList, self).create(request, *args, **kwargs)
+            return super(SliceDeploymentsList, self).create(request, *args, **kwargs)
         else:
             raise Exception("failed obj.can_update")
 
-        ret = super(PlanetStackList, self).create(request, *args, **kwargs)
+        ret = super(SliceDeploymentsList, self).create(request, *args, **kwargs)
         if (ret.status_code%100 != 200):
             raise Exception(ret.data)
 
         return ret
 
 
-class PlanetStackDetail(PlanetStackRetrieveUpdateDestroyAPIView):
-    queryset = PlanetStack.objects.select_related().all()
-    serializer_class = PlanetStackSerializer
-    id_serializer_class = PlanetStackIdSerializer
+class SliceDeploymentsDetail(PlanetStackRetrieveUpdateDestroyAPIView):
+    queryset = SliceDeployments.objects.select_related().all()
+    serializer_class = SliceDeploymentsSerializer
+    id_serializer_class = SliceDeploymentsIdSerializer
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -4345,7 +4345,7 @@ class PlanetStackDetail(PlanetStackRetrieveUpdateDestroyAPIView):
             return self.serializer_class
     
     def get_queryset(self):
-        return PlanetStack.select_by_user(self.request.user)
+        return SliceDeployments.select_by_user(self.request.user)
 
     # update() is handled by PlanetStackRetrieveUpdateDestroyAPIView
 
@@ -4356,9 +4356,9 @@ class PlanetStackDetail(PlanetStackRetrieveUpdateDestroyAPIView):
     filled with defaults. I solved it another way, so this code may soon be
     abandoned.
 
-class PlanetStackNew(GenericAPIView):
-    serializer_class = PlanetStackSerializer
-    id_serializer_class = PlanetStackIdSerializer
+class SliceDeploymentsNew(GenericAPIView):
+    serializer_class = SliceDeploymentsSerializer
+    id_serializer_class = SliceDeploymentsIdSerializer
 
     def get(self, request, *args, **kwargs):
         return self.makenew(request, *args, **kwargs)
@@ -4371,7 +4371,7 @@ class PlanetStackNew(GenericAPIView):
             return self.serializer_class
 
     def makenew(self, request, *args, **kwargs):
-        obj = PlanetStack()
+        obj = SliceDeployments()
         serializer = self.get_serializer(obj)
         return Response(serializer.data)
 """
@@ -4783,12 +4783,12 @@ class DeploymentPrivilegeNew(GenericAPIView):
 
 
 
-class DeploymentRoleList(generics.ListCreateAPIView):
-    queryset = DeploymentRole.objects.select_related().all()
-    serializer_class = DeploymentRoleSerializer
-    id_serializer_class = DeploymentRoleIdSerializer
+class ImageDeploymentsList(generics.ListCreateAPIView):
+    queryset = ImageDeployments.objects.select_related().all()
+    serializer_class = ImageDeploymentsSerializer
+    id_serializer_class = ImageDeploymentsIdSerializer
     filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','backend_status','deleted','role',)
+    filter_fields = ('id','created','updated','enacted','backend_status','deleted','image','deployment','glance_image_id',)
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -4798,7 +4798,7 @@ class DeploymentRoleList(generics.ListCreateAPIView):
             return self.serializer_class
 
     def get_queryset(self):
-        return DeploymentRole.select_by_user(self.request.user)
+        return ImageDeployments.select_by_user(self.request.user)
 
     def create(self, request, *args, **kwargs):
         serializer = self.get_serializer(data=request.DATA, files=request.FILES)
@@ -4807,21 +4807,21 @@ class DeploymentRoleList(generics.ListCreateAPIView):
         obj = serializer.object
         obj.caller = request.user
         if obj.can_update(request.user):
-            return super(DeploymentRoleList, self).create(request, *args, **kwargs)
+            return super(ImageDeploymentsList, self).create(request, *args, **kwargs)
         else:
             raise Exception("failed obj.can_update")
 
-        ret = super(DeploymentRoleList, self).create(request, *args, **kwargs)
+        ret = super(ImageDeploymentsList, self).create(request, *args, **kwargs)
         if (ret.status_code%100 != 200):
             raise Exception(ret.data)
 
         return ret
 
 
-class DeploymentRoleDetail(PlanetStackRetrieveUpdateDestroyAPIView):
-    queryset = DeploymentRole.objects.select_related().all()
-    serializer_class = DeploymentRoleSerializer
-    id_serializer_class = DeploymentRoleIdSerializer
+class ImageDeploymentsDetail(PlanetStackRetrieveUpdateDestroyAPIView):
+    queryset = ImageDeployments.objects.select_related().all()
+    serializer_class = ImageDeploymentsSerializer
+    id_serializer_class = ImageDeploymentsIdSerializer
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -4831,7 +4831,7 @@ class DeploymentRoleDetail(PlanetStackRetrieveUpdateDestroyAPIView):
             return self.serializer_class
     
     def get_queryset(self):
-        return DeploymentRole.select_by_user(self.request.user)
+        return ImageDeployments.select_by_user(self.request.user)
 
     # update() is handled by PlanetStackRetrieveUpdateDestroyAPIView
 
@@ -4842,9 +4842,9 @@ class DeploymentRoleDetail(PlanetStackRetrieveUpdateDestroyAPIView):
     filled with defaults. I solved it another way, so this code may soon be
     abandoned.
 
-class DeploymentRoleNew(GenericAPIView):
-    serializer_class = DeploymentRoleSerializer
-    id_serializer_class = DeploymentRoleIdSerializer
+class ImageDeploymentsNew(GenericAPIView):
+    serializer_class = ImageDeploymentsSerializer
+    id_serializer_class = ImageDeploymentsIdSerializer
 
     def get(self, request, *args, **kwargs):
         return self.makenew(request, *args, **kwargs)
@@ -4857,19 +4857,19 @@ class DeploymentRoleNew(GenericAPIView):
             return self.serializer_class
 
     def makenew(self, request, *args, **kwargs):
-        obj = DeploymentRole()
+        obj = ImageDeployments()
         serializer = self.get_serializer(obj)
         return Response(serializer.data)
 """
 
 
 
-class UserCredentialList(generics.ListCreateAPIView):
-    queryset = UserCredential.objects.select_related().all()
-    serializer_class = UserCredentialSerializer
-    id_serializer_class = UserCredentialIdSerializer
+class DeploymentRoleList(generics.ListCreateAPIView):
+    queryset = DeploymentRole.objects.select_related().all()
+    serializer_class = DeploymentRoleSerializer
+    id_serializer_class = DeploymentRoleIdSerializer
     filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','backend_status','deleted','user','name','key_id','enc_value',)
+    filter_fields = ('id','created','updated','enacted','backend_status','deleted','role',)
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -4879,7 +4879,7 @@ class UserCredentialList(generics.ListCreateAPIView):
             return self.serializer_class
 
     def get_queryset(self):
-        return UserCredential.select_by_user(self.request.user)
+        return DeploymentRole.select_by_user(self.request.user)
 
     def create(self, request, *args, **kwargs):
         serializer = self.get_serializer(data=request.DATA, files=request.FILES)
@@ -4888,21 +4888,21 @@ class UserCredentialList(generics.ListCreateAPIView):
         obj = serializer.object
         obj.caller = request.user
         if obj.can_update(request.user):
-            return super(UserCredentialList, self).create(request, *args, **kwargs)
+            return super(DeploymentRoleList, self).create(request, *args, **kwargs)
         else:
             raise Exception("failed obj.can_update")
 
-        ret = super(UserCredentialList, self).create(request, *args, **kwargs)
+        ret = super(DeploymentRoleList, self).create(request, *args, **kwargs)
         if (ret.status_code%100 != 200):
             raise Exception(ret.data)
 
         return ret
 
 
-class UserCredentialDetail(PlanetStackRetrieveUpdateDestroyAPIView):
-    queryset = UserCredential.objects.select_related().all()
-    serializer_class = UserCredentialSerializer
-    id_serializer_class = UserCredentialIdSerializer
+class DeploymentRoleDetail(PlanetStackRetrieveUpdateDestroyAPIView):
+    queryset = DeploymentRole.objects.select_related().all()
+    serializer_class = DeploymentRoleSerializer
+    id_serializer_class = DeploymentRoleIdSerializer
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -4912,7 +4912,7 @@ class UserCredentialDetail(PlanetStackRetrieveUpdateDestroyAPIView):
             return self.serializer_class
     
     def get_queryset(self):
-        return UserCredential.select_by_user(self.request.user)
+        return DeploymentRole.select_by_user(self.request.user)
 
     # update() is handled by PlanetStackRetrieveUpdateDestroyAPIView
 
@@ -4923,9 +4923,9 @@ class UserCredentialDetail(PlanetStackRetrieveUpdateDestroyAPIView):
     filled with defaults. I solved it another way, so this code may soon be
     abandoned.
 
-class UserCredentialNew(GenericAPIView):
-    serializer_class = UserCredentialSerializer
-    id_serializer_class = UserCredentialIdSerializer
+class DeploymentRoleNew(GenericAPIView):
+    serializer_class = DeploymentRoleSerializer
+    id_serializer_class = DeploymentRoleIdSerializer
 
     def get(self, request, *args, **kwargs):
         return self.makenew(request, *args, **kwargs)
@@ -4938,19 +4938,19 @@ class UserCredentialNew(GenericAPIView):
             return self.serializer_class
 
     def makenew(self, request, *args, **kwargs):
-        obj = UserCredential()
+        obj = DeploymentRole()
         serializer = self.get_serializer(obj)
         return Response(serializer.data)
 """
 
 
 
-class SiteDeploymentsList(generics.ListCreateAPIView):
-    queryset = SiteDeployments.objects.select_related().all()
-    serializer_class = SiteDeploymentsSerializer
-    id_serializer_class = SiteDeploymentsIdSerializer
+class UserCredentialList(generics.ListCreateAPIView):
+    queryset = UserCredential.objects.select_related().all()
+    serializer_class = UserCredentialSerializer
+    id_serializer_class = UserCredentialIdSerializer
     filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','backend_status','deleted','site','deployment','tenant_id',)
+    filter_fields = ('id','created','updated','enacted','backend_status','deleted','user','name','key_id','enc_value',)
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -4960,7 +4960,7 @@ class SiteDeploymentsList(generics.ListCreateAPIView):
             return self.serializer_class
 
     def get_queryset(self):
-        return SiteDeployments.select_by_user(self.request.user)
+        return UserCredential.select_by_user(self.request.user)
 
     def create(self, request, *args, **kwargs):
         serializer = self.get_serializer(data=request.DATA, files=request.FILES)
@@ -4969,21 +4969,21 @@ class SiteDeploymentsList(generics.ListCreateAPIView):
         obj = serializer.object
         obj.caller = request.user
         if obj.can_update(request.user):
-            return super(SiteDeploymentsList, self).create(request, *args, **kwargs)
+            return super(UserCredentialList, self).create(request, *args, **kwargs)
         else:
             raise Exception("failed obj.can_update")
 
-        ret = super(SiteDeploymentsList, self).create(request, *args, **kwargs)
+        ret = super(UserCredentialList, self).create(request, *args, **kwargs)
         if (ret.status_code%100 != 200):
             raise Exception(ret.data)
 
         return ret
 
 
-class SiteDeploymentsDetail(PlanetStackRetrieveUpdateDestroyAPIView):
-    queryset = SiteDeployments.objects.select_related().all()
-    serializer_class = SiteDeploymentsSerializer
-    id_serializer_class = SiteDeploymentsIdSerializer
+class UserCredentialDetail(PlanetStackRetrieveUpdateDestroyAPIView):
+    queryset = UserCredential.objects.select_related().all()
+    serializer_class = UserCredentialSerializer
+    id_serializer_class = UserCredentialIdSerializer
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
@@ -4993,7 +4993,7 @@ class SiteDeploymentsDetail(PlanetStackRetrieveUpdateDestroyAPIView):
             return self.serializer_class
     
     def get_queryset(self):
-        return SiteDeployments.select_by_user(self.request.user)
+        return UserCredential.select_by_user(self.request.user)
 
     # update() is handled by PlanetStackRetrieveUpdateDestroyAPIView
 
@@ -5004,9 +5004,9 @@ class SiteDeploymentsDetail(PlanetStackRetrieveUpdateDestroyAPIView):
     filled with defaults. I solved it another way, so this code may soon be
     abandoned.
 
-class SiteDeploymentsNew(GenericAPIView):
-    serializer_class = SiteDeploymentsSerializer
-    id_serializer_class = SiteDeploymentsIdSerializer
+class UserCredentialNew(GenericAPIView):
+    serializer_class = UserCredentialSerializer
+    id_serializer_class = UserCredentialIdSerializer
 
     def get(self, request, *args, **kwargs):
         return self.makenew(request, *args, **kwargs)
@@ -5019,7 +5019,7 @@ class SiteDeploymentsNew(GenericAPIView):
             return self.serializer_class
 
     def makenew(self, request, *args, **kwargs):
-        obj = SiteDeployments()
+        obj = UserCredential()
         serializer = self.get_serializer(obj)
         return Response(serializer.data)
 """
@@ -5112,7 +5112,7 @@ class NetworkTemplateList(generics.ListCreateAPIView):
     serializer_class = NetworkTemplateSerializer
     id_serializer_class = NetworkTemplateIdSerializer
     filter_backends = (filters.DjangoFilterBackend,)
-    filter_fields = ('id','created','updated','enacted','backend_status','deleted','name','description','guaranteedBandwidth','visibility','translation','sharedNetworkName','sharedNetworkId',)
+    filter_fields = ('id','created','updated','enacted','backend_status','deleted','name','description','guaranteedBandwidth','visibility','translation','sharedNetworkName','sharedNetworkId','topologyKind','controllerKind',)
 
     def get_serializer_class(self):
         no_hyperlinks = self.request.QUERY_PARAMS.get('no_hyperlinks', False)
index 88c9f1d..f48b25a 100644 (file)
@@ -1,11 +1,11 @@
 from core.models import *
 
 def handle(network):
-       from core.models import SliceDeployment,NetworkDeployments
+       from core.models import SliceDeployments,NetworkDeployments
        from collections import defaultdict
        # network deployments are not visible to users. We must ensure
        # networks are deployed at all deploymets available to their slices.
-       slice_deployments = SliceDeployment.objects.all()
+       slice_deployments = SliceDeployments.objects.all()
        slice_deploy_lookup = defaultdict(list)
        for slice_deployment in slice_deployments:
                slice_deploy_lookup[slice_deployment.slice].append(slice_deployment.deployment)
index 7b436b4..ee34b14 100644 (file)
@@ -1,13 +1,13 @@
 
 def handle(slice):
-       from core.models import SiteDeployment,SliceDeployment,Deployment,Network,NetworkSlice,NetworkTemplate
+       from core.models import SiteDeployments,SliceDeployments,Deployment,Network,NetworkSlice,NetworkTemplate
        from collections import defaultdict
-       site_deployments = SiteDeployment.objects.all()
+       site_deployments = SiteDeployments.objects.all()
        site_deploy_lookup = defaultdict(list)
        for site_deployment in site_deployments:
                site_deploy_lookup[site_deployment.site].append(site_deployment.deployment)
        
-       slice_deployments = SliceDeployment.objects.all()
+       slice_deployments = SliceDeployments.objects.all()
        slice_deploy_lookup = defaultdict(list)
        for slice_deployment in slice_deployments:
                slice_deploy_lookup[slice_deployment.slice].append(slice_deployment.deployment)
@@ -19,7 +19,7 @@ def handle(slice):
        for expected_deployment in expected_deployments:
                if slice not in slice_deploy_lookup or \
                   expected_deployment not in slice_deploy_lookup[slice]:
-                       sd = SliceDeployment(slice=slice, deployment=expected_deployment)
+                       sd = SliceDeployments(slice=slice, deployment=expected_deployment)
                        sd.save()
 
        # make sure slice has at least 1 public and 1 private networkd
index cc8bbe6..6118a7b 100644 (file)
@@ -1,16 +1,16 @@
 from core.models import *
 
 def handle(user):
-       from core.models import Deployment,SiteDeployment,UserDeployment
+       from core.models import Deployment,SiteDeployments,UserDeployments
        from collections import defaultdict
        deployments = Deployment.objects.all()
-       site_deployments = SiteDeployment.objects.all()
+       site_deployments = SiteDeployments.objects.all()
        site_deploy_lookup = defaultdict(list)
        for site_deployment in site_deployments:
                site_deploy_lookup[site_deployment.site].append(site_deployment.deployment)
 
        user_deploy_lookup = defaultdict(list)
-       for user_deployment in UserDeployment.objects.all():
+       for user_deployment in UserDeployments.objects.all():
                user_deploy_lookup[user_deployment.user].append(user_deployment.deployment)
    
        all_deployments = Deployment.objects.filter() 
@@ -27,6 +27,6 @@ def handle(user):
                if not user in user_deploy_lookup or \
                  expected_deployment not in user_deploy_lookup[user]: 
                        # add new record
-                       ud = UserDeployment(user=user, deployment=expected_deployment)
+                       ud = UserDeployments(user=user, deployment=expected_deployment)
                        ud.save()    
 
index 74f38b7..0151af3 100644 (file)
@@ -12,5 +12,5 @@
 #from .sync_roles import SyncRoles
 #from .sync_nodes import SyncNodes
 #from .sync_images import SyncImages
-#from .sync_image_deployments import SyncImageDeployment
+#from .sync_image_deployments import SyncImageDeployments
 #from .garbage_collector import GarbageCollector
index 4bdad87..20c22a2 100644 (file)
@@ -5,24 +5,24 @@ from django.db.models import F, Q
 from planetstack.config import Config
 from observer.openstacksyncstep import OpenStackSyncStep
 from core.models import Deployment
-from core.models import Image, ImageDeployment
+from core.models import Image, ImageDeployments
 from util.logger import Logger, logging
 \r
 logger = Logger(level=logging.INFO)
 
-class SyncImageDeployment(OpenStackSyncStep):
-    provides=[ImageDeployment]
+class SyncImageDeployments(OpenStackSyncStep):
+    provides=[ImageDeployments]
     requested_interval=0
 
     def fetch_pending(self, deleted):
         if (deleted):
             return []
-         # smbaker: commented out automatic creation of ImageDeployment as
+         # smbaker: commented out automatic creation of ImageDeployments as
          #    as they will now be configured in GUI. Not sure if this is
          #    sufficient.
 
 #        # ensure images are available across all deployments
-#        image_deployments = ImageDeployment.objects.all()
+#        image_deployments = ImageDeployments.objects.all()
 #        image_deploy_lookup = defaultdict(list)
 #        for image_deployment in image_deployments:
 #            image_deploy_lookup[image_deployment.image].append(image_deployment.deployment)
@@ -33,11 +33,11 @@ class SyncImageDeployment(OpenStackSyncStep):
 #            for expected_deployment in expected_deployments:
 #                if image not in image_deploy_lookup or \
 #                  expected_deployment not in image_deploy_lookup[image]:
-#                    id = ImageDeployment(image=image, deployment=expected_deployment)
+#                    id = ImageDeployments(image=image, deployment=expected_deployment)
 #                    id.save()
 
         # now we return all images that need to be enacted
-        return ImageDeployment.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
+        return ImageDeployments.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
 
     def sync_record(self, image_deployment):
         logger.info("Working on image %s on deployment %s" % (image_deployment.image.name, image_deployment.deployment.name))
index 27b8648..b5e9f9a 100644 (file)
@@ -6,9 +6,9 @@ from observer.openstacksyncstep import OpenStackSyncStep
 from core.models.site import *
 from observer.ansible import *
 
-class SyncSiteDeployment(OpenStackSyncStep):
+class SyncSiteDeployments(OpenStackSyncStep):
     requested_interval=0
-    provides=[SiteDeployment, Site]
+    provides=[SiteDeployments, Site]
 
     def sync_record(self, site_deployment):
 
index 78da7b2..d07b279 100644 (file)
@@ -3,7 +3,7 @@ import base64
 from django.db.models import F, Q
 from planetstack.config import Config
 from observer.openstacksyncstep import OpenStackSyncStep
-from core.models import User, UserDeployment, SitePrivilege, SiteDeployment   
+from core.models import User, UserDeployments, SitePrivilege, SiteDeployments   
 
 class SyncSitePrivileges(OpenStackSyncStep):
     requested_interval=0
@@ -18,9 +18,9 @@ class SyncSitePrivileges(OpenStackSyncStep):
 
     def sync_record(self, site_priv):
         # sync site privileges at all site deployments
-        site_deployments = SiteDeployment.objects.filter(site=site_priv.site)
+        site_deployments = SiteDeployments.objects.filter(site=site_priv.site)
         for site_deployment in site_deployments:
-            user_deployments = UserDeployment.objects.filter(deployment=site_deployment.deployment)
+            user_deployments = UserDeployments.objects.filter(deployment=site_deployment.deployment)
             if user_deployments:
                 kuser_id  = user_deployments[0].kuser_id
                 driver = self.driver.admin_driver(deployment=site_deployment.deployment.name)
index 4672878..c560a6a 100644 (file)
@@ -14,7 +14,7 @@ class SyncSites(OpenStackSyncStep):
         site.save()
 
     def delete_record(self, site):
-        site_deployments = SiteDeployment.objects.filter(site=site)
-        site_deployment_deleter = SyncSiteDeployment().delete_record
+        site_deployments = SiteDeployments.objects.filter(site=site)
+        site_deployment_deleter = SyncSiteDeployments().delete_record
         for site_deployment in site_deployments:
             site_deployment_deleter(site_deployment)
index 2bc2082..97196d6 100644 (file)
@@ -5,23 +5,23 @@ from netaddr import IPAddress, IPNetwork
 from django.db.models import F, Q
 from planetstack.config import Config
 from observer.openstacksyncstep import OpenStackSyncStep
-from core.models.site import Deployment, SiteDeployment
-from core.models.slice import Slice, SliceDeployment
-from core.models.userdeployments import UserDeployment
+from core.models.site import Deployment, SiteDeployments
+from core.models.slice import Slice, SliceDeployments
+from core.models.userdeployments import UserDeployments
 from util.logger import Logger, logging
 from observer.ansible import *
 
 logger = Logger(level=logging.INFO)
 
-class SyncSliceDeployment(OpenStackSyncStep):
-    provides=[SliceDeployment]
+class SyncSliceDeployments(OpenStackSyncStep):
+    provides=[SliceDeployments]
     requested_interval=0
 
     def fetch_pending(self, deleted):
         if (deleted):
-            return SliceDeployment.deleted_objects.all()
+            return SliceDeployments.deleted_objects.all()
         else:
-            return SliceDeployment.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
+            return SliceDeployments.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
 
     def get_next_subnet(self, deployment=None):
         # limit ourself to 10.0.x.x for now
@@ -48,7 +48,7 @@ class SyncSliceDeployment(OpenStackSyncStep):
             logger.info("deployment %r has no admin_user, skipping" % slice_deployment.deployment)
             return
 
-       deployment_users = UserDeployment.objects.filter(user=slice_deployment.slice.creator,
+       deployment_users = UserDeployments.objects.filter(user=slice_deployment.slice.creator,
                                                              deployment=slice_deployment.deployment)            
        if not deployment_users:
            logger.info("slice createor %s has not accout at deployment %s" % (slice_deployment.slice.creator, slice_deployment.deployment.name))
index f51a96b..b1cd223 100644 (file)
@@ -4,7 +4,7 @@ from django.db.models import F, Q
 from planetstack.config import Config
 from observer.openstacksyncstep import OpenStackSyncStep
 from core.models.slice import *
-from core.models.userdeployments import UserDeployment
+from core.models.userdeployments import UserDeployments
 from util.logger import Logger, logging
 
 logger = Logger(level=logging.INFO)
@@ -22,11 +22,11 @@ class SyncSliceMemberships(OpenStackSyncStep):
     def sync_record(self, slice_memb):
         # sync slice memberships at all slice deployments 
         logger.info("syncing slice privilege: %s %s" % (slice_memb.slice.name, slice_memb.user.email))
-        slice_deployments = SliceDeployment.objects.filter(slice=slice_memb.slice)
+        slice_deployments = SliceDeployments.objects.filter(slice=slice_memb.slice)
         for slice_deployment in slice_deployments:
             if not slice_deployment.tenant_id:
                 continue
-            user_deployments = UserDeployment.objects.filter(deployment=slice_deployment.deployment,
+            user_deployments = UserDeployments.objects.filter(deployment=slice_deployment.deployment,
                                                               user=slice_memb.user)
             if user_deployments:
                 kuser_id  = user_deployments[0].kuser_id
index 6d6ca46..a6073b6 100644 (file)
@@ -4,7 +4,7 @@ from netaddr import IPAddress, IPNetwork
 from django.db.models import F, Q
 from planetstack.config import Config
 from observer.openstacksyncstep import OpenStackSyncStep
-from core.models.slice import Slice, SliceDeployment
+from core.models.slice import Slice, SliceDeployments
 from util.logger import Logger, logging
 from observer.steps.sync_slice_deployments import *
 
@@ -15,14 +15,14 @@ class SyncSlices(OpenStackSyncStep):
     requested_interval=0
 
     def sync_record(self, slice):
-        for slice_deployment in SliceDeployment.objects.filter(slice=slice):
+        for slice_deployment in SliceDeployments.objects.filter(slice=slice):
             # bump the 'updated' timestamp and trigger observer to update
             # slice across all deployments 
             slice_deployment.save()    
 
     def delete_record(self, slice):
-        slice_deployment_deleter = SyncSliceDeployment().delete_record
-        for slice_deployment in SliceDeployment.objects.filter(slice=slice):
+        slice_deployment_deleter = SyncSliceDeployments().delete_record
+        for slice_deployment in SliceDeployments.objects.filter(slice=slice):
             try:
                 slice_deployment_deleter(slice_deployment)
             except Exception,e:
index 133c0e0..8237896 100644 (file)
@@ -4,7 +4,7 @@ from django.db.models import F, Q
 from planetstack.config import Config
 from observer.openstacksyncstep import OpenStackSyncStep
 from core.models.sliver import Sliver
-from core.models.slice import Slice, SlicePrivilege, SliceDeployment
+from core.models.slice import Slice, SlicePrivilege, SliceDeployments
 from core.models.network import Network, NetworkSlice, NetworkDeployments
 from util.logger import Logger, logging
 from observer.ansible import *
index 69faa9f..2e8256f 100644 (file)
@@ -5,25 +5,25 @@ from collections import defaultdict
 from django.db.models import F, Q
 from planetstack.config import Config
 from observer.openstacksyncstep import OpenStackSyncStep
-from core.models.site import SiteDeployment, Deployment
+from core.models.site import SiteDeployments, Deployment
 from core.models.user import User
-from core.models.userdeployments import UserDeployment
+from core.models.userdeployments import UserDeployments
 from util.logger import Logger, logging
 
 from observer.ansible import *
 
 logger = Logger(level=logging.INFO)
 
-class SyncUserDeployment(OpenStackSyncStep):
-    provides=[UserDeployment, User]
+class SyncUserDeployments(OpenStackSyncStep):
+    provides=[UserDeployments, User]
     requested_interval=0
 
     def fetch_pending(self, deleted):
 
         if (deleted):
-            return UserDeployment.deleted_objects.all()
+            return UserDeployments.deleted_objects.all()
         else:
-            return UserDeployment.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)) 
+            return UserDeployments.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None)) 
 
     def sync_record(self, user_deployment):
         logger.info("sync'ing user %s at deployment %s" % (user_deployment.user, user_deployment.deployment.name))
@@ -39,7 +39,7 @@ class SyncUserDeployment(OpenStackSyncStep):
        roles = []
        # setup user deployment home site roles  
         if user_deployment.user.site:
-            site_deployments = SiteDeployment.objects.filter(site=user_deployment.user.site,
+            site_deployments = SiteDeployments.objects.filter(site=user_deployment.user.site,
                                                               deployment=user_deployment.deployment)
             if site_deployments:
                 # need the correct tenant id for site at the deployment
@@ -50,7 +50,7 @@ class SyncUserDeployment(OpenStackSyncStep):
                 if user_deployment.user.is_admin:
                     roles.append('admin')
            else:
-               raise Exception('Internal error. Missing SiteDeployment for user %s'%user_deployment.user.email)
+               raise Exception('Internal error. Missing SiteDeployments for user %s'%user_deployment.user.email)
        else:
            raise Exception('Siteless user %s'%user_deployment.user.email)
 
index 242b8be..a22c213 100644 (file)
@@ -5,20 +5,20 @@ from django.db.models import F, Q
 from planetstack.config import Config
 from observer.openstacksyncstep import OpenStackSyncStep
 from core.models.user import User
-from core.models.userdeployments import  UserDeployment
-from observer.steps.sync_user_deployments import SyncUserDeployment
+from core.models.userdeployments import  UserDeployments
+from observer.steps.sync_user_deployments import SyncUserDeployments
 
 class SyncUsers(OpenStackSyncStep):
     provides=[User]
     requested_interval=0
 
     def sync_record(self, user):
-        for user_deployment in UserDeployment.objects.filter(user=user):
+        for user_deployment in UserDeployments.objects.filter(user=user):
             # bump the 'updated' field so user account are updated across 
             # deployments.
             user_deployment.save()
 
     def delete_record(self, user):
-        user_deployment_deleter = SyncUserDeployment().delete_record
-        for user_deployment in UserDeployment.objects.filter(user=user):
+        user_deployment_deleter = SyncUserDeployments().delete_record
+        for user_deployment in UserDeployments.objects.filter(user=user):
             user_deployment_deleter(user_deployment)
diff --git a/planetstack/servcomp/migrations/0001_initial.py b/planetstack/servcomp/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..f7fd1ea
--- /dev/null
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0005_network_ports'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Composition',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('created', models.DateTimeField(default=django.utils.timezone.now, auto_now_add=True)),
+                ('updated', models.DateTimeField(default=django.utils.timezone.now, auto_now=True)),
+                ('enacted', models.DateTimeField(default=None, null=True)),
+                ('backend_status', models.CharField(default=b'Provisioning in progress', max_length=140)),
+                ('deleted', models.BooleanField(default=False)),
+                ('name', models.CharField(max_length=255)),
+            ],
+            options={
+            },
+            bases=(models.Model,),
+        ),
+        migrations.CreateModel(
+            name='CompositionService',
+            fields=[
+                ('service_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='core.Service')),
+            ],
+            options={
+                'verbose_name': 'Service Composition Service',
+            },
+            bases=('core.service', models.Model),
+        ),
+        migrations.CreateModel(
+            name='CompositionServiceThrough',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('created', models.DateTimeField(default=django.utils.timezone.now, auto_now_add=True)),
+                ('updated', models.DateTimeField(default=django.utils.timezone.now, auto_now=True)),
+                ('enacted', models.DateTimeField(default=None, null=True)),
+                ('backend_status', models.CharField(default=b'Provisioning in progress', max_length=140)),
+                ('deleted', models.BooleanField(default=False)),
+                ('order', models.IntegerField(default=0)),
+                ('composition', models.ForeignKey(to='servcomp.Composition')),
+                ('service', models.ForeignKey(related_name=b'compositions', to='core.Service')),
+            ],
+            options={
+                'ordering': ('order',),
+            },
+            bases=(models.Model,),
+        ),
+        migrations.CreateModel(
+            name='EndUser',
+            fields=[
+                ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
+                ('created', models.DateTimeField(default=django.utils.timezone.now, auto_now_add=True)),
+                ('updated', models.DateTimeField(default=django.utils.timezone.now, auto_now=True)),
+                ('enacted', models.DateTimeField(default=None, null=True)),
+                ('backend_status', models.CharField(default=b'Provisioning in progress', max_length=140)),
+                ('deleted', models.BooleanField(default=False)),
+                ('email', models.CharField(max_length=255)),
+                ('firstName', models.CharField(max_length=80)),
+                ('lastName', models.CharField(max_length=80)),
+                ('macAddress', models.CharField(max_length=80)),
+                ('composition', models.ForeignKey(related_name=b'endUsers', blank=True, to='servcomp.Composition', null=True)),
+            ],
+            options={
+            },
+            bases=(models.Model,),
+        ),
+        migrations.AddField(
+            model_name='composition',
+            name='services',
+            field=models.ManyToManyField(to='core.Service', through='servcomp.CompositionServiceThrough', blank=True),
+            preserve_default=True,
+        ),
+    ]
diff --git a/planetstack/servcomp/migrations/__init__.py b/planetstack/servcomp/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
deleted file mode 120000 (symlink)
index c2ca3ee1c9d7a2eb1e966557775dcfd5043947e0..0000000000000000000000000000000000000000
+++ /dev/null
@@ -1 +0,0 @@
-config-opencloud.py
\ No newline at end of file
new file mode 100644 (file)
index 0000000000000000000000000000000000000000..54000ffc7e73c6a148c6be1952a48d46a6c40cce
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+
+# ---------------------------------
+# This is the configuration file used by the Syndicate observer.
+# It is a well-formed Python file, and will be imported into the
+# observer as a Python module.  This means you can run any config-
+# generation code here you like, but all of the following global 
+# variables must be defined.
+# ---------------------------------
+
+# URL to the Syndicate SMI.  For example, https://syndicate-metadata.appspot.com
+SYNDICATE_SMI_URL="http://localhost:8080"
+
+# If you are going to use OpenID to authenticate the Syndicate sliver daemon,
+# this is the OpenID provider URL.  It is currently used only to generate 
+# identity pages for users, so you can put whatever you want here for now.
+SYNDICATE_OPENID_TRUSTROOT="http://localhost:8081"
+
+# This is the observer's user account on Syndicate.  You must create it out-of-band
+# prior to using the observer, and it must be an admin user since it will
+# create other users (i.e. for slices).
+SYNDICATE_OPENCLOUD_USER="jcnelson@cs.princeton.edu"
+
+# This is the password for the observer to authenticate itself to Syndicate.
+SYNDICATE_OPENCLOUD_PASSWORD="nya"
+
+# If the observer uses public-key authentication with Syndicate, you will 
+# need to identify the absolute path to its private key here.  It must be 
+# a 4096-bit PEM-encoded RSA key, and the Syndicate observer's user account
+# must have been given the public key on activation.
+SYNDICATE_OPENCLOUD_PKEY=None
+
+# This is the location on disk where Syndicate observer code can be found, 
+# if it is not already in the Python path.  This is optional.
+SYNDICATE_PYTHONPATH="/root/syndicate/build/out/python"
+
+# This is the location of the observer's private key.  It must be an absolute
+# path, and refer to a 4096-bit PEM-encoded RSA key.
+SYNDICATE_PRIVATE_KEY="/opt/planetstack/syndicate_observer/syndicatelib_config/pollserver.pem"
+
+# This is the master secret used to generate secrets to seal sensitive information sent to the 
+# Syndicate sliver mount daemons.  It is also used to seal sensitive information
+# stored to the Django database.  
+# TODO: think of a way to not have to store this on disk.  Maybe we feed into the
+# observer when it starts up?
+SYNDICATE_OPENCLOUD_SECRET="e4988309a5005edb8ea185f16f607938c0fb7657e4d7609853bcb7c4884d1c92"
+
+# This is the default port number on which a Syndicate Replica Gateway
+# will be provisioned.  It's a well-known port, and can be the same across
+# slivers, since in OpenCloud, an RG instance only listens to localhost.
+SYNDICATE_RG_DEFAULT_PORT=38800
+
+# This is the absolute path to the RG's storage driver (which will be automatically
+# pushed to slivers by Syndicate).  See https://github.com/jcnelson/syndicate/wiki/Replica-Gateways
+SYNDICATE_RG_CLOSURE=None
+
+# This is the port number the observer listens on for GETs from the Syndicate sliver mount 
+# daemons.  Normally, the oserver pushes (encrypted) commands to the daemons, but if the 
+# daemons are NAT'ed or temporarily partitioned, they will pull commands instead.
+SYNDICATE_HTTP_PORT=65321
+
+# This is the path to the logfile for the observer's HTTP server.
+SYNDICATE_HTTP_LOGFILE="/tmp/syndicate-observer.log"
+
+# This is the number of seconds to wait for pushing a slice credential before timing out.
+SYNDICATE_HTTP_PUSH_TIMEOUT=60
+
+# This is the port number the Syndicate sliver mount daemons listen on.  The observer will 
+# push commands to them on this port.
+SYNDICATE_SLIVER_PORT=65322
+
+# If true, print verbose debug messages.
+DEBUG=True
index f11c05c..49c6791 100644 (file)
@@ -12,8 +12,8 @@
   <script src="{% static 'suit/js/jquery-1.9.1.min.js' %}"></script>
   <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
   <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
-<script type="text/javascript" src="{% static 'log4javascript-1.4.6/log4javascript.js' %}"></script>
-
+  <script type="text/javascript" src="{% static 'log4javascript-1.4.6/log4javascript.js' %}"></script>
+  <script type="text/javascript" src="{% static 'uploadTextarea.js' %}"></script>
 
   <script type="text/javascript">var Suit = { $: $.noConflict() }; if (!$) $ = Suit.$; </script>
   {% if 'SHOW_REQUIRED_ASTERISK'|suit_conf %}
diff --git a/planetstack/urlfilter/migrations/0001_initial.py b/planetstack/urlfilter/migrations/0001_initial.py
new file mode 100644 (file)
index 0000000..da06233
--- /dev/null
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import models, migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('core', '0005_network_ports'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='UrlFilterService',
+            fields=[
+                ('service_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='core.Service')),
+            ],
+            options={
+                'verbose_name': 'URL Filter Service',
+            },
+            bases=('core.service', models.Model),
+        ),
+    ]
diff --git a/planetstack/urlfilter/migrations/__init__.py b/planetstack/urlfilter/migrations/__init__.py
new file mode 100644 (file)
index 0000000..e69de29