Merge "Role based resource access control - get executions"
This commit is contained in:
commit
93591469d9
@ -227,13 +227,14 @@ class ExecutionsController(rest.RestController):
|
|||||||
types.uniquelist, types.list, types.uniquelist,
|
types.uniquelist, types.list, types.uniquelist,
|
||||||
wtypes.text, types.uuid, wtypes.text, types.jsontype,
|
wtypes.text, types.uuid, wtypes.text, types.jsontype,
|
||||||
types.uuid, STATE_TYPES, wtypes.text, types.jsontype,
|
types.uuid, STATE_TYPES, wtypes.text, types.jsontype,
|
||||||
types.jsontype, wtypes.text, wtypes.text, bool)
|
types.jsontype, wtypes.text, wtypes.text, bool,
|
||||||
|
types.uuid, bool)
|
||||||
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
def get_all(self, marker=None, limit=None, sort_keys='created_at',
|
||||||
sort_dirs='asc', fields='', workflow_name=None,
|
sort_dirs='asc', fields='', workflow_name=None,
|
||||||
workflow_id=None, description=None, params=None,
|
workflow_id=None, description=None, params=None,
|
||||||
task_execution_id=None, state=None, state_info=None,
|
task_execution_id=None, state=None, state_info=None,
|
||||||
input=None, output=None, created_at=None, updated_at=None,
|
input=None, output=None, created_at=None, updated_at=None,
|
||||||
include_output=None):
|
include_output=None, project_id=None, all_projects=False):
|
||||||
"""Return all Executions.
|
"""Return all Executions.
|
||||||
|
|
||||||
:param marker: Optional. Pagination marker for large data sets.
|
:param marker: Optional. Pagination marker for large data sets.
|
||||||
@ -269,10 +270,17 @@ class ExecutionsController(rest.RestController):
|
|||||||
:param updated_at: Optional. Keep only resources with specific latest
|
:param updated_at: Optional. Keep only resources with specific latest
|
||||||
update time and date.
|
update time and date.
|
||||||
:param include_output: Optional. Include the output for all executions
|
:param include_output: Optional. Include the output for all executions
|
||||||
in the list
|
in the list.
|
||||||
|
:param project_id: Optional. Only get exectuions belong to the project.
|
||||||
|
Admin required.
|
||||||
|
:param all_projects: Optional. Get resources of all projects. Admin
|
||||||
|
required.
|
||||||
"""
|
"""
|
||||||
acl.enforce('executions:list', context.ctx())
|
acl.enforce('executions:list', context.ctx())
|
||||||
|
|
||||||
|
if all_projects or project_id:
|
||||||
|
acl.enforce('executions:list:all_projects', context.ctx())
|
||||||
|
|
||||||
filters = filter_utils.create_filters_from_request_params(
|
filters = filter_utils.create_filters_from_request_params(
|
||||||
created_at=created_at,
|
created_at=created_at,
|
||||||
workflow_name=workflow_name,
|
workflow_name=workflow_name,
|
||||||
@ -284,13 +292,14 @@ class ExecutionsController(rest.RestController):
|
|||||||
input=input,
|
input=input,
|
||||||
output=output,
|
output=output,
|
||||||
updated_at=updated_at,
|
updated_at=updated_at,
|
||||||
description=description
|
description=description,
|
||||||
|
project_id=project_id
|
||||||
)
|
)
|
||||||
|
|
||||||
LOG.info(
|
LOG.info(
|
||||||
"Fetch executions. marker=%s, limit=%s, sort_keys=%s, "
|
"Fetch executions. marker=%s, limit=%s, sort_keys=%s, "
|
||||||
"sort_dirs=%s, filters=%s", marker, limit, sort_keys, sort_dirs,
|
"sort_dirs=%s, filters=%s, all_projects=%s", marker, limit,
|
||||||
filters
|
sort_keys, sort_dirs, filters, all_projects
|
||||||
)
|
)
|
||||||
|
|
||||||
if include_output:
|
if include_output:
|
||||||
@ -309,5 +318,6 @@ class ExecutionsController(rest.RestController):
|
|||||||
sort_keys=sort_keys,
|
sort_keys=sort_keys,
|
||||||
sort_dirs=sort_dirs,
|
sort_dirs=sort_dirs,
|
||||||
fields=fields,
|
fields=fields,
|
||||||
|
all_projects=all_projects,
|
||||||
**filters
|
**filters
|
||||||
)
|
)
|
||||||
|
@ -22,6 +22,7 @@ import json
|
|||||||
import mock
|
import mock
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
import oslo_messaging
|
import oslo_messaging
|
||||||
|
from oslo_utils import uuidutils
|
||||||
from webtest import app as webtest_app
|
from webtest import app as webtest_app
|
||||||
|
|
||||||
from mistral.api.controllers.v2 import execution
|
from mistral.api.controllers.v2 import execution
|
||||||
@ -31,10 +32,10 @@ from mistral.db.v2.sqlalchemy import models
|
|||||||
from mistral.engine.rpc_backend import rpc
|
from mistral.engine.rpc_backend import rpc
|
||||||
from mistral import exceptions as exc
|
from mistral import exceptions as exc
|
||||||
from mistral.tests.unit.api import base
|
from mistral.tests.unit.api import base
|
||||||
|
from mistral.tests.unit import base as unit_base
|
||||||
from mistral import utils
|
from mistral import utils
|
||||||
from mistral.utils import rest_utils
|
from mistral.utils import rest_utils
|
||||||
from mistral.workflow import states
|
from mistral.workflow import states
|
||||||
from oslo_utils import uuidutils
|
|
||||||
|
|
||||||
# This line is needed for correct initialization of messaging config.
|
# This line is needed for correct initialization of messaging config.
|
||||||
oslo_messaging.get_transport(cfg.CONF)
|
oslo_messaging.get_transport(cfg.CONF)
|
||||||
@ -630,3 +631,40 @@ class TestExecutionsController(base.APITest):
|
|||||||
resource_function = kwargs['resource_function']
|
resource_function = kwargs['resource_function']
|
||||||
|
|
||||||
self.assertIsNone(resource_function)
|
self.assertIsNone(resource_function)
|
||||||
|
|
||||||
|
@mock.patch('mistral.db.v2.api.get_workflow_executions')
|
||||||
|
@mock.patch('mistral.context.context_from_headers_and_env')
|
||||||
|
def test_get_all_projects_admin(self, mock_context, mock_get_execs):
|
||||||
|
admin_ctx = unit_base.get_context(admin=True)
|
||||||
|
mock_context.return_value = admin_ctx
|
||||||
|
|
||||||
|
resp = self.app.get('/v2/executions?all_projects=true')
|
||||||
|
|
||||||
|
self.assertEqual(200, resp.status_int)
|
||||||
|
|
||||||
|
self.assertTrue(mock_get_execs.call_args[1].get('insecure', False))
|
||||||
|
|
||||||
|
def test_get_all_projects_normal_user(self):
|
||||||
|
resp = self.app.get(
|
||||||
|
'/v2/executions?all_projects=true',
|
||||||
|
expect_errors=True
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(403, resp.status_int)
|
||||||
|
|
||||||
|
@mock.patch('mistral.db.v2.api.get_workflow_executions')
|
||||||
|
@mock.patch('mistral.context.context_from_headers_and_env')
|
||||||
|
def test_get_all_filter_by_project_id(self, mock_context, mock_get_execs):
|
||||||
|
admin_ctx = unit_base.get_context(admin=True)
|
||||||
|
mock_context.return_value = admin_ctx
|
||||||
|
|
||||||
|
fake_project_id = uuidutils.generate_uuid()
|
||||||
|
|
||||||
|
resp = self.app.get('/v2/executions?project_id=%s' % fake_project_id)
|
||||||
|
|
||||||
|
self.assertEqual(200, resp.status_int)
|
||||||
|
|
||||||
|
self.assertTrue(mock_get_execs.call_args[1].get('insecure', False))
|
||||||
|
self.assertTrue(
|
||||||
|
mock_get_execs.call_args[1].get('project_id', fake_project_id)
|
||||||
|
)
|
||||||
|
@ -44,6 +44,7 @@ policy_data = """{
|
|||||||
"executions:delete": "rule:admin_or_owner",
|
"executions:delete": "rule:admin_or_owner",
|
||||||
"executions:get": "rule:admin_or_owner",
|
"executions:get": "rule:admin_or_owner",
|
||||||
"executions:list": "rule:admin_or_owner",
|
"executions:list": "rule:admin_or_owner",
|
||||||
|
"executions:list:all_projects": "rule:admin_only",
|
||||||
"executions:update": "rule:admin_or_owner",
|
"executions:update": "rule:admin_or_owner",
|
||||||
|
|
||||||
"members:create": "rule:admin_or_owner",
|
"members:create": "rule:admin_or_owner",
|
||||||
|
Loading…
Reference in New Issue
Block a user