Expand policies for admin_actions extension

Fixes bug 924417

Change-Id: Ibf62e8e824753dff43e0e86cb9d320086c2c753b
This commit is contained in:
Brian Waldon
2012-01-31 22:56:37 -08:00
parent 79746bbe52
commit a2d9645703
4 changed files with 38 additions and 34 deletions

View File

@@ -12,6 +12,17 @@
"admin_api": [["role:admin"]],
"compute_extension:accounts": [["rule:admin_api"]],
"compute_extension:admin_actions": [["rule:admin_api"]],
"compute_extension:admin_actions:pause": [["rule:admin_or_owner"]],
"compute_extension:admin_actions:unpause": [["rule:admin_or_owner"]],
"compute_extension:admin_actions:suspend": [["rule:admin_or_owner"]],
"compute_extension:admin_actions:resume": [["rule:admin_or_owner"]],
"compute_extension:admin_actions:lock": [["rule:admin_api"]],
"compute_extension:admin_actions:unlock": [["rule:admin_api"]],
"compute_extension:admin_actions:resetNetwork": [["rule:admin_api"]],
"compute_extension:admin_actions:injectNetworkInfo": [["rule:admin_api"]],
"compute_extension:admin_actions:createBackup": [["rule:admin_or_owner"]],
"compute_extension:admin_actions:migrateLive": [["rule:admin_api"]],
"compute_extension:admin_actions:migrate": [["rule:admin_api"]],
"compute_extension:aggregates": [["rule:admin_api"]],
"compute_extension:certificates": [],
"compute_extension:cloudpipe": [],

View File

