summaryrefslogtreecommitdiffstats
path: root/nova/api
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-02-28 09:17:18 +0000
committerGerrit Code Review <review@openstack.org>2012-02-28 09:17:18 +0000
commit54956b21387327f2731bf935db76678b298fa77a (patch)
tree0c59ae7866a296eb0da93aa45184e3e291dc9efe /nova/api
parentb793dd9b870438d8f9936fa9216a023e8dc1f052 (diff)
parent8da178d7f7334dfa0027a8ae74129943856c1fb2 (diff)
Merge "Fixes cloudpipe extension to work with keystone"
Diffstat (limited to 'nova/api')
-rw-r--r--nova/api/openstack/common.py11
-rw-r--r--nova/api/openstack/compute/contrib/cloudpipe.py88
2 files changed, 59 insertions, 40 deletions
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index 92ef17687..12fbb509b 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -304,6 +304,11 @@ def get_networks_for_instance_from_nw_info(nw_info):
return networks
+def get_nw_info_for_instance(context, instance):
+ cached_nwinfo = instance['info_cache'].get('network_info') or []
+ return network_model.NetworkInfo.hydrate(cached_nwinfo)
+
+
def get_networks_for_instance(context, instance):
"""Returns a prepared nw_info list for passing into the view
builders
@@ -315,11 +320,7 @@ def get_networks_for_instance(context, instance):
{'addr': '172.16.2.1', 'version': 4}]},
...}
"""
-
- cached_nwinfo = instance['info_cache']['network_info']
- if not cached_nwinfo:
- return {}
- nw_info = network_model.NetworkInfo.hydrate(cached_nwinfo)
+ nw_info = get_nw_info_for_instance(context, instance)
return get_networks_for_instance_from_nw_info(nw_info)
diff --git a/nova/api/openstack/compute/contrib/cloudpipe.py b/nova/api/openstack/compute/contrib/cloudpipe.py
index 83c4bb47a..f47f107ea 100644
--- a/nova/api/openstack/compute/contrib/cloudpipe.py
+++ b/nova/api/openstack/compute/contrib/cloudpipe.py
@@ -16,6 +16,7 @@
import os
+from nova.api.openstack import common
from nova.api.openstack import wsgi
from nova.api.openstack import xmlutil
from nova.api.openstack import extensions
@@ -27,6 +28,7 @@ from nova import db
from nova import exception
from nova import flags
from nova import log as logging
+from nova import network
from nova import utils
@@ -54,6 +56,7 @@ class CloudpipeController(object):
def __init__(self):
self.compute_api = compute.API()
+ self.network_api = network.API()
self.auth_manager = manager.AuthManager()
self.cloudpipe = pipelib.CloudPipe()
self.setup()
@@ -66,58 +69,76 @@ class CloudpipeController(object):
if not os.path.exists(FLAGS.keys_path):
os.makedirs(FLAGS.keys_path)
+ def _get_all_cloudpipes(self, context):
+ """Get all cloudpipes"""
+ return [instance for instance in self.compute_api.get_all(context)
+ if instance['image_ref'] == str(FLAGS.vpn_image_id)
+ and instance['vm_state'] != vm_states.DELETED]
+
def _get_cloudpipe_for_project(self, context, project_id):
"""Get the cloudpipe instance for a project ID."""
- # NOTE(todd): this should probably change to compute_api.get_all
- # or db.instance_get_project_vpn
- for instance in db.instance_get_all_by_project(context, project_id):
- if (instance['image_id'] == str(FLAGS.vpn_image_id)
- and instance['vm_state'] != vm_states.DELETED):
- return instance
-
- def _vpn_dict(self, project, vpn_instance):
- rv = {'project_id': project.id,
- 'public_ip': project.vpn_ip,
- 'public_port': project.vpn_port}
- if vpn_instance:
- rv['instance_id'] = vpn_instance['uuid']
- rv['created_at'] = utils.isotime(vpn_instance['created_at'])
- address = vpn_instance.get('fixed_ip', None)
- if address:
- rv['internal_ip'] = address['address']
- if project.vpn_ip and project.vpn_port:
- if utils.vpn_ping(project.vpn_ip, project.vpn_port):
+ cloudpipes = self._get_all_cloudpipes(context) or [None]
+ return cloudpipes[0]
+
+ def _get_ip_and_port(self, instance):
+ pass
+
+ def _vpn_dict(self, context, project_id, instance):
+ elevated = context.elevated()
+ rv = {'project_id': project_id}
+ if not instance:
+ rv['state'] = 'pending'
+ return rv
+ rv['instance_id'] = instance['uuid']
+ rv['created_at'] = utils.isotime(instance['created_at'])
+ nw_info = common.get_nw_info_for_instance(elevated, instance)
+ if not nw_info:
+ return rv
+ vif = nw_info[0]
+ ips = [ip for ip in vif.fixed_ips() if ip['version'] == 4]
+ if ips:
+ rv['internal_ip'] = ips[0]['address']
+ network = self.network_api.get(elevated, vif['network']['id'])
+ if network:
+ vpn_ip = network['vpn_public_address']
+ vpn_port = network['vpn_public_port']
+ rv['public_ip'] = vpn_ip
+ rv['public_port'] = vpn_port
+ if vpn_ip and vpn_port:
+ if utils.vpn_ping(vpn_ip, vpn_port):
rv['state'] = 'running'
else:
rv['state'] = 'down'
else:
rv['state'] = 'invalid'
- else:
- rv['state'] = 'pending'
return rv
@wsgi.serializers(xml=CloudpipeTemplate)
def create(self, req, body):
"""Create a new cloudpipe instance, if none exists.
- Parameters: {cloudpipe: {project_id: XYZ}}
+ Parameters: {cloudpipe: {'project_id': ''}}
"""
- ctxt = req.environ['nova.context']
- authorize(ctxt)
+ context = req.environ['nova.context']
+ authorize(context)
params = body.get('cloudpipe', {})
- project_id = params.get('project_id', ctxt.project_id)
- instance = self._get_cloudpipe_for_project(ctxt, project_id)
+ project_id = params.get('project_id', context.project_id)
+ # NOTE(vish): downgrade to project context. Note that we keep
+ # the same token so we can still talk to glance
+ context.project_id = project_id
+ context.user_id = 'project-vpn'
+ context.is_admin = False
+ context.roles = []
+ instance = self._get_cloudpipe_for_project(context, project_id)
if not instance:
- proj = self.auth_manager.get_project(project_id)
- user_id = proj.project_manager_id
try:
- self.cloudpipe.launch_vpn_instance(project_id, user_id)
+ result = self.cloudpipe.launch_vpn_instance(context)
+ instance = result[0][0]
except db.NoMoreNetworks:
msg = _("Unable to claim IP for VPN instances, ensure it "
"isn't running, and try again in a few minutes")
raise exception.HTTPBadRequest(explanation=msg)
- instance = self._get_cloudpipe_for_project(ctxt, proj)
return {'instance_id': instance['uuid']}
@wsgi.serializers(xml=CloudpipesTemplate)
@@ -125,11 +146,8 @@ class CloudpipeController(object):
"""List running cloudpipe instances."""
context = req.environ['nova.context']
authorize(context)
- vpns = []
- # TODO(todd): could use compute_api.get_all with admin context?
- for project in self.auth_manager.get_projects():
- instance = self._get_cloudpipe_for_project(context, project.id)
- vpns.append(self._vpn_dict(project, instance))
+ vpns = [self._vpn_dict(context, x['project_id'], x)
+ for x in self._get_all_cloudpipes(context)]
return {'cloudpipes': vpns}