Merge "Allow authorization by user_id for server rebuild"
This commit is contained in:
commit
0bd28f9cbf
@ -912,9 +912,10 @@ class ServersController(wsgi.Controller):
|
||||
password = self._get_server_admin_password(rebuild_dict)
|
||||
|
||||
context = req.environ['nova.context']
|
||||
context.can(server_policies.SERVERS % 'rebuild')
|
||||
instance = self._get_server(context, req, id)
|
||||
|
||||
context.can(server_policies.SERVERS % 'rebuild',
|
||||
target={'user_id': instance.user_id,
|
||||
'project_id': instance.project_id})
|
||||
attr_map = {
|
||||
'name': 'display_name',
|
||||
'description': 'display_description',
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
import datetime
|
||||
|
||||
import mock
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
from nova.api.openstack import compute
|
||||
@ -353,11 +354,20 @@ class DiskConfigTestCaseV21(test.TestCase):
|
||||
self.assertEqual(jsonutils.loads(expected_msg),
|
||||
jsonutils.loads(res.body))
|
||||
|
||||
def _test_rebuild_server_disk_config(self, uuid, disk_config):
|
||||
@mock.patch('nova.api.openstack.common.get_instance')
|
||||
def _test_rebuild_server_disk_config(self, uuid, disk_config,
|
||||
get_instance_mock):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/fake/servers/%s/action' % uuid)
|
||||
req.method = 'POST'
|
||||
req.content_type = 'application/json'
|
||||
auto_disk_config = (disk_config == 'AUTO')
|
||||
instance = fakes.stub_instance_obj(
|
||||
req.environ['nova.context'],
|
||||
project_id=req.environ['nova.context'].project_id,
|
||||
user_id=req.environ['nova.context'].user_id,
|
||||
auto_disk_config=auto_disk_config)
|
||||
get_instance_mock.return_value = instance
|
||||
body = {"rebuild": {
|
||||
'imageRef': 'cedef40a-ed67-4d10-800e-17455edce175',
|
||||
API_DISK_CONFIG: disk_config
|
||||
@ -397,11 +407,18 @@ class DiskConfigTestCaseV21(test.TestCase):
|
||||
server_dict = jsonutils.loads(res.body)['server']
|
||||
self.assertDiskConfig(server_dict, 'AUTO')
|
||||
|
||||
def test_rebuild_server_with_auto_disk_config(self):
|
||||
@mock.patch('nova.api.openstack.common.get_instance')
|
||||
def test_rebuild_server_with_auto_disk_config(self, get_instance_mock):
|
||||
req = fakes.HTTPRequest.blank(
|
||||
'/fake/servers/%s/action' % AUTO_INSTANCE_UUID)
|
||||
req.method = 'POST'
|
||||
req.content_type = 'application/json'
|
||||
instance = fakes.stub_instance_obj(
|
||||
req.environ['nova.context'],
|
||||
project_id=req.environ['nova.context'].project_id,
|
||||
user_id=req.environ['nova.context'].user_id,
|
||||
auto_disk_config=True)
|
||||
get_instance_mock.return_value = instance
|
||||
body = {"rebuild": {
|
||||
'imageRef': 'cedef40a-ed67-4d10-800e-17455edce175',
|
||||
API_DISK_CONFIG: 'AUTO'
|
||||
|
@ -112,12 +112,14 @@ class ServerActionsControllerTestV21(test.TestCase):
|
||||
compute_api.API.rebuild(context, mox.IgnoreArg(), image_ref,
|
||||
mox.IgnoreArg())
|
||||
|
||||
def _stub_instance_get(self, uuid=None):
|
||||
def _stub_instance_get(self, context, uuid=None):
|
||||
self.mox.StubOutWithMock(compute_api.API, 'get')
|
||||
if uuid is None:
|
||||
uuid = uuidutils.generate_uuid()
|
||||
instance = fake_instance.fake_db_instance(
|
||||
id=1, uuid=uuid, vm_state=vm_states.ACTIVE, task_state=None)
|
||||
id=1, uuid=uuid, vm_state=vm_states.ACTIVE, task_state=None,
|
||||
project_id=context.project_id,
|
||||
user_id=context.user_id)
|
||||
instance = objects.Instance._from_db_object(
|
||||
self.context, objects.Instance(), instance)
|
||||
|
||||
@ -134,7 +136,7 @@ class ServerActionsControllerTestV21(test.TestCase):
|
||||
if compute_api_args_map is None:
|
||||
compute_api_args_map = {}
|
||||
|
||||
instance = self._stub_instance_get()
|
||||
instance = self._stub_instance_get(self.req.environ['nova.context'])
|
||||
args, kwargs = compute_api_args_map.get(action, ((), {}))
|
||||
|
||||
getattr(compute_api.API, method)(self.context, instance,
|
||||
|
@ -1579,19 +1579,27 @@ class ServersControllerRebuildInstanceTest(ControllerTest):
|
||||
|
||||
def setUp(self):
|
||||
super(ServersControllerRebuildInstanceTest, self).setUp()
|
||||
self.req = fakes.HTTPRequest.blank('/fake/servers/a/action')
|
||||
self.req.method = 'POST'
|
||||
self.req.headers["content-type"] = "application/json"
|
||||
self.req_user_id = self.req.environ['nova.context'].user_id
|
||||
self.req_project_id = self.req.environ['nova.context'].project_id
|
||||
|
||||
def fake_get(ctrl, ctxt, uuid):
|
||||
if uuid == 'test_inst':
|
||||
raise webob.exc.HTTPNotFound(explanation='fakeout')
|
||||
return fakes.stub_instance_obj(None,
|
||||
vm_state=vm_states.ACTIVE,
|
||||
project_id='fake')
|
||||
project_id=self.req_project_id,
|
||||
user_id=self.req_user_id)
|
||||
|
||||
self.useFixture(
|
||||
fixtures.MonkeyPatch('nova.api.openstack.compute.servers.'
|
||||
'ServersController._get_instance',
|
||||
fake_get))
|
||||
fake_get = fakes.fake_compute_get(vm_state=vm_states.ACTIVE)
|
||||
fake_get = fakes.fake_compute_get(vm_state=vm_states.ACTIVE,
|
||||
project_id=self.req_project_id,
|
||||
user_id=self.req_user_id)
|
||||
self.stubs.Set(compute_api.API, 'get',
|
||||
lambda api, *a, **k: fake_get(*a, **k))
|
||||
|
||||
@ -1604,9 +1612,6 @@ class ServersControllerRebuildInstanceTest(ControllerTest):
|
||||
},
|
||||
},
|
||||
}
|
||||
self.req = fakes.HTTPRequest.blank('/fake/servers/a/action')
|
||||
self.req.method = 'POST'
|
||||
self.req.headers["content-type"] = "application/json"
|
||||
|
||||
def test_rebuild_server_with_image_not_uuid(self):
|
||||
self.body['rebuild']['imageRef'] = 'not-uuid'
|
||||
@ -1894,7 +1899,9 @@ class ServersControllerRebuildTestV219(ServersControllerRebuildInstanceTest):
|
||||
|
||||
def _rebuild_server(self, set_desc, desc):
|
||||
fake_get = fakes.fake_compute_get(vm_state=vm_states.ACTIVE,
|
||||
display_description=desc)
|
||||
display_description=desc,
|
||||
project_id=self.req_project_id,
|
||||
user_id=self.req_user_id)
|
||||
self.stubs.Set(compute_api.API, 'get',
|
||||
lambda api, *a, **k: fake_get(*a, **k))
|
||||
|
||||
@ -4297,6 +4304,52 @@ class ServersPolicyEnforcementV21(test.NoDBTestCase):
|
||||
rule, rule_name, self.controller._resize, self.req,
|
||||
FAKE_UUID, flavor_id)
|
||||
|
||||
@mock.patch('nova.api.openstack.common.get_instance')
|
||||
def test_rebuild_policy_failed(self, get_instance_mock):
|
||||
get_instance_mock.return_value = (
|
||||
fake_instance.fake_instance_obj(self.req.environ['nova.context']))
|
||||
rule_name = "os_compute_api:servers:rebuild"
|
||||
rule = {rule_name: "project:non_fake"}
|
||||
body = {'rebuild': {'imageRef': self.image_uuid}}
|
||||
self._common_policy_check(
|
||||
rule, rule_name, self.controller._action_rebuild,
|
||||
self.req, FAKE_UUID, body=body)
|
||||
|
||||
@mock.patch('nova.api.openstack.common.get_instance')
|
||||
def test_rebuild_overridden_policy_failed_with_other_user_in_same_project(
|
||||
self, get_instance_mock):
|
||||
get_instance_mock.return_value = (
|
||||
fake_instance.fake_instance_obj(self.req.environ['nova.context']))
|
||||
rule_name = "os_compute_api:servers:rebuild"
|
||||
rule = {rule_name: "user_id:%(user_id)s"}
|
||||
body = {'rebuild': {'imageRef': self.image_uuid}}
|
||||
# Change the user_id in request context.
|
||||
self.req.environ['nova.context'].user_id = 'other-user'
|
||||
self._common_policy_check(
|
||||
rule, rule_name, self.controller._action_rebuild,
|
||||
self.req, FAKE_UUID, body=body)
|
||||
|
||||
@mock.patch('nova.api.openstack.compute.views.servers.ViewBuilder.show')
|
||||
@mock.patch('nova.compute.api.API.rebuild')
|
||||
@mock.patch('nova.api.openstack.common.get_instance')
|
||||
def test_rebuild_overridden_policy_pass_with_same_user(self,
|
||||
get_instance_mock,
|
||||
rebuild_mock,
|
||||
view_show_mock):
|
||||
instance = fake_instance.fake_instance_obj(
|
||||
self.req.environ['nova.context'],
|
||||
user_id=self.req.environ['nova.context'].user_id)
|
||||
get_instance_mock.return_value = instance
|
||||
rule_name = "os_compute_api:servers:rebuild"
|
||||
self.policy.set_rules({rule_name: "user_id:%(user_id)s"})
|
||||
body = {'rebuild': {'imageRef': self.image_uuid,
|
||||
'adminPass': 'dumpy_password'}}
|
||||
self.controller._action_rebuild(self.req, fakes.FAKE_UUID, body=body)
|
||||
rebuild_mock.assert_called_once_with(self.req.environ['nova.context'],
|
||||
instance,
|
||||
self.image_uuid,
|
||||
'dumpy_password')
|
||||
|
||||
def test_create_image_policy_failed(self):
|
||||
rule_name = "os_compute_api:servers:create_image"
|
||||
rule = {rule_name: "project:non_fake"}
|
||||
|
Loading…
Reference in New Issue
Block a user