From: Tony Mack Date: Wed, 10 Apr 2013 02:36:27 +0000 (-0400) Subject: enable slices X-Git-Tag: 1.0~141 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=3a1af417383bee4968b2f445987054e00d7a6bed;p=plstackapi.git enable slices --- diff --git a/plstackapi/core/api/slices.py b/plstackapi/core/api/slices.py new file mode 100644 index 0000000..93b7ba2 --- /dev/null +++ b/plstackapi/core/api/slices.py @@ -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 + + + diff --git a/plstackapi/core/models.py b/plstackapi/core/models.py index 1ae0a44..e70da9b 100644 --- a/plstackapi/core/models.py +++ b/plstackapi/core/models.py @@ -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) diff --git a/plstackapi/core/serializers.py b/plstackapi/core/serializers.py index 0ffd86b..db5af0f 100644 --- a/plstackapi/core/serializers.py +++ b/plstackapi/core/serializers.py @@ -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') diff --git a/plstackapi/core/urls.py b/plstackapi/core/urls.py index 5d9df50..5a97354 100644 --- a/plstackapi/core/urls.py +++ b/plstackapi/core/urls.py @@ -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[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[0-9]+)/$', views.SliceDetail.as_view(), name='slice-detail'), + url(r'^plstackapi/slices/$', SliceListCreate.as_view(), name='slice-list'), + url(r'^plstackapi/slices/(?P[0-9]+)/$', SliceRetrieveUpdateDestroy.as_view(), name='slice-detail'), #url(r'^plstackapi/slivers/$', views.SliverList.as_view()), #url(r'^plstackapi/slivers/(?P[0-9]+)/$', views.SliverDetail.as_view()), diff --git a/plstackapi/core/views/slices.py b/plstackapi/core/views/slices.py new file mode 100644 index 0000000..6015f4d --- /dev/null +++ b/plstackapi/core/views/slices.py @@ -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) + + +