Merge branch 'master' of git://git.planet-lab.org/plstackapi
diff --git a/planetstack/core/admin.py b/planetstack/core/admin.py
index c9d3172..f4a78a3 100644
--- a/planetstack/core/admin.py
+++ b/planetstack/core/admin.py
@@ -542,7 +542,7 @@
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.all()]
+ self.fields['sites'].initial = [x for x in self.instance.sites.all()]
self.fields['images'].initial = [x.image for x in self.instance.imagedeployments.all()]
self.fields['flavors'].initial = self.instance.flavors.all()
@@ -594,7 +594,7 @@
# create/destroy the through models ourselves. There has to be
# a better way...
- self.manipulate_m2m_objs(deployment, self.cleaned_data['sites'], deployment.sitedeployments.all(), SiteDeployment, "deployment", "site")
+ self.manipulate_m2m_objs(deployment, self.cleaned_data['sites'], deployment.sitedeployment.all(), SiteDeployment, "deployment", "site")
self.manipulate_m2m_objs(deployment, self.cleaned_data['images'], deployment.imagedeployments.all(), ImageDeployments, "deployment", "image")
# manipulate_m2m_objs doesn't work for Flavor/Deployment relationship
# so well handle that manually here
diff --git a/planetstack/core/dashboard/views/view_common.py b/planetstack/core/dashboard/views/view_common.py
index f05d40a..bccd7d2 100644
--- a/planetstack/core/dashboard/views/view_common.py
+++ b/planetstack/core/dashboard/views/view_common.py
@@ -73,14 +73,14 @@
for sliver in slice.slivers.all():
#sites_used['deploymentSites'] = sliver.node.deployment.name
# sites_used[sliver.image.name] = sliver.image.name
- sites_used[sliver.node.site.name] = 1 #sliver.numberCores
+ sites_used[sliver.node.site_deployment.site.name] = 1 #sliver.numberCores
sliceid = Slice.objects.get(id=entry.slice.id).id
try:
sliverList = Sliver.objects.filter(slice=entry.slice.id)
siteList = {}
for x in sliverList:
- if x.node.site not in siteList:
- siteList[x.node.site] = 1
+ if x.node.site_deployment.site not in siteList:
+ siteList[x.node.site_deployment.site] = 1
slivercount = len(sliverList)
sitecount = len(siteList)
except:
diff --git a/planetstack/core/xoslib/methods/sliceplus.py b/planetstack/core/xoslib/methods/sliceplus.py
index 48102df..25e4d1e 100644
--- a/planetstack/core/xoslib/methods/sliceplus.py
+++ b/planetstack/core/xoslib/methods/sliceplus.py
@@ -15,11 +15,19 @@
# rest_framework 2.x
IdField = serializers.Field
+class NetworkPortsField(serializers.WritableField): # note: maybe just Field in rest_framework 3.x instead of WritableField
+ def to_representation(self, obj):
+ return obj
+
+ def to_internal_value(self, data):
+ return data
+
class SlicePlusIdSerializer(serializers.ModelSerializer, PlusSerializerMixin):
id = IdField()
sliceInfo = serializers.SerializerMethodField("getSliceInfo")
humanReadableName = serializers.SerializerMethodField("getHumanReadableName")
+ network_ports = NetworkPortsField()
def getSliceInfo(self, slice):
return slice.getSliceInfo(user=self.context['request'].user)
@@ -27,12 +35,12 @@
def getHumanReadableName(self, obj):
return str(obj)
- networks = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='network-detail')
- availableNetworks = serializers.HyperlinkedRelatedField(many=True, read_only=True, view_name='network-detail')
+ networks = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
+# availableNetworks = serializers.PrimaryKeyRelatedField(many=True, read_only=True, view_name='network-detail')
class Meta:
model = SlicePlus
- fields = ('humanReadableName', 'id','created','updated','enacted','name','enabled','omf_friendly','description','slice_url','site','max_slivers','image_preference','service','network','mount_data_sets','serviceClass','creator','networks','availableNetworks','sliceInfo','backendIcon','backendHtml')
+ fields = ('humanReadableName', 'id','created','updated','enacted','name','enabled','omf_friendly','description','slice_url','site','max_slivers','image_preference','service','network','mount_data_sets','serviceClass','creator','networks','sliceInfo','network_ports','backendIcon','backendHtml')
class SlicePlusList(generics.ListCreateAPIView):
queryset = SlicePlus.objects.select_related().all()
diff --git a/planetstack/core/xoslib/methods/tenantview.py b/planetstack/core/xoslib/methods/tenantview.py
new file mode 100644
index 0000000..c7ce500
--- /dev/null
+++ b/planetstack/core/xoslib/methods/tenantview.py
@@ -0,0 +1,64 @@
+from rest_framework.decorators import api_view
+from rest_framework.response import Response
+from rest_framework.reverse import reverse
+from rest_framework import serializers
+from rest_framework import generics
+from rest_framework.views import APIView
+from core.models import *
+from django.forms import widgets
+from syndicate_storage.models import Volume
+
+# This REST API endpoint contains a bunch of misc information that the
+# tenant view needs to display
+
+BLESSED_DEPLOYMENTS = ["ViCCI"] # ["US-MaxPlanck", "US-GeorgiaTech", "US-Princeton", "US-Washington", "US-Stanford"]
+
+
+def getTenantViewDict():
+ blessed_sites = []
+ for site in Site.objects.all():
+ good=False
+ for deployment in site.deployments.all():
+ if deployment.name in BLESSED_DEPLOYMENTS:
+ good=True
+ if good:
+ blessed_sites.append(site)
+
+ blessed_images=[]
+ for image in Image.objects.all():
+ good = False
+ for deployment in image.deployments.all():
+ if deployment.name in BLESSED_DEPLOYMENTS:
+ good=True
+ if good:
+ blessed_images.append(image)
+
+ volumes=[]
+ for volume in Volume.objects.all():
+ if not volume.private:
+ volumes.append(volume)
+
+ return {"id": 0,
+ "blessed_deployment_names": BLESSED_DEPLOYMENTS,
+ "blessed_site_names": [site.name for site in blessed_sites],
+ "blessed_sites": [site.id for site in blessed_sites],
+ "blessed_image_names": [image.name for image in blessed_images],
+ "blessed_images": [image.id for image in blessed_images],
+ "public_volume_names": [volume.name for volume in volumes],
+ "public_volumes": [volume.id for volume in volumes],
+ }
+
+class TenantList(APIView):
+ method_kind = "list"
+ method_name = "tenantview"
+
+ def get(self, request, format=None):
+ return Response( getTenantViewDict() )
+
+class TenantDetail(APIView):
+ method_kind = "detail"
+ method_name = "tenantview"
+
+ def get(self, request, format=None, pk=0):
+ return Response( [getTenantViewDict()] )
+
diff --git a/planetstack/core/xoslib/objects/sliceplus.py b/planetstack/core/xoslib/objects/sliceplus.py
index ddec295..efb6b2a 100644
--- a/planetstack/core/xoslib/objects/sliceplus.py
+++ b/planetstack/core/xoslib/objects/sliceplus.py
@@ -26,6 +26,23 @@
"siteCount": len(used_sites.keys()),
"roles": roles}
+ @property
+ def network_ports(self):
+ # XXX this assumes there is only one network that can have ports bound
+ # to it for a given slice. This is intended for the tenant view, which
+ # will obey this field.
+ networkPorts = ""
+ for networkSlice in self.networkslices.all():
+ network = networkSlice.network
+ if network.ports:
+ networkPorts = network.ports
+
+ return networkPorts
+
+ @network_ports.setter
+ def network_ports(self, value):
+ print "XXX set networkPorts to", value
+
@staticmethod
def select_by_user(user):
if user.is_admin:
diff --git a/planetstack/openstack/client.py b/planetstack/openstack/client.py
index 72c5cb4..0aa6c7d 100644
--- a/planetstack/openstack/client.py
+++ b/planetstack/openstack/client.py
@@ -84,7 +84,7 @@
return getattr(self.client, name)
-class GlanceClient(Client):
+class Glance(Client):
def __init__(self, *args, **kwds):
Client.__init__(self, *args, **kwds)
if has_openstack:
@@ -97,11 +97,15 @@
def __getattr__(self, name):
return getattr(self.client, name)
-class GlanceClientNew(Client):
- def __init__(self, version, endpoint, token, *args, **kwds):
+class GlanceClient(Client):
+ def __init__(self, version, endpoint, token, cacert=None, *args, **kwds):
Client.__init__(self, *args, **kwds)
if has_openstack:
- self.client = glanceclient.Client(version, endpoint=endpoint, token=token)
+ self.client = glanceclient.Client(version,
+ endpoint=endpoint,
+ token=token,
+ cacert=cacert
+ )
@require_enabled
def __getattr__(self, name):
@@ -174,9 +178,9 @@
url_parsed = urlparse.urlparse(self.keystone.url)
hostname = url_parsed.netloc.split(':')[0]
token = self.keystone.client.tokens.authenticate(username=self.keystone.username, password=self.keystone.password, tenant_name=self.keystone.tenant)
- #self.glance = GlanceClient(*args, **kwds)
+ glance_endpoint = self.keystone.service_catalog.url_for(service_type='image', endpoint_type='publicURL')
- self.glanceclient = GlanceClientNew('1', endpoint='https://%s:9292' % hostname, token=token.id, **kwds)
+ self.glanceclient = GlanceClient('1', endpoint=glance_endpoint, token=token.id, **kwds)
self.nova = NovaClient(*args, **kwds)
# self.nova_db = NovaDB(*args, **kwds)
self.quantum = QuantumClient(*args, **kwds)
diff --git a/planetstack/openstack/driver.py b/planetstack/openstack/driver.py
index 53b8e3f..2edf10e 100644
--- a/planetstack/openstack/driver.py
+++ b/planetstack/openstack/driver.py
@@ -32,7 +32,7 @@
auth = {'username': caller.email,
'password': hashlib.md5(caller.password).hexdigest()[:6],
'tenant': tenant}
- client = OpenStackClient(controller=controller, **auth)
+ client = OpenStackClient(controller=controller, cacert=self.config.nova_ca_ssl_cert, **auth)
else:
admin_driver = self.admin_driver(tenant=tenant, controller=controller)
client = OpenStackClient(tenant=tenant, controller=admin_driver.controller)
@@ -45,7 +45,7 @@
def admin_driver(self, tenant=None, controller=None):
if isinstance(controller, int):
controller = Controller.objects.get(id=controller.id)
- client = OpenStackClient(tenant=tenant, controller=controller)
+ client = OpenStackClient(tenant=tenant, controller=controller, cacert=self.config.nova_ca_ssl_cert)
driver = OpenStackDriver(client=client)
driver.admin_user = client.keystone.users.find(name=controller.admin_user)
driver.controller = controller
diff --git a/planetstack/plstackapi_config b/planetstack/plstackapi_config
index a61e7ed..fb846b3 100644
--- a/planetstack/plstackapi_config
+++ b/planetstack/plstackapi_config
@@ -29,6 +29,7 @@
default_image=None
default_flavor=m1.small
default_security_group=default
+ca_ssl_cert=/etc/ssl/certs/ca-certificates.crt
[observer]
images_directory=/opt/planetstack/images