enable slices
authorTony Mack <tmack@paris.CS.Princeton.EDU>
Wed, 10 Apr 2013 02:36:27 +0000 (22:36 -0400)
committerTony Mack <tmack@paris.CS.Princeton.EDU>
Wed, 10 Apr 2013 02:36:27 +0000 (22:36 -0400)
plstackapi/core/api/slices.py [new file with mode: 0644]
plstackapi/core/models.py
plstackapi/core/serializers.py
plstackapi/core/urls.py
plstackapi/core/views/slices.py [new file with mode: 0644]

diff --git a/plstackapi/core/api/slices.py b/plstackapi/core/api/slices.py
new file mode 100644 (file)
index 0000000..93b7ba2
--- /dev/null
@@ -0,0 +1,82 @@
+from plstackapi.openstack.client import OpenStackClient
+from plstackapi.openstack.driver import OpenStackDriver
+from plstackapi.core.api.auth import auth_check
+from plstackapi.core.models import Site
+def lookup_site(fields):
+    site = None
+    if 'site' in fields:
+        if isinstance(fields['site'], int):
+            sites = Site.objects.filter(id=fields['site'])
+        else:
+            sites = Site.objects.filter(login_base=fields['site'])
+        if sites:
+            site = sites[0]
+    if not site:
+        raise Exception, "No such site: %s" % fields['site']
+    return site 
+
+def add_slice(auth, fields):
+    driver = OpenStackDriver(client = auth_check(auth))
+    site = lookup_site(fields) 
+    if site: fields['site'] = site     
+    slice = Slice(**fields)
+    # create tenant
+    nova_fields = {'tenant_name': slice.name,
+                   'description': slice.description,
+                   'enabled': slice.enabled}
+    tenant = driver.create_tenant(**nova_fields)
+    slice.tenant_id=tenant.id
+    
+    # create network
+    network = driver.create_network(name=self.name)
+    self.network_id = network['id']
+
+    # create router
+    router = driver.create_router(name=self.name)
+    self.router_id = router['id']    
+
+    slice.save()
+    return slice
+
+def update_slice(auth, id, **fields):
+    driver = OpenStackDriver(client = auth_check(auth))
+    slices = Slice.objects.filter(id=id)
+    if not slices:
+        return
+
+    # update tenant
+    slice = slices[0]
+    nova_fields = {}
+    if 'name' in fields:
+        nova_fields['tenant_name'] = fields['name']
+    if 'description' in fields:
+        nova_fields['description'] = fields['description']
+    if 'enabled' in fields:
+        nova_fields['enabled'] = fields['enabled']
+    driver.update_tenant(slice.tenant_id, **nova_fields)
+
+    # update db record 
+    site = lookup_site(fields)
+    if site: fields['site'] = site
+    slice.update(**fields)
+
+    return slice 
+
+def delete_slice(auth, filter={}):
+    driver = OpenStackDriver(client = auth_check(auth))   
+    slices = Slice.objects.filter(**filter)
+    for slice in slices:
+        driver.delete_slice(id=slice.tenant_id) 
+        slice.delete()
+    return 1
+
+def get_slices(auth, filter={}):
+    client = auth_check(auth)
+    site = lookup_site(fields)
+    if site: fields['site'] = site
+    slices = Slice.objects.filter(**filter)
+    return slices             
+        
+
+    
index 1ae0a44..e70da9b 100644 (file)
@@ -238,7 +238,7 @@ class Sliver(PlCoreBase):
     flavor = models.ForeignKey(Flavor)
     image = models.ForeignKey(Image) 
     key = models.ForeignKey(Key)        
-    slice = models.ForeignKey(Slice)
+    slice = models.ForeignKey(Slice, related_name='slivers')
     siteDeploymentNetwork = models.ForeignKey(SiteDeploymentNetwork)
     node = models.ForeignKey(Node)
 
index 0ffd86b..db5af0f 100644 (file)
@@ -51,17 +51,23 @@ class SliceSerializer(serializers.HyperlinkedModelSerializer):
     # HyperlinkedModelSerializer doesn't include the id by default
     id = serializers.Field()
     site = serializers.HyperlinkedRelatedField(view_name='site-detail')
-
+    slivers = serializers.HyperlinkedRelatedField(view_name='sliver-detail')
     class Meta:
         model = Slice
         fields = ('id',
-                  'url',
+                  'tenant_id',
+                  'enabled',
                   'name',
+                  'url',
                   'instantiation',
                   'omf_friendly',
                   'description',
                   'slice_url',
+                  'network_id',
+                  'router_id',
                   'site',
+                  'slivers',
+                  'subnets',
                   'updated',
                   'created')
 