@@ -30,7 +30,11 @@ from nova.scheduler import api as scheduler_api
FLAGS = flags.FLAGS
LOG = logging.getLogger("nova.api.openstack.compute.contrib.admin_actions")
authorize = extensions.extension_authorizer('compute', 'admin_actions')
def authorize(context, action_name):
action = 'admin_actions:%s' % action_name
extensions.extension_authorizer('compute', action)(context)
class AdminActionsController(wsgi.Controller):
@@ -46,7 +50,7 @@ class AdminActionsController(wsgi.Controller):
def _pause(self, req, id, body):
"""Permit Admins to pause the server"""
ctxt = req.environ['nova.context']
authorize(ctxt)
authorize(ctxt, 'pause')
try:
server = self.compute_api.get(ctxt, id)
self.compute_api.pause(ctxt, server)
@@ -65,7 +69,7 @@ class AdminActionsController(wsgi.Controller):
def _unpause(self, req, id, body):
"""Permit Admins to unpause the server"""
ctxt = req.environ['nova.context']
authorize(ctxt)
authorize(ctxt, 'unpause')
try:
server = self.compute_api.get(ctxt, id)
self.compute_api.unpause(ctxt, server)
@@ -84,7 +88,7 @@ class AdminActionsController(wsgi.Controller):
def _suspend(self, req, id, body):
"""Permit admins to suspend the server"""
context = req.environ['nova.context']
authorize(context)
authorize(context, 'suspend')
try:
server = self.compute_api.get(context, id)
self.compute_api.suspend(context, server)
@@ -103,7 +107,7 @@ class AdminActionsController(wsgi.Controller):
def _resume(self, req, id, body):
"""Permit admins to resume the server from suspend"""
context = req.environ['nova.context']
authorize(context)
authorize(context, 'resume')
try:
server = self.compute_api.get(context, id)
self.compute_api.resume(context, server)
@@ -122,7 +126,7 @@ class AdminActionsController(wsgi.Controller):
def _migrate(self, req, id, body):
"""Permit admins to migrate a server to a new host"""
context = req.environ['nova.context']
authorize(context)
authorize(context, 'migrate')
try:
instance = self.compute_api.get(context, id)
self.compute_api.resize(req.environ['nova.context'], instance)
@@ -140,7 +144,7 @@ class AdminActionsController(wsgi.Controller):
def _reset_network(self, req, id, body):
"""Permit admins to reset networking on an server"""
context = req.environ['nova.context']
authorize(context)
authorize(context, 'resetNetwork')
try:
instance = self.compute_api.get(context, id)
self.compute_api.reset_network(context, instance)
@@ -156,7 +160,7 @@ class AdminActionsController(wsgi.Controller):
def _inject_network_info(self, req, id, body):
"""Permit admins to inject network info into a server"""
context = req.environ['nova.context']
authorize(context)
authorize(context, 'injectNetworkInfo')
try:
instance = self.compute_api.get(context, id)
self.compute_api.inject_network_info(context, instance)
@@ -174,7 +178,7 @@ class AdminActionsController(wsgi.Controller):
def _lock(self, req, id, body):
"""Permit admins to lock a server"""
context = req.environ['nova.context']
authorize(context)
authorize(context, 'lock')
try:
instance = self.compute_api.get(context, id)
self.compute_api.lock(context, instance)
@@ -192,7 +196,7 @@ class AdminActionsController(wsgi.Controller):
def _unlock(self, req, id, body):
"""Permit admins to lock a server"""
context = req.environ['nova.context']
authorize(context)
authorize(context, 'unlock')
try:
instance = self.compute_api.get(context, id)
self.compute_api.unlock(context, instance)
@@ -217,7 +221,7 @@ class AdminActionsController(wsgi.Controller):
"""
context = req.environ["nova.context"]
authorize(context)
authorize(context, 'createBackup')
try:
entity = body["createBackup"]
@@ -278,11 +282,7 @@ class AdminActionsController(wsgi.Controller):
def _migrate_live(self, req, id, body):
"""Permit admins to (live) migrate a server to a new host"""
context = req.environ["nova.context"]
# Expected to use AuthMiddleware.
# Otherwise, non-admin user can use live migration
if not context.is_admin:
msg = _("Live migration is admin only functionality")
raise exc.HTTPForbidden(explanation=msg)
authorize(context, 'migrateLive')
try:
block_migration = body["os-migrateLive"]["block_migration"]

View File

@@ -18,8 +18,6 @@ import json
import webob
from nova.api.openstack import compute as compute_api
from nova.api.openstack.compute import extensions
from nova.api.openstack import wsgi
from nova import compute
from nova import context
from nova import exception
@@ -138,21 +136,6 @@ class AdminActionsTest(test.TestCase):
res = req.get_response(app)
self.assertEqual(res.status_int, 202)
def test_migrate_live_forbidden(self):
ctxt = context.get_admin_context()
ctxt.user_id = 'fake'
ctxt.project_id = 'fake'
ctxt.is_admin = False
app = fakes.wsgi_app(fake_auth_context=ctxt)
req = webob.Request.blank('/v2/fake/servers/%s/action' % self.UUID)
req.method = 'POST'
req.body = json.dumps({'os-migrateLive': {'host': 'hostname',
'block_migration': False,
'disk_over_commit': False}})
req.content_type = 'application/json'
res = req.get_response(app)
self.assertEqual(res.status_int, 403)
def test_migrate_live_missing_dict_param(self):
ctxt = context.get_admin_context()
ctxt.user_id = 'fake'

View File

@@ -70,7 +70,17 @@
"compute_extension:accounts": [],
"compute_extension:admin_actions": [],
"compute_extension:admin_actions:pause": [],
"compute_extension:admin_actions:unpause": [],
"compute_extension:admin_actions:suspend": [],
"compute_extension:admin_actions:resume": [],
"compute_extension:admin_actions:lock": [],
"compute_extension:admin_actions:unlock": [],
"compute_extension:admin_actions:resetNetwork": [],
"compute_extension:admin_actions:injectNetworkInfo": [],
"compute_extension:admin_actions:createBackup": [],
"compute_extension:admin_actions:migrateLive": [],
"compute_extension:admin_actions:migrate": [],
"compute_extension:aggregates": [],
"compute_extension:certificates": [],
"compute_extension:cloudpipe": [],