Merge "Allow authorization by user_id for server rebuild"

This commit is contained in:
Jenkins 2016-08-11 20:36:16 +00:00 committed by Gerrit Code Review
commit 0bd28f9cbf
4 changed files with 86 additions and 13 deletions

View File

@ -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',

View File

@ -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'

View File

@ -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,

View File

@ -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"}