From 398ec325160acf039e1070718e898339a4b2d268 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Mon, 15 Nov 2010 01:25:42 -0400 Subject: base commit --- nova/api/openstack/__init__.py | 49 ++++++++++++------ nova/tests/api/openstack/test_restrictedapi.py | 70 ++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 15 deletions(-) create mode 100644 nova/tests/api/openstack/test_restrictedapi.py diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 1dd3ba770..338d642bc 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -47,6 +47,9 @@ flags.DEFINE_string('nova_api_auth', 'nova.api.openstack.auth.BasicApiAuthManager', 'The auth mechanism to use for the OpenStack API implemenation') +flags.DEFINE_list('nova_api_permitted_operations', + [], + 'A comma-separated list of permitted api operations. Empty for all.') class API(wsgi.Middleware): """WSGI entry point for all OpenStack API requests.""" @@ -165,21 +168,37 @@ class APIRouter(wsgi.Router): def __init__(self): mapper = routes.Mapper() - mapper.resource("server", "servers", controller=servers.Controller(), - collection={'detail': 'GET'}, - member={'action': 'POST'}) - - mapper.resource("backup_schedule", "backup_schedules", - controller=backup_schedules.Controller(), - parent_resource=dict(member_name='server', - collection_name='servers')) - - mapper.resource("image", "images", controller=images.Controller(), - collection={'detail': 'GET'}) - mapper.resource("flavor", "flavors", controller=flavors.Controller(), - collection={'detail': 'GET'}) - mapper.resource("sharedipgroup", "sharedipgroups", - controller=sharedipgroups.Controller()) + commands = { + "server" : dict(plural='servers', + controller=servers.Controller(), + collection={'detail': 'GET'}, + member={'action': 'POST'}), + "backup_schedule" : dict(plural='backup_schedules', + controller=backup_schedules.Controller(), + parent_resource=dict(member_name='server', + collection_name='servers')), + "image" : dict(plural='images', + controller=images.Controller(), + collection={'detail': 'GET'}), + "flavor" : dict(plural='flavors', + controller=flavors.Controller(), + collection={'detail': 'GET'}), + "sharedipgroup" : dict(plural="sharedipgroups", + controller=sharedipgroups.Controller()), + } + + permitted = commands.keys() + if len(FLAGS.nova_api_permitted_operations) > 0: + permitted = FLAGS.nova_api_permitted_operations + logging.debug("Permitted operation set: %s" % (permitted,)) + for command in permitted: + options = commands.get(command, None) + if not options: + logging.warning("Unknown option in nova_api_permitted_operations: '%s' (skipping)" % (command,)) + continue + collection = options['plural'] + del options['plural'] + mapper.resource(command, collection, **options) super(APIRouter, self).__init__(mapper) diff --git a/nova/tests/api/openstack/test_restrictedapi.py b/nova/tests/api/openstack/test_restrictedapi.py new file mode 100644 index 000000000..560a66e8c --- /dev/null +++ b/nova/tests/api/openstack/test_restrictedapi.py @@ -0,0 +1,70 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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. + +import unittest + +import stubout +import webob + +import nova.api +from nova import flags +from nova.api.openstack import flavors +from nova.tests.api.openstack import fakes + +FLAGS = flags.FLAGS + +class RestrictedAPITest(unittest.TestCase): + def setUp(self): + self.stubs = stubout.StubOutForTesting() + fakes.FakeAuthManager.auth_data = {} + fakes.FakeAuthDatabase.data = {} + fakes.stub_out_networking(self.stubs) + fakes.stub_out_rate_limiting(self.stubs) + fakes.stub_out_auth(self.stubs) + self.original_permissions = FLAGS.nova_api_permitted_operations + + def tearDown(self): + self.stubs.UnsetAll() + FLAGS.nova_api_permitted_operations = self.original_permissions + + def test_permitted(self): + req = webob.Request.blank('/v1.0/flavors') + FLAGS.nova_api_permitted_operations = ["server", "backup_schedule", "image", "flavor", "sharedipgroup"] + res = req.get_response(nova.api.API('os')) + self.assertEqual(res.status_int, 200) + + def test_bad_list(self): + req = webob.Request.blank('/v1.0/flavors') + FLAGS.nova_api_permitted_operations = ["foo", "bar", "zoo"] + res = req.get_response(nova.api.API('os')) + self.assertEqual(res.status_int, 404) + + def test_default_all_permitted(self): + req = webob.Request.blank('/v1.0/flavors') + # empty means all operations available. + FLAGS.nova_api_permitted_operations = [] + res = req.get_response(nova.api.API('os')) + self.assertEqual(res.status_int, 200) + + def test_disallowed(self): + req = webob.Request.blank('/v1.0/flavors') + FLAGS.nova_api_permitted_operations = ["server", "backup_schedule", "image", "sharedipgroup"] + res = req.get_response(nova.api.API('os')) + self.assertEqual(res.status_int, 404) + +if __name__ == '__main__': + unittest.main() -- cgit From 66a5ac31c4a5f24da9c0335cf934bbf545c0d95f Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Tue, 16 Nov 2010 02:54:13 -0400 Subject: Changed from fine-grained operation control to binary admin on/off setting. --- nova/api/openstack/__init__.py | 56 ++++++++------------- nova/tests/api/openstack/test_adminapi.py | 60 ++++++++++++++++++++++ nova/tests/api/openstack/test_restrictedapi.py | 70 -------------------------- 3 files changed, 82 insertions(+), 104 deletions(-) create mode 100644 nova/tests/api/openstack/test_adminapi.py delete mode 100644 nova/tests/api/openstack/test_restrictedapi.py diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 338d642bc..23ac033cf 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -47,9 +47,9 @@ flags.DEFINE_string('nova_api_auth', 'nova.api.openstack.auth.BasicApiAuthManager', 'The auth mechanism to use for the OpenStack API implemenation') -flags.DEFINE_list('nova_api_permitted_operations', - [], - 'A comma-separated list of permitted api operations. Empty for all.') +flags.DEFINE_bool('allow_admin_api', + False, + 'When True, this API service will accept admin operations.') class API(wsgi.Middleware): """WSGI entry point for all OpenStack API requests.""" @@ -168,37 +168,25 @@ class APIRouter(wsgi.Router): def __init__(self): mapper = routes.Mapper() - commands = { - "server" : dict(plural='servers', - controller=servers.Controller(), - collection={'detail': 'GET'}, - member={'action': 'POST'}), - "backup_schedule" : dict(plural='backup_schedules', - controller=backup_schedules.Controller(), - parent_resource=dict(member_name='server', - collection_name='servers')), - "image" : dict(plural='images', - controller=images.Controller(), - collection={'detail': 'GET'}), - "flavor" : dict(plural='flavors', - controller=flavors.Controller(), - collection={'detail': 'GET'}), - "sharedipgroup" : dict(plural="sharedipgroups", - controller=sharedipgroups.Controller()), - } - - permitted = commands.keys() - if len(FLAGS.nova_api_permitted_operations) > 0: - permitted = FLAGS.nova_api_permitted_operations - logging.debug("Permitted operation set: %s" % (permitted,)) - for command in permitted: - options = commands.get(command, None) - if not options: - logging.warning("Unknown option in nova_api_permitted_operations: '%s' (skipping)" % (command,)) - continue - collection = options['plural'] - del options['plural'] - mapper.resource(command, collection, **options) + mapper.resource("server", "servers", controller=servers.Controller(), + collection={'detail': 'GET'}, + member={'action': 'POST'}) + + mapper.resource("backup_schedule", "backup_schedules", + controller=backup_schedules.Controller(), + parent_resource=dict(member_name='server', + collection_name='servers')) + + mapper.resource("image", "images", controller=images.Controller(), + collection={'detail': 'GET'}) + mapper.resource("flavor", "flavors", controller=flavors.Controller(), + collection={'detail': 'GET'}) + mapper.resource("sharedipgroup", "sharedipgroups", + controller=sharedipgroups.Controller()) + + if FLAGS.allow_admin_api: + logging.debug("Including admin operations in API.") + # TODO: Place routes for admin operations here. super(APIRouter, self).__init__(mapper) diff --git a/nova/tests/api/openstack/test_adminapi.py b/nova/tests/api/openstack/test_adminapi.py new file mode 100644 index 000000000..54cb40e84 --- /dev/null +++ b/nova/tests/api/openstack/test_adminapi.py @@ -0,0 +1,60 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2010 OpenStack LLC. +# 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. + +import unittest + +import stubout +import webob + +import nova.api +from nova import flags +from nova.tests.api.openstack import fakes + +FLAGS = flags.FLAGS + +class RestrictedAPITest(unittest.TestCase): + def setUp(self): + self.stubs = stubout.StubOutForTesting() + fakes.FakeAuthManager.auth_data = {} + fakes.FakeAuthDatabase.data = {} + fakes.stub_out_networking(self.stubs) + fakes.stub_out_rate_limiting(self.stubs) + fakes.stub_out_auth(self.stubs) + self.allow_admin = FLAGS.allow_admin_api + + def tearDown(self): + self.stubs.UnsetAll() + FLAGS.allow_admin_api = self.allow_admin + + def test_admin_enabled(self): + FLAGS.allow_admin_api = True + # We should still be able to access public operations. + req = webob.Request.blank('/v1.0/flavors') + res = req.get_response(nova.api.API('os')) + self.assertEqual(res.status_int, 200) + # TODO: Confirm admin operations are available. + + def test_admin_disabled(self): + FLAGS.allow_admin_api = False + # We should still be able to access public operations. + req = webob.Request.blank('/v1.0/flavors') + res = req.get_response(nova.api.API('os')) + self.assertEqual(res.status_int, 200) + # TODO: Confirm admin operations are unavailable. + +if __name__ == '__main__': + unittest.main() diff --git a/nova/tests/api/openstack/test_restrictedapi.py b/nova/tests/api/openstack/test_restrictedapi.py deleted file mode 100644 index 560a66e8c..000000000 --- a/nova/tests/api/openstack/test_restrictedapi.py +++ /dev/null @@ -1,70 +0,0 @@ -# vim: tabstop=4 shiftwidth=4 softtabstop=4 - -# Copyright 2010 OpenStack LLC. -# 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. - -import unittest - -import stubout -import webob - -import nova.api -from nova import flags -from nova.api.openstack import flavors -from nova.tests.api.openstack import fakes - -FLAGS = flags.FLAGS - -class RestrictedAPITest(unittest.TestCase): - def setUp(self): - self.stubs = stubout.StubOutForTesting() - fakes.FakeAuthManager.auth_data = {} - fakes.FakeAuthDatabase.data = {} - fakes.stub_out_networking(self.stubs) - fakes.stub_out_rate_limiting(self.stubs) - fakes.stub_out_auth(self.stubs) - self.original_permissions = FLAGS.nova_api_permitted_operations - - def tearDown(self): - self.stubs.UnsetAll() - FLAGS.nova_api_permitted_operations = self.original_permissions - - def test_permitted(self): - req = webob.Request.blank('/v1.0/flavors') - FLAGS.nova_api_permitted_operations = ["server", "backup_schedule", "image", "flavor", "sharedipgroup"] - res = req.get_response(nova.api.API('os')) - self.assertEqual(res.status_int, 200) - - def test_bad_list(self): - req = webob.Request.blank('/v1.0/flavors') - FLAGS.nova_api_permitted_operations = ["foo", "bar", "zoo"] - res = req.get_response(nova.api.API('os')) - self.assertEqual(res.status_int, 404) - - def test_default_all_permitted(self): - req = webob.Request.blank('/v1.0/flavors') - # empty means all operations available. - FLAGS.nova_api_permitted_operations = [] - res = req.get_response(nova.api.API('os')) - self.assertEqual(res.status_int, 200) - - def test_disallowed(self): - req = webob.Request.blank('/v1.0/flavors') - FLAGS.nova_api_permitted_operations = ["server", "backup_schedule", "image", "sharedipgroup"] - res = req.get_response(nova.api.API('os')) - self.assertEqual(res.status_int, 404) - -if __name__ == '__main__': - unittest.main() -- cgit From 10756392157aa5e6029a50a9f38718f3024731c7 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Tue, 16 Nov 2010 05:46:40 -0400 Subject: added myself to Authors file. Enjoy spiders. --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index ef1a535ca..22acc34d2 100644 --- a/Authors +++ b/Authors @@ -20,6 +20,7 @@ Michael Gundlach Monty Taylor Paul Voccio Rick Clark +Sandy Walsh Soren Hansen Todd Willey Vishvananda Ishaya -- cgit From f0b53131569cd409a95c68b435ec56a69dcdc897 Mon Sep 17 00:00:00 2001 From: Sandy Walsh Date: Tue, 16 Nov 2010 05:53:21 -0400 Subject: PEP8 fixes --- nova/api/openstack/__init__.py | 1 + nova/tests/api/openstack/test_adminapi.py | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py index 23ac033cf..80b27c7e5 100644 --- a/nova/api/openstack/__init__.py +++ b/nova/api/openstack/__init__.py @@ -51,6 +51,7 @@ flags.DEFINE_bool('allow_admin_api', False, 'When True, this API service will accept admin operations.') + class API(wsgi.Middleware): """WSGI entry point for all OpenStack API requests.""" diff --git a/nova/tests/api/openstack/test_adminapi.py b/nova/tests/api/openstack/test_adminapi.py index 54cb40e84..1b2e1654d 100644 --- a/nova/tests/api/openstack/test_adminapi.py +++ b/nova/tests/api/openstack/test_adminapi.py @@ -26,7 +26,8 @@ from nova.tests.api.openstack import fakes FLAGS = flags.FLAGS -class RestrictedAPITest(unittest.TestCase): + +class AdminAPITest(unittest.TestCase): def setUp(self): self.stubs = stubout.StubOutForTesting() fakes.FakeAuthManager.auth_data = {} @@ -42,7 +43,7 @@ class RestrictedAPITest(unittest.TestCase): def test_admin_enabled(self): FLAGS.allow_admin_api = True - # We should still be able to access public operations. + # We should still be able to access public operations. req = webob.Request.blank('/v1.0/flavors') res = req.get_response(nova.api.API('os')) self.assertEqual(res.status_int, 200) @@ -50,7 +51,7 @@ class RestrictedAPITest(unittest.TestCase): def test_admin_disabled(self): FLAGS.allow_admin_api = False - # We should still be able to access public operations. + # We should still be able to access public operations. req = webob.Request.blank('/v1.0/flavors') res = req.get_response(nova.api.API('os')) self.assertEqual(res.status_int, 200) -- cgit From 88c0e3e380d50d5794970063bbe464171089f260 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Tue, 7 Dec 2010 04:41:53 +0000 Subject: modified a few files --- nova/api/ec2/cloud.py | 1 - nova/compute/api.py | 14 ++++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index e50906ae1..a05dc0f1c 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -760,7 +760,6 @@ class CloudController(object): ramdisk_id=kwargs.get('ramdisk_id'), name=kwargs.get('display_name'), description=kwargs.get('display_description'), - user_data=kwargs.get('user_data', ''), key_name=kwargs.get('key_name'), security_group=kwargs.get('security_group'), generate_hostname=internal_id_to_ec2_id) diff --git a/nova/compute/api.py b/nova/compute/api.py index 929342a1e..6830bacb8 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -52,7 +52,7 @@ class ComputeAPI(base.Base): def create_instances(self, context, instance_type, image_service, image_id, network_topic, min_count=1, max_count=1, kernel_id=None, ramdisk_id=None, name='', - description='', user_data='', key_name=None, + description='', key_name=None, key_data=None, security_group='default', generate_hostname=generate_default_hostname): """Create the number of instances requested if quote and @@ -143,8 +143,8 @@ class ComputeAPI(base.Base): {"method": "setup_fixed_ip", "args": {"address": address}}) - logging.debug("Casting to scheduler for %s/%s's instance %s" % - (context.project_id, context.user_id, instance_id)) + logging.debug("Casting to scheduler for %s/%s's instance %s", + context.project_id, context.user_id, instance_id) rpc.cast(context, FLAGS.scheduler_topic, {"method": "run_instance", @@ -154,6 +154,12 @@ class ComputeAPI(base.Base): return instances def ensure_default_security_group(self, context): + """ Create security group for the security context if it + does not already exist + + :param context: the security context + + """ try: db.security_group_get_by_name(context, context.project_id, 'default') @@ -162,7 +168,7 @@ class ComputeAPI(base.Base): 'description': 'default', 'user_id': context.user_id, 'project_id': context.project_id} - group = db.security_group_create(context, values) + db.security_group_create(context, values) def create_instance(self, context, security_groups=None, **kwargs): """Creates the instance in the datastore and returns the -- cgit From 708425aa5b42aae0f399b127ee5a648b7162b05e Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Wed, 8 Dec 2010 12:20:44 -0800 Subject: add bzr to the dev dependencies --- tools/pip-requires | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/pip-requires b/tools/pip-requires index 548073326..17a1a4c5c 100644 --- a/tools/pip-requires +++ b/tools/pip-requires @@ -20,3 +20,4 @@ mox==0.5.0 -f http://pymox.googlecode.com/files/mox-0.5.0.tar.gz greenlet==0.3.1 nose +bzr -- cgit From 0ae019062712fd15dd9e040a3fa60546db9c4111 Mon Sep 17 00:00:00 2001 From: Trey Morris Date: Wed, 8 Dec 2010 23:47:25 +0000 Subject: added to Authors --- Authors | 1 + 1 file changed, 1 insertion(+) diff --git a/Authors b/Authors index 62f0c49d5..a1703b279 100644 --- a/Authors +++ b/Authors @@ -23,6 +23,7 @@ Rick Clark Ryan Lucio Soren Hansen Todd Willey +Trey Morris Vishvananda Ishaya Youcef Laribi Zhixue Wu -- cgit