Add project parameter to filters resource with admin role

Currently, an user admin can list all profiles, clusters,.. and I
can using name, limit, marker when list. But, when I have so many
clusters, profiles, ... I can't list them only in a project.

So, I hope this patch can resolve above problem.

Change-Id: I76bf03478938b2b42996898a9538aa40cf2643ac
This commit is contained in:
Bo Tran 2020-03-27 21:09:25 +07:00
parent 5552e197b3
commit fce8635d4e
19 changed files with 54 additions and 5 deletions

View File

@ -130,3 +130,7 @@ it can be used by both users and developers.
1.14
----
- Added ``cluster_id`` to filters result returned action APIs.
1.15
----
- Added ``project`` to filters result returned action APIs.

View File

@ -72,6 +72,7 @@ class ActionController(wsgi.Controller):
consts.ACTION_TARGET: 'mixed',
consts.ACTION_ACTION: 'mixed',
consts.ACTION_STATUS: 'mixed',
consts.ACTION_PROJECT: 'mixed',
consts.PARAM_LIMIT: 'single',
consts.PARAM_MARKER: 'single',
consts.PARAM_SORT: 'single',

View File

@ -45,6 +45,7 @@ class ClusterController(wsgi.Controller):
whitelist = {
consts.CLUSTER_NAME: 'mixed',
consts.CLUSTER_STATUS: 'mixed',
consts.CLUSTER_PROJECT: 'mixed',
consts.PARAM_LIMIT: 'single',
consts.PARAM_MARKER: 'single',
consts.PARAM_SORT: 'single',

View File

@ -38,6 +38,7 @@ class EventController(wsgi.Controller):
consts.EVENT_CLUSTER_ID: 'mixed',
consts.EVENT_ACTION: 'mixed',
consts.EVENT_LEVEL: 'mixed',
consts.EVENT_PROJECT: 'mixed',
consts.PARAM_LIMIT: 'single',
consts.PARAM_MARKER: 'single',
consts.PARAM_SORT: 'single',

View File

@ -48,6 +48,7 @@ class NodeController(wsgi.Controller):
consts.NODE_CLUSTER_ID: 'single',
consts.NODE_NAME: 'mixed',
consts.NODE_STATUS: 'mixed',
consts.NODE_PROJECT: 'mixed',
consts.PARAM_LIMIT: 'single',
consts.PARAM_MARKER: 'single',
consts.PARAM_SORT: 'single',

View File

@ -35,6 +35,7 @@ class PolicyController(wsgi.Controller):
whitelist = {
consts.POLICY_NAME: 'mixed',
consts.POLICY_TYPE: 'mixed',
consts.POLICY_PROJECT: 'mixed',
consts.PARAM_LIMIT: 'single',
consts.PARAM_MARKER: 'single',
consts.PARAM_SORT: 'single',

View File

@ -35,6 +35,7 @@ class ProfileController(wsgi.Controller):
whitelist = {
consts.PROFILE_NAME: 'mixed',
consts.PROFILE_TYPE: 'mixed',
consts.PROFILE_PROJECT: 'single',
consts.PARAM_LIMIT: 'single',
consts.PARAM_MARKER: 'single',
consts.PARAM_SORT: 'single',

View File

@ -35,6 +35,7 @@ class ReceiverController(wsgi.Controller):
consts.RECEIVER_CLUSTER_ID: 'mixed',
consts.RECEIVER_USER_ID: 'mixed',
consts.RECEIVER_ACTION: 'mixed',
consts.RECEIVER_PROJECT: 'mixed',
consts.PARAM_LIMIT: 'single',
consts.PARAM_MARKER: 'single',
consts.PARAM_SORT: 'single',

View File

@ -23,7 +23,7 @@ class VersionController(object):
# This includes any semantic changes which may not affect the input or
# output formats or even originate in the API code layer.
_MIN_API_VERSION = "1.0"
_MAX_API_VERSION = "1.14"
_MAX_API_VERSION = "1.15"
DEFAULT_API_VERSION = _MIN_API_VERSION

View File

@ -139,10 +139,12 @@ NODE_ATTRS = (
NODE_INDEX, NODE_NAME, NODE_PROFILE_ID, NODE_CLUSTER_ID,
NODE_INIT_AT, NODE_CREATED_AT, NODE_UPDATED_AT,
NODE_STATUS, NODE_ROLE, NODE_METADATA, NODE_TAINTED,
NODE_PROJECT,
) = (
'index', 'name', 'profile_id', 'cluster_id',
'init_at', 'created_at', 'updated_at',
'status', 'role', 'metadata', 'tainted',
'project',
)
NODE_SORT_KEYS = [
@ -160,10 +162,12 @@ PROFILE_ATTRS = (
PROFILE_ID, PROFILE_NAME, PROFILE_TYPE,
PROFILE_CREATED_AT, PROFILE_UPDATED_AT,
PROFILE_SPEC, PROFILE_METADATA, PROFILE_CONTEXT,
PROFILE_PROJECT,
) = (
'id', 'name', 'type',
'created_at', 'updated_at',
'spec', 'metadata', 'context',
'project',
)
PROFILE_SORT_KEYS = [
@ -172,10 +176,10 @@ PROFILE_SORT_KEYS = [
POLICY_ATTRS = (
POLICY_ID, POLICY_NAME, POLICY_TYPE, POLICY_SPEC,
POLICY_CREATED_AT, POLICY_UPDATED_AT,
POLICY_CREATED_AT, POLICY_UPDATED_AT, POLICY_PROJECT
) = (
'id', 'name', 'type', 'spec',
'created_at', 'updated_at',
'created_at', 'updated_at', 'project',
)
POLICY_SORT_KEYS = [
@ -198,11 +202,11 @@ CLUSTER_POLICY_SORT_KEYS = [
EVENT_ATTRS = (
EVENT_TIMESTAMP, EVENT_OBJ_ID, EVENT_OBJ_NAME, EVENT_OBJ_TYPE,
EVENT_USER, EVENT_ACTION, EVENT_STATUS, EVENT_STATUS_REASON,
EVENT_LEVEL, EVENT_CLUSTER_ID,
EVENT_LEVEL, EVENT_CLUSTER_ID, EVENT_PROJECT
) = (
'timestamp', 'oid', 'oname', 'otype',
'user', 'action', 'status', 'status_reason',
'level', 'cluster_id',
'level', 'cluster_id', 'project',
)
EVENT_SORT_KEYS = [
@ -216,12 +220,14 @@ ACTION_ATTRS = (
ACTION_TIMEOUT, ACTION_STATUS, ACTION_STATUS_REASON,
ACTION_INPUTS, ACTION_OUTPUTS, ACTION_DEPENDS_ON, ACTION_DEPENDED_BY,
ACTION_CREATED_AT, ACTION_UPDATED_AT,
ACTION_PROJECT,
) = (
'name', 'cluster_id', 'target', 'action', 'cause',
'interval', 'start_time', 'end_time',
'timeout', 'status', 'status_reason',
'inputs', 'outputs', 'depends_on', 'depended_by',
'created_at', 'updated_at',
'project',
)
ACTION_SORT_KEYS = [
@ -239,10 +245,12 @@ RECEIVER_ATTRS = (
RECEIVER_NAME, RECEIVER_TYPE, RECEIVER_CLUSTER, RECEIVER_CLUSTER_ID,
RECEIVER_CREATED_AT, RECEIVER_UPDATED_AT, RECEIVER_USER_ID,
RECEIVER_ACTOR, RECEIVER_ACTION, RECEIVER_PARAMS, RECEIVER_CHANNEL,
RECEIVER_PROJECT,
) = (
'name', 'type', 'cluster', 'cluster_id',
'created_at', 'updated_at', 'user',
'actor', 'action', 'params', 'channel',
'project',
)
RECEIVER_SORT_KEYS = [

View File

@ -236,6 +236,9 @@ class ConductorService(service.Service):
filters['name'] = req.name
if req.obj_attr_is_set('type'):
filters['type'] = req.type
# allow filter by project when is admin
if ctx.is_admin and req.obj_attr_is_set('project'):
filters['project'] = req.project
if filters:
query['filters'] = filters
@ -442,6 +445,9 @@ class ConductorService(service.Service):
filters['name'] = req.name
if req.obj_attr_is_set('type'):
filters['type'] = req.type
# allow filter by project when is admin
if ctx.is_admin and req.obj_attr_is_set('project'):
filters['project'] = req.project
if filters:
query['filters'] = filters
@ -602,6 +608,9 @@ class ConductorService(service.Service):
filters['name'] = req.name
if req.obj_attr_is_set('status'):
filters['status'] = req.status
# allow filter by project when is admin
if ctx.is_admin and req.obj_attr_is_set('project'):
filters['project'] = req.project
if filters:
query['filters'] = filters
@ -1520,6 +1529,9 @@ class ConductorService(service.Service):
filters['name'] = req.name
if req.obj_attr_is_set('status'):
filters['status'] = req.status
# allow filter by project when is admin
if ctx.is_admin and req.obj_attr_is_set('project'):
filters['project'] = req.project
if filters:
query['filters'] = filters
@ -2189,6 +2201,9 @@ class ConductorService(service.Service):
filters['target'] = req.target
if req.obj_attr_is_set('status'):
filters['status'] = req.status
# allow filter by project when is admin
if ctx.is_admin and req.obj_attr_is_set('project'):
filters['project'] = req.project
if filters:
query['filters'] = filters
@ -2319,6 +2334,9 @@ class ConductorService(service.Service):
filters['cluster_id'] = req.cluster_id
if req.obj_attr_is_set('user'):
filters['user'] = req.user
# allow filter by project when is admin
if ctx.is_admin and req.obj_attr_is_set('project'):
filters['project'] = req.project
if filters:
query['filters'] = filters
@ -2566,6 +2584,9 @@ class ConductorService(service.Service):
return []
if len(cluster_ids) > 0:
filters['cluster_id'] = cluster_ids
# allow filter by project when is admin
if ctx.is_admin and req.obj_attr_is_set('project'):
filters['project'] = req.project
if filters:
query['filters'] = filters

View File

@ -54,6 +54,7 @@ class ActionListRequest(base.SenlinObject):
'target': fields.ListOfStringsField(nullable=True),
'status': fields.ListOfEnumField(
valid_values=list(consts.ACTION_STATUSES), nullable=True),
'project': fields.ListOfStringsField(nullable=True),
'limit': fields.NonNegativeIntegerField(nullable=True),
'marker': fields.UUIDField(nullable=True),
'sort': fields.SortField(

View File

@ -28,6 +28,7 @@ class ClusterListRequest(base.SenlinObject):
'name': fields.ListOfStringsField(nullable=True),
'status': fields.ListOfEnumField(
valid_values=list(consts.CLUSTER_STATUSES), nullable=True),
'project': fields.ListOfStringsField(nullable=True),
'limit': fields.NonNegativeIntegerField(nullable=True),
'marker': fields.UUIDField(nullable=True),
'sort': fields.SortField(

View File

@ -25,6 +25,7 @@ class EventListRequest(base.SenlinObject):
'oid': fields.ListOfStringsField(nullable=True),
'oname': fields.ListOfStringsField(nullable=True),
'otype': fields.ListOfStringsField(nullable=True),
'project': fields.ListOfStringsField(nullable=True),
'action': fields.ListOfEnumField(
valid_values=action_name_list, nullable=True),
'cluster_id': fields.ListOfStringsField(nullable=True),

View File

@ -43,6 +43,7 @@ class NodeListRequest(base.SenlinObject):
fields = {
'cluster_id': fields.StringField(nullable=True),
'name': fields.ListOfStringsField(nullable=True),
'project': fields.ListOfStringsField(nullable=True),
'status': fields.ListOfEnumField(
valid_values=list(consts.NODE_STATUSES), nullable=True),
'limit': fields.NonNegativeIntegerField(nullable=True),

View File

@ -21,6 +21,7 @@ class PolicyListRequest(base.SenlinObject):
fields = {
'name': fields.ListOfStringsField(nullable=True),
'type': fields.ListOfStringsField(nullable=True),
'project': fields.ListOfStringsField(nullable=True),
'limit': fields.NonNegativeIntegerField(nullable=True),
'marker': fields.UUIDField(nullable=True),
'sort': fields.SortField(

View File

@ -39,6 +39,7 @@ class ProfileListRequest(base.SenlinObject):
fields = {
'name': fields.ListOfStringsField(nullable=True),
'type': fields.ListOfStringsField(nullable=True),
'project': fields.ListOfStringsField(nullable=True),
'limit': fields.NonNegativeIntegerField(nullable=True),
'marker': fields.UUIDField(nullable=True),
'sort': fields.SortField(

View File

@ -50,6 +50,7 @@ class ReceiverListRequest(base.SenlinObject):
fields = {
'name': fields.ListOfStringsField(nullable=True),
'project': fields.ListOfStringsField(nullable=True),
'type': fields.ListOfEnumField(
valid_values=list(consts.RECEIVER_TYPES), nullable=True),
'action': fields.ListOfEnumField(

View File

@ -39,6 +39,7 @@ from senlin.tests.unit.common import utils
class ClusterTest(base.SenlinTestCase):
def setUp(self):
super(ClusterTest, self).setUp()
@ -101,6 +102,7 @@ class ClusterTest(base.SenlinTestCase):
'name': ['test_cluster'],
'status': ['ACTIVE'],
'sort': 'name:asc',
'project': 'cluster_test_project',
'project_safe': True
}
self._prepare_request(req)