Merge "Public environment template"

This commit is contained in:
Jenkins 2015-11-24 12:58:28 +00:00 committed by Gerrit Code Review
commit 4d8799e453
11 changed files with 562 additions and 82 deletions

View File

@ -65,6 +65,13 @@ List Environments Templates
| | | environment 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* *Response*
This call returns a list of environment templates. Only the basic properties are This call returns a list of environment templates. Only the basic properties are
@ -81,6 +88,7 @@ returned.
"created": "2014-05-14T13:02:46", "created": "2014-05-14T13:02:46",
"tenant_id": "726ed856965f43cc8e565bc991fa76c3", "tenant_id": "726ed856965f43cc8e565bc991fa76c3",
"version": 0, "version": 0,
"is_public": false,
"id": "2fa5ab704749444bbeafe7991b412c33" "id": "2fa5ab704749444bbeafe7991b412c33"
}, },
{ {
@ -88,8 +96,9 @@ returned.
"networking": {}, "networking": {},
"name": "test2", "name": "test2",
"created": "2014-05-14T13:02:51", "created": "2014-05-14T13:02:51",
"tenant_id": "726ed856965f43cc8e565bc991fa76c3", "tenant_id": "123452452345346345634563456345346",
"version": 0, "version": 0,
"is_public": true,
"id": "744e44812da84e858946f5d817de4f72" "id": "744e44812da84e858946f5d817de4f72"
} }
] ]
@ -414,3 +423,58 @@ Create an environment from an environment template
+----------------+-----------------------------------------------------------+ +----------------+-----------------------------------------------------------+
| 409 | The environment already exists | | 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 |
+----------------+-----------------------------------------------------------+

View File

