summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonal Lafferty <donal.lafferty@citrix.com>2011-08-08 15:15:49 +0100
committerDonal Lafferty <donal.lafferty@citrix.com>2011-08-08 15:15:49 +0100
commitd2aa9ddcb26b1217de55fc5cd6c886059e781cda (patch)
tree82e8ae1c8df1ebca7f3b89731af3c7b7fcfb9c23
parent157d85633bf11e91a17d9181cb56c45a4074ac66 (diff)
parentec57e2a27ebfc8eba84d82f5372408e3d85a9272 (diff)
Remove nova/tests/network, which was accidentally included in commit.
-rw-r--r--nova/api/openstack/__init__.py3
-rw-r--r--nova/api/openstack/common.py13
-rw-r--r--nova/api/openstack/images.py1
-rw-r--r--nova/api/openstack/servers.py2
-rw-r--r--nova/tests/api/openstack/test_images.py10
-rw-r--r--nova/tests/api/openstack/test_server_actions.py18
-rw-r--r--nova/tests/network/__init__.py67
-rw-r--r--nova/tests/network/base.py155
8 files changed, 47 insertions, 222 deletions
diff --git a/nova/api/openstack/__init__.py b/nova/api/openstack/__init__.py
index d6a98c2cd..4d49df2ad 100644
--- a/nova/api/openstack/__init__.py
+++ b/nova/api/openstack/__init__.py
@@ -50,6 +50,9 @@ FLAGS = flags.FLAGS
flags.DEFINE_bool('allow_admin_api',
False,
'When True, this API service will accept admin operations.')
+flags.DEFINE_bool('allow_instance_snapshots',
+ True,
+ 'When True, this API service will permit instance snapshot operations.')
class FaultWrapper(base_wsgi.Middleware):
diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py
index 4548c2c75..5226cdf9a 100644
--- a/nova/api/openstack/common.py
+++ b/nova/api/openstack/common.py
@@ -15,6 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import functools
import re
import urlparse
from xml.dom import minidom
@@ -280,3 +281,15 @@ class MetadataXMLSerializer(wsgi.XMLDictSerializer):
def default(self, *args, **kwargs):
return ''
+
+
+def check_snapshots_enabled(f):
+ @functools.wraps(f)
+ def inner(*args, **kwargs):
+ if not FLAGS.allow_instance_snapshots:
+ LOG.warn(_('Rejecting snapshot request, snapshots currently'
+ ' disabled'))
+ msg = _("Instance snapshots are not permitted at this time.")
+ raise webob.exc.HTTPBadRequest(explanation=msg)
+ return f(*args, **kwargs)
+ return inner
diff --git a/nova/api/openstack/images.py b/nova/api/openstack/images.py
index b9bc83fde..0aabb9e56 100644
--- a/nova/api/openstack/images.py
+++ b/nova/api/openstack/images.py
@@ -106,6 +106,7 @@ class Controller(object):
class ControllerV10(Controller):
"""Version 1.0 specific controller logic."""
+ @common.check_snapshots_enabled
def create(self, req, body):
"""Snapshot a server instance and save the image."""
try:
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py
index 1051ba571..f1a27a98c 100644
--- a/nova/api/openstack/servers.py
+++ b/nova/api/openstack/servers.py
@@ -240,6 +240,7 @@ class Controller(object):
resp.headers['Location'] = image_ref
return resp
+ @common.check_snapshots_enabled
def _action_create_image(self, input_dict, req, id):
return exc.HTTPNotImplemented()
@@ -689,6 +690,7 @@ class ControllerV11(Controller):
return webob.Response(status_int=202)
+ @common.check_snapshots_enabled
def _action_create_image(self, input_dict, req, instance_id):
"""Snapshot a server instance."""
entity = input_dict.get("createImage", {})
diff --git a/nova/tests/api/openstack/test_images.py b/nova/tests/api/openstack/test_images.py
index 8e2e3f390..38495bbe7 100644
--- a/nova/tests/api/openstack/test_images.py
+++ b/nova/tests/api/openstack/test_images.py
@@ -1049,6 +1049,16 @@ class ImageControllerWithGlanceServiceTest(test.TestCase):
response = req.get_response(fakes.wsgi_app())
self.assertEqual(400, response.status_int)
+ def test_create_image_snapshots_disabled(self):
+ self.flags(allow_instance_snapshots=False)
+ body = dict(image=dict(serverId='123', name='Snapshot 1'))
+ req = webob.Request.blank('/v1.0/images')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
@classmethod
def _make_image_fixtures(cls):
image_id = 123
diff --git a/nova/tests/api/openstack/test_server_actions.py b/nova/tests/api/openstack/test_server_actions.py
index 7e24d24fd..bf18bc1b0 100644
--- a/nova/tests/api/openstack/test_server_actions.py
+++ b/nova/tests/api/openstack/test_server_actions.py
@@ -458,6 +458,7 @@ class ServerActionsTestV11(test.TestCase):
self.service.delete_all()
self.sent_to_glance = {}
fakes.stub_out_glance_add_image(self.stubs, self.sent_to_glance)
+ self.flags(allow_instance_snapshots=True)
def tearDown(self):
self.stubs.UnsetAll()
@@ -775,6 +776,23 @@ class ServerActionsTestV11(test.TestCase):
location = response.headers['Location']
self.assertEqual('http://localhost/v1.1/images/123', location)
+ def test_create_image_snapshots_disabled(self):
+ """Don't permit a snapshot if the allow_instance_snapshots flag is
+ False
+ """
+ self.flags(allow_instance_snapshots=False)
+ body = {
+ 'createImage': {
+ 'name': 'Snapshot 1',
+ },
+ }
+ req = webob.Request.blank('/v1.1/servers/1/action')
+ req.method = 'POST'
+ req.body = json.dumps(body)
+ req.headers["content-type"] = "application/json"
+ response = req.get_response(fakes.wsgi_app())
+ self.assertEqual(400, response.status_int)
+
def test_create_image_with_metadata(self):
body = {
'createImage': {
diff --git a/nova/tests/network/__init__.py b/nova/tests/network/__init__.py
deleted file mode 100644
index 97f96b6fa..000000000
--- a/nova/tests/network/__init__.py
+++ /dev/null
@@ -1,67 +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.
-"""
-Utility methods
-"""
-import os
-
-from nova import context
-from nova import db
-from nova import flags
-from nova import log as logging
-from nova import utils
-
-FLAGS = flags.FLAGS
-LOG = logging.getLogger('nova.tests.network')
-
-
-def binpath(script):
- """Returns the absolute path to a script in bin"""
- return os.path.abspath(os.path.join(__file__, "../../../../bin", script))
-
-
-def lease_ip(private_ip):
- """Run add command on dhcpbridge"""
- network_ref = db.fixed_ip_get_network(context.get_admin_context(),
- private_ip)
- instance_ref = db.fixed_ip_get_instance(context.get_admin_context(),
- private_ip)
- cmd = (binpath('nova-dhcpbridge'), 'add',
- instance_ref['mac_address'],
- private_ip, 'fake')
- env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
- 'TESTING': '1',
- 'FLAGFILE': FLAGS.dhcpbridge_flagfile}
- (out, err) = utils.execute(*cmd, addl_env=env)
- LOG.debug("ISSUE_IP: %s, %s ", out, err)
-
-
-def release_ip(private_ip):
- """Run del command on dhcpbridge"""
- network_ref = db.fixed_ip_get_network(context.get_admin_context(),
- private_ip)
- instance_ref = db.fixed_ip_get_instance(context.get_admin_context(),
- private_ip)
- cmd = (binpath('nova-dhcpbridge'), 'del',
- instance_ref['mac_address'],
- private_ip, 'fake')
- env = {'DNSMASQ_INTERFACE': network_ref['bridge'],
- 'TESTING': '1',
- 'FLAGFILE': FLAGS.dhcpbridge_flagfile}
- (out, err) = utils.execute(*cmd, addl_env=env)
- LOG.debug("RELEASE_IP: %s, %s ", out, err)
diff --git a/nova/tests/network/base.py b/nova/tests/network/base.py
deleted file mode 100644
index f65416824..000000000
--- a/nova/tests/network/base.py
+++ /dev/null
@@ -1,155 +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.
-"""
-Base class of Unit Tests for all network models
-"""
-import netaddr
-import os
-
-from nova import context
-from nova import db
-from nova import exception
-from nova import flags
-from nova import ipv6
-from nova import log as logging
-from nova import test
-from nova import utils
-from nova.auth import manager
-
-FLAGS = flags.FLAGS
-LOG = logging.getLogger('nova.tests.network')
-
-
-class NetworkTestCase(test.TestCase):
- """Test cases for network code"""
- def setUp(self):
- super(NetworkTestCase, self).setUp()
- # NOTE(vish): if you change these flags, make sure to change the
- # flags in the corresponding section in nova-dhcpbridge
- self.flags(connection_type='fake',
- fake_call=True,
- fake_network=True)
- self.manager = manager.AuthManager()
- self.user = self.manager.create_user('netuser', 'netuser', 'netuser')
- self.projects = []
- self.network = utils.import_object(FLAGS.network_manager)
- self.context = context.RequestContext(project=None, user=self.user)
- for i in range(FLAGS.num_networks):
- name = 'project%s' % i
- project = self.manager.create_project(name, 'netuser', name)
- self.projects.append(project)
- # create the necessary network data for the project
- user_context = context.RequestContext(project=self.projects[i],
- user=self.user)
- host = self.network.get_network_host(user_context.elevated())
- instance_ref = self._create_instance(0)
- self.instance_id = instance_ref['id']
- instance_ref = self._create_instance(1)
- self.instance2_id = instance_ref['id']
-
- def tearDown(self):
- # TODO(termie): this should really be instantiating clean datastores
- # in between runs, one failure kills all the tests
- db.instance_destroy(context.get_admin_context(), self.instance_id)
- db.instance_destroy(context.get_admin_context(), self.instance2_id)
- for project in self.projects:
- self.manager.delete_project(project)
- self.manager.delete_user(self.user)
- super(NetworkTestCase, self).tearDown()
-
- def _create_instance(self, project_num, mac=None):
- if not mac:
- mac = utils.generate_mac()
- project = self.projects[project_num]
- self.context._project = project
- self.context.project_id = project.id
- return db.instance_create(self.context,
- {'project_id': project.id,
- 'mac_address': mac})
-
- def _create_address(self, project_num, instance_id=None):
- """Create an address in given project num"""
- if instance_id is None:
- instance_id = self.instance_id
- self.context._project = self.projects[project_num]
- self.context.project_id = self.projects[project_num].id
- return self.network.allocate_fixed_ip(self.context, instance_id)
-
- def _deallocate_address(self, project_num, address):
- self.context._project = self.projects[project_num]
- self.context.project_id = self.projects[project_num].id
- self.network.deallocate_fixed_ip(self.context, address)
-
- def _is_allocated_in_project(self, address, project_id):
- """Returns true if address is in specified project"""
- project_net = db.network_get_by_bridge(context.get_admin_context(),
- FLAGS.flat_network_bridge)
- network = db.fixed_ip_get_network(context.get_admin_context(),
- address)
- instance = db.fixed_ip_get_instance(context.get_admin_context(),
- address)
- # instance exists until release
- return instance is not None and network['id'] == project_net['id']
-
- def test_private_ipv6(self):
- """Make sure ipv6 is OK"""
- if FLAGS.use_ipv6:
- instance_ref = self._create_instance(0)
- address = self._create_address(0, instance_ref['id'])
- network_ref = db.project_get_network(
- context.get_admin_context(),
- self.context.project_id)
- address_v6 = db.instance_get_fixed_address_v6(
- context.get_admin_context(),
- instance_ref['id'])
- self.assertEqual(instance_ref['mac_address'],
- ipv6.to_mac(address_v6))
- instance_ref2 = db.fixed_ip_get_instance_v6(
- context.get_admin_context(),
- address_v6)
- self.assertEqual(instance_ref['id'], instance_ref2['id'])
- self.assertEqual(address_v6,
- ipv6.to_global(network_ref['cidr_v6'],
- instance_ref['mac_address'],
- 'test'))
- self._deallocate_address(0, address)
- db.instance_destroy(context.get_admin_context(),
- instance_ref['id'])
-
- def test_available_ips(self):
- """Make sure the number of available ips for the network is correct
-
- The number of available IP addresses depends on the test
- environment's setup.
-
- Network size is set in test fixture's setUp method.
-
- There are ips reserved at the bottom and top of the range.
- services (network, gateway, CloudPipe, broadcast)
- """
- network = db.project_get_network(context.get_admin_context(),
- self.projects[0].id)
- net_size = flags.FLAGS.network_size
- admin_context = context.get_admin_context()
- total_ips = (db.network_count_available_ips(admin_context,
- network['id']) +
- db.network_count_reserved_ips(admin_context,
- network['id']) +
- db.network_count_allocated_ips(admin_context,
- network['id']))
- self.assertEqual(total_ips, net_size)