index 5d9df50..5a97354 100644 (file)
@@ -5,6 +5,7 @@ from django.contrib import admin
 from plstackapi.core.views.roles import RoleListCreate, RoleRetrieveUpdateDestroy
 from plstackapi.core.views.sites import SiteListCreate, SiteRetrieveUpdateDestroy
 from plstackapi.core.views.users import UserListCreate, UserRetrieveUpdateDestroy
+from plstackapi.core.views.slices import SliceListCreate, SliceRetrieveUpdateDestroy
 from plstackapi.core.views.keys import KeyListCreate, KeyRetrieveUpdateDestroy
 from plstackapi.core.views.deployment_networks import DeploymentNetworkListCreate, DeploymentNetworkRetrieveUpdateDestroy
 from plstackapi.core.views.images import ImageListCreate, ImageRetrieveUpdateDestroy
@@ -41,8 +42,8 @@ urlpatterns = patterns('',
     url(r'^plstackapi/sites/(?P<pk>[a-zA-Z0-9_]+)/$', SiteRetrieveUpdateDestroy.as_view(), name='site-detail'),
 
 
-    #url(r'^plstackapi/slices/$', views.SliceList.as_view(), name='slice-list'),
-    #url(r'^plstackapi/slices/(?P<pk>[0-9]+)/$', views.SliceDetail.as_view(), name='slice-detail'),
+    url(r'^plstackapi/slices/$', SliceListCreate.as_view(), name='slice-list'),
+    url(r'^plstackapi/slices/(?P<pk>[0-9]+)/$', SliceRetrieveUpdateDestroy.as_view(), name='slice-detail'),
 
     #url(r'^plstackapi/slivers/$', views.SliverList.as_view()),
     #url(r'^plstackapi/slivers/(?P<pk>[0-9]+)/$', views.SliverDetail.as_view()),
diff --git a/plstackapi/core/views/slices.py b/plstackapi/core/views/slices.py
new file mode 100644 (file)
index 0000000..6015f4d
--- /dev/null
@@ -0,0 +1,66 @@
+from django.http import Http404
+from rest_framework.views import APIView
+from rest_framework.response import Response
+from rest_framework import status
+
+from plstackapi.core.api.slices import add_slice, delete_slice, get_slices, update_slice
+from plstackapi.core.serializers import SliceSerializer
+from plstackapi.util.request import parse_request
+
+
+class SliceListCreate(APIView):
+    """ 
+    List all slices or create a new slice.
+    """
+
+    def post(self, request, format = None):
+        data = parse_request(request.DATA)  
+        if 'auth' not in data:
+            return Response(status=status.HTTP_400_BAD_REQUEST)        
+        elif 'slice' in data:
+            slice = add_slice(data['auth'], data['slice'])
+            serializer = SliceSerializer(slice)
+            return Response(serializer.data, status=status.HTTP_201_CREATED)
+        else:
+            slices = get_slices(data['auth'])
+            serializer = SliceSerializer(slices, many=True)
+            return Response(serializer.data)
+        
+            
+class SliceRetrieveUpdateDestroy(APIView):
+    """
+    Retrieve, update or delete a slice 
+    """
+
+    def post(self, request, pk, format=None):
+        """Retrieve a slice"""
+        data = parse_request(request.DATA)
+        if 'auth' not in data:
+            return Response(status=status.HTTP_400_BAD_REQUEST)
+        slices = get_slices(data['auth'], {'id': pk})
+        if not slices:
+            return Response(status=status.HTTP_404_NOT_FOUND)
+        serializer = UserSerializer(slices[0])
+        return Response(serializer.data)                  
+
+    def put(self, request, pk, format=None):
+        """update a slice""" 
+        data = parse_request(request.DATA)
+        if 'auth' not in data:
+            return Response(status=status.HTTP_400_BAD_REQUEST)
+        elif 'slice' not in data:
+            return Response(status=status.HTTP_400_BAD_REQUEST)
+
+        slice = update_slice(pk, data['slice'])
+        serializer = UserSerializer(slice)
+        return Response(serializer.data) 
+
+    def delete(self, request, pk, format=None):
+        data = parse_request(request.DATA) 
+        if 'auth' not in data:
+            return Response(status=status.HTTP_400_BAD_REQUEST)
+        delete_slice(data['auth'], {'id': pk})
+        return Response(status=status.HTTP_204_NO_CONTENT) 
+            
+            
+