Merge "Public environment template"
This commit is contained in:
commit
4d8799e453
@ -65,6 +65,13 @@ List Environments Templates
|
||||
| | | environment templates |
|
||||
+----------+----------------------------------+----------------------------------+
|
||||
|
||||
*Parameters:*
|
||||
|
||||
* `is_public` - boolean, indicates whether public environment templates are listed or not.
|
||||
*True* public environments templates from all tenants are listed.
|
||||
*False* private environments templates from current tenant are listed
|
||||
*empty* all tenant templates plus public templates from all tenants are listed
|
||||
|
||||
*Response*
|
||||
|
||||
This call returns a list of environment templates. Only the basic properties are
|
||||
@ -81,6 +88,7 @@ returned.
|
||||
"created": "2014-05-14T13:02:46",
|
||||
"tenant_id": "726ed856965f43cc8e565bc991fa76c3",
|
||||
"version": 0,
|
||||
"is_public": false,
|
||||
"id": "2fa5ab704749444bbeafe7991b412c33"
|
||||
},
|
||||
{
|
||||
@ -88,8 +96,9 @@ returned.
|
||||
"networking": {},
|
||||
"name": "test2",
|
||||
"created": "2014-05-14T13:02:51",
|
||||
"tenant_id": "726ed856965f43cc8e565bc991fa76c3",
|
||||
"tenant_id": "123452452345346345634563456345346",
|
||||
"version": 0,
|
||||
"is_public": true,
|
||||
"id": "744e44812da84e858946f5d817de4f72"
|
||||
}
|
||||
]
|
||||
@ -414,3 +423,58 @@ Create an environment from an environment template
|
||||
+----------------+-----------------------------------------------------------+
|
||||
| 409 | The environment already exists |
|
||||
+----------------+-----------------------------------------------------------+
|
||||
|
||||
|
||||
**POST /templates/{env-temp-id}/clone**
|
||||
|
||||
*Request*
|
||||
|
||||
+----------+--------------------------------+-------------------------------------------------+
|
||||
| Method | URI | Description |
|
||||
+==========+================================+=================================================+
|
||||
| POST | /templates/{env-temp-id}/clone | It clones a public template from one tenant |
|
||||
| | | to another |
|
||||
+----------+--------------------------------+-------------------------------------------------+
|
||||
|
||||
*Parameters:*
|
||||
|
||||
* `env-temp-id` - environment template ID, required
|
||||
|
||||
*Example Payload*
|
||||
::
|
||||
|
||||
{
|
||||
'name': 'cloned_env_template_name'
|
||||
}
|
||||
|
||||
*Content-Type*
|
||||
application/json
|
||||
|
||||
*Response*
|
||||
|
||||
::
|
||||
|
||||
{
|
||||
"updated": "2015-01-26T09:12:51",
|
||||
"name": "cloned_env_template_name",
|
||||
"created": "2015-01-26T09:12:51",
|
||||
"tenant_id": "00000000000000000000000000000001",
|
||||
"version": 0,
|
||||
"is_public": False,
|
||||
"id": "aa9033ca7ce245fca10e38e1c8c4bbf7",
|
||||
}
|
||||
|
||||
+----------------+-----------------------------------------------------------+
|
||||
| Code | Description |
|
||||
+================+===========================================================+
|
||||
| 200 | OK. Environment Template cloned successfully |
|
||||
+----------------+-----------------------------------------------------------+
|
||||
| 401 | User is not authorized to access this session |
|
||||
+----------------+-----------------------------------------------------------+
|
||||
| 403 | User has no access to these resources |
|
||||
+----------------+-----------------------------------------------------------+
|
||||
| 404 | The environment template does not exist |
|
||||
+----------------+-----------------------------------------------------------+
|
||||
| 409 | Conflict. The environment template name already exists |
|
||||
+----------------+-----------------------------------------------------------+
|
||||
|
||||
|
@ -121,6 +121,10 @@ class API(wsgi.Router):
|
||||
controller=templates_resource,
|
||||
action='create_environment',
|
||||
conditions={'method': ['POST']})
|
||||
mapper.connect('/templates/{env_template_id}/clone',
|
||||
controller=templates_resource,
|
||||
action='clone',
|
||||
conditions={'method': ['POST']})
|
||||
|
||||
applications_resource = template_applications.create_resource()
|
||||
mapper.connect('/templates/{env_template_id}/services',
|
||||
|
@ -17,10 +17,11 @@ from oslo_log import log as logging
|
||||
from webob import exc
|
||||
|
||||
from murano.api.v1 import request_statistics
|
||||
from murano.common.i18n import _
|
||||
from murano.common.i18n import _, _LE
|
||||
from murano.common import policy
|
||||
from murano.common import utils
|
||||
from murano.common import wsgi
|
||||
from murano.db.models import EnvironmentTemplate
|
||||
from murano.db.services import core_services
|
||||
from murano.db.services import environment_templates as env_temps
|
||||
from murano.db.services import environments as envs
|
||||
@ -40,12 +41,27 @@ class Controller(object):
|
||||
"""
|
||||
LOG.debug('EnvTemplates:List')
|
||||
policy.check('list_env_templates', request.context)
|
||||
tenant_id = request.context.tenant
|
||||
filters = {}
|
||||
if request.GET.get('is_public'):
|
||||
is_public = request.GET.get('is_public', 'false').lower() == 'true'
|
||||
if not is_public:
|
||||
|
||||
filters['is_public'] = False
|
||||
filters = {'tenant_id': tenant_id}
|
||||
elif is_public:
|
||||
filters['is_public'] = True
|
||||
|
||||
list_templates = env_temps.EnvTemplateServices.\
|
||||
get_env_templates_by(filters)
|
||||
|
||||
else:
|
||||
filters = (EnvironmentTemplate.is_public is True,
|
||||
EnvironmentTemplate.tenant_id == tenant_id)
|
||||
list_templates = env_temps.EnvTemplateServices.\
|
||||
get_env_templates_or_by(filters)
|
||||
|
||||
filters = {'tenant_id': request.context.tenant}
|
||||
list_templates = env_temps.EnvTemplateServices.\
|
||||
get_env_templates_by(filters)
|
||||
list_templates = [temp.to_dict() for temp in list_templates]
|
||||
|
||||
return {"templates": list_templates}
|
||||
|
||||
@request_statistics.stats_count(API_NAME, 'Create')
|
||||
@ -59,24 +75,11 @@ class Controller(object):
|
||||
"""
|
||||
LOG.debug('EnvTemplates:Create <Body {body}>'.format(body=body))
|
||||
policy.check('create_env_template', request.context)
|
||||
|
||||
self._validate_body_name(body)
|
||||
try:
|
||||
LOG.debug('ENV TEMP NAME: {templ_name}>'.format(
|
||||
templ_name=body['name']))
|
||||
if not str(body['name']).strip():
|
||||
msg = _('Environment Template must contain at least one '
|
||||
'non-white space symbol')
|
||||
LOG.error(msg)
|
||||
raise exc.HTTPBadRequest(msg)
|
||||
except Exception:
|
||||
msg = _('Env template body is incorrect')
|
||||
LOG.exception(msg)
|
||||
raise exc.HTTPClientError(msg)
|
||||
if len(body['name']) > 255:
|
||||
msg = _('Environment Template name should be 255 characters '
|
||||
'maximum')
|
||||
LOG.exception(msg)
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
try:
|
||||
LOG.debug('ENV TEMP NAME: {templ_name}>'.
|
||||
format(templ_name=body['name']))
|
||||
template = env_temps.EnvTemplateServices.create(
|
||||
body.copy(), request.context.tenant)
|
||||
return template.to_dict()
|
||||
@ -172,23 +175,15 @@ class Controller(object):
|
||||
:param body: the environment name
|
||||
:return: session_id and environment_id
|
||||
"""
|
||||
LOG.debug('Templates:Create environment <Id: {templ_id}>'.
|
||||
format(templ_id=env_template_id))
|
||||
target = {"env_template_id": env_template_id}
|
||||
policy.check('create_environment', request.context, target)
|
||||
|
||||
self._validate_request(request, env_template_id)
|
||||
LOG.debug('Templates:Create environment <Id: {templ_id}>'.
|
||||
format(templ_id=env_template_id))
|
||||
template = env_temps.EnvTemplateServices.\
|
||||
get_env_template(env_template_id)
|
||||
|
||||
if ('name' not in body or not str(body['name']).strip()):
|
||||
msg = _('Environment Template must contain at least one '
|
||||
'non-white space symbol')
|
||||
LOG.error(msg)
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
LOG.debug('ENVIRONMENT NAME: {env_name}>'.format(
|
||||
env_name=body['name']))
|
||||
|
||||
self._validate_body_name(body)
|
||||
try:
|
||||
environment = envs.EnvironmentServices.create(
|
||||
body.copy(), request.context)
|
||||
@ -214,19 +209,75 @@ class Controller(object):
|
||||
)
|
||||
return {"session_id": session.id, "environment_id": environment.id}
|
||||
|
||||
@request_statistics.stats_count(API_NAME, 'Clone')
|
||||
def clone(self, request, env_template_id, body):
|
||||
"""It clones the env template from another env template
|
||||
from other tenant.
|
||||
:param request: the operation request.
|
||||
:param env_template_id: the env template ID.
|
||||
:param body: the request body.
|
||||
:return: the description of the created template.
|
||||
"""
|
||||
|
||||
LOG.debug('EnvTemplates:Clone <Env Template {0} for body {1}>'.
|
||||
format(body, env_template_id))
|
||||
policy.check('clone_env_template', request.context)
|
||||
|
||||
old_env_template = self._validate_exists(env_template_id)
|
||||
|
||||
if not old_env_template.get('is_public'):
|
||||
msg = _LE('User has no access to these resources.')
|
||||
LOG.error(msg)
|
||||
raise exc.HTTPForbidden(explanation=msg)
|
||||
self._validate_body_name(body)
|
||||
LOG.debug('ENV TEMP NAME: {0}'.format(body['name']))
|
||||
|
||||
try:
|
||||
is_public = body.get('is_public', False)
|
||||
template = env_temps.EnvTemplateServices.clone(
|
||||
env_template_id, request.context.tenant, body['name'],
|
||||
is_public)
|
||||
except db_exc.DBDuplicateEntry:
|
||||
msg = _('Environment with specified name already exists')
|
||||
LOG.error(msg)
|
||||
raise exc.HTTPConflict(explanation=msg)
|
||||
|
||||
return template.to_dict()
|
||||
|
||||
def _validate_request(self, request, env_template_id):
|
||||
self._validate_exists(env_template_id)
|
||||
get_env_template = env_temps.EnvTemplateServices.get_env_template
|
||||
env_template = get_env_template(env_template_id)
|
||||
if env_template.is_public or request.context.is_admin:
|
||||
return
|
||||
if env_template.tenant_id != request.context.tenant:
|
||||
msg = _LE('User has no access to these resources.')
|
||||
LOG.error(msg)
|
||||
raise exc.HTTPForbidden(explanation=msg)
|
||||
|
||||
def _validate_exists(self, env_template_id):
|
||||
env_template_exists = env_temps.EnvTemplateServices.env_template_exist
|
||||
if not env_template_exists(env_template_id):
|
||||
msg = _('EnvTemplate <TempId {temp_id}> is not found').format(
|
||||
temp_id=env_template_id)
|
||||
LOG.exception(msg)
|
||||
LOG.error(msg)
|
||||
raise exc.HTTPNotFound(explanation=msg)
|
||||
get_env_template = env_temps.EnvTemplateServices.get_env_template
|
||||
env_template = get_env_template(env_template_id)
|
||||
if env_template.tenant_id != request.context.tenant:
|
||||
msg = _('User is not authorized to access this tenant resources')
|
||||
LOG.error(msg)
|
||||
raise exc.HTTPForbidden(explanation=msg)
|
||||
return get_env_template(env_template_id)
|
||||
|
||||
def _validate_body_name(self, body):
|
||||
|
||||
if not('name' in body and body['name'].strip()):
|
||||
msg = _('Please, specify a name of the environment template.')
|
||||
LOG.exception(msg)
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
name = unicode(body['name'])
|
||||
if len(name) > 255:
|
||||
msg = _('Environment template name should be 255 characters '
|
||||
'maximum')
|
||||
LOG.exception(msg)
|
||||
raise exc.HTTPBadRequest(explanation=msg)
|
||||
|
||||
|
||||
def create_resource():
|
||||
|
@ -0,0 +1,44 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""
|
||||
Add the is_public column to the environment-template for public
|
||||
environment template functionality.
|
||||
|
||||
Revision ID: 011
|
||||
Revises: table template
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '011'
|
||||
down_revision = '010'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
MYSQL_ENGINE = 'InnoDB'
|
||||
MYSQL_CHARSET = 'utf8'
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column('environment-template',
|
||||
sa.Column('is_public', sa.Boolean(),
|
||||
default=False, nullable=True))
|
||||
# end Alembic commands #
|
||||
|
||||
|
||||
def downgrade():
|
||||
op.drop_column('environment-template', 'is_public')
|
||||
# end Alembic commands #
|
@ -97,6 +97,7 @@ class EnvironmentTemplate(Base, TimestampMixin):
|
||||
tenant_id = sa.Column(sa.String(36), nullable=False)
|
||||
version = sa.Column(sa.BigInteger, nullable=False, default=0)
|
||||
description = sa.Column(st.JsonBlob(), nullable=False, default={})
|
||||
is_public = sa.Column(sa.Boolean, default=False)
|
||||
|
||||
def to_dict(self):
|
||||
dictionary = super(EnvironmentTemplate, self).to_dict()
|
||||
|
@ -19,6 +19,7 @@ from murano.db import session as db_session
|
||||
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_log import log as logging
|
||||
from sqlalchemy.sql import or_
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
@ -38,6 +39,19 @@ class EnvTemplateServices(object):
|
||||
|
||||
return templates
|
||||
|
||||
@staticmethod
|
||||
def get_env_templates_or_by(filters):
|
||||
"""Returns list of environment-templates.
|
||||
|
||||
:param filters: property filters
|
||||
:return: Returns list of environment-templates
|
||||
"""
|
||||
unit = db_session.get_session()
|
||||
templates = unit.query(models.EnvironmentTemplate). \
|
||||
filter(or_(*filters)).all()
|
||||
|
||||
return templates
|
||||
|
||||
@staticmethod
|
||||
def create(env_template_params, tenant_id):
|
||||
"""Creates environment-template with specified params, in particular - name.
|
||||
@ -166,3 +180,32 @@ class EnvTemplateServices(object):
|
||||
"""
|
||||
session = db_session.get_session()
|
||||
return session.query(models.EnvironmentTemplate).get(env_template_id)
|
||||
|
||||
@staticmethod
|
||||
def clone(env_template_id, tenant_id, env_template_name, is_public):
|
||||
"""Clones environment-template with specified params, in particular - name.
|
||||
|
||||
:param env_template_params: Dict, e.g. {'name': 'temp-name'}
|
||||
:param tenant_id: Tenant Id
|
||||
:return: Created Template
|
||||
"""
|
||||
|
||||
template = EnvTemplateServices.get_env_template(env_template_id)
|
||||
env_template_params = template.to_dict()
|
||||
env_template_params['id'] = uuidutils.generate_uuid()
|
||||
env_template_params['tenant_id'] = tenant_id
|
||||
env_template_params['name'] = env_template_name
|
||||
env_template_params['is_public'] = is_public
|
||||
env_temp_desc = EnvTemplateServices.get_description(env_template_id)
|
||||
if "services" in env_temp_desc:
|
||||
env_template_params['services'] = env_temp_desc['services']
|
||||
|
||||
env_template = models.EnvironmentTemplate()
|
||||
env_template.update(env_template_params)
|
||||
|
||||
unit = db_session.get_session()
|
||||
with unit.begin():
|
||||
unit.add(env_template)
|
||||
env_template.update({'description': env_template_params})
|
||||
env_template.save(unit)
|
||||
return env_template
|
||||
|
@ -245,15 +245,40 @@ class MuranoClient(rest_client.RestClient):
|
||||
"""Check the environment templates deployed by the user."""
|
||||
resp, body = self.get('v1/templates')
|
||||
|
||||
return resp, json.loads(body)['templates']
|
||||
|
||||
def get_public_env_templates_list(self):
|
||||
"""Check the public environment templates deployed by the user."""
|
||||
resp, body = self.get('v1/templates?is_public=true')
|
||||
return resp, json.loads(body)
|
||||
|
||||
def get_private_env_templates_list(self):
|
||||
"""Check the public environment templates deployed by the user."""
|
||||
resp, body = self.get('v1/templates?is_public=false')
|
||||
return resp, json.loads(body)
|
||||
|
||||
def create_env_template(self, env_template_name):
|
||||
"""Check the creation of an environment template."""
|
||||
body = {'name': env_template_name}
|
||||
body = {'name': env_template_name, "is_public": False}
|
||||
resp, body = self.post('v1/templates', json.dumps(body))
|
||||
|
||||
return resp, json.loads(body)
|
||||
|
||||
def create_clone_env_template(self, env_template_id,
|
||||
cloned_env_template_name):
|
||||
"""Clone an environment template."""
|
||||
body = {'name': cloned_env_template_name}
|
||||
resp, body = self.post('v1/templates/{0}/clone'.
|
||||
format(env_template_id), json.dumps(body))
|
||||
|
||||
return resp, json.loads(body)
|
||||
|
||||
def create_public_env_template(self, env_template_name):
|
||||
"""Check the creation of an environment template."""
|
||||
body = {'name': env_template_name, "is_public": True}
|
||||
resp, body = self.post('v1/templates', json.dumps(body))
|
||||
return resp, json.loads(body)
|
||||
|
||||
def create_env_template_with_apps(self, env_template_name):
|
||||
"""Check the creation of an environment template."""
|
||||
body = {'name': env_template_name}
|
||||
@ -427,10 +452,34 @@ class TestCase(TestAuth):
|
||||
return environment
|
||||
|
||||
def create_env_template(self, name):
|
||||
env_template = self.client.create_env_template(name)[1]
|
||||
resp, env_template = self.client.create_env_template(name)
|
||||
self.env_templates.append(env_template)
|
||||
return resp, env_template
|
||||
|
||||
return env_template
|
||||
def create_public_env_template(self, name):
|
||||
resp, env_template = self.client.create_public_env_template(name)
|
||||
self.env_templates.append(env_template)
|
||||
return resp, env_template
|
||||
|
||||
def create_env_template_with_apps(self, name):
|
||||
resp, env_template = self.client.create_env_template_with_apps(name)
|
||||
self.env_templates.append(env_template)
|
||||
return resp, env_template
|
||||
|
||||
def clone_env_template(self, env_template_id, cloned_env_template_name):
|
||||
create_clone_env_temp = self.client.create_clone_env_template
|
||||
resp, env_template = create_clone_env_temp(env_template_id,
|
||||
cloned_env_template_name)
|
||||
self.env_templates.append(env_template)
|
||||
return resp, env_template
|
||||
|
||||
def create_env_from_template(self, env_template_id, env_name):
|
||||
resp, env_id = self.client.create_env_from_template(env_template_id,
|
||||
env_name)
|
||||
resp, env = self.client.get_environment(env_id['environment_id'])
|
||||
|
||||
self.environments.append(env)
|
||||
return resp, env
|
||||
|
||||
def create_demo_service(self, environment_id, session_id, client=None):
|
||||
if not client:
|
||||
|
@ -23,11 +23,11 @@ class TestEnvTemplate(base.TestCase):
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_list_env_templates(self):
|
||||
def test_list_empty_env_templates(self):
|
||||
"""Check getting the list of environment templates."""
|
||||
resp, body = self.client.get_env_templates_list()
|
||||
|
||||
self.assertIn('templates', body)
|
||||
self.assertEqual(0, len(body))
|
||||
self.assertEqual(resp.status, 200)
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@ -36,23 +36,24 @@ class TestEnvTemplate(base.TestCase):
|
||||
"""It checks the creation and deletion of an enviroment template."""
|
||||
env_templates_list_start = self.client.get_env_templates_list()[1]
|
||||
|
||||
resp, env_template = self.client.create_env_template('test_env_temp')
|
||||
resp, env_template = self.create_env_template('test_env_temp')
|
||||
self.env_templates.append(env_template)
|
||||
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertFalse(env_template['is_public'])
|
||||
self.assertEqual('test_env_temp', env_template['name'])
|
||||
|
||||
env_templates_list = self.client.get_env_templates_list()[1]
|
||||
|
||||
self.assertEqual(len(env_templates_list_start['templates']) + 1,
|
||||
len(env_templates_list['templates']))
|
||||
self.assertEqual(len(env_templates_list_start) + 1,
|
||||
len(env_templates_list))
|
||||
|
||||
self.client.delete_env_template(env_template['id'])
|
||||
|
||||
env_templates_list = self.client.get_env_templates_list()[1]
|
||||
|
||||
self.assertEqual(len(env_templates_list_start['templates']),
|
||||
len(env_templates_list['templates']))
|
||||
self.assertEqual(len(env_templates_list_start),
|
||||
len(env_templates_list))
|
||||
|
||||
self.env_templates.pop(self.env_templates.index(env_template))
|
||||
|
||||
@ -60,78 +61,151 @@ class TestEnvTemplate(base.TestCase):
|
||||
@attr(type='smoke')
|
||||
def test_get_env_template(self):
|
||||
"""Check getting information about an environment template."""
|
||||
resp, env_template = self.client.create_env_template('test_env_temp')
|
||||
resp, env_template = self.create_env_template('test_env_temp')
|
||||
|
||||
resp, env_obtained_template =\
|
||||
self.client.get_env_template(env_template['id'])
|
||||
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(env_obtained_template['name'], 'test_env_temp')
|
||||
self.client.delete_env_template(env_template['id'])
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_create_env_template_with_apps(self):
|
||||
"""Check the creation of an environment template with applications."""
|
||||
resp, env_template = \
|
||||
self.client.create_env_template_with_apps('test_env_temp')
|
||||
self.create_env_template_with_apps('test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
resp, apps_template = \
|
||||
self.client.get_apps_in_env_template(env_template['id'])
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(len(apps_template), 1)
|
||||
self.client.delete_env_template(env_template['id'])
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_create_app_in_env_template(self):
|
||||
"""Check the creationg of applications in an environment template."""
|
||||
resp, env_template = self.client.create_env_template('test_env_temp')
|
||||
resp, apps = self.client.get_apps_in_env_template(env_template['id'])
|
||||
resp, env_temp = self.create_env_template('test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
|
||||
resp, apps = self.client.get_apps_in_env_template(env_temp['id'])
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(len(apps), 0)
|
||||
|
||||
resp, apps = self.client.create_app_in_env_template(env_template['id'])
|
||||
resp, apps = self.client.create_app_in_env_template(env_temp['id'])
|
||||
self.assertEqual(resp.status, 200)
|
||||
resp, apps = self.client.get_apps_in_env_template(env_template['id'])
|
||||
resp, apps = self.client.get_apps_in_env_template(env_temp['id'])
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(len(apps), 1)
|
||||
|
||||
self.client.delete_env_template(env_template['id'])
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_delete_app_in_env_template(self):
|
||||
"""Check the deletion of applications in an environmente template."""
|
||||
resp, env_template = self.client.create_env_template('test_env_temp')
|
||||
|
||||
resp, apps = self.client.create_app_in_env_template(env_template['id'])
|
||||
resp, env_temp = self.create_env_template_with_apps('test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
resp, apps = self.client.get_apps_in_env_template(env_template['id'])
|
||||
resp, apps = self.client.get_apps_in_env_template(env_temp['id'])
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(len(apps), 1)
|
||||
resp = self.client.delete_app_in_env_template(env_template['id'])
|
||||
resp = self.client.delete_app_in_env_template(env_temp['id'])
|
||||
self.assertEqual(resp.status, 200)
|
||||
resp, apps = self.client.get_apps_in_env_template(env_template['id'])
|
||||
resp, apps = self.client.get_apps_in_env_template(env_temp['id'])
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(len(apps), 0)
|
||||
|
||||
self.client.delete_env_template(env_template['id'])
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_create_public_env_template(self):
|
||||
"""Check the creation of a public environment template."""
|
||||
resp, env_temp = self.create_public_env_template('test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
resp, env = self.client.get_env_template(env_temp['id'])
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertTrue(env['is_public'], 200)
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_clone_env_template(self):
|
||||
"""Check the creation of a public environment template."""
|
||||
resp, env_template = self.\
|
||||
create_public_env_template('test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
resp, cloned_templ = self.clone_env_template(env_template['id'],
|
||||
'cloned_template')
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertTrue(cloned_templ['name'], 'cloned_template')
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_clone_env_template_private(self):
|
||||
"""Check the creation of a public environment template."""
|
||||
resp, env_template = self.\
|
||||
create_env_template('test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertRaises(exceptions.Forbidden,
|
||||
self.clone_env_template,
|
||||
env_template['id'], 'cloned_template')
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_get_public_env_templates(self):
|
||||
"""Check the deletion of applications in an environmente template."""
|
||||
resp, public_env_template = \
|
||||
self.create_public_env_template('public_test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(public_env_template['is_public'], True)
|
||||
resp, private_env_template = \
|
||||
self.create_env_template('private_test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(private_env_template['is_public'], False)
|
||||
resp, public_envs = self.client.get_public_env_templates_list()
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(len(public_envs), 1)
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_get_private_env_templates(self):
|
||||
"""Check the deletion of applications in an environmente template."""
|
||||
resp, public_env_template = \
|
||||
self.create_public_env_template('public_test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(public_env_template['is_public'], True)
|
||||
resp, private_env_template = \
|
||||
self.create_env_template('private_test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(private_env_template['is_public'], False)
|
||||
resp, private_envs = self.client.get_private_env_templates_list()
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(len(private_envs), 1)
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_get_env_templates(self):
|
||||
"""Check the deletion of applications in an environmente template."""
|
||||
resp, public_env_template = \
|
||||
self.create_public_env_template('public_test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(public_env_template['is_public'], True)
|
||||
resp, private_env_template = \
|
||||
self.create_env_template('private_test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(private_env_template['is_public'], False)
|
||||
resp, envs_templates = self.client.get_env_templates_list()
|
||||
self.assertEqual(resp.status, 200)
|
||||
self.assertEqual(len(envs_templates), 2)
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='smoke')
|
||||
def test_create_env_from_template(self):
|
||||
"""Check the creation of an environment from a template."""
|
||||
resp, env_template = \
|
||||
self.client.create_env_template_with_apps('test_env_temp')
|
||||
self.create_env_template_with_apps('test_env_temp')
|
||||
self.assertEqual(resp.status, 200)
|
||||
|
||||
resp, env = self.client.create_env_from_template(env_template['id'],
|
||||
"env")
|
||||
resp, env = self.create_env_from_template(env_template['id'],
|
||||
"env")
|
||||
self.assertEqual(resp.status, 200)
|
||||
|
||||
self.client.delete_env_template(env_template['id'])
|
||||
self.client.delete_environment(env['environment_id'])
|
||||
self.assertIsNotNone(env)
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='negative')
|
||||
@ -153,7 +227,7 @@ class TestEnvTemplate(base.TestCase):
|
||||
@attr(type='negative')
|
||||
def test_double_delete_env_template(self):
|
||||
"""Check the deletion of an wrong environment template request."""
|
||||
_, env_template = self.client.create_env_template('test_env_temp')
|
||||
_, env_template = self.create_env_template('test_env_temp')
|
||||
|
||||
self.client.delete_env_template(env_template['id'])
|
||||
|
||||
@ -165,7 +239,7 @@ class TestEnvTemplate(base.TestCase):
|
||||
@attr(type='negative')
|
||||
def test_get_deleted_env_template(self):
|
||||
"""Check the deletion of an wrong environment template request."""
|
||||
_, env_template = self.client.create_env_template('test_env_temp')
|
||||
_, env_template = self.create_env_template('test_env_temp')
|
||||
|
||||
self.client.delete_env_template(env_template['id'])
|
||||
|
||||
@ -182,22 +256,19 @@ class TestEnvTemplatesTenantIsolation(base.NegativeTestCase):
|
||||
"""It tests getting information from an environment
|
||||
template from another user.
|
||||
"""
|
||||
env_template = self.create_env_template('test_env_temp')
|
||||
_, env_template = self.create_env_template('test_env_temp')
|
||||
|
||||
self.assertRaises(exceptions.Forbidden,
|
||||
self.alt_client.get_env_template, env_template['id'])
|
||||
|
||||
self.client.delete_env_template(env_template['id'])
|
||||
|
||||
@tag('all', 'coverage')
|
||||
@attr(type='negative')
|
||||
def test_delete_env_template_from_another_tenant(self):
|
||||
"""It tests deleting information from an environment
|
||||
template from another user.
|
||||
"""
|
||||
env_template = self.create_env_template('test_env_temp')
|
||||
_, env_template = self.create_env_template('test_env_temp')
|
||||
|
||||
self.assertRaises(exceptions.Forbidden,
|
||||
self.alt_client.delete_env_template,
|
||||
env_template['id'])
|
||||
self.client.delete_env_template(env_template['id'])
|
||||
|
@ -59,6 +59,7 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase):
|
||||
|
||||
expected = {'tenant_id': self.tenant,
|
||||
'id': 'env_template_id',
|
||||
'is_public': False,
|
||||
'name': 'mytemp',
|
||||
'version': 0,
|
||||
'created': timeutils.isotime(fake_now)[:-1],
|
||||
@ -86,6 +87,138 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase):
|
||||
result = req.get_response(self.api)
|
||||
self.assertEqual(expected, json.loads(result.body))
|
||||
|
||||
def test_list_public_env_templates(self):
|
||||
"""Create an template, test templates.public()."""
|
||||
self._set_policy_rules(
|
||||
{'create_env_template': '@',
|
||||
'list_env_templates': '@'}
|
||||
)
|
||||
|
||||
self.expect_policy_check('create_env_template')
|
||||
|
||||
body = {'name': 'mytemp2', 'is_public': True}
|
||||
req = self._post('/templates', json.dumps(body))
|
||||
result = req.get_response(self.api)
|
||||
self.assertTrue(json.loads(result.body)['is_public'])
|
||||
|
||||
self.expect_policy_check('list_env_templates')
|
||||
req = self._get('/templates', {'is_public': True})
|
||||
|
||||
result = req.get_response(self.api)
|
||||
self.assertEqual(1, len(json.loads(result.body)))
|
||||
self.assertTrue(json.loads(result.body)['templates'][0]['is_public'])
|
||||
|
||||
def test_clone_env_templates(self):
|
||||
"""Create an template, test templates.public()."""
|
||||
self._set_policy_rules(
|
||||
{'create_env_template': '@',
|
||||
'clone_env_template': '@'}
|
||||
)
|
||||
|
||||
self.expect_policy_check('create_env_template')
|
||||
body = {'name': 'mytemp2', 'is_public': True}
|
||||
req = self._post('/templates', json.dumps(body))
|
||||
result = req.get_response(self.api)
|
||||
env_template_id = json.loads(result.body)['id']
|
||||
self.assertTrue(json.loads(result.body)['is_public'])
|
||||
|
||||
self.expect_policy_check('clone_env_template')
|
||||
body = {'name': 'clone', 'is_public': False}
|
||||
req = self._post('/templates/%s/clone' % env_template_id,
|
||||
json.dumps(body))
|
||||
result = req.get_response(self.api)
|
||||
self.assertFalse(json.loads(result.body)['is_public'])
|
||||
self.assertEqual('clone', json.loads(result.body)['name'])
|
||||
|
||||
def test_clone_env_templates_private(self):
|
||||
"""Create an template, test templates.public()."""
|
||||
self._set_policy_rules(
|
||||
{'create_env_template': '@',
|
||||
'clone_env_template': '@'}
|
||||
)
|
||||
|
||||
self.expect_policy_check('create_env_template')
|
||||
body = {'name': 'mytemp2', 'is_public': False}
|
||||
req = self._post('/templates', json.dumps(body))
|
||||
result = req.get_response(self.api)
|
||||
env_template_id = json.loads(result.body)['id']
|
||||
self.assertFalse(json.loads(result.body)['is_public'])
|
||||
|
||||
self.expect_policy_check('clone_env_template')
|
||||
body = {'name': 'clone', 'is_public': False}
|
||||
req = self._post('/templates/%s/clone' % env_template_id,
|
||||
json.dumps(body))
|
||||
result = req.get_response(self.api)
|
||||
self.assertEqual(result.status_code, 403)
|
||||
|
||||
def test_list_public_env_templates_default(self):
|
||||
"""Create an template, test list public with no
|
||||
public templates.
|
||||
"""
|
||||
self._set_policy_rules(
|
||||
{'create_env_template': '@',
|
||||
'list_env_templates': '@'}
|
||||
)
|
||||
|
||||
self.expect_policy_check('create_env_template')
|
||||
body = {'name': 'mytemp'}
|
||||
req = self._post('/templates', json.dumps(body))
|
||||
result = req.get_response(self.api)
|
||||
self.assertFalse(json.loads(result.body)['is_public'])
|
||||
|
||||
self.expect_policy_check('list_env_templates')
|
||||
req = self._get('/templates', {'is_public': True})
|
||||
result = req.get_response(self.api)
|
||||
|
||||
self.assertFalse(0, len(json.loads(result.body)))
|
||||
|
||||
def test_list_private_env_templates(self):
|
||||
"""Create an template, test list public with no
|
||||
public templates.
|
||||
"""
|
||||
self._set_policy_rules(
|
||||
{'create_env_template': '@',
|
||||
'list_env_templates': '@'}
|
||||
)
|
||||
|
||||
self.expect_policy_check('create_env_template')
|
||||
body = {'name': 'mytemp', 'is_public': False}
|
||||
req = self._post('/templates', json.dumps(body))
|
||||
result = req.get_response(self.api)
|
||||
self.assertFalse(json.loads(result.body)['is_public'])
|
||||
|
||||
self.expect_policy_check('list_env_templates')
|
||||
req = self._get('/templates', {'is_public': False})
|
||||
result = req.get_response(self.api)
|
||||
self.assertEqual(1, len(json.loads(result.body)['templates']))
|
||||
|
||||
def test_list_env_templates(self):
|
||||
"""Create an template, test list public with no
|
||||
public templates.
|
||||
"""
|
||||
self._set_policy_rules(
|
||||
{'create_env_template': '@',
|
||||
'list_env_templates': '@'}
|
||||
)
|
||||
|
||||
self.expect_policy_check('create_env_template')
|
||||
body = {'name': 'mytemp', 'is_public': False}
|
||||
req = self._post('/templates', json.dumps(body))
|
||||
result = req.get_response(self.api)
|
||||
self.assertFalse(json.loads(result.body)['is_public'])
|
||||
|
||||
self.expect_policy_check('create_env_template')
|
||||
body = {'name': 'mytemp1', 'is_public': True}
|
||||
req = self._post('/templates', json.dumps(body))
|
||||
result = req.get_response(self.api)
|
||||
self.assertTrue(json.loads(result.body)['is_public'])
|
||||
|
||||
self.expect_policy_check('list_env_templates')
|
||||
req = self._get('/templates')
|
||||
result = req.get_response(self.api)
|
||||
|
||||
self.assertEqual(2, len(json.loads(result.body)['templates']))
|
||||
|
||||
def test_illegal_template_name_create(self):
|
||||
"""Check that an illegal temp name results in an HTTPClientError."""
|
||||
self._set_policy_rules(
|
||||
@ -114,7 +247,7 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase):
|
||||
result = req.get_response(self.api)
|
||||
self.assertEqual(400, result.status_code)
|
||||
result_msg = result.text.replace('\n', '')
|
||||
self.assertIn('Environment Template name should be 255 characters '
|
||||
self.assertIn('Environment template name should be 255 characters '
|
||||
'maximum',
|
||||
result_msg)
|
||||
|
||||
@ -158,6 +291,7 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase):
|
||||
|
||||
expected = dict(
|
||||
id='12345',
|
||||
is_public=False,
|
||||
name='my-temp',
|
||||
version=0,
|
||||
created=fake_now,
|
||||
@ -242,6 +376,7 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase):
|
||||
timeutils.utcnow.override_time = fake_now
|
||||
expected = {'tenant_id': self.tenant,
|
||||
'id': self.uuids[0],
|
||||
'is_public': False,
|
||||
'name': 'env_template_name',
|
||||
'version': 0,
|
||||
'created': timeutils.isotime(fake_now)[:-1],
|
||||
|
@ -27,7 +27,7 @@ class TestTemplateServices(base.MuranoWithDBTestCase,
|
||||
def setUp(self):
|
||||
super(TestTemplateServices, self).setUp()
|
||||
self.template_services = env_temp.EnvTemplateServices
|
||||
self.uuids = ['template_id']
|
||||
self.uuids = ['template_id', 'template_id2']
|
||||
self.mock_uuid = self._stub_uuid(self.uuids)
|
||||
self.addCleanup(mock.patch.stopall)
|
||||
|
||||
@ -42,6 +42,18 @@ class TestTemplateServices(base.MuranoWithDBTestCase,
|
||||
self.assertEqual(fixture.environment_template_desc,
|
||||
template_des.description)
|
||||
|
||||
def test_clone_template(self):
|
||||
"""Check the clonation of a template."""
|
||||
body = {
|
||||
"name": "my_template"
|
||||
}
|
||||
template = self.template_services.create(body, 'tenant_id')
|
||||
cloned_template = self.template_services.clone(template['id'],
|
||||
'id2',
|
||||
"my_template2", False)
|
||||
self.assertEqual(cloned_template.description['name'], 'my_template2')
|
||||
self.assertEqual(cloned_template.description['tenant_id'], 'id2')
|
||||
|
||||
def test_get_empty_template(self):
|
||||
"""Check obtaining information about a template without services."""
|
||||
fixture = self.useFixture(et.EmptyEnvironmentTemplateFixture())
|
||||
|
6
releasenotes/notes/public-template-a8853ac02dcf9396.yaml
Normal file
6
releasenotes/notes/public-template-a8853ac02dcf9396.yaml
Normal file
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- Added public field to environment templates. GET method
|
||||
for api now displays public templates from other projects(tenants).
|
||||
- Added public filter to environment templates api.
|
||||
- Added clone action to environment templates.
|
Loading…
Reference in New Issue
Block a user