Allows fetching of deployments from all environments.
Adds new endpoint /deployments to Murano, to enable Murano Dashboard to get all deployments for all environments. This is needed in order to improve log browsing for deployments, which calls for creating a new view in which all deployments across all environments can be viewed. Also made deployment unit tests more robust. Partially-implements: blueprint improve-deployment-log-browsing Change-Id: I1b6a313af1a0c4aa57bd4e6f51da92b396b35165
This commit is contained in:
parent
e9fa1114bf
commit
c30c27fb0c
@ -679,6 +679,9 @@ Returns information about all deployments of the specified environment.
|
|||||||
+==========+====================================+======================================+
|
+==========+====================================+======================================+
|
||||||
| GET | /environments/<env_id>/deployments | Get list of environment deployments |
|
| GET | /environments/<env_id>/deployments | Get list of environment deployments |
|
||||||
+----------+------------------------------------+--------------------------------------+
|
+----------+------------------------------------+--------------------------------------+
|
||||||
|
| GET | /deployments | Get list of deployments for all |
|
||||||
|
| | | environments in user's project |
|
||||||
|
+----------+---------------------------------------------------------------------------+
|
||||||
|
|
||||||
*Response*
|
*Response*
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"add_category": "rule:admin_api",
|
"add_category": "rule:admin_api",
|
||||||
|
|
||||||
"list_deployments": "rule:default",
|
"list_deployments": "rule:default",
|
||||||
|
"list_deployments_all_environments": "rule:default",
|
||||||
"statuses_deployments": "rule:default",
|
"statuses_deployments": "rule:default",
|
||||||
|
|
||||||
"list_environments": "rule:default",
|
"list_environments": "rule:default",
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from sqlalchemy import desc
|
from sqlalchemy import desc
|
||||||
|
from sqlalchemy.orm import load_only
|
||||||
from webob import exc
|
from webob import exc
|
||||||
|
|
||||||
from murano.api.v1 import request_statistics
|
from murano.api.v1 import request_statistics
|
||||||
@ -24,7 +25,7 @@ from murano.common import utils
|
|||||||
from murano.common import wsgi
|
from murano.common import wsgi
|
||||||
from murano.db import models
|
from murano.db import models
|
||||||
from murano.db import session as db_session
|
from murano.db import session as db_session
|
||||||
from murano.utils import verify_env
|
from murano.utils import check_env
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -33,18 +34,41 @@ API_NAME = 'Deployments'
|
|||||||
|
|
||||||
class Controller(object):
|
class Controller(object):
|
||||||
@request_statistics.stats_count(API_NAME, 'Index')
|
@request_statistics.stats_count(API_NAME, 'Index')
|
||||||
@verify_env
|
def index(self, request, environment_id=None):
|
||||||
def index(self, request, environment_id):
|
all_environments = environment_id is None
|
||||||
|
LOG.debug('Deployments:List <all_environments: {0}>'
|
||||||
|
.format(all_environments))
|
||||||
|
|
||||||
|
if all_environments:
|
||||||
|
policy.check("list_deployments_all_environments", request.context)
|
||||||
|
else:
|
||||||
|
check_env(request, environment_id)
|
||||||
target = {"environment_id": environment_id}
|
target = {"environment_id": environment_id}
|
||||||
policy.check("list_deployments", request.context, target)
|
policy.check("list_deployments", request.context, target)
|
||||||
|
|
||||||
unit = db_session.get_session()
|
unit = db_session.get_session()
|
||||||
|
|
||||||
|
if all_environments:
|
||||||
|
query = unit.query(models.Environment) \
|
||||||
|
.options(load_only('tenant_id')) \
|
||||||
|
.filter_by(tenant_id=request.context.tenant) \
|
||||||
|
.join(models.Task) \
|
||||||
|
.order_by(desc(models.Task.created))
|
||||||
|
result = query.all()
|
||||||
|
# The join statement above fetches the deployments into
|
||||||
|
# Environment.tasks. Iterate over that to get the deployments.
|
||||||
|
deployments = []
|
||||||
|
for row in result:
|
||||||
|
for deployment in row.tasks:
|
||||||
|
deployment = set_dep_state(deployment, unit).to_dict()
|
||||||
|
deployments.append(deployment)
|
||||||
|
else:
|
||||||
query = unit.query(models.Task) \
|
query = unit.query(models.Task) \
|
||||||
.filter_by(environment_id=environment_id) \
|
.filter_by(environment_id=environment_id) \
|
||||||
.order_by(desc(models.Task.created))
|
.order_by(desc(models.Task.created))
|
||||||
result = query.all()
|
result = query.all()
|
||||||
deployments = [set_dep_state(deployment, unit).to_dict() for deployment
|
deployments = [set_dep_state(deployment, unit).to_dict()
|
||||||
in result]
|
for deployment in result]
|
||||||
return {'deployments': deployments}
|
return {'deployments': deployments}
|
||||||
|
|
||||||
@request_statistics.stats_count(API_NAME, 'Statuses')
|
@request_statistics.stats_count(API_NAME, 'Statuses')
|
||||||
|
@ -168,6 +168,10 @@ class API(wsgi.Router):
|
|||||||
controller=deployments_resource,
|
controller=deployments_resource,
|
||||||
action='statuses',
|
action='statuses',
|
||||||
conditions={'method': ['GET']})
|
conditions={'method': ['GET']})
|
||||||
|
mapper.connect('/deployments',
|
||||||
|
controller=deployments_resource,
|
||||||
|
action='index',
|
||||||
|
conditions={'method': ['GET']})
|
||||||
|
|
||||||
sessions_resource = sessions.create_resource()
|
sessions_resource = sessions.create_resource()
|
||||||
mapper.connect('/environments/{environment_id}/configure',
|
mapper.connect('/environments/{environment_id}/configure',
|
||||||
|
@ -39,25 +39,156 @@ class TestDeploymentsApi(tb.ControllerTest, tb.MuranoApiTestCase):
|
|||||||
{'create_environment': '@',
|
{'create_environment': '@',
|
||||||
'list_deployments': '@'}
|
'list_deployments': '@'}
|
||||||
)
|
)
|
||||||
self.expect_policy_check('create_environment')
|
|
||||||
|
|
||||||
# Create environment
|
# Create an environment.
|
||||||
|
self.expect_policy_check('create_environment')
|
||||||
request = self._post(
|
request = self._post(
|
||||||
'/environments',
|
'/environments',
|
||||||
jsonutils.dump_as_bytes({'name': 'test_environment_1'}),
|
jsonutils.dump_as_bytes({'name': 'test_environment_1'}),
|
||||||
**CREDENTIALS
|
**CREDENTIALS
|
||||||
)
|
)
|
||||||
response_body = jsonutils.loads(request.get_response(self.api).body)
|
response_body = jsonutils.loads(request.get_response(self.api).body)
|
||||||
self.assertEqual(CREDENTIALS['tenant'],
|
self.assertEqual(CREDENTIALS['tenant'], response_body['tenant_id'])
|
||||||
response_body['tenant_id'])
|
self.assertEqual('test_environment_1', response_body['name'])
|
||||||
|
|
||||||
ENVIRONMENT_ID = response_body['id']
|
ENVIRONMENT_ID = response_body['id']
|
||||||
|
|
||||||
|
# Verify that the environment has not yet been deployed.
|
||||||
self.expect_policy_check('list_deployments',
|
self.expect_policy_check('list_deployments',
|
||||||
{'environment_id': ENVIRONMENT_ID})
|
{'environment_id': ENVIRONMENT_ID})
|
||||||
result = self.deployments_controller.index(request, ENVIRONMENT_ID)
|
result = self.deployments_controller.index(request, ENVIRONMENT_ID)
|
||||||
self.assertEqual([], result['deployments'])
|
self.assertEqual([], result['deployments'])
|
||||||
|
|
||||||
|
# Deploy the environment.
|
||||||
|
request = self._post('/environments/{environment_id}/configure'
|
||||||
|
.format(environment_id=ENVIRONMENT_ID),
|
||||||
|
b'', **CREDENTIALS)
|
||||||
|
response_body = jsonutils.loads(request.get_response(self.api).body)
|
||||||
|
|
||||||
|
SESSION_ID = response_body['id']
|
||||||
|
|
||||||
|
request = self._post('/environments/{environment_id}/sessions/'
|
||||||
|
'{session_id}/deploy'
|
||||||
|
.format(environment_id=ENVIRONMENT_ID,
|
||||||
|
session_id=SESSION_ID),
|
||||||
|
b'', **CREDENTIALS)
|
||||||
|
result = request.get_response(self.api)
|
||||||
|
self.assertEqual('200 OK', result.status)
|
||||||
|
|
||||||
|
# Verify that the environment was deployed.
|
||||||
|
self.expect_policy_check('list_deployments',
|
||||||
|
{'environment_id': ENVIRONMENT_ID})
|
||||||
|
result = self.deployments_controller.index(request, ENVIRONMENT_ID)
|
||||||
|
deployment_id = result['deployments'][0]['id']
|
||||||
|
self.assertEqual(1, len(result['deployments']))
|
||||||
|
self.assertIsNotNone(deployment_id)
|
||||||
|
|
||||||
|
def test_deployments_all_environments(self):
|
||||||
|
"""Test list deployments for all environments.
|
||||||
|
|
||||||
|
Create 2 environments, deploy both, and check that 2 deployments exist.
|
||||||
|
"""
|
||||||
|
CREDENTIALS = {'tenant': 'test_tenant_1', 'user': 'test_user_1'}
|
||||||
|
self._set_policy_rules(
|
||||||
|
{'create_environment': '@',
|
||||||
|
'list_deployments_all_environments': '@'}
|
||||||
|
)
|
||||||
|
|
||||||
|
for count in range(2):
|
||||||
|
# Create environment.
|
||||||
|
self.expect_policy_check('create_environment')
|
||||||
|
request = self._post(
|
||||||
|
'/environments',
|
||||||
|
jsonutils.dump_as_bytes(
|
||||||
|
{'name': 'test_environment_{0}'.format(count)}),
|
||||||
|
**CREDENTIALS
|
||||||
|
)
|
||||||
|
response_body = jsonutils.loads(
|
||||||
|
request.get_response(self.api).body)
|
||||||
|
self.assertEqual(CREDENTIALS['tenant'], response_body['tenant_id'])
|
||||||
|
self.assertEqual('test_environment_{0}'.format(count),
|
||||||
|
response_body['name'])
|
||||||
|
ENVIRONMENT_ID = response_body['id']
|
||||||
|
|
||||||
|
# Deploy environment.
|
||||||
|
request = self._post('/environments/{environment_id}/configure'
|
||||||
|
.format(environment_id=ENVIRONMENT_ID),
|
||||||
|
b'', **CREDENTIALS)
|
||||||
|
response_body = jsonutils.loads(
|
||||||
|
request.get_response(self.api).body)
|
||||||
|
SESSION_ID = response_body['id']
|
||||||
|
request = self._post('/environments/{environment_id}/sessions/'
|
||||||
|
'{session_id}/deploy'
|
||||||
|
.format(environment_id=ENVIRONMENT_ID,
|
||||||
|
session_id=SESSION_ID),
|
||||||
|
b'', **CREDENTIALS)
|
||||||
|
result = request.get_response(self.api)
|
||||||
|
self.assertEqual('200 OK', result.status)
|
||||||
|
|
||||||
|
# Check that 2 deployments exist.
|
||||||
|
self.expect_policy_check('list_deployments_all_environments')
|
||||||
|
result = self.deployments_controller.index(request, None)
|
||||||
|
self.assertEqual(2, len(result['deployments']))
|
||||||
|
for deployment in result['deployments']:
|
||||||
|
self.assertIsNotNone(deployment)
|
||||||
|
self.assertNotEqual(result['deployments'][0], result['deployments'][1])
|
||||||
|
|
||||||
|
def test_deployments_all_environments_different_tenants(self):
|
||||||
|
"""Test list deployments for all environments in different tenants.
|
||||||
|
|
||||||
|
Should only return return environments for current tenant.
|
||||||
|
"""
|
||||||
|
CREDENTIALS = {'tenant': 'test_tenant_1', 'user': 'test_user_1'}
|
||||||
|
ALT_CREDENTIALS = {'tenant': 'test_tenant_2', 'user': 'test_user_2'}
|
||||||
|
self._set_policy_rules(
|
||||||
|
{'create_environment': '@',
|
||||||
|
'list_deployments_all_environments': '@'}
|
||||||
|
)
|
||||||
|
|
||||||
|
deployments = []
|
||||||
|
|
||||||
|
# Create the first environment inside first tenant and the second
|
||||||
|
# environments inside the alternate tenant. Then deploy both.
|
||||||
|
for count, creds in enumerate([CREDENTIALS, ALT_CREDENTIALS]):
|
||||||
|
# Create each environment.
|
||||||
|
self.expect_policy_check('create_environment')
|
||||||
|
request = self._post(
|
||||||
|
'/environments',
|
||||||
|
jsonutils.dump_as_bytes(
|
||||||
|
{'name': 'test_environment_{0}'.format(count)}),
|
||||||
|
**creds
|
||||||
|
)
|
||||||
|
response_body = jsonutils.loads(
|
||||||
|
request.get_response(self.api).body)
|
||||||
|
self.assertEqual(creds['tenant'], response_body['tenant_id'])
|
||||||
|
self.assertEqual('test_environment_{0}'.format(count),
|
||||||
|
response_body['name'])
|
||||||
|
ENVIRONMENT_ID = response_body['id']
|
||||||
|
|
||||||
|
# Deploy each environment.
|
||||||
|
request = self._post('/environments/{environment_id}/configure'
|
||||||
|
.format(environment_id=ENVIRONMENT_ID),
|
||||||
|
b'', **creds)
|
||||||
|
response_body = jsonutils.loads(
|
||||||
|
request.get_response(self.api).body)
|
||||||
|
SESSION_ID = response_body['id']
|
||||||
|
request = self._post('/environments/{environment_id}/sessions/'
|
||||||
|
'{session_id}/deploy'
|
||||||
|
.format(environment_id=ENVIRONMENT_ID,
|
||||||
|
session_id=SESSION_ID),
|
||||||
|
b'', **creds)
|
||||||
|
result = request.get_response(self.api)
|
||||||
|
self.assertEqual('200 OK', result.status)
|
||||||
|
|
||||||
|
# Check that each tenant only returns one deployment.
|
||||||
|
self.expect_policy_check('list_deployments_all_environments')
|
||||||
|
result = self.deployments_controller.index(request, None)
|
||||||
|
self.assertEqual(1, len(result['deployments']))
|
||||||
|
deployment_id = result['deployments'][0]['id']
|
||||||
|
self.assertIsNotNone(deployment_id)
|
||||||
|
deployments.append(deployment_id)
|
||||||
|
|
||||||
|
self.assertNotEqual(deployments[0], deployments[1])
|
||||||
|
|
||||||
def test_deployments_not_found_statuses(self):
|
def test_deployments_not_found_statuses(self):
|
||||||
CREDENTIALS = {'tenant': 'test_tenant_1', 'user': 'test_user_1'}
|
CREDENTIALS = {'tenant': 'test_tenant_1', 'user': 'test_user_1'}
|
||||||
self._set_policy_rules(
|
self._set_policy_rules(
|
||||||
|
5
releasenotes/notes/deployment-list-8c2da5a5efc6dbac.yaml
Normal file
5
releasenotes/notes/deployment-list-8c2da5a5efc6dbac.yaml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- It is now possible to make a GET request to '/deployments' endpoint.
|
||||||
|
This will result in deployments for all environments in a specific project
|
||||||
|
(tenant) being returned.
|
Loading…
Reference in New Issue
Block a user