Merge "Fix sort of *list command output"
This commit is contained in:
@@ -205,7 +205,7 @@ class ActionCollection(collection.Collection):
|
|||||||
collection = ActionCollection()
|
collection = ActionCollection()
|
||||||
collection.actions = [Action.convert_with_links(p, expand)
|
collection.actions = [Action.convert_with_links(p, expand)
|
||||||
for p in actions]
|
for p in actions]
|
||||||
|
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||||
return collection
|
return collection
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@@ -232,6 +232,10 @@ class ActionsController(rest.RestController):
|
|||||||
sort_key, sort_dir, expand=False,
|
sort_key, sort_dir, expand=False,
|
||||||
resource_url=None,
|
resource_url=None,
|
||||||
action_plan_uuid=None, audit_uuid=None):
|
action_plan_uuid=None, audit_uuid=None):
|
||||||
|
additional_fields = ['action_plan_uuid']
|
||||||
|
|
||||||
|
api_utils.validate_sort_key(sort_key, list(objects.Action.fields) +
|
||||||
|
additional_fields)
|
||||||
limit = api_utils.validate_limit(limit)
|
limit = api_utils.validate_limit(limit)
|
||||||
api_utils.validate_sort_dir(sort_dir)
|
api_utils.validate_sort_dir(sort_dir)
|
||||||
|
|
||||||
@@ -247,7 +251,10 @@ class ActionsController(rest.RestController):
|
|||||||
if audit_uuid:
|
if audit_uuid:
|
||||||
filters['audit_uuid'] = audit_uuid
|
filters['audit_uuid'] = audit_uuid
|
||||||
|
|
||||||
sort_db_key = sort_key
|
need_api_sort = api_utils.check_need_api_sort(sort_key,
|
||||||
|
additional_fields)
|
||||||
|
sort_db_key = (sort_key if not need_api_sort
|
||||||
|
else None)
|
||||||
|
|
||||||
actions = objects.Action.list(pecan.request.context,
|
actions = objects.Action.list(pecan.request.context,
|
||||||
limit,
|
limit,
|
||||||
@@ -255,11 +262,15 @@ class ActionsController(rest.RestController):
|
|||||||
sort_dir=sort_dir,
|
sort_dir=sort_dir,
|
||||||
filters=filters)
|
filters=filters)
|
||||||
|
|
||||||
return ActionCollection.convert_with_links(actions, limit,
|
actions_collection = ActionCollection.convert_with_links(
|
||||||
url=resource_url,
|
actions, limit, url=resource_url, expand=expand,
|
||||||
expand=expand,
|
sort_key=sort_key, sort_dir=sort_dir)
|
||||||
sort_key=sort_key,
|
|
||||||
sort_dir=sort_dir)
|
if need_api_sort:
|
||||||
|
api_utils.make_api_sort(actions_collection.actions,
|
||||||
|
sort_key, sort_dir)
|
||||||
|
|
||||||
|
return actions_collection
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(ActionCollection, types.uuid, int,
|
@wsme_pecan.wsexpose(ActionCollection, types.uuid, int,
|
||||||
wtypes.text, wtypes.text, types.uuid,
|
wtypes.text, wtypes.text, types.uuid,
|
||||||
|
|||||||
@@ -305,17 +305,6 @@ class ActionPlanCollection(collection.Collection):
|
|||||||
ap_collection = ActionPlanCollection()
|
ap_collection = ActionPlanCollection()
|
||||||
ap_collection.action_plans = [ActionPlan.convert_with_links(
|
ap_collection.action_plans = [ActionPlan.convert_with_links(
|
||||||
p, expand) for p in rpc_action_plans]
|
p, expand) for p in rpc_action_plans]
|
||||||
|
|
||||||
if 'sort_key' in kwargs:
|
|
||||||
reverse = False
|
|
||||||
if kwargs['sort_key'] == 'audit_uuid':
|
|
||||||
if 'sort_dir' in kwargs:
|
|
||||||
reverse = True if kwargs['sort_dir'] == 'desc' else False
|
|
||||||
ap_collection.action_plans = sorted(
|
|
||||||
ap_collection.action_plans,
|
|
||||||
key=lambda action_plan: action_plan.audit_uuid,
|
|
||||||
reverse=reverse)
|
|
||||||
|
|
||||||
ap_collection.next = ap_collection.get_next(limit, url=url, **kwargs)
|
ap_collection.next = ap_collection.get_next(limit, url=url, **kwargs)
|
||||||
return ap_collection
|
return ap_collection
|
||||||
|
|
||||||
@@ -344,7 +333,10 @@ class ActionPlansController(rest.RestController):
|
|||||||
sort_key, sort_dir, expand=False,
|
sort_key, sort_dir, expand=False,
|
||||||
resource_url=None, audit_uuid=None,
|
resource_url=None, audit_uuid=None,
|
||||||
strategy=None):
|
strategy=None):
|
||||||
|
additional_fields = ['audit_uuid', 'strategy_uuid', 'strategy_name']
|
||||||
|
|
||||||
|
api_utils.validate_sort_key(
|
||||||
|
sort_key, list(objects.ActionPlan.fields) + additional_fields)
|
||||||
limit = api_utils.validate_limit(limit)
|
limit = api_utils.validate_limit(limit)
|
||||||
api_utils.validate_sort_dir(sort_dir)
|
api_utils.validate_sort_dir(sort_dir)
|
||||||
|
|
||||||
@@ -363,10 +355,10 @@ class ActionPlansController(rest.RestController):
|
|||||||
else:
|
else:
|
||||||
filters['strategy_name'] = strategy
|
filters['strategy_name'] = strategy
|
||||||
|
|
||||||
if sort_key == 'audit_uuid':
|
need_api_sort = api_utils.check_need_api_sort(sort_key,
|
||||||
sort_db_key = None
|
additional_fields)
|
||||||
else:
|
sort_db_key = (sort_key if not need_api_sort
|
||||||
sort_db_key = sort_key
|
else None)
|
||||||
|
|
||||||
action_plans = objects.ActionPlan.list(
|
action_plans = objects.ActionPlan.list(
|
||||||
pecan.request.context,
|
pecan.request.context,
|
||||||
@@ -374,12 +366,15 @@ class ActionPlansController(rest.RestController):
|
|||||||
marker_obj, sort_key=sort_db_key,
|
marker_obj, sort_key=sort_db_key,
|
||||||
sort_dir=sort_dir, filters=filters)
|
sort_dir=sort_dir, filters=filters)
|
||||||
|
|
||||||
return ActionPlanCollection.convert_with_links(
|
action_plans_collection = ActionPlanCollection.convert_with_links(
|
||||||
action_plans, limit,
|
action_plans, limit, url=resource_url, expand=expand,
|
||||||
url=resource_url,
|
sort_key=sort_key, sort_dir=sort_dir)
|
||||||
expand=expand,
|
|
||||||
sort_key=sort_key,
|
if need_api_sort:
|
||||||
sort_dir=sort_dir)
|
api_utils.make_api_sort(action_plans_collection.action_plans,
|
||||||
|
sort_key, sort_dir)
|
||||||
|
|
||||||
|
return action_plans_collection
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(ActionPlanCollection, types.uuid, int, wtypes.text,
|
@wsme_pecan.wsexpose(ActionPlanCollection, types.uuid, int, wtypes.text,
|
||||||
wtypes.text, types.uuid, wtypes.text)
|
wtypes.text, types.uuid, wtypes.text)
|
||||||
|
|||||||
@@ -389,17 +389,6 @@ class AuditCollection(collection.Collection):
|
|||||||
collection = AuditCollection()
|
collection = AuditCollection()
|
||||||
collection.audits = [Audit.convert_with_links(p, expand)
|
collection.audits = [Audit.convert_with_links(p, expand)
|
||||||
for p in rpc_audits]
|
for p in rpc_audits]
|
||||||
|
|
||||||
if 'sort_key' in kwargs:
|
|
||||||
reverse = False
|
|
||||||
if kwargs['sort_key'] == 'goal_uuid':
|
|
||||||
if 'sort_dir' in kwargs:
|
|
||||||
reverse = True if kwargs['sort_dir'] == 'desc' else False
|
|
||||||
collection.audits = sorted(
|
|
||||||
collection.audits,
|
|
||||||
key=lambda audit: audit.goal_uuid,
|
|
||||||
reverse=reverse)
|
|
||||||
|
|
||||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||||
return collection
|
return collection
|
||||||
|
|
||||||
@@ -427,8 +416,14 @@ class AuditsController(rest.RestController):
|
|||||||
sort_key, sort_dir, expand=False,
|
sort_key, sort_dir, expand=False,
|
||||||
resource_url=None, goal=None,
|
resource_url=None, goal=None,
|
||||||
strategy=None):
|
strategy=None):
|
||||||
|
additional_fields = ["goal_uuid", "goal_name", "strategy_uuid",
|
||||||
|
"strategy_name"]
|
||||||
|
|
||||||
|
api_utils.validate_sort_key(
|
||||||
|
sort_key, list(objects.Audit.fields) + additional_fields)
|
||||||
limit = api_utils.validate_limit(limit)
|
limit = api_utils.validate_limit(limit)
|
||||||
api_utils.validate_sort_dir(sort_dir)
|
api_utils.validate_sort_dir(sort_dir)
|
||||||
|
|
||||||
marker_obj = None
|
marker_obj = None
|
||||||
if marker:
|
if marker:
|
||||||
marker_obj = objects.Audit.get_by_uuid(pecan.request.context,
|
marker_obj = objects.Audit.get_by_uuid(pecan.request.context,
|
||||||
@@ -449,23 +444,25 @@ class AuditsController(rest.RestController):
|
|||||||
# TODO(michaelgugino): add method to get goal by name.
|
# TODO(michaelgugino): add method to get goal by name.
|
||||||
filters['strategy_name'] = strategy
|
filters['strategy_name'] = strategy
|
||||||
|
|
||||||
if sort_key == 'goal_uuid':
|
need_api_sort = api_utils.check_need_api_sort(sort_key,
|
||||||
sort_db_key = 'goal_id'
|
additional_fields)
|
||||||
elif sort_key == 'strategy_uuid':
|
sort_db_key = (sort_key if not need_api_sort
|
||||||
sort_db_key = 'strategy_id'
|
else None)
|
||||||
else:
|
|
||||||
sort_db_key = sort_key
|
|
||||||
|
|
||||||
audits = objects.Audit.list(pecan.request.context,
|
audits = objects.Audit.list(pecan.request.context,
|
||||||
limit,
|
limit,
|
||||||
marker_obj, sort_key=sort_db_key,
|
marker_obj, sort_key=sort_db_key,
|
||||||
sort_dir=sort_dir, filters=filters)
|
sort_dir=sort_dir, filters=filters)
|
||||||
|
|
||||||
return AuditCollection.convert_with_links(audits, limit,
|
audits_collection = AuditCollection.convert_with_links(
|
||||||
url=resource_url,
|
audits, limit, url=resource_url, expand=expand,
|
||||||
expand=expand,
|
sort_key=sort_key, sort_dir=sort_dir)
|
||||||
sort_key=sort_key,
|
|
||||||
sort_dir=sort_dir)
|
if need_api_sort:
|
||||||
|
api_utils.make_api_sort(audits_collection.audits, sort_key,
|
||||||
|
sort_dir)
|
||||||
|
|
||||||
|
return audits_collection
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(AuditCollection, types.uuid, int, wtypes.text,
|
@wsme_pecan.wsexpose(AuditCollection, types.uuid, int, wtypes.text,
|
||||||
wtypes.text, wtypes.text, wtypes.text, int)
|
wtypes.text, wtypes.text, wtypes.text, int)
|
||||||
|
|||||||
@@ -474,9 +474,13 @@ class AuditTemplatesController(rest.RestController):
|
|||||||
def _get_audit_templates_collection(self, filters, marker, limit,
|
def _get_audit_templates_collection(self, filters, marker, limit,
|
||||||
sort_key, sort_dir, expand=False,
|
sort_key, sort_dir, expand=False,
|
||||||
resource_url=None):
|
resource_url=None):
|
||||||
|
additional_fields = ["goal_uuid", "goal_name", "strategy_uuid",
|
||||||
|
"strategy_name"]
|
||||||
|
|
||||||
|
api_utils.validate_sort_key(
|
||||||
|
sort_key, list(objects.AuditTemplate.fields) + additional_fields)
|
||||||
api_utils.validate_search_filters(
|
api_utils.validate_search_filters(
|
||||||
filters, list(objects.audit_template.AuditTemplate.fields) +
|
filters, list(objects.AuditTemplate.fields) + additional_fields)
|
||||||
["goal_uuid", "goal_name", "strategy_uuid", "strategy_name"])
|
|
||||||
limit = api_utils.validate_limit(limit)
|
limit = api_utils.validate_limit(limit)
|
||||||
api_utils.validate_sort_dir(sort_dir)
|
api_utils.validate_sort_dir(sort_dir)
|
||||||
|
|
||||||
@@ -486,19 +490,26 @@ class AuditTemplatesController(rest.RestController):
|
|||||||
pecan.request.context,
|
pecan.request.context,
|
||||||
marker)
|
marker)
|
||||||
|
|
||||||
audit_templates = objects.AuditTemplate.list(
|
need_api_sort = api_utils.check_need_api_sort(sort_key,
|
||||||
pecan.request.context,
|
additional_fields)
|
||||||
filters,
|
sort_db_key = (sort_key if not need_api_sort
|
||||||
limit,
|
else None)
|
||||||
marker_obj, sort_key=sort_key,
|
|
||||||
sort_dir=sort_dir)
|
|
||||||
|
|
||||||
return AuditTemplateCollection.convert_with_links(audit_templates,
|
audit_templates = objects.AuditTemplate.list(
|
||||||
limit,
|
pecan.request.context, filters, limit, marker_obj,
|
||||||
url=resource_url,
|
sort_key=sort_db_key, sort_dir=sort_dir)
|
||||||
expand=expand,
|
|
||||||
sort_key=sort_key,
|
audit_templates_collection = \
|
||||||
sort_dir=sort_dir)
|
AuditTemplateCollection.convert_with_links(
|
||||||
|
audit_templates, limit, url=resource_url, expand=expand,
|
||||||
|
sort_key=sort_key, sort_dir=sort_dir)
|
||||||
|
|
||||||
|
if need_api_sort:
|
||||||
|
api_utils.make_api_sort(
|
||||||
|
audit_templates_collection.audit_templates, sort_key,
|
||||||
|
sort_dir)
|
||||||
|
|
||||||
|
return audit_templates_collection
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(AuditTemplateCollection, wtypes.text, wtypes.text,
|
@wsme_pecan.wsexpose(AuditTemplateCollection, wtypes.text, wtypes.text,
|
||||||
types.uuid, int, wtypes.text, wtypes.text)
|
types.uuid, int, wtypes.text, wtypes.text)
|
||||||
|
|||||||
@@ -130,17 +130,6 @@ class GoalCollection(collection.Collection):
|
|||||||
goal_collection = GoalCollection()
|
goal_collection = GoalCollection()
|
||||||
goal_collection.goals = [
|
goal_collection.goals = [
|
||||||
Goal.convert_with_links(g, expand) for g in goals]
|
Goal.convert_with_links(g, expand) for g in goals]
|
||||||
|
|
||||||
if 'sort_key' in kwargs:
|
|
||||||
reverse = False
|
|
||||||
if kwargs['sort_key'] == 'strategy':
|
|
||||||
if 'sort_dir' in kwargs:
|
|
||||||
reverse = True if kwargs['sort_dir'] == 'desc' else False
|
|
||||||
goal_collection.goals = sorted(
|
|
||||||
goal_collection.goals,
|
|
||||||
key=lambda goal: goal.uuid,
|
|
||||||
reverse=reverse)
|
|
||||||
|
|
||||||
goal_collection.next = goal_collection.get_next(
|
goal_collection.next = goal_collection.get_next(
|
||||||
limit, url=url, **kwargs)
|
limit, url=url, **kwargs)
|
||||||
return goal_collection
|
return goal_collection
|
||||||
@@ -167,17 +156,19 @@ class GoalsController(rest.RestController):
|
|||||||
|
|
||||||
def _get_goals_collection(self, marker, limit, sort_key, sort_dir,
|
def _get_goals_collection(self, marker, limit, sort_key, sort_dir,
|
||||||
expand=False, resource_url=None):
|
expand=False, resource_url=None):
|
||||||
|
api_utils.validate_sort_key(
|
||||||
|
sort_key, list(objects.Goal.fields))
|
||||||
limit = api_utils.validate_limit(limit)
|
limit = api_utils.validate_limit(limit)
|
||||||
api_utils.validate_sort_dir(sort_dir)
|
api_utils.validate_sort_dir(sort_dir)
|
||||||
|
|
||||||
sort_db_key = (sort_key if sort_key in objects.Goal.fields
|
|
||||||
else None)
|
|
||||||
|
|
||||||
marker_obj = None
|
marker_obj = None
|
||||||
if marker:
|
if marker:
|
||||||
marker_obj = objects.Goal.get_by_uuid(
|
marker_obj = objects.Goal.get_by_uuid(
|
||||||
pecan.request.context, marker)
|
pecan.request.context, marker)
|
||||||
|
|
||||||
|
sort_db_key = (sort_key if sort_key in objects.Goal.fields
|
||||||
|
else None)
|
||||||
|
|
||||||
goals = objects.Goal.list(pecan.request.context, limit, marker_obj,
|
goals = objects.Goal.list(pecan.request.context, limit, marker_obj,
|
||||||
sort_key=sort_db_key, sort_dir=sort_dir)
|
sort_key=sort_db_key, sort_dir=sort_dir)
|
||||||
|
|
||||||
|
|||||||
@@ -123,17 +123,6 @@ class ScoringEngineCollection(collection.Collection):
|
|||||||
collection = ScoringEngineCollection()
|
collection = ScoringEngineCollection()
|
||||||
collection.scoring_engines = [ScoringEngine.convert_with_links(
|
collection.scoring_engines = [ScoringEngine.convert_with_links(
|
||||||
se, expand) for se in scoring_engines]
|
se, expand) for se in scoring_engines]
|
||||||
|
|
||||||
if 'sort_key' in kwargs:
|
|
||||||
reverse = False
|
|
||||||
if kwargs['sort_key'] == 'name':
|
|
||||||
if 'sort_dir' in kwargs:
|
|
||||||
reverse = True if kwargs['sort_dir'] == 'desc' else False
|
|
||||||
collection.goals = sorted(
|
|
||||||
collection.scoring_engines,
|
|
||||||
key=lambda se: se.name,
|
|
||||||
reverse=reverse)
|
|
||||||
|
|
||||||
collection.next = collection.get_next(limit, url=url, **kwargs)
|
collection.next = collection.get_next(limit, url=url, **kwargs)
|
||||||
return collection
|
return collection
|
||||||
|
|
||||||
@@ -160,7 +149,8 @@ class ScoringEngineController(rest.RestController):
|
|||||||
def _get_scoring_engines_collection(self, marker, limit,
|
def _get_scoring_engines_collection(self, marker, limit,
|
||||||
sort_key, sort_dir, expand=False,
|
sort_key, sort_dir, expand=False,
|
||||||
resource_url=None):
|
resource_url=None):
|
||||||
|
api_utils.validate_sort_key(
|
||||||
|
sort_key, list(objects.ScoringEngine.fields))
|
||||||
limit = api_utils.validate_limit(limit)
|
limit = api_utils.validate_limit(limit)
|
||||||
api_utils.validate_sort_dir(sort_dir)
|
api_utils.validate_sort_dir(sort_dir)
|
||||||
|
|
||||||
@@ -171,7 +161,8 @@ class ScoringEngineController(rest.RestController):
|
|||||||
|
|
||||||
filters = {}
|
filters = {}
|
||||||
|
|
||||||
sort_db_key = sort_key
|
sort_db_key = (sort_key if sort_key in objects.ScoringEngine.fields
|
||||||
|
else None)
|
||||||
|
|
||||||
scoring_engines = objects.ScoringEngine.list(
|
scoring_engines = objects.ScoringEngine.list(
|
||||||
context=pecan.request.context,
|
context=pecan.request.context,
|
||||||
|
|||||||
@@ -154,17 +154,6 @@ class ServiceCollection(collection.Collection):
|
|||||||
service_collection = ServiceCollection()
|
service_collection = ServiceCollection()
|
||||||
service_collection.services = [
|
service_collection.services = [
|
||||||
Service.convert_with_links(g, expand) for g in services]
|
Service.convert_with_links(g, expand) for g in services]
|
||||||
|
|
||||||
if 'sort_key' in kwargs:
|
|
||||||
reverse = False
|
|
||||||
if kwargs['sort_key'] == 'service':
|
|
||||||
if 'sort_dir' in kwargs:
|
|
||||||
reverse = True if kwargs['sort_dir'] == 'desc' else False
|
|
||||||
service_collection.services = sorted(
|
|
||||||
service_collection.services,
|
|
||||||
key=lambda service: service.id,
|
|
||||||
reverse=reverse)
|
|
||||||
|
|
||||||
service_collection.next = service_collection.get_next(
|
service_collection.next = service_collection.get_next(
|
||||||
limit, url=url, marker_field='id', **kwargs)
|
limit, url=url, marker_field='id', **kwargs)
|
||||||
return service_collection
|
return service_collection
|
||||||
@@ -191,17 +180,19 @@ class ServicesController(rest.RestController):
|
|||||||
|
|
||||||
def _get_services_collection(self, marker, limit, sort_key, sort_dir,
|
def _get_services_collection(self, marker, limit, sort_key, sort_dir,
|
||||||
expand=False, resource_url=None):
|
expand=False, resource_url=None):
|
||||||
|
api_utils.validate_sort_key(
|
||||||
|
sort_key, list(objects.Service.fields))
|
||||||
limit = api_utils.validate_limit(limit)
|
limit = api_utils.validate_limit(limit)
|
||||||
api_utils.validate_sort_dir(sort_dir)
|
api_utils.validate_sort_dir(sort_dir)
|
||||||
|
|
||||||
sort_db_key = (sort_key if sort_key in objects.Service.fields
|
|
||||||
else None)
|
|
||||||
|
|
||||||
marker_obj = None
|
marker_obj = None
|
||||||
if marker:
|
if marker:
|
||||||
marker_obj = objects.Service.get(
|
marker_obj = objects.Service.get(
|
||||||
pecan.request.context, marker)
|
pecan.request.context, marker)
|
||||||
|
|
||||||
|
sort_db_key = (sort_key if sort_key in objects.Service.fields
|
||||||
|
else None)
|
||||||
|
|
||||||
services = objects.Service.list(
|
services = objects.Service.list(
|
||||||
pecan.request.context, limit, marker_obj,
|
pecan.request.context, limit, marker_obj,
|
||||||
sort_key=sort_db_key, sort_dir=sort_dir)
|
sort_key=sort_db_key, sort_dir=sort_dir)
|
||||||
|
|||||||
@@ -173,17 +173,6 @@ class StrategyCollection(collection.Collection):
|
|||||||
strategy_collection = StrategyCollection()
|
strategy_collection = StrategyCollection()
|
||||||
strategy_collection.strategies = [
|
strategy_collection.strategies = [
|
||||||
Strategy.convert_with_links(g, expand) for g in strategies]
|
Strategy.convert_with_links(g, expand) for g in strategies]
|
||||||
|
|
||||||
if 'sort_key' in kwargs:
|
|
||||||
reverse = False
|
|
||||||
if kwargs['sort_key'] == 'strategy':
|
|
||||||
if 'sort_dir' in kwargs:
|
|
||||||
reverse = True if kwargs['sort_dir'] == 'desc' else False
|
|
||||||
strategy_collection.strategies = sorted(
|
|
||||||
strategy_collection.strategies,
|
|
||||||
key=lambda strategy: strategy.uuid,
|
|
||||||
reverse=reverse)
|
|
||||||
|
|
||||||
strategy_collection.next = strategy_collection.get_next(
|
strategy_collection.next = strategy_collection.get_next(
|
||||||
limit, url=url, **kwargs)
|
limit, url=url, **kwargs)
|
||||||
return strategy_collection
|
return strategy_collection
|
||||||
@@ -211,28 +200,39 @@ class StrategiesController(rest.RestController):
|
|||||||
|
|
||||||
def _get_strategies_collection(self, filters, marker, limit, sort_key,
|
def _get_strategies_collection(self, filters, marker, limit, sort_key,
|
||||||
sort_dir, expand=False, resource_url=None):
|
sort_dir, expand=False, resource_url=None):
|
||||||
|
additional_fields = ["goal_uuid", "goal_name"]
|
||||||
|
|
||||||
|
api_utils.validate_sort_key(
|
||||||
|
sort_key, list(objects.Strategy.fields) + additional_fields)
|
||||||
api_utils.validate_search_filters(
|
api_utils.validate_search_filters(
|
||||||
filters, list(objects.strategy.Strategy.fields) +
|
filters, list(objects.Strategy.fields) + additional_fields)
|
||||||
["goal_uuid", "goal_name"])
|
|
||||||
limit = api_utils.validate_limit(limit)
|
limit = api_utils.validate_limit(limit)
|
||||||
api_utils.validate_sort_dir(sort_dir)
|
api_utils.validate_sort_dir(sort_dir)
|
||||||
|
|
||||||
sort_db_key = (sort_key if sort_key in objects.Strategy.fields
|
|
||||||
else None)
|
|
||||||
|
|
||||||
marker_obj = None
|
marker_obj = None
|
||||||
if marker:
|
if marker:
|
||||||
marker_obj = objects.Strategy.get_by_uuid(
|
marker_obj = objects.Strategy.get_by_uuid(
|
||||||
pecan.request.context, marker)
|
pecan.request.context, marker)
|
||||||
|
|
||||||
|
need_api_sort = api_utils.check_need_api_sort(sort_key,
|
||||||
|
additional_fields)
|
||||||
|
sort_db_key = (sort_key if not need_api_sort
|
||||||
|
else None)
|
||||||
|
|
||||||
strategies = objects.Strategy.list(
|
strategies = objects.Strategy.list(
|
||||||
pecan.request.context, limit, marker_obj, filters=filters,
|
pecan.request.context, limit, marker_obj, filters=filters,
|
||||||
sort_key=sort_db_key, sort_dir=sort_dir)
|
sort_key=sort_db_key, sort_dir=sort_dir)
|
||||||
|
|
||||||
return StrategyCollection.convert_with_links(
|
strategies_collection = StrategyCollection.convert_with_links(
|
||||||
strategies, limit, url=resource_url, expand=expand,
|
strategies, limit, url=resource_url, expand=expand,
|
||||||
sort_key=sort_key, sort_dir=sort_dir)
|
sort_key=sort_key, sort_dir=sort_dir)
|
||||||
|
|
||||||
|
if need_api_sort:
|
||||||
|
api_utils.make_api_sort(strategies_collection.strategies,
|
||||||
|
sort_key, sort_dir)
|
||||||
|
|
||||||
|
return strategies_collection
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(StrategyCollection, wtypes.text, wtypes.text,
|
@wsme_pecan.wsexpose(StrategyCollection, wtypes.text, wtypes.text,
|
||||||
int, wtypes.text, wtypes.text)
|
int, wtypes.text, wtypes.text)
|
||||||
def get_all(self, goal=None, marker=None, limit=None,
|
def get_all(self, goal=None, marker=None, limit=None,
|
||||||
|
|||||||
@@ -13,6 +13,8 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
import jsonpatch
|
import jsonpatch
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_utils import reflection
|
from oslo_utils import reflection
|
||||||
@@ -54,6 +56,13 @@ def validate_sort_dir(sort_dir):
|
|||||||
"'asc' or 'desc'") % sort_dir)
|
"'asc' or 'desc'") % sort_dir)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_sort_key(sort_key, allowed_fields):
|
||||||
|
# Very lightweight validation for now
|
||||||
|
if sort_key not in allowed_fields:
|
||||||
|
raise wsme.exc.ClientSideError(
|
||||||
|
_("Invalid sort key: %s") % sort_key)
|
||||||
|
|
||||||
|
|
||||||
def validate_search_filters(filters, allowed_fields):
|
def validate_search_filters(filters, allowed_fields):
|
||||||
# Very lightweight validation for now
|
# Very lightweight validation for now
|
||||||
# todo: improve this (e.g. https://www.parse.com/docs/rest/guide/#queries)
|
# todo: improve this (e.g. https://www.parse.com/docs/rest/guide/#queries)
|
||||||
@@ -63,6 +72,19 @@ def validate_search_filters(filters, allowed_fields):
|
|||||||
_("Invalid filter: %s") % filter_name)
|
_("Invalid filter: %s") % filter_name)
|
||||||
|
|
||||||
|
|
||||||
|
def check_need_api_sort(sort_key, additional_fields):
|
||||||
|
return sort_key in additional_fields
|
||||||
|
|
||||||
|
|
||||||
|
def make_api_sort(sorting_list, sort_key, sort_dir):
|
||||||
|
# First sort by uuid field, than sort by sort_key
|
||||||
|
# sort() ensures stable sorting, so we could
|
||||||
|
# make lexicographical sort
|
||||||
|
reverse_direction = (sort_dir == 'desc')
|
||||||
|
sorting_list.sort(key=attrgetter('uuid'), reverse=reverse_direction)
|
||||||
|
sorting_list.sort(key=attrgetter(sort_key), reverse=reverse_direction)
|
||||||
|
|
||||||
|
|
||||||
def apply_jsonpatch(doc, patch):
|
def apply_jsonpatch(doc, patch):
|
||||||
for p in patch:
|
for p in patch:
|
||||||
if p['op'] == 'add' and p['path'].count('/') == 1:
|
if p['op'] == 'add' and p['path'].count('/') == 1:
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
import itertools
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
@@ -267,6 +268,67 @@ class TestListAction(api_base.FunctionalTest):
|
|||||||
response = self.get_json(url, expect_errors=True)
|
response = self.get_json(url, expect_errors=True)
|
||||||
self.assertEqual(400, response.status_int)
|
self.assertEqual(400, response.status_int)
|
||||||
|
|
||||||
|
def test_many_with_sort_key_uuid(self):
|
||||||
|
action_plan = obj_utils.create_test_action_plan(
|
||||||
|
self.context,
|
||||||
|
uuid=utils.generate_uuid(),
|
||||||
|
audit_id=self.audit.id)
|
||||||
|
|
||||||
|
actions_list = []
|
||||||
|
for id_ in range(1, 3):
|
||||||
|
action = obj_utils.create_test_action(
|
||||||
|
self.context, id=id_,
|
||||||
|
action_plan_id=action_plan.id,
|
||||||
|
uuid=utils.generate_uuid())
|
||||||
|
actions_list.append(action)
|
||||||
|
|
||||||
|
response = self.get_json('/actions?sort_key=%s' % 'uuid')
|
||||||
|
names = [s['uuid'] for s in response['actions']]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
sorted([a.uuid for a in actions_list]),
|
||||||
|
names)
|
||||||
|
|
||||||
|
def test_many_with_sort_key_action_plan_uuid(self):
|
||||||
|
action_plan_1 = obj_utils.create_test_action_plan(
|
||||||
|
self.context,
|
||||||
|
uuid=utils.generate_uuid(),
|
||||||
|
audit_id=self.audit.id)
|
||||||
|
|
||||||
|
action_plan_2 = obj_utils.create_test_action_plan(
|
||||||
|
self.context,
|
||||||
|
uuid=utils.generate_uuid(),
|
||||||
|
audit_id=self.audit.id)
|
||||||
|
|
||||||
|
action_plans_uuid_list = []
|
||||||
|
for id_, action_plan_id in enumerate(itertools.chain.from_iterable([
|
||||||
|
itertools.repeat(action_plan_1.id, 3),
|
||||||
|
itertools.repeat(action_plan_2.id, 2)]), 1):
|
||||||
|
action = obj_utils.create_test_action(
|
||||||
|
self.context, id=id_,
|
||||||
|
action_plan_id=action_plan_id,
|
||||||
|
uuid=utils.generate_uuid())
|
||||||
|
action_plans_uuid_list.append(action.action_plan.uuid)
|
||||||
|
|
||||||
|
for direction in ['asc', 'desc']:
|
||||||
|
response = self.get_json(
|
||||||
|
'/actions?sort_key={0}&sort_dir={1}'
|
||||||
|
.format('action_plan_uuid', direction))
|
||||||
|
|
||||||
|
action_plan_uuids = \
|
||||||
|
[s['action_plan_uuid'] for s in response['actions']]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
sorted(action_plans_uuid_list, reverse=(direction == 'desc')),
|
||||||
|
action_plan_uuids,
|
||||||
|
message='Failed on %s direction' % direction)
|
||||||
|
|
||||||
|
def test_sort_key_validation(self):
|
||||||
|
response = self.get_json(
|
||||||
|
'/actions?sort_key=%s' % 'bad_name',
|
||||||
|
expect_errors=True)
|
||||||
|
self.assertEqual(400, response.status_int)
|
||||||
|
|
||||||
def test_many_with_soft_deleted_action_plan_uuid(self):
|
def test_many_with_soft_deleted_action_plan_uuid(self):
|
||||||
action_plan1 = obj_utils.create_test_action_plan(
|
action_plan1 = obj_utils.create_test_action_plan(
|
||||||
self.context,
|
self.context,
|
||||||
|
|||||||
@@ -256,6 +256,12 @@ class TestListActionPlan(api_base.FunctionalTest):
|
|||||||
uuids = [s['audit_uuid'] for s in response['action_plans']]
|
uuids = [s['audit_uuid'] for s in response['action_plans']]
|
||||||
self.assertEqual(sorted(audit_list), uuids)
|
self.assertEqual(sorted(audit_list), uuids)
|
||||||
|
|
||||||
|
def test_sort_key_validation(self):
|
||||||
|
response = self.get_json(
|
||||||
|
'/action_plans?sort_key=%s' % 'bad_name',
|
||||||
|
expect_errors=True)
|
||||||
|
self.assertEqual(400, response.status_int)
|
||||||
|
|
||||||
def test_links(self):
|
def test_links(self):
|
||||||
uuid = utils.generate_uuid()
|
uuid = utils.generate_uuid()
|
||||||
obj_utils.create_test_action_plan(self.context, id=1, uuid=uuid)
|
obj_utils.create_test_action_plan(self.context, id=1, uuid=uuid)
|
||||||
|
|||||||
@@ -294,6 +294,50 @@ class TestListAuditTemplate(FunctionalTestWithSetup):
|
|||||||
'/audit_templates?strategy=%s' % self.fake_strategy2.name)
|
'/audit_templates?strategy=%s' % self.fake_strategy2.name)
|
||||||
self.assertEqual(2, len(response['audit_templates']))
|
self.assertEqual(2, len(response['audit_templates']))
|
||||||
|
|
||||||
|
def test_many_with_sort_key_name(self):
|
||||||
|
audit_template_list = []
|
||||||
|
for id_ in range(1, 6):
|
||||||
|
audit_template = obj_utils.create_test_audit_template(
|
||||||
|
self.context, id=id_, uuid=utils.generate_uuid(),
|
||||||
|
name='My Audit Template {0}'.format(id_))
|
||||||
|
audit_template_list.append(audit_template)
|
||||||
|
|
||||||
|
response = self.get_json('/audit_templates?sort_key=%s' % 'name')
|
||||||
|
|
||||||
|
names = [s['name'] for s in response['audit_templates']]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
sorted([at.name for at in audit_template_list]),
|
||||||
|
names)
|
||||||
|
|
||||||
|
def test_many_with_sort_key_goal_name(self):
|
||||||
|
goal_names_list = []
|
||||||
|
for id_, goal_id in enumerate(itertools.chain.from_iterable([
|
||||||
|
itertools.repeat(self.fake_goal1.id, 3),
|
||||||
|
itertools.repeat(self.fake_goal2.id, 2)]), 1):
|
||||||
|
audit_template = obj_utils.create_test_audit_template(
|
||||||
|
self.context, id=id_, uuid=utils.generate_uuid(),
|
||||||
|
name='My Audit Template {0}'.format(id_),
|
||||||
|
goal_id=goal_id)
|
||||||
|
goal_names_list.append(audit_template.goal.name)
|
||||||
|
|
||||||
|
for direction in ['asc', 'desc']:
|
||||||
|
response = self.get_json(
|
||||||
|
'/audit_templates?sort_key={0}&sort_dir={1}'
|
||||||
|
.format('goal_name', direction))
|
||||||
|
|
||||||
|
goal_names = [s['goal_name'] for s in response['audit_templates']]
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
sorted(goal_names_list, reverse=(direction == 'desc')),
|
||||||
|
goal_names)
|
||||||
|
|
||||||
|
def test_sort_key_validation(self):
|
||||||
|
response = self.get_json(
|
||||||
|
'/audit_templates?sort_key=%s' % 'goal_bad_name',
|
||||||
|
expect_errors=True)
|
||||||
|
self.assertEqual(400, response.status_int)
|
||||||
|
|
||||||
|
|
||||||
class TestPatch(FunctionalTestWithSetup):
|
class TestPatch(FunctionalTestWithSetup):
|
||||||
|
|
||||||
|
|||||||
@@ -217,6 +217,12 @@ class TestListAudit(api_base.FunctionalTest):
|
|||||||
uuids = [s['goal_uuid'] for s in response['audits']]
|
uuids = [s['goal_uuid'] for s in response['audits']]
|
||||||
self.assertEqual(sorted(goal_list), uuids)
|
self.assertEqual(sorted(goal_list), uuids)
|
||||||
|
|
||||||
|
def test_sort_key_validation(self):
|
||||||
|
response = self.get_json(
|
||||||
|
'/audits?sort_key=%s' % 'bad_name',
|
||||||
|
expect_errors=True)
|
||||||
|
self.assertEqual(400, response.status_int)
|
||||||
|
|
||||||
def test_links(self):
|
def test_links(self):
|
||||||
uuid = utils.generate_uuid()
|
uuid = utils.generate_uuid()
|
||||||
obj_utils.create_test_audit(
|
obj_utils.create_test_audit(
|
||||||
|
|||||||
@@ -120,6 +120,27 @@ class TestListGoal(api_base.FunctionalTest):
|
|||||||
response = self.get_json('/goals')
|
response = self.get_json('/goals')
|
||||||
self.assertEqual(3, len(response['goals']))
|
self.assertEqual(3, len(response['goals']))
|
||||||
|
|
||||||
|
def test_many_with_sort_key_uuid(self):
|
||||||
|
goal_list = []
|
||||||
|
for idx in range(1, 6):
|
||||||
|
goal = obj_utils.create_test_goal(
|
||||||
|
self.context, id=idx,
|
||||||
|
uuid=utils.generate_uuid(),
|
||||||
|
name='GOAL_{0}'.format(idx))
|
||||||
|
goal_list.append(goal.uuid)
|
||||||
|
|
||||||
|
response = self.get_json('/goals/?sort_key=uuid')
|
||||||
|
|
||||||
|
self.assertEqual(5, len(response['goals']))
|
||||||
|
uuids = [s['uuid'] for s in response['goals']]
|
||||||
|
self.assertEqual(sorted(goal_list), uuids)
|
||||||
|
|
||||||
|
def test_sort_key_validation(self):
|
||||||
|
response = self.get_json(
|
||||||
|
'/goals?sort_key=%s' % 'bad_name',
|
||||||
|
expect_errors=True)
|
||||||
|
self.assertEqual(400, response.status_int)
|
||||||
|
|
||||||
|
|
||||||
class TestGoalPolicyEnforcement(api_base.FunctionalTest):
|
class TestGoalPolicyEnforcement(api_base.FunctionalTest):
|
||||||
|
|
||||||
|
|||||||
@@ -113,6 +113,26 @@ class TestListScoringEngine(api_base.FunctionalTest):
|
|||||||
response = self.get_json('/scoring_engines')
|
response = self.get_json('/scoring_engines')
|
||||||
self.assertEqual(3, len(response['scoring_engines']))
|
self.assertEqual(3, len(response['scoring_engines']))
|
||||||
|
|
||||||
|
def test_many_with_sort_key_uuid(self):
|
||||||
|
scoring_engine_list = []
|
||||||
|
for idx in range(1, 6):
|
||||||
|
scoring_engine = obj_utils.create_test_scoring_engine(
|
||||||
|
self.context, id=idx, uuid=utils.generate_uuid(),
|
||||||
|
name=str(idx), description='SE_{0}'.format(idx))
|
||||||
|
scoring_engine_list.append(scoring_engine.uuid)
|
||||||
|
|
||||||
|
response = self.get_json('/scoring_engines/?sort_key=uuid')
|
||||||
|
|
||||||
|
self.assertEqual(5, len(response['scoring_engines']))
|
||||||
|
uuids = [s['uuid'] for s in response['scoring_engines']]
|
||||||
|
self.assertEqual(sorted(scoring_engine_list), uuids)
|
||||||
|
|
||||||
|
def test_sort_key_validation(self):
|
||||||
|
response = self.get_json(
|
||||||
|
'/goals?sort_key=%s' % 'bad_name',
|
||||||
|
expect_errors=True)
|
||||||
|
self.assertEqual(400, response.status_int)
|
||||||
|
|
||||||
|
|
||||||
class TestScoringEnginePolicyEnforcement(api_base.FunctionalTest):
|
class TestScoringEnginePolicyEnforcement(api_base.FunctionalTest):
|
||||||
|
|
||||||
|
|||||||
@@ -131,6 +131,26 @@ class TestListService(api_base.FunctionalTest):
|
|||||||
response = self.get_json('/services')
|
response = self.get_json('/services')
|
||||||
self.assertEqual(3, len(response['services']))
|
self.assertEqual(3, len(response['services']))
|
||||||
|
|
||||||
|
def test_many_with_sort_key_name(self):
|
||||||
|
service_list = []
|
||||||
|
for id_ in range(1, 4):
|
||||||
|
service = obj_utils.create_test_service(
|
||||||
|
self.context, id=id_, host='CONTROLLER',
|
||||||
|
name='SERVICE_{0}'.format(id_))
|
||||||
|
service_list.append(service.name)
|
||||||
|
|
||||||
|
response = self.get_json('/services/?sort_key=name')
|
||||||
|
|
||||||
|
self.assertEqual(3, len(response['services']))
|
||||||
|
names = [s['name'] for s in response['services']]
|
||||||
|
self.assertEqual(sorted(service_list), names)
|
||||||
|
|
||||||
|
def test_sort_key_validation(self):
|
||||||
|
response = self.get_json(
|
||||||
|
'/services?sort_key=%s' % 'bad_name',
|
||||||
|
expect_errors=True)
|
||||||
|
self.assertEqual(400, response.status_int)
|
||||||
|
|
||||||
|
|
||||||
class TestServicePolicyEnforcement(api_base.FunctionalTest):
|
class TestServicePolicyEnforcement(api_base.FunctionalTest):
|
||||||
|
|
||||||
|
|||||||
@@ -221,6 +221,27 @@ class TestListStrategy(api_base.FunctionalTest):
|
|||||||
for strategy in strategies:
|
for strategy in strategies:
|
||||||
self.assertEqual(goal1['uuid'], strategy['goal_uuid'])
|
self.assertEqual(goal1['uuid'], strategy['goal_uuid'])
|
||||||
|
|
||||||
|
def test_many_with_sort_key_goal_uuid(self):
|
||||||
|
goals_uuid_list = []
|
||||||
|
for idx in range(1, 6):
|
||||||
|
strategy = obj_utils.create_test_strategy(
|
||||||
|
self.context, id=idx,
|
||||||
|
uuid=utils.generate_uuid(),
|
||||||
|
name='STRATEGY_{0}'.format(idx))
|
||||||
|
goals_uuid_list.append(strategy.goal.uuid)
|
||||||
|
|
||||||
|
response = self.get_json('/strategies/?sort_key=goal_uuid')
|
||||||
|
|
||||||
|
self.assertEqual(5, len(response['strategies']))
|
||||||
|
goal_uuids = [s['goal_uuid'] for s in response['strategies']]
|
||||||
|
self.assertEqual(sorted(goals_uuid_list), goal_uuids)
|
||||||
|
|
||||||
|
def test_sort_key_validation(self):
|
||||||
|
response = self.get_json(
|
||||||
|
'/strategies?sort_key=%s' % 'bad_name',
|
||||||
|
expect_errors=True)
|
||||||
|
self.assertEqual(400, response.status_int)
|
||||||
|
|
||||||
|
|
||||||
class TestStrategyPolicyEnforcement(api_base.FunctionalTest):
|
class TestStrategyPolicyEnforcement(api_base.FunctionalTest):
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user