summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Gundlach <michael.gundlach@rackspace.com>2010-09-23 16:21:02 -0400
committerMichael Gundlach <michael.gundlach@rackspace.com>2010-09-23 16:21:02 -0400
commit4846b63a861ee7eafc642dc93f70fa8b85dfa625 (patch)
treede5d48399b3339e7524628d4e7bfdb87e23b63c4
parentc29c68f0fa27fa81f22ca42958bbd564f719f3ae (diff)
parent2b30ffe2f3c79e3701487d18fe1d4eef671aa335 (diff)
downloadnova-4846b63a861ee7eafc642dc93f70fa8b85dfa625.tar.gz
nova-4846b63a861ee7eafc642dc93f70fa8b85dfa625.tar.xz
nova-4846b63a861ee7eafc642dc93f70fa8b85dfa625.zip
Merge lp:~eday/nova/endpoint-cleanup
-rwxr-xr-xbin/nova-api47
-rwxr-xr-xbin/nova-api-new49
-rwxr-xr-xbin/nova-manage3
-rw-r--r--nova/api/__init__.py2
-rw-r--r--nova/api/cloudpipe/__init__.py69
-rw-r--r--nova/api/ec2/metadatarequesthandler.py6
-rw-r--r--nova/cloudpipe/api.py59
-rw-r--r--nova/cloudpipe/pipelib.py6
-rw-r--r--nova/rpc.py47
-rw-r--r--nova/tests/cloud_unittest.py1
10 files changed, 122 insertions, 167 deletions
diff --git a/bin/nova-api b/bin/nova-api
index ede09d38c..a5027700b 100755
--- a/bin/nova-api
+++ b/bin/nova-api
@@ -1,31 +1,28 @@
#!/usr/bin/env python
+# pylint: disable-msg=C0103
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
#
-# http://www.apache.org/licenses/LICENSE-2.0
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
"""
-Tornado daemon for the main API endpoint.
+Nova API daemon.
"""
-import logging
import os
import sys
-from tornado import httpserver
-from tornado import ioloop
# If ../nova/__init__.py exists, add ../ to Python search path, so that
# it will override what happens to be installed in /usr/(local/)lib/python...
@@ -36,28 +33,16 @@ if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
sys.path.insert(0, possible_topdir)
from nova import flags
-from nova import server
from nova import utils
-from nova.endpoint import admin
-from nova.endpoint import api
-from nova.endpoint import cloud
+from nova import server
FLAGS = flags.FLAGS
+flags.DEFINE_integer('api_port', 8773, 'API port')
-
-def main(_argv):
- """Load the controllers and start the tornado I/O loop."""
- controllers = {
- 'Cloud': cloud.CloudController(),
- 'Admin': admin.AdminController()}
- _app = api.APIServerApplication(controllers)
-
- io_inst = ioloop.IOLoop.instance()
- http_server = httpserver.HTTPServer(_app)
- http_server.listen(FLAGS.cc_port)
- logging.debug('Started HTTP server on %s', FLAGS.cc_port)
- io_inst.start()
-
+def main(_args):
+ from nova import api
+ from nova import wsgi
+ wsgi.run_server(api.API(), FLAGS.api_port)
if __name__ == '__main__':
utils.default_flagfile()
diff --git a/bin/nova-api-new b/bin/nova-api-new
deleted file mode 100755
index a5027700b..000000000
--- a/bin/nova-api-new
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# pylint: disable-msg=C0103
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""
-Nova API daemon.
-"""
-
-import os
-import sys
-
-# If ../nova/__init__.py exists, add ../ to Python search path, so that
-# it will override what happens to be installed in /usr/(local/)lib/python...
-possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]),
- os.pardir,
- os.pardir))
-if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
- sys.path.insert(0, possible_topdir)
-
-from nova import flags
-from nova import utils
-from nova import server
-
-FLAGS = flags.FLAGS
-flags.DEFINE_integer('api_port', 8773, 'API port')
-
-def main(_args):
- from nova import api
- from nova import wsgi
- wsgi.run_server(api.API(), FLAGS.api_port)
-
-if __name__ == '__main__':
- utils.default_flagfile()
- server.serve('nova-api', main)
diff --git a/bin/nova-manage b/bin/nova-manage
index e9219c515..baa1cb4db 100755
--- a/bin/nova-manage
+++ b/bin/nova-manage
@@ -73,7 +73,6 @@ from nova import quota
from nova import utils
from nova.auth import manager
from nova.cloudpipe import pipelib
-from nova.api.ec2 import cloud
FLAGS = flags.FLAGS
@@ -84,7 +83,7 @@ class VpnCommands(object):
def __init__(self):
self.manager = manager.AuthManager()
- self.pipe = pipelib.CloudPipe(cloud.CloudController())
+ self.pipe = pipelib.CloudPipe()
def list(self):
"""Print a listing of the VPNs for all projects."""
diff --git a/nova/api/__init__.py b/nova/api/__init__.py
index 8e4d844b2..744abd621 100644
--- a/nova/api/__init__.py
+++ b/nova/api/__init__.py
@@ -25,6 +25,7 @@ import webob.dec
from nova import flags
from nova import wsgi
+from nova.api import cloudpipe
from nova.api import ec2
from nova.api import rackspace
from nova.api.ec2 import metadatarequesthandler
@@ -63,6 +64,7 @@ class API(wsgi.Router):
conditions=ec2domain)
mapper.connect("/services/{path_info:.*}", controller=ec2.API(),
conditions=ec2domain)
+ mapper.connect("/cloudpipe/{path_info:.*}", controller=cloudpipe.API())
mrh = metadatarequesthandler.MetadataRequestHandler()
for s in ['/latest',
'/2009-04-04',
diff --git a/nova/api/cloudpipe/__init__.py b/nova/api/cloudpipe/__init__.py
new file mode 100644
index 000000000..6d40990a8
--- /dev/null
+++ b/nova/api/cloudpipe/__init__.py
@@ -0,0 +1,69 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2010 United States Government as represented by the
+# Administrator of the National Aeronautics and Space Administration.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+"""
+REST API Request Handlers for CloudPipe
+"""
+
+import logging
+import urllib
+import webob
+import webob.dec
+import webob.exc
+
+from nova import crypto
+from nova import wsgi
+from nova.auth import manager
+from nova.api.ec2 import cloud
+
+
+_log = logging.getLogger("api")
+_log.setLevel(logging.DEBUG)
+
+
+class API(wsgi.Application):
+
+ def __init__(self):
+ self.controller = cloud.CloudController()
+
+ @webob.dec.wsgify
+ def __call__(self, req):
+ if req.method == 'POST':
+ return self.sign_csr(req)
+ _log.debug("Cloudpipe path is %s" % req.path_info)
+ if req.path_info.endswith("/getca/"):
+ return self.send_root_ca(req)
+ return webob.exc.HTTPNotFound()
+
+ def get_project_id_from_ip(self, ip):
+ # TODO(eday): This was removed with the ORM branch, fix!
+ instance = self.controller.get_instance_by_ip(ip)
+ return instance['project_id']
+
+ def send_root_ca(self, req):
+ _log.debug("Getting root ca")
+ project_id = self.get_project_id_from_ip(req.remote_addr)
+ res = webob.Response()
+ res.headers["Content-Type"] = "text/plain"
+ res.body = crypto.fetch_ca(project_id)
+ return res
+
+ def sign_csr(self, req):
+ project_id = self.get_project_id_from_ip(req.remote_addr)
+ cert = self.str_params['cert']
+ return crypto.sign_csr(urllib.unquote(cert), project_id)
diff --git a/nova/api/ec2/metadatarequesthandler.py b/nova/api/ec2/metadatarequesthandler.py
index 229e5a78d..08a8040ca 100644
--- a/nova/api/ec2/metadatarequesthandler.py
+++ b/nova/api/ec2/metadatarequesthandler.py
@@ -18,6 +18,8 @@
"""Metadata request handler."""
+import logging
+
import webob.dec
import webob.exc
@@ -63,9 +65,9 @@ class MetadataRequestHandler(object):
cc = cloud.CloudController()
meta_data = cc.get_metadata(req.remote_addr)
if meta_data is None:
- _log.error('Failed to get metadata for ip: %s' % req.remote_addr)
+ logging.error('Failed to get metadata for ip: %s' % req.remote_addr)
raise webob.exc.HTTPNotFound()
- data = self.lookup(path, meta_data)
+ data = self.lookup(req.path_info, meta_data)
if data is None:
raise webob.exc.HTTPNotFound()
return self.print_data(data)
diff --git a/nova/cloudpipe/api.py b/nova/cloudpipe/api.py
deleted file mode 100644
index 56aa89834..000000000
--- a/nova/cloudpipe/api.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2010 United States Government as represented by the
-# Administrator of the National Aeronautics and Space Administration.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-Tornado REST API Request Handlers for CloudPipe
-"""
-
-import logging
-import urllib
-
-import tornado.web
-
-from nova import crypto
-from nova.auth import manager
-
-
-_log = logging.getLogger("api")
-_log.setLevel(logging.DEBUG)
-
-
-class CloudPipeRequestHandler(tornado.web.RequestHandler):
- def get(self, path):
- path = self.request.path
- _log.debug( "Cloudpipe path is %s" % path)
- if path.endswith("/getca/"):
- self.send_root_ca()
- self.finish()
-
- def get_project_id_from_ip(self, ip):
- cc = self.application.controllers['Cloud']
- instance = cc.get_instance_by_ip(ip)
- instance['project_id']
-
- def send_root_ca(self):
- _log.debug( "Getting root ca")
- project_id = self.get_project_id_from_ip(self.request.remote_ip)
- self.set_header("Content-Type", "text/plain")
- self.write(crypto.fetch_ca(project_id))
-
- def post(self, *args, **kwargs):
- project_id = self.get_project_id_from_ip(self.request.remote_ip)
- cert = self.get_argument('cert', '')
- self.write(crypto.sign_csr(urllib.unquote(cert), project_id))
- self.finish()
diff --git a/nova/cloudpipe/pipelib.py b/nova/cloudpipe/pipelib.py
index b13a60292..706a175d9 100644
--- a/nova/cloudpipe/pipelib.py
+++ b/nova/cloudpipe/pipelib.py
@@ -32,6 +32,8 @@ from nova import exception
from nova import flags
from nova import utils
from nova.auth import manager
+# TODO(eday): Eventually changes these to something not ec2-specific
+from nova.api.ec2 import cloud
from nova.api.ec2 import context
@@ -42,8 +44,8 @@ flags.DEFINE_string('boot_script_template',
class CloudPipe(object):
- def __init__(self, cloud_controller):
- self.controller = cloud_controller
+ def __init__(self):
+ self.controller = cloud.CloudController()
self.manager = manager.AuthManager()
def launch_vpn_instance(self, project_id):
diff --git a/nova/rpc.py b/nova/rpc.py
index 84a9b5590..6363335ea 100644
--- a/nova/rpc.py
+++ b/nova/rpc.py
@@ -46,9 +46,9 @@ LOG.setLevel(logging.DEBUG)
class Connection(carrot_connection.BrokerConnection):
"""Connection instance object"""
@classmethod
- def instance(cls):
+ def instance(cls, new=False):
"""Returns the instance"""
- if not hasattr(cls, '_instance'):
+ if new or not hasattr(cls, '_instance'):
params = dict(hostname=FLAGS.rabbit_host,
port=FLAGS.rabbit_port,
userid=FLAGS.rabbit_userid,
@@ -60,7 +60,10 @@ class Connection(carrot_connection.BrokerConnection):
# NOTE(vish): magic is fun!
# pylint: disable-msg=W0142
- cls._instance = cls(**params)
+ if new:
+ return cls(**params)
+ else:
+ cls._instance = cls(**params)
return cls._instance
@classmethod
@@ -94,8 +97,6 @@ class Consumer(messaging.Consumer):
injected.start()
return injected
- attachToTornado = attach_to_tornado
-
def fetch(self, no_ack=None, auto_ack=None, enable_callbacks=False):
"""Wraps the parent fetch with some logic for failed connections"""
# TODO(vish): the logic for failed connections and logging should be
@@ -265,28 +266,32 @@ def call(topic, msg):
msg.update({'_msg_id': msg_id})
LOG.debug("MSG_ID is %s" % (msg_id))
- conn = Connection.instance()
- d = defer.Deferred()
- consumer = DirectConsumer(connection=conn, msg_id=msg_id)
-
- def deferred_receive(data, message):
- """Acks message and callbacks or errbacks"""
- message.ack()
- if data['failure']:
- return d.errback(RemoteError(*data['failure']))
- else:
- return d.callback(data['result'])
+ class WaitMessage(object):
- consumer.register_callback(deferred_receive)
- injected = consumer.attach_to_tornado()
+ def __call__(self, data, message):
+ """Acks message and sets result."""
+ message.ack()
+ if data['failure']:
+ self.result = RemoteError(*data['failure'])
+ else:
+ self.result = data['result']
- # clean up after the injected listened and return x
- d.addCallback(lambda x: injected.stop() and x or x)
+ wait_msg = WaitMessage()
+ conn = Connection.instance(True)
+ consumer = DirectConsumer(connection=conn, msg_id=msg_id)
+ consumer.register_callback(wait_msg)
+ conn = Connection.instance()
publisher = TopicPublisher(connection=conn, topic=topic)
publisher.send(msg)
publisher.close()
- return d
+
+ try:
+ consumer.wait(limit=1)
+ except StopIteration:
+ pass
+ consumer.close()
+ return wait_msg.result
def cast(topic, msg):
diff --git a/nova/tests/cloud_unittest.py b/nova/tests/cloud_unittest.py
index 2f22982eb..756ce519e 100644
--- a/nova/tests/cloud_unittest.py
+++ b/nova/tests/cloud_unittest.py
@@ -22,7 +22,6 @@ from M2Crypto import RSA
import StringIO
import time
-from tornado import ioloop
from twisted.internet import defer
import unittest
from xml.etree import ElementTree