@ -121,6 +121,10 @@ class API(wsgi.Router):
controller=templates_resource, controller=templates_resource,
action='create_environment', action='create_environment',
conditions={'method': ['POST']}) conditions={'method': ['POST']})
mapper.connect('/templates/{env_template_id}/clone',
controller=templates_resource,
action='clone',
conditions={'method': ['POST']})
applications_resource = template_applications.create_resource() applications_resource = template_applications.create_resource()
mapper.connect('/templates/{env_template_id}/services', mapper.connect('/templates/{env_template_id}/services',

View File

@ -17,10 +17,11 @@ from oslo_log import log as logging
from webob import exc from webob import exc
from murano.api.v1 import request_statistics 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 policy
from murano.common import utils from murano.common import utils
from murano.common import wsgi from murano.common import wsgi
from murano.db.models import EnvironmentTemplate
from murano.db.services import core_services from murano.db.services import core_services
from murano.db.services import environment_templates as env_temps from murano.db.services import environment_templates as env_temps
from murano.db.services import environments as envs from murano.db.services import environments as envs
@ -40,12 +41,27 @@ class Controller(object):
""" """
LOG.debug('EnvTemplates:List') LOG.debug('EnvTemplates:List')
policy.check('list_env_templates', request.context) 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] list_templates = [temp.to_dict() for temp in list_templates]
return {"templates": list_templates} return {"templates": list_templates}
@request_statistics.stats_count(API_NAME, 'Create') @request_statistics.stats_count(API_NAME, 'Create')
@ -59,24 +75,11 @@ class Controller(object):
""" """
LOG.debug('EnvTemplates:Create <Body {body}>'.format(body=body)) LOG.debug('EnvTemplates:Create <Body {body}>'.format(body=body))
policy.check('create_env_template', request.context) policy.check('create_env_template', request.context)
self._validate_body_name(body)
try: try:
LOG.debug('ENV TEMP NAME: {templ_name}>'.format( LOG.debug('ENV TEMP NAME: {templ_name}>'.
templ_name=body['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:
template = env_temps.EnvTemplateServices.create( template = env_temps.EnvTemplateServices.create(
body.copy(), request.context.tenant) body.copy(), request.context.tenant)
return template.to_dict() return template.to_dict()
@ -172,23 +175,15 @@ class Controller(object):
:param body: the environment name :param body: the environment name
:return: session_id and environment_id :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} target = {"env_template_id": env_template_id}
policy.check('create_environment', request.context, target) policy.check('create_environment', request.context, target)
self._validate_request(request, env_template_id) 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.\ template = env_temps.EnvTemplateServices.\
get_env_template(env_template_id) get_env_template(env_template_id)
self._validate_body_name(body)
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']))
try: try:
environment = envs.EnvironmentServices.create( environment = envs.EnvironmentServices.create(
body.copy(), request.context) body.copy(), request.context)
@ -214,19 +209,75 @@ class Controller(object):
) )
return {"session_id": session.id, "environment_id": environment.id} 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): 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 env_template_exists = env_temps.EnvTemplateServices.env_template_exist
if not env_template_exists(env_template_id): if not env_template_exists(env_template_id):
msg = _('EnvTemplate <TempId {temp_id}> is not found').format( msg = _('EnvTemplate <TempId {temp_id}> is not found').format(
temp_id=env_template_id) temp_id=env_template_id)
LOG.exception(msg) LOG.error(msg)
raise exc.HTTPNotFound(explanation=msg) raise exc.HTTPNotFound(explanation=msg)
get_env_template = env_temps.EnvTemplateServices.get_env_template get_env_template = env_temps.EnvTemplateServices.get_env_template
env_template = get_env_template(env_template_id) return get_env_template(env_template_id)
if env_template.tenant_id != request.context.tenant:
msg = _('User is not authorized to access this tenant resources') def _validate_body_name(self, body):
LOG.error(msg)
raise exc.HTTPForbidden(explanation=msg) 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(): def create_resource():

View File

@ -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 #

View File

@ -97,6 +97,7 @@ class EnvironmentTemplate(Base, TimestampMixin):
tenant_id = sa.Column(sa.String(36), nullable=False) tenant_id = sa.Column(sa.String(36), nullable=False)
version = sa.Column(sa.BigInteger, nullable=False, default=0) version = sa.Column(sa.BigInteger, nullable=False, default=0)
description = sa.Column(st.JsonBlob(), nullable=False, default={}) description = sa.Column(st.JsonBlob(), nullable=False, default={})
is_public = sa.Column(sa.Boolean, default=False)
def to_dict(self): def to_dict(self):
dictionary = super(EnvironmentTemplate, self).to_dict() dictionary = super(EnvironmentTemplate, self).to_dict()

View File

@ -19,6 +19,7 @@ from murano.db import session as db_session
from oslo_db import exception as db_exc from oslo_db import exception as db_exc
from oslo_log import log as logging from oslo_log import log as logging
from sqlalchemy.sql import or_
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -38,6 +39,19 @@ class EnvTemplateServices(object):
return templates 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 @staticmethod
def create(env_template_params, tenant_id): def create(env_template_params, tenant_id):
"""Creates environment-template with specified params, in particular - name. """Creates environment-template with specified params, in particular - name.
@ -166,3 +180,32 @@ class EnvTemplateServices(object):
""" """
session = db_session.get_session() session = db_session.get_session()
return session.query(models.EnvironmentTemplate).get(env_template_id) 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

View File

@ -245,15 +245,40 @@ class MuranoClient(rest_client.RestClient):
"""Check the environment templates deployed by the user.""" """Check the environment templates deployed by the user."""
resp, body = self.get('v1/templates') 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) return resp, json.loads(body)
def create_env_template(self, env_template_name): def create_env_template(self, env_template_name):
"""Check the creation of an environment template.""" """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)) resp, body = self.post('v1/templates', json.dumps(body))
return resp, json.loads(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): def create_env_template_with_apps(self, env_template_name):
"""Check the creation of an environment template.""" """Check the creation of an environment template."""
body = {'name': env_template_name} body = {'name': env_template_name}
@ -427,10 +452,34 @@ class TestCase(TestAuth):
return environment return environment
def create_env_template(self, name): 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) 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): def create_demo_service(self, environment_id, session_id, client=None):
if not client: if not client:

View File

@ -23,11 +23,11 @@ class TestEnvTemplate(base.TestCase):
@tag('all', 'coverage') @tag('all', 'coverage')
@attr(type='smoke') @attr(type='smoke')
def test_list_env_templates(self): def test_list_empty_env_templates(self):
"""Check getting the list of environment templates.""" """Check getting the list of environment templates."""
resp, body = self.client.get_env_templates_list() resp, body = self.client.get_env_templates_list()
self.assertIn('templates', body) self.assertEqual(0, len(body))
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
@tag('all', 'coverage') @tag('all', 'coverage')
@ -36,23 +36,24 @@ class TestEnvTemplate(base.TestCase):
"""It checks the creation and deletion of an enviroment template.""" """It checks the creation and deletion of an enviroment template."""
env_templates_list_start = self.client.get_env_templates_list()[1] 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.env_templates.append(env_template)
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertFalse(env_template['is_public'])
self.assertEqual('test_env_temp', env_template['name']) self.assertEqual('test_env_temp', env_template['name'])
env_templates_list = self.client.get_env_templates_list()[1] env_templates_list = self.client.get_env_templates_list()[1]
self.assertEqual(len(env_templates_list_start['templates']) + 1, self.assertEqual(len(env_templates_list_start) + 1,
len(env_templates_list['templates'])) len(env_templates_list))
self.client.delete_env_template(env_template['id']) self.client.delete_env_template(env_template['id'])
env_templates_list = self.client.get_env_templates_list()[1] env_templates_list = self.client.get_env_templates_list()[1]
self.assertEqual(len(env_templates_list_start['templates']), self.assertEqual(len(env_templates_list_start),
len(env_templates_list['templates'])) len(env_templates_list))
self.env_templates.pop(self.env_templates.index(env_template)) self.env_templates.pop(self.env_templates.index(env_template))
@ -60,78 +61,151 @@ class TestEnvTemplate(base.TestCase):
@attr(type='smoke') @attr(type='smoke')
def test_get_env_template(self): def test_get_env_template(self):
"""Check getting information about an environment template.""" """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 =\ resp, env_obtained_template =\
self.client.get_env_template(env_template['id']) self.client.get_env_template(env_template['id'])
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertEqual(env_obtained_template['name'], 'test_env_temp') self.assertEqual(env_obtained_template['name'], 'test_env_temp')
self.client.delete_env_template(env_template['id'])
@tag('all', 'coverage') @tag('all', 'coverage')
@attr(type='smoke') @attr(type='smoke')
def test_create_env_template_with_apps(self): def test_create_env_template_with_apps(self):
"""Check the creation of an environment template with applications.""" """Check the creation of an environment template with applications."""
resp, env_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) self.assertEqual(resp.status, 200)
resp, apps_template = \ resp, apps_template = \
self.client.get_apps_in_env_template(env_template['id']) self.client.get_apps_in_env_template(env_template['id'])
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertEqual(len(apps_template), 1) self.assertEqual(len(apps_template), 1)
self.client.delete_env_template(env_template['id'])
@tag('all', 'coverage') @tag('all', 'coverage')
@attr(type='smoke') @attr(type='smoke')
def test_create_app_in_env_template(self): def test_create_app_in_env_template(self):
"""Check the creationg of applications in an environment template.""" """Check the creationg of applications in an environment template."""
resp, env_template = self.client.create_env_template('test_env_temp') resp, env_temp = self.create_env_template('test_env_temp')
resp, apps = self.client.get_apps_in_env_template(env_template['id']) self.assertEqual(resp.status, 200)
resp, apps = self.client.get_apps_in_env_template(env_temp['id'])
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertEqual(len(apps), 0) 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) 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(resp.status, 200)
self.assertEqual(len(apps), 1) self.assertEqual(len(apps), 1)
self.client.delete_env_template(env_template['id'])
@tag('all', 'coverage') @tag('all', 'coverage')
@attr(type='smoke') @attr(type='smoke')
def test_delete_app_in_env_template(self): def test_delete_app_in_env_template(self):
"""Check the deletion of applications in an environmente template.""" """Check the deletion of applications in an environmente template."""
resp, env_template = self.client.create_env_template('test_env_temp') resp, env_temp = self.create_env_template_with_apps('test_env_temp')
resp, apps = self.client.create_app_in_env_template(env_template['id'])
self.assertEqual(resp.status, 200) 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(resp.status, 200)
self.assertEqual(len(apps), 1) 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) 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(resp.status, 200)
self.assertEqual(len(apps), 0) 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') @tag('all', 'coverage')
@attr(type='smoke') @attr(type='smoke')
def test_create_env_from_template(self): def test_create_env_from_template(self):
"""Check the creation of an environment from a template.""" """Check the creation of an environment from a template."""
resp, env_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) self.assertEqual(resp.status, 200)
resp, env = self.client.create_env_from_template(env_template['id'], resp, env = self.create_env_from_template(env_template['id'],
"env") "env")
self.assertEqual(resp.status, 200) self.assertEqual(resp.status, 200)
self.assertIsNotNone(env)
self.client.delete_env_template(env_template['id'])
self.client.delete_environment(env['environment_id'])
@tag('all', 'coverage') @tag('all', 'coverage')
@attr(type='negative') @attr(type='negative')
@ -153,7 +227,7 @@ class TestEnvTemplate(base.TestCase):
@attr(type='negative') @attr(type='negative')
def test_double_delete_env_template(self): def test_double_delete_env_template(self):
"""Check the deletion of an wrong environment template request.""" """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']) self.client.delete_env_template(env_template['id'])
@ -165,7 +239,7 @@ class TestEnvTemplate(base.TestCase):
@attr(type='negative') @attr(type='negative')
def test_get_deleted_env_template(self): def test_get_deleted_env_template(self):
"""Check the deletion of an wrong environment template request.""" """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']) self.client.delete_env_template(env_template['id'])
@ -182,22 +256,19 @@ class TestEnvTemplatesTenantIsolation(base.NegativeTestCase):
"""It tests getting information from an environment """It tests getting information from an environment
template from another user. 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.assertRaises(exceptions.Forbidden,
self.alt_client.get_env_template, env_template['id']) self.alt_client.get_env_template, env_template['id'])
self.client.delete_env_template(env_template['id'])
@tag('all', 'coverage') @tag('all', 'coverage')
@attr(type='negative') @attr(type='negative')
def test_delete_env_template_from_another_tenant(self): def test_delete_env_template_from_another_tenant(self):
"""It tests deleting information from an environment """It tests deleting information from an environment
template from another user. 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.assertRaises(exceptions.Forbidden,
self.alt_client.delete_env_template, self.alt_client.delete_env_template,
env_template['id']) env_template['id'])
self.client.delete_env_template(env_template['id'])

