view hypervisor details rest api should be allowed for non-admins

The current call to show hypervisor is broken and expects the
user to have admin privileges always.It does not allow non-
admin users to view hypervisor details. This should be
controlled based on the rule defined in the policy.json rather
than have the permissions mandated programmatically. This bug
is caused due to regression and was working earlier.So the
changes proposed here is merely retaining the older behavior.
To ensure that this works as before, the context passed to the
db api layer is elevated so that it passes the requires_admin_
context check that is present in the db layer.

Change-Id: I50437788aac72608998cf9c24d4d562b1ff20301
Closes-Bug: 1447084
(cherry picked from commit 6be11856c6)
This commit is contained in:
Divya 2015-04-23 09:38:52 +02:00
parent a0efbbcfc7
commit cbf606bdba
3 changed files with 29 additions and 4 deletions

View File

@ -113,7 +113,8 @@ class HypervisorsController(object):
except (ValueError, exception.ComputeHostNotFound):
msg = _("Hypervisor with ID '%s' could not be found.") % id
raise webob.exc.HTTPNotFound(explanation=msg)
service = self.host_api.service_get_by_compute_host(context, hyp.host)
service = self.host_api.service_get_by_compute_host(
context.elevated(), hyp.host)
return dict(hypervisor=self._view_hypervisor(hyp, service, True))
def uptime(self, req, id):

View File

@ -109,7 +109,8 @@ class HypervisorsController(wsgi.Controller):
except (ValueError, exception.ComputeHostNotFound):
msg = _("Hypervisor with ID '%s' could not be found.") % id
raise webob.exc.HTTPNotFound(explanation=msg)
service = self.host_api.service_get_by_compute_host(context, hyp.host)
service = self.host_api.service_get_by_compute_host(
context.elevated(), hyp.host)
return dict(hypervisor=self._view_hypervisor(hyp, service, True))
@extensions.expected_errors((404, 501))

View File

@ -13,8 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
import contextlib
import copy
import mock
import netaddr
from webob import exc
@ -195,7 +195,7 @@ class HypervisorsTestV21(test.NoDBTestCase):
def setUp(self):
super(HypervisorsTestV21, self).setUp()
self._set_up_controller()
self.rule_hyp_show = "os_compute_api:os-hypervisors"
self.stubs.Set(self.controller.host_api, 'compute_node_get_all',
fake_compute_node_get_all)
self.stubs.Set(self.controller.host_api, 'service_get_by_compute_host',
@ -271,6 +271,25 @@ class HypervisorsTestV21(test.NoDBTestCase):
self.assertEqual(result, dict(hypervisor=self.DETAIL_HYPERS_DICTS[0]))
def test_show_non_admin_elevated(self):
non_adm = "is_admin:False"
self.policy.set_rules({self.rule_hyp_show: non_adm})
req = self._get_request(False)
ctxt = req.environ['nova.context']
elevated_context = ctxt.elevated()
with contextlib.nested(
mock.patch.object(ctxt, 'elevated',
return_value=elevated_context),
mock.patch.object(self.controller.host_api,
'service_get_by_compute_host')
) as (
elevated_mock,
mock_service
):
self.controller.show(req, self.TEST_HYPERS_OBJ[0].id)
mock_service.assert_called_once_with(elevated_context,
self.TEST_HYPERS_OBJ[0].host)
def test_show_non_admin(self):
req = self._get_request(False)
self.assertRaises(exception.PolicyNotAuthorized,
@ -435,6 +454,10 @@ class HypervisorsTestV2(HypervisorsTestV21):
del INDEX_HYPER_DICTS[0]['status']
del INDEX_HYPER_DICTS[1]['status']
def setUp(self):
super(HypervisorsTestV2, self).setUp()
self.rule_hyp_show = "compute_extension:hypervisors"
def _set_up_controller(self):
self.context = context.get_admin_context()
self.ext_mgr = extensions.ExtensionManager()