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 | /deployments | Get list of deployments for all |
|
||||
| | | environments in user's project |
|
||||
+----------+---------------------------------------------------------------------------+
|
||||
|
||||
*Response*
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
"add_category": "rule:admin_api",
|
||||
|
||||
"list_deployments": "rule:default",
|
||||
"list_deployments_all_environments": "rule:default",
|
||||
"statuses_deployments": "rule:default",
|
||||
|
||||
"list_environments": "rule:default",
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
from oslo_log import log as logging
|
||||
from sqlalchemy import desc
|
||||
from sqlalchemy.orm import load_only
|
||||
from webob import exc
|
||||
|
||||
from murano.api.v1 import request_statistics
|
||||
@ -24,7 +25,7 @@ from murano.common import utils
|
||||
from murano.common import wsgi
|
||||
from murano.db import models
|
||||
from murano.db import session as db_session
|
||||
from murano.utils import verify_env
|
||||
from murano.utils import check_env
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -33,18 +34,41 @@ API_NAME = 'Deployments'
|
||||
|
||||
class Controller(object):
|
||||
@request_statistics.stats_count(API_NAME, 'Index')
|
||||
@verify_env
|
||||
def index(self, request, environment_id):
|
||||
def index(self, request, environment_id=None):
|
||||
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}
|
||||
policy.check("list_deployments", request.context, target)
|
||||
|
||||
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) \
|
||||
.filter_by(environment_id=environment_id) \
|
||||
.order_by(desc(models.Task.created))
|
||||
result = query.all()
|
||||
deployments = [set_dep_state(deployment, unit).to_dict() for deployment
|
||||
in result]
|
||||
deployments = [set_dep_state(deployment, unit).to_dict()
|
||||
for deployment in result]
|
||||
return {'deployments': deployments}
|
||||
|
||||
@request_statistics.stats_count(API_NAME, 'Statuses')
|
||||
|
@ -168,6 +168,10 @@ class API(wsgi.Router):
|
||||
controller=deployments_resource,
|
||||
action='statuses',
|
||||
conditions={'method': ['GET']})
|
||||
mapper.connect('/deployments',
|
||||
controller=deployments_resource,
|
||||
action='index',
|
||||
conditions={'method': ['GET']})
|
||||
|
||||
sessions_resource = sessions.create_resource()
|
||||
mapper.connect('/environments/{environment_id}/configure',
|
||||
|
@ -39,25 +39,156 @@ class TestDeploymentsApi(tb.ControllerTest, tb.MuranoApiTestCase):
|
||||
{'create_environment': '@',
|
||||
'list_deployments': '@'}
|
||||
)
|
||||
self.expect_policy_check('create_environment')
|
||||
|
||||
# Create environment
|
||||
# Create an environment.
|
||||
self.expect_policy_check('create_environment')
|
||||
request = self._post(
|
||||
'/environments',
|
||||
jsonutils.dump_as_bytes({'name': 'test_environment_1'}),
|
||||
**CREDENTIALS
|
||||
)
|
||||
response_body = jsonutils.loads(request.get_response(self.api).body)
|
||||
self.assertEqual(CREDENTIALS['tenant'],
|
||||
response_body['tenant_id'])
|
||||
|
||||
self.assertEqual(CREDENTIALS['tenant'], response_body['tenant_id'])
|
||||
self.assertEqual('test_environment_1', response_body['name'])
|
||||
ENVIRONMENT_ID = response_body['id']
|
||||
|
||||
# Verify that the environment has not yet been deployed.
|
||||
self.expect_policy_check('list_deployments',
|
||||
{'environment_id': ENVIRONMENT_ID})
|
||||
result = self.deployments_controller.index(request, ENVIRONMENT_ID)
|
||||
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):
|
||||
CREDENTIALS = {'tenant': 'test_tenant_1', 'user': 'test_user_1'}
|
||||
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