View File

@ -59,6 +59,7 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase):
expected = {'tenant_id': self.tenant, expected = {'tenant_id': self.tenant,
'id': 'env_template_id', 'id': 'env_template_id',
'is_public': False,
'name': 'mytemp', 'name': 'mytemp',
'version': 0, 'version': 0,
'created': timeutils.isotime(fake_now)[:-1], 'created': timeutils.isotime(fake_now)[:-1],
@ -86,6 +87,138 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase):
result = req.get_response(self.api) result = req.get_response(self.api)
self.assertEqual(expected, json.loads(result.body)) 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): def test_illegal_template_name_create(self):
"""Check that an illegal temp name results in an HTTPClientError.""" """Check that an illegal temp name results in an HTTPClientError."""
self._set_policy_rules( self._set_policy_rules(
@ -114,7 +247,7 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase):
result = req.get_response(self.api) result = req.get_response(self.api)
self.assertEqual(400, result.status_code) self.assertEqual(400, result.status_code)
result_msg = result.text.replace('\n', '') 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', 'maximum',
result_msg) result_msg)
@ -158,6 +291,7 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase):
expected = dict( expected = dict(
id='12345', id='12345',
is_public=False,
name='my-temp', name='my-temp',
version=0, version=0,
created=fake_now, created=fake_now,
@ -242,6 +376,7 @@ class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase):
timeutils.utcnow.override_time = fake_now timeutils.utcnow.override_time = fake_now
expected = {'tenant_id': self.tenant, expected = {'tenant_id': self.tenant,
'id': self.uuids[0], 'id': self.uuids[0],
'is_public': False,
'name': 'env_template_name', 'name': 'env_template_name',
'version': 0, 'version': 0,
'created': timeutils.isotime(fake_now)[:-1], 'created': timeutils.isotime(fake_now)[:-1],

View File

@ -27,7 +27,7 @@ class TestTemplateServices(base.MuranoWithDBTestCase,
def setUp(self): def setUp(self):
super(TestTemplateServices, self).setUp() super(TestTemplateServices, self).setUp()
self.template_services = env_temp.EnvTemplateServices 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.mock_uuid = self._stub_uuid(self.uuids)
self.addCleanup(mock.patch.stopall) self.addCleanup(mock.patch.stopall)
@ -42,6 +42,18 @@ class TestTemplateServices(base.MuranoWithDBTestCase,
self.assertEqual(fixture.environment_template_desc, self.assertEqual(fixture.environment_template_desc,
template_des.description) 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): def test_get_empty_template(self):
"""Check obtaining information about a template without services.""" """Check obtaining information about a template without services."""
fixture = self.useFixture(et.EmptyEnvironmentTemplateFixture()) fixture = self.useFixture(et.EmptyEnvironmentTemplateFixture())

View 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.