426 lines
16 KiB
Python
426 lines
16 KiB
Python
# Copyright 2013 IBM Corp.
|
|
#
|
|
# 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 webob
|
|
|
|
from nova.api.openstack.compute import access_ips
|
|
from nova.api.openstack.compute import extension_info
|
|
from nova.api.openstack.compute.legacy_v2 import servers as servers_v20
|
|
from nova.api.openstack.compute import servers as servers_v21
|
|
from nova.api.openstack import extensions as extensions_v20
|
|
from nova.api.openstack import wsgi
|
|
from nova.compute import api as compute_api
|
|
from nova import db
|
|
from nova import exception
|
|
from nova.objects import instance as instance_obj
|
|
from nova import test
|
|
from nova.tests.unit.api.openstack import fakes
|
|
from nova.tests.unit.image import fake
|
|
|
|
|
|
class AccessIPsExtTestV21(test.NoDBTestCase):
|
|
def setUp(self):
|
|
super(AccessIPsExtTestV21, self).setUp()
|
|
self.access_ips_ext = access_ips.AccessIPs(None)
|
|
|
|
def _test(self, func):
|
|
server_dict = {access_ips.AccessIPs.v4_key: '1.1.1.1',
|
|
access_ips.AccessIPs.v6_key: 'fe80::'}
|
|
create_kwargs = {}
|
|
func(server_dict, create_kwargs)
|
|
self.assertEqual(create_kwargs, {'access_ip_v4': '1.1.1.1',
|
|
'access_ip_v6': 'fe80::'})
|
|
|
|
def _test_with_ipv4_only(self, func):
|
|
server_dict = {access_ips.AccessIPs.v4_key: '1.1.1.1'}
|
|
create_kwargs = {}
|
|
func(server_dict, create_kwargs)
|
|
self.assertEqual(create_kwargs, {'access_ip_v4': '1.1.1.1'})
|
|
|
|
def _test_with_ipv6_only(self, func):
|
|
server_dict = {access_ips.AccessIPs.v6_key: 'fe80::'}
|
|
create_kwargs = {}
|
|
func(server_dict, create_kwargs)
|
|
self.assertEqual(create_kwargs, {'access_ip_v6': 'fe80::'})
|
|
|
|
def _test_without_ipv4_and_ipv6(self, func):
|
|
server_dict = {}
|
|
create_kwargs = {}
|
|
func(server_dict, create_kwargs)
|
|
self.assertEqual(create_kwargs, {})
|
|
|
|
def _test_with_ipv4_null(self, func):
|
|
server_dict = {access_ips.AccessIPs.v4_key: None}
|
|
create_kwargs = {}
|
|
func(server_dict, create_kwargs)
|
|
self.assertEqual(create_kwargs, {'access_ip_v4': None})
|
|
|
|
def _test_with_ipv6_null(self, func):
|
|
server_dict = {access_ips.AccessIPs.v6_key: None}
|
|
create_kwargs = {}
|
|
func(server_dict, create_kwargs)
|
|
self.assertEqual(create_kwargs, {'access_ip_v6': None})
|
|
|
|
def _test_with_ipv4_blank(self, func):
|
|
server_dict = {access_ips.AccessIPs.v4_key: ''}
|
|
create_kwargs = {}
|
|
func(server_dict, create_kwargs)
|
|
self.assertEqual(create_kwargs, {'access_ip_v4': None})
|
|
|
|
def _test_with_ipv6_blank(self, func):
|
|
server_dict = {access_ips.AccessIPs.v6_key: ''}
|
|
create_kwargs = {}
|
|
func(server_dict, create_kwargs)
|
|
self.assertEqual(create_kwargs, {'access_ip_v6': None})
|
|
|
|
def test_server_create(self):
|
|
self._test(self.access_ips_ext.server_create)
|
|
|
|
def test_server_create_with_ipv4_only(self):
|
|
self._test_with_ipv4_only(self.access_ips_ext.server_create)
|
|
|
|
def test_server_create_with_ipv6_only(self):
|
|
self._test_with_ipv6_only(self.access_ips_ext.server_create)
|
|
|
|
def test_server_create_without_ipv4_and_ipv6(self):
|
|
self._test_without_ipv4_and_ipv6(self.access_ips_ext.server_create)
|
|
|
|
def test_server_create_with_ipv4_null(self):
|
|
self._test_with_ipv4_null(self.access_ips_ext.server_create)
|
|
|
|
def test_server_create_with_ipv6_null(self):
|
|
self._test_with_ipv6_null(self.access_ips_ext.server_create)
|
|
|
|
def test_server_create_with_ipv4_blank(self):
|
|
self._test_with_ipv4_blank(self.access_ips_ext.server_create)
|
|
|
|
def test_server_create_with_ipv6_blank(self):
|
|
self._test_with_ipv6_blank(self.access_ips_ext.server_create)
|
|
|
|
def test_server_update(self):
|
|
self._test(self.access_ips_ext.server_update)
|
|
|
|
def test_server_update_with_ipv4_only(self):
|
|
self._test_with_ipv4_only(self.access_ips_ext.server_update)
|
|
|
|
def test_server_update_with_ipv6_only(self):
|
|
self._test_with_ipv6_only(self.access_ips_ext.server_update)
|
|
|
|
def test_server_update_without_ipv4_and_ipv6(self):
|
|
self._test_without_ipv4_and_ipv6(self.access_ips_ext.server_update)
|
|
|
|
def test_server_update_with_ipv4_null(self):
|
|
self._test_with_ipv4_null(self.access_ips_ext.server_update)
|
|
|
|
def test_server_update_with_ipv6_null(self):
|
|
self._test_with_ipv6_null(self.access_ips_ext.server_update)
|
|
|
|
def test_server_update_with_ipv4_blank(self):
|
|
self._test_with_ipv4_blank(self.access_ips_ext.server_update)
|
|
|
|
def test_server_update_with_ipv6_blank(self):
|
|
self._test_with_ipv6_blank(self.access_ips_ext.server_update)
|
|
|
|
def test_server_rebuild(self):
|
|
self._test(self.access_ips_ext.server_rebuild)
|
|
|
|
def test_server_rebuild_with_ipv4_only(self):
|
|
self._test_with_ipv4_only(self.access_ips_ext.server_rebuild)
|
|
|
|
def test_server_rebuild_with_ipv6_only(self):
|
|
self._test_with_ipv6_only(self.access_ips_ext.server_rebuild)
|
|
|
|
def test_server_rebuild_without_ipv4_and_ipv6(self):
|
|
self._test_without_ipv4_and_ipv6(self.access_ips_ext.server_rebuild)
|
|
|
|
def test_server_rebuild_with_ipv4_null(self):
|
|
self._test_with_ipv4_null(self.access_ips_ext.server_rebuild)
|
|
|
|
def test_server_rebuild_with_ipv6_null(self):
|
|
self._test_with_ipv6_null(self.access_ips_ext.server_rebuild)
|
|
|
|
def test_server_rebuild_with_ipv4_blank(self):
|
|
self._test_with_ipv4_blank(self.access_ips_ext.server_rebuild)
|
|
|
|
def test_server_rebuild_with_ipv6_blank(self):
|
|
self._test_with_ipv6_blank(self.access_ips_ext.server_rebuild)
|
|
|
|
|
|
class AccessIPsExtAPIValidationTestV21(test.TestCase):
|
|
validation_error = exception.ValidationError
|
|
|
|
def setUp(self):
|
|
super(AccessIPsExtAPIValidationTestV21, self).setUp()
|
|
|
|
def fake_save(context, **kwargs):
|
|
pass
|
|
|
|
def fake_rebuild(*args, **kwargs):
|
|
pass
|
|
|
|
self._set_up_controller()
|
|
fake.stub_out_image_service(self.stubs)
|
|
self.stubs.Set(db, 'instance_get_by_uuid', fakes.fake_instance_get())
|
|
self.stubs.Set(instance_obj.Instance, 'save', fake_save)
|
|
self.stubs.Set(compute_api.API, 'rebuild', fake_rebuild)
|
|
|
|
self.req = fakes.HTTPRequest.blank('')
|
|
|
|
def _set_up_controller(self):
|
|
ext_info = extension_info.LoadedExtensionInfo()
|
|
self.controller = servers_v21.ServersController(
|
|
extension_info=ext_info)
|
|
|
|
# Note(gmann): V2.1 has Access IP as separate extension. This class tests
|
|
# calls controller directly so Access IPs will not be present in server
|
|
# response. Those are being tested in AccessIPsExtTest class.
|
|
def _verify_update_access_ip(self, res_dict, params):
|
|
pass
|
|
|
|
def _test_create(self, params):
|
|
body = {
|
|
'server': {
|
|
'name': 'server_test',
|
|
'imageRef': '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
|
|
'flavorRef': 'http://localhost/123/flavors/3',
|
|
},
|
|
}
|
|
body['server'].update(params)
|
|
res_dict = self.controller.create(self.req, body=body).obj
|
|
return res_dict
|
|
|
|
def _test_update(self, params):
|
|
body = {
|
|
'server': {
|
|
},
|
|
}
|
|
body['server'].update(params)
|
|
|
|
res_dict = self.controller.update(self.req, fakes.FAKE_UUID, body=body)
|
|
self._verify_update_access_ip(res_dict, params)
|
|
|
|
def _test_rebuild(self, params):
|
|
body = {
|
|
'rebuild': {
|
|
'imageRef': '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6',
|
|
},
|
|
}
|
|
body['rebuild'].update(params)
|
|
self.controller._action_rebuild(self.req, fakes.FAKE_UUID, body=body)
|
|
|
|
def test_create_server_with_access_ipv4(self):
|
|
params = {access_ips.AccessIPs.v4_key: '192.168.0.10'}
|
|
self._test_create(params)
|
|
|
|
def test_create_server_with_access_ip_pass_disabled(self):
|
|
# test with admin passwords disabled See lp bug 921814
|
|
self.flags(enable_instance_password=False)
|
|
params = {access_ips.AccessIPs.v4_key: '192.168.0.10',
|
|
access_ips.AccessIPs.v6_key: '2001:db8::9abc'}
|
|
res = self._test_create(params)
|
|
|
|
server = res['server']
|
|
self.assertNotIn("admin_password", server)
|
|
|
|
def test_create_server_with_invalid_access_ipv4(self):
|
|
params = {access_ips.AccessIPs.v4_key: '1.1.1.1.1.1'}
|
|
self.assertRaises(self.validation_error, self._test_create, params)
|
|
|
|
def test_create_server_with_access_ipv6(self):
|
|
params = {access_ips.AccessIPs.v6_key: '2001:db8::9abc'}
|
|
self._test_create(params)
|
|
|
|
def test_create_server_with_invalid_access_ipv6(self):
|
|
params = {access_ips.AccessIPs.v6_key: 'fe80:::::::'}
|
|
self.assertRaises(self.validation_error, self._test_create, params)
|
|
|
|
def test_update_server_with_access_ipv4(self):
|
|
params = {access_ips.AccessIPs.v4_key: '192.168.0.10'}
|
|
self._test_update(params)
|
|
|
|
def test_update_server_with_invalid_access_ipv4(self):
|
|
params = {access_ips.AccessIPs.v4_key: '1.1.1.1.1.1'}
|
|
self.assertRaises(self.validation_error, self._test_update, params)
|
|
|
|
def test_update_server_with_access_ipv6(self):
|
|
params = {access_ips.AccessIPs.v6_key: '2001:db8::9abc'}
|
|
self._test_update(params)
|
|
|
|
def test_update_server_with_invalid_access_ipv6(self):
|
|
params = {access_ips.AccessIPs.v6_key: 'fe80:::::::'}
|
|
self.assertRaises(self.validation_error, self._test_update, params)
|
|
|
|
def test_rebuild_server_with_access_ipv4(self):
|
|
params = {access_ips.AccessIPs.v4_key: '192.168.0.10'}
|
|
self._test_rebuild(params)
|
|
|
|
def test_rebuild_server_with_invalid_access_ipv4(self):
|
|
params = {access_ips.AccessIPs.v4_key: '1.1.1.1.1.1'}
|
|
self.assertRaises(self.validation_error, self._test_rebuild,
|
|
params)
|
|
|
|
def test_rebuild_server_with_access_ipv6(self):
|
|
params = {access_ips.AccessIPs.v6_key: '2001:db8::9abc'}
|
|
self._test_rebuild(params)
|
|
|
|
def test_rebuild_server_with_invalid_access_ipv6(self):
|
|
params = {access_ips.AccessIPs.v6_key: 'fe80:::::::'}
|
|
self.assertRaises(self.validation_error, self._test_rebuild,
|
|
params)
|
|
|
|
|
|
class AccessIPsExtAPIValidationTestV2(AccessIPsExtAPIValidationTestV21):
|
|
validation_error = webob.exc.HTTPBadRequest
|
|
|
|
def _set_up_controller(self):
|
|
self.ext_mgr = extensions_v20.ExtensionManager()
|
|
self.ext_mgr.extensions = {}
|
|
self.controller = servers_v20.Controller(self.ext_mgr)
|
|
|
|
def _verify_update_access_ip(self, res_dict, params):
|
|
for key, value in params.items():
|
|
value = value or ''
|
|
self.assertEqual(res_dict['server'][key], value)
|
|
|
|
# Note(gmann): Below tests are only valid for V2 as
|
|
# V2.1 has strong input validation and does not allow
|
|
# None or blank access ips.
|
|
def test_update_server_access_ipv4_none(self):
|
|
params = {access_ips.AccessIPs.v4_key: None}
|
|
self._test_update(params)
|
|
|
|
def test_update_server_access_ipv4_blank(self):
|
|
params = {access_ips.AccessIPs.v4_key: ''}
|
|
self._test_update(params)
|
|
|
|
def test_update_server_access_ipv6_none(self):
|
|
params = {access_ips.AccessIPs.v6_key: None}
|
|
self._test_update(params)
|
|
|
|
def test_update_server_access_ipv6_blank(self):
|
|
params = {access_ips.AccessIPs.v6_key: ''}
|
|
self._test_update(params)
|
|
|
|
|
|
class AccessIPsControllerTestV21(test.NoDBTestCase):
|
|
def setUp(self):
|
|
super(AccessIPsControllerTestV21, self).setUp()
|
|
self.controller = access_ips.AccessIPsController()
|
|
|
|
def _test_with_access_ips(self, func, kwargs={'id': 'fake'}):
|
|
req = wsgi.Request({'nova.context':
|
|
fakes.FakeRequestContext('fake_user', 'fake',
|
|
is_admin=True)})
|
|
instance = {'uuid': 'fake',
|
|
'access_ip_v4': '1.1.1.1',
|
|
'access_ip_v6': 'fe80::'}
|
|
req.cache_db_instance(instance)
|
|
resp_obj = wsgi.ResponseObject(
|
|
{"server": {'id': 'fake'}})
|
|
func(req, resp_obj, **kwargs)
|
|
self.assertEqual(resp_obj.obj['server'][access_ips.AccessIPs.v4_key],
|
|
'1.1.1.1')
|
|
self.assertEqual(resp_obj.obj['server'][access_ips.AccessIPs.v6_key],
|
|
'fe80::')
|
|
|
|
def _test_without_access_ips(self, func, kwargs={'id': 'fake'}):
|
|
req = wsgi.Request({'nova.context':
|
|
fakes.FakeRequestContext('fake_user', 'fake',
|
|
is_admin=True)})
|
|
instance = {'uuid': 'fake',
|
|
'access_ip_v4': None,
|
|
'access_ip_v6': None}
|
|
req.cache_db_instance(instance)
|
|
resp_obj = wsgi.ResponseObject(
|
|
{"server": {'id': 'fake'}})
|
|
func(req, resp_obj, **kwargs)
|
|
self.assertEqual(resp_obj.obj['server'][access_ips.AccessIPs.v4_key],
|
|
'')
|
|
self.assertEqual(resp_obj.obj['server'][access_ips.AccessIPs.v6_key],
|
|
'')
|
|
|
|
def test_show(self):
|
|
self._test_with_access_ips(self.controller.show)
|
|
|
|
def test_show_without_access_ips(self):
|
|
self._test_without_access_ips(self.controller.show)
|
|
|
|
def test_detail(self):
|
|
req = wsgi.Request({'nova.context':
|
|
fakes.FakeRequestContext('fake_user', 'fake',
|
|
is_admin=True)})
|
|
instance1 = {'uuid': 'fake1',
|
|
'access_ip_v4': '1.1.1.1',
|
|
'access_ip_v6': 'fe80::'}
|
|
instance2 = {'uuid': 'fake2',
|
|
'access_ip_v4': '1.1.1.2',
|
|
'access_ip_v6': 'fe81::'}
|
|
req.cache_db_instance(instance1)
|
|
req.cache_db_instance(instance2)
|
|
resp_obj = wsgi.ResponseObject(
|
|
{"servers": [{'id': 'fake1'}, {'id': 'fake2'}]})
|
|
self.controller.detail(req, resp_obj)
|
|
self.assertEqual(
|
|
resp_obj.obj['servers'][0][access_ips.AccessIPs.v4_key],
|
|
'1.1.1.1')
|
|
self.assertEqual(
|
|
resp_obj.obj['servers'][0][access_ips.AccessIPs.v6_key],
|
|
'fe80::')
|
|
self.assertEqual(
|
|
resp_obj.obj['servers'][1][access_ips.AccessIPs.v4_key],
|
|
'1.1.1.2')
|
|
self.assertEqual(
|
|
resp_obj.obj['servers'][1][access_ips.AccessIPs.v6_key],
|
|
'fe81::')
|
|
|
|
def test_detail_without_access_ips(self):
|
|
req = wsgi.Request({'nova.context':
|
|
fakes.FakeRequestContext('fake_user', 'fake',
|
|
is_admin=True)})
|
|
instance1 = {'uuid': 'fake1',
|
|
'access_ip_v4': None,
|
|
'access_ip_v6': None}
|
|
instance2 = {'uuid': 'fake2',
|
|
'access_ip_v4': None,
|
|
'access_ip_v6': None}
|
|
req.cache_db_instance(instance1)
|
|
req.cache_db_instance(instance2)
|
|
resp_obj = wsgi.ResponseObject(
|
|
{"servers": [{'id': 'fake1'}, {'id': 'fake2'}]})
|
|
self.controller.detail(req, resp_obj)
|
|
self.assertEqual(
|
|
resp_obj.obj['servers'][0][access_ips.AccessIPs.v4_key], '')
|
|
self.assertEqual(
|
|
resp_obj.obj['servers'][0][access_ips.AccessIPs.v6_key], '')
|
|
self.assertEqual(
|
|
resp_obj.obj['servers'][1][access_ips.AccessIPs.v4_key], '')
|
|
self.assertEqual(
|
|
resp_obj.obj['servers'][1][access_ips.AccessIPs.v6_key], '')
|
|
|
|
def test_update(self):
|
|
self._test_with_access_ips(self.controller.update, {'id': 'fake',
|
|
'body': {}})
|
|
|
|
def test_update_without_access_ips(self):
|
|
self._test_without_access_ips(self.controller.update, {'id': 'fake',
|
|
'body': {}})
|
|
|
|
def test_rebuild(self):
|
|
self._test_with_access_ips(self.controller.rebuild, {'id': 'fake',
|
|
'body': {}})
|
|
|
|
def test_rebuild_without_access_ips(self):
|
|
self._test_without_access_ips(self.controller.rebuild, {'id': 'fake',
|
|
'body': {}})
|