Add project_id to API resources
Currently our API doesn't return any project info in many resources, like execution, cron-trigger, workbook, etc. As a essential property in those resources, it's really helpful for users to process resources if we return project_id in resource endpoints. Closes-Bug: 1707573 Closes-Bug: 1694398 Change-Id: I866d20cf1f5129b6249140063aa0836f63626767
This commit is contained in:
parent
1a8837b9d2
commit
2018962568
mistral
@ -33,6 +33,7 @@ class Workbook(resource.Resource):
|
||||
tags = [wtypes.text]
|
||||
scope = SCOPE_TYPES
|
||||
"'private' or 'public'"
|
||||
project_id = wsme.wsattr(wtypes.text, readonly=True)
|
||||
|
||||
created_at = wtypes.text
|
||||
updated_at = wtypes.text
|
||||
@ -45,6 +46,7 @@ class Workbook(resource.Resource):
|
||||
'WORKBOOK DEFINITION IN MISTRAL DSL v2',
|
||||
tags=['large', 'expensive'],
|
||||
scope='private',
|
||||
project_id='a7eb669e9819420ea4bd1453e672c0a7',
|
||||
created_at='1970-01-01T00:00:00.000000',
|
||||
updated_at='1970-01-01T00:00:00.000000')
|
||||
|
||||
@ -167,6 +169,7 @@ class Action(resource.Resource):
|
||||
tags = [wtypes.text]
|
||||
definition = wtypes.text
|
||||
scope = SCOPE_TYPES
|
||||
project_id = wsme.wsattr(wtypes.text, readonly=True)
|
||||
|
||||
created_at = wtypes.text
|
||||
updated_at = wtypes.text
|
||||
@ -179,6 +182,7 @@ class Action(resource.Resource):
|
||||
definition='HERE GOES ACTION DEFINITION IN MISTRAL DSL v2',
|
||||
tags=['large', 'expensive'],
|
||||
scope='private',
|
||||
project_id='a7eb669e9819420ea4bd1453e672c0a7',
|
||||
created_at='1970-01-01T00:00:00.000000',
|
||||
updated_at='1970-01-01T00:00:00.000000'
|
||||
)
|
||||
@ -252,6 +256,8 @@ class Execution(resource.Resource):
|
||||
created_at = wtypes.text
|
||||
updated_at = wtypes.text
|
||||
|
||||
project_id = wsme.wsattr(wtypes.text, readonly=True)
|
||||
|
||||
@classmethod
|
||||
def sample(cls):
|
||||
return cls(id='123e4567-e89b-12d3-a456-426655440000',
|
||||
@ -259,6 +265,7 @@ class Execution(resource.Resource):
|
||||
workflow_namespace='some_namespace',
|
||||
workflow_id='123e4567-e89b-12d3-a456-426655441111',
|
||||
description='this is the first execution.',
|
||||
project_id='40a908dbddfe48ad80a87fb30fa70a03',
|
||||
state='SUCCESS',
|
||||
input={},
|
||||
output={},
|
||||
@ -309,6 +316,8 @@ class Task(resource.Resource):
|
||||
state_info = wtypes.text
|
||||
"an optional state information string"
|
||||
|
||||
project_id = wsme.wsattr(wtypes.text, readonly=True)
|
||||
|
||||
runtime_context = types.jsontype
|
||||
|
||||
result = wtypes.text
|
||||
@ -332,6 +341,7 @@ class Task(resource.Resource):
|
||||
workflow_execution_id='123e4567-e89b-12d3-a456-426655440000',
|
||||
name='task',
|
||||
state=states.SUCCESS,
|
||||
project_id='40a908dbddfe48ad80a87fb30fa70a03',
|
||||
runtime_context={
|
||||
'triggered_by': [
|
||||
{
|
||||
@ -380,6 +390,7 @@ class ActionExecution(resource.Resource):
|
||||
tags = [wtypes.text]
|
||||
name = wtypes.text
|
||||
description = wtypes.text
|
||||
project_id = wsme.wsattr(wtypes.text, readonly=True)
|
||||
accepted = bool
|
||||
input = types.jsontype
|
||||
output = types.jsontype
|
||||
@ -400,6 +411,7 @@ class ActionExecution(resource.Resource):
|
||||
tags=['foo', 'fee'],
|
||||
name='std.echo',
|
||||
description='My running action',
|
||||
project_id='40a908dbddfe48ad80a87fb30fa70a03',
|
||||
accepted=True,
|
||||
input={'first_name': 'John', 'last_name': 'Doe'},
|
||||
output={'some_output': 'Hello, John Doe!'},
|
||||
@ -433,6 +445,7 @@ class CronTrigger(resource.Resource):
|
||||
workflow_id = wtypes.text
|
||||
workflow_input = types.jsontype
|
||||
workflow_params = types.jsontype
|
||||
project_id = wsme.wsattr(wtypes.text, readonly=True)
|
||||
|
||||
scope = SCOPE_TYPES
|
||||
|
||||
@ -453,6 +466,7 @@ class CronTrigger(resource.Resource):
|
||||
workflow_id='123e4567-e89b-12d3-a456-426655441111',
|
||||
workflow_input={},
|
||||
workflow_params={},
|
||||
project_id='40a908dbddfe48ad80a87fb30fa70a03',
|
||||
scope='private',
|
||||
pattern='* * * * *',
|
||||
remaining_executions=42,
|
||||
@ -484,6 +498,7 @@ class Environment(resource.Resource):
|
||||
description = wtypes.text
|
||||
variables = types.jsontype
|
||||
scope = SCOPE_TYPES
|
||||
project_id = wsme.wsattr(wtypes.text, readonly=True)
|
||||
created_at = wtypes.text
|
||||
updated_at = wtypes.text
|
||||
|
||||
@ -500,6 +515,7 @@ class Environment(resource.Resource):
|
||||
'verbose': True
|
||||
},
|
||||
scope='private',
|
||||
project_id='40a908dbddfe48ad80a87fb30fa70a03',
|
||||
created_at='1970-01-01T00:00:00.000000',
|
||||
updated_at='1970-01-01T00:00:00.000000'
|
||||
)
|
||||
|
@ -206,6 +206,9 @@ MOCK_EMPTY = mock.MagicMock(return_value=[])
|
||||
MOCK_NOT_FOUND = mock.MagicMock(side_effect=exc.DBEntityNotFoundError())
|
||||
MOCK_DELETE = mock.MagicMock(return_value=None)
|
||||
|
||||
ACTION_EX_DB_WITH_PROJECT_ID = AD_HOC_ACTION_EX_DB.get_clone()
|
||||
ACTION_EX_DB_WITH_PROJECT_ID.project_id = '<default-project>'
|
||||
|
||||
|
||||
@mock.patch.object(rpc_base, '_IMPL_CLIENT', mock.Mock())
|
||||
class TestActionExecutionsController(base.APITest):
|
||||
@ -236,6 +239,14 @@ class TestActionExecutionsController(base.APITest):
|
||||
|
||||
self.assertEqual(404, resp.status_int)
|
||||
|
||||
@mock.patch.object(db_api, 'get_action_execution',
|
||||
return_value=ACTION_EX_DB_WITH_PROJECT_ID)
|
||||
def test_get_within_project_id(self, mock_get):
|
||||
resp = self.app.get('/v2/action_executions/123')
|
||||
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertTrue('project_id' in resp.json)
|
||||
|
||||
@mock.patch.object(rpc_clients.EngineClient, 'start_action')
|
||||
def test_post(self, f):
|
||||
f.return_value = ACTION_EX_DB.to_dict()
|
||||
|
@ -95,6 +95,9 @@ ACTION_DB.update(ACTION)
|
||||
SYSTEM_ACTION_DB = models.ActionDefinition()
|
||||
SYSTEM_ACTION_DB.update(SYSTEM_ACTION)
|
||||
|
||||
PROJECT_ID_ACTION_DB = ACTION_DB.get_clone()
|
||||
PROJECT_ID_ACTION_DB.project_id = '<default-project>'
|
||||
|
||||
UPDATED_ACTION_DEFINITION = """
|
||||
---
|
||||
version: '2.0'
|
||||
@ -155,6 +158,14 @@ class TestActionsController(base.APITest):
|
||||
|
||||
self.assertEqual(404, resp.status_int)
|
||||
|
||||
@mock.patch.object(
|
||||
db_api, "get_action_definition", return_value=PROJECT_ID_ACTION_DB)
|
||||
def test_get_within_project_id(self, mock_get):
|
||||
url = '/v2/actions/1234'
|
||||
resp = self.app.get(url, expect_errors=True)
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertTrue('project_id' in resp.json)
|
||||
|
||||
@mock.patch.object(
|
||||
db_api, "get_action_definition", MOCK_ACTION)
|
||||
@mock.patch.object(
|
||||
|
@ -57,6 +57,8 @@ trigger_values['workflow_params'] = json.loads(
|
||||
|
||||
TRIGGER_DB = models.CronTrigger()
|
||||
TRIGGER_DB.update(trigger_values)
|
||||
TRIGGER_DB_WITH_PROJECT_ID = TRIGGER_DB.get_clone()
|
||||
TRIGGER_DB_WITH_PROJECT_ID.project_id = '<default-project>'
|
||||
|
||||
MOCK_WF = mock.MagicMock(return_value=WF)
|
||||
MOCK_TRIGGER = mock.MagicMock(return_value=TRIGGER_DB)
|
||||
@ -75,6 +77,14 @@ class TestCronTriggerController(base.APITest):
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertDictEqual(TRIGGER, resp.json)
|
||||
|
||||
@mock.patch.object(db_api, "get_cron_trigger",
|
||||
return_value=TRIGGER_DB_WITH_PROJECT_ID)
|
||||
def test_get_within_project_id(self, mock_get):
|
||||
resp = self.app.get('/v2/cron_triggers/my_cron_trigger')
|
||||
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertTrue('project_id' in resp.json)
|
||||
|
||||
@mock.patch.object(db_api, "get_cron_trigger", MOCK_NOT_FOUND)
|
||||
def test_get_not_found(self):
|
||||
resp = self.app.get(
|
||||
|
@ -66,6 +66,7 @@ ENVIRONMENT = {
|
||||
'description': 'my test settings',
|
||||
'variables': VARIABLES,
|
||||
'scope': 'private',
|
||||
'project_id': '<default-project>',
|
||||
'created_at': str(datetime.datetime.utcnow()),
|
||||
'updated_at': str(datetime.datetime.utcnow())
|
||||
}
|
||||
@ -85,12 +86,16 @@ ENVIRONMENT_DB = db.Environment(
|
||||
description=ENVIRONMENT['description'],
|
||||
variables=copy.deepcopy(VARIABLES),
|
||||
scope=ENVIRONMENT['scope'],
|
||||
project_id=ENVIRONMENT['project_id'],
|
||||
created_at=datetime.datetime.strptime(ENVIRONMENT['created_at'],
|
||||
DATETIME_FORMAT),
|
||||
updated_at=datetime.datetime.strptime(ENVIRONMENT['updated_at'],
|
||||
DATETIME_FORMAT)
|
||||
)
|
||||
|
||||
ENVIRONMENT_DB_WITH_PROJECT_ID = ENVIRONMENT_DB.get_clone()
|
||||
ENVIRONMENT_DB_WITH_PROJECT_ID.project_id = '<default-project>'
|
||||
|
||||
ENVIRONMENT_DB_DICT = {k: v for k, v in ENVIRONMENT_DB.items()}
|
||||
|
||||
UPDATED_VARIABLES = copy.deepcopy(VARIABLES)
|
||||
@ -168,6 +173,14 @@ class TestEnvironmentController(base.APITest):
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self._assert_dict_equal(ENVIRONMENT, resp.json)
|
||||
|
||||
@mock.patch.object(db_api, 'get_environment',
|
||||
return_value=ENVIRONMENT_DB_WITH_PROJECT_ID)
|
||||
def test_get_within_project_id(self, mock_get):
|
||||
resp = self.app.get('/v2/environments/123')
|
||||
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertEqual('<default-project>', resp.json['project_id'])
|
||||
|
||||
@mock.patch.object(db_api, "get_environment", MOCK_NOT_FOUND)
|
||||
def test_get_not_found(self):
|
||||
resp = self.app.get('/v2/environments/123', expect_errors=True)
|
||||
|
@ -121,6 +121,8 @@ UPDATED_WF_EX_ENV_DESC['params'] = {'env': {'k1': 'def'}}
|
||||
|
||||
WF_EX_JSON_WITH_DESC = copy.deepcopy(WF_EX_JSON)
|
||||
WF_EX_JSON_WITH_DESC['description'] = WF_EX.description
|
||||
WF_EX_WITH_PROJECT_ID = WF_EX.get_clone()
|
||||
WF_EX_WITH_PROJECT_ID.project_id = '<default-project>'
|
||||
|
||||
MOCK_WF_EX = mock.MagicMock(return_value=WF_EX)
|
||||
MOCK_SUB_WF_EX = mock.MagicMock(return_value=SUB_WF_EX)
|
||||
@ -154,6 +156,13 @@ class TestExecutionsController(base.APITest):
|
||||
|
||||
self.assertEqual(404, resp.status_int)
|
||||
|
||||
@mock.patch.object(db_api, 'get_workflow_execution',
|
||||
return_value=WF_EX_WITH_PROJECT_ID)
|
||||
def test_get_within_project_id(self, mock_get):
|
||||
resp = self.app.get('/v2/executions/123', expect_errors=True)
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertTrue('project_id' in resp.json)
|
||||
|
||||
@mock.patch.object(
|
||||
db_api,
|
||||
'ensure_workflow_execution_exists',
|
||||
|
@ -143,6 +143,9 @@ MOCK_NOT_FOUND = mock.MagicMock(side_effect=exc.DBEntityNotFoundError())
|
||||
MOCK_ERROR_TASK = mock.MagicMock(return_value=ERROR_TASK_EX)
|
||||
MOCK_ERROR_ITEMS_TASK = mock.MagicMock(return_value=ERROR_ITEMS_TASK_EX)
|
||||
|
||||
TASK_EX_WITH_PROJECT_ID = TASK_EX.get_clone()
|
||||
TASK_EX_WITH_PROJECT_ID.project_id = '<default-project>'
|
||||
|
||||
|
||||
@mock.patch.object(
|
||||
data_flow,
|
||||
@ -171,6 +174,14 @@ class TestTasksController(base.APITest):
|
||||
self.assertEqual(1, len(resp.json['tasks']))
|
||||
self.assertDictEqual(TASK_WITHOUT_RESULT, resp.json['tasks'][0])
|
||||
|
||||
@mock.patch.object(db_api, 'get_task_execution',
|
||||
return_value=TASK_EX_WITH_PROJECT_ID)
|
||||
def test_get_within_project_id(self, mock_get):
|
||||
resp = self.app.get('/v2/tasks/123')
|
||||
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertTrue('project_id' in resp.json)
|
||||
|
||||
@mock.patch.object(db_api, 'get_task_executions', MOCK_EMPTY)
|
||||
def test_get_all_empty(self):
|
||||
resp = self.app.get('/v2/tasks')
|
||||
|
@ -55,6 +55,9 @@ WORKBOOK = {
|
||||
'updated_at': '1970-01-01 00:00:00'
|
||||
}
|
||||
|
||||
WORKBOOK_DB_PROJECT_ID = WORKBOOK_DB.get_clone()
|
||||
WORKBOOK_DB_PROJECT_ID.project_id = '<default-project>'
|
||||
|
||||
UPDATED_WORKBOOK_DB = copy.copy(WORKBOOK_DB)
|
||||
UPDATED_WORKBOOK_DB['definition'] = UPDATED_WORKBOOK_DEF
|
||||
UPDATED_WORKBOOK = copy.deepcopy(WORKBOOK)
|
||||
@ -115,6 +118,14 @@ class TestWorkbooksController(base.APITest):
|
||||
|
||||
self.assertEqual(404, resp.status_int)
|
||||
|
||||
@mock.patch.object(db_api, "get_workbook",
|
||||
return_value=WORKBOOK_DB_PROJECT_ID)
|
||||
def test_get_within_project_id(self, mock_get):
|
||||
resp = self.app.get('/v2/workbooks/123')
|
||||
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertTrue('project_id' in resp.json)
|
||||
|
||||
@mock.patch.object(workbooks, "update_workbook_v2", MOCK_UPDATED_WORKBOOK)
|
||||
def test_put(self):
|
||||
resp = self.app.put(
|
||||
|
@ -111,6 +111,9 @@ WF_WITH_DEFAULT_INPUT = {
|
||||
'input': 'param1, param2=2'
|
||||
}
|
||||
|
||||
WF_DB_PROJECT_ID = WF_DB.get_clone()
|
||||
WF_DB_PROJECT_ID.project_id = '<default-project>'
|
||||
|
||||
UPDATED_WF_DEFINITION = """
|
||||
---
|
||||
version: '2.0'
|
||||
@ -666,3 +669,11 @@ class TestWorkflowsController(base.APITest):
|
||||
namespace='abc'
|
||||
)
|
||||
self.assertDictEqual(WF_WITH_NAMESPACE, resp.json)
|
||||
|
||||
@mock.patch.object(db_api, "get_workflow_definition")
|
||||
def test_workflow_within_project_id(self, mock_get):
|
||||
mock_get.return_value = WF_DB_PROJECT_ID
|
||||
resp = self.app.get(
|
||||
'/v2/workflows/123e4567-e89b-12d3-a456-426655440000')
|
||||
self.assertEqual(200, resp.status_int)
|
||||
self.assertTrue('project_id' in resp.json)
|
||||
|
Loading…
x
Reference in New Issue
Block a user