# Copyright (c) 2015 Telefonica I+D. # 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. import json from oslo_config import cfg from oslo_utils import timeutils from murano.api.v1 import templates from murano.common import config from murano.db import models import murano.tests.unit.api.base as tb import murano.tests.unit.utils as test_utils class TestEnvTemplateApi(tb.ControllerTest, tb.MuranoApiTestCase): def setUp(self): super(TestEnvTemplateApi, self).setUp() self.controller = templates.Controller() self.uuids = ['env_template_id', 'other', 'network_id', 'environment_id', 'session_id'] self.mock_uuid = self._stub_uuid(self.uuids) def test_list_empty_env_templates(self): """Check that with no templates an empty list is returned.""" self._set_policy_rules( {'list_env_templates': '@'} ) self.expect_policy_check('list_env_templates') req = self._get('/templates') result = req.get_response(self.api) self.assertEqual({'templates': []}, json.loads(result.body)) def test_create_env_templates(self): """Create an template, test template.show().""" self._set_policy_rules( {'list_env_templates': '@', 'create_env_template': '@', 'show_env_template': '@'} ) self.expect_policy_check('create_env_template') fake_now = timeutils.utcnow() timeutils.utcnow.override_time = fake_now expected = {'tenant_id': self.tenant, 'id': 'env_template_id', 'name': 'mytemp', 'networking': {}, 'version': 0, 'created': timeutils.isotime(fake_now)[:-1], 'updated': timeutils.isotime(fake_now)[:-1]} body = {'name': 'mytemp'} req = self._post('/templates', json.dumps(body)) result = req.get_response(self.api) self.assertEqual(expected, json.loads(result.body)) # Reset the policy expectation self.expect_policy_check('list_env_templates') req = self._get('/templates') result = req.get_response(self.api) self.assertEqual(200, result.status_code) self.assertEqual({'templates': [expected]}, json.loads(result.body)) expected['services'] = [] self.expect_policy_check('show_env_template', {'env_template_id': self.uuids[0]}) req = self._get('/templates/%s' % self.uuids[0]) result = req.get_response(self.api) self.assertEqual(expected, json.loads(result.body)) def test_illegal_template_name_create(self): """Check that an illegal temp name results in an HTTPClientError.""" self._set_policy_rules( {'list_env_templates': '@', 'create_env_template': '@', 'show_env_template': '@'} ) self.expect_policy_check('create_env_template') body = {'name': 'my+#temp'} req = self._post('/templates', json.dumps(body)) result = req.get_response(self.api) self.assertEqual(400, result.status_code) def test_mallformed_body(self): """Check that an illegal temp name results in an HTTPClientError.""" self._set_policy_rules( {'create_env_template': '@'} ) self.expect_policy_check('create_env_template') body = {'invalid': 'test'} req = self._post('/templates', json.dumps(body)) result = req.get_response(self.api) self.assertEqual(400, result.status_code) def test_missing_env_template(self): """Check that a missing environment template results in an HTTPNotFound. """ self._set_policy_rules( {'show_env_template': '@'} ) self.expect_policy_check('show_env_template', {'env_template_id': 'no-such-id'}) req = self._get('/templates/no-such-id') result = req.get_response(self.api) self.assertEqual(404, result.status_code) def test_update_env_template(self): """Check that environment rename works.""" self._set_policy_rules( {'show_env_template': '@', 'update_env_template': '@'} ) self.expect_policy_check('update_env_template', {'env_template_id': '12345'}) fake_now = timeutils.utcnow() timeutils.utcnow.override_time = fake_now expected = dict( id='12345', name='my-temp', version=0, networking={}, created=fake_now, updated=fake_now, tenant_id=self.tenant, description={ 'name': 'my-temp', '?': {'id': '12345'} } ) e = models.EnvironmentTemplate(**expected) test_utils.save_models(e) fake_now = timeutils.utcnow() timeutils.utcnow.override_time = fake_now del expected['description'] expected['services'] = [] expected['name'] = 'renamed_temp' expected['updated'] = fake_now body = { 'name': 'renamed_temp' } req = self._put('/templates/12345', json.dumps(body)) result = req.get_response(self.api) self.assertEqual(200, result.status_code) self.expect_policy_check('show_env_template', {'env_template_id': '12345'}) req = self._get('/templates/12345') result = req.get_response(self.api) self.assertEqual(200, result.status_code) expected['created'] = timeutils.isotime(expected['created'])[:-1] expected['updated'] = timeutils.isotime(expected['updated'])[:-1] self.assertEqual(expected, json.loads(result.body)) def test_delete_env_templates(self): """Test that environment deletion results in the correct rpc call.""" self._set_policy_rules( {'delete_env_template': '@'} ) self.expect_policy_check( 'delete_env_template', {'env_template_id': '12345'} ) fake_now = timeutils.utcnow() expected = dict( id='12345', name='my-temp', version=0, networking={}, created=fake_now, updated=fake_now, tenant_id=self.tenant, description={ 'name': 'my-temp', '?': {'id': '12345'} } ) e = models.EnvironmentTemplate(**expected) test_utils.save_models(e) req = self._delete('/templates/12345') result = req.get_response(self.api) # Should this be expected behavior? self.assertEqual('', result.body) self.assertEqual(200, result.status_code) def test_create_env_templates_with_applications(self): """Create an template, test template.show().""" self._set_policy_rules( {'list_env_templates': '@', 'create_env_template': '@', 'show_env_template': '@'} ) self.expect_policy_check('create_env_template') fake_now = timeutils.utcnow() timeutils.utcnow.override_time = fake_now expected = {'tenant_id': self.tenant, 'id': self.uuids[0], 'name': 'env_template_name', 'networking': {}, 'version': 0, 'created': timeutils.isotime(fake_now)[:-1], 'updated': timeutils.isotime(fake_now)[:-1]} services = [ { "instance": { "assignFloatingIp": "true", "keyname": "mykeyname", "image": "cloud-fedora-v3", "flavor": "m1.medium", "?": { "type": "io.murano.resources.Linux", "id": "ef984a74-29a4-45c0-b1dc-2ab9f075732e" } }, "name": "orion", "port": "8080", "?": { "type": "io.murano.apps.apache.Tomcat", "id": "54cea43d-5970-4c73-b9ac-fea656f3c722" } } ] expected['services'] = services body = { "name": "env_template_name", "services": [ { "instance": { "assignFloatingIp": "true", "keyname": "mykeyname", "image": "cloud-fedora-v3", "flavor": "m1.medium", "?": { "type": "io.murano.resources.Linux", "id": "ef984a74-29a4-45c0-b1dc-2ab9f075732e" } }, "name": "orion", "port": "8080", "?": { "type": "io.murano.apps.apache.Tomcat", "id": "54cea43d-5970-4c73-b9ac-fea656f3c722" } } ] } req = self._post('/templates', json.dumps(body)) result = req.get_response(self.api) self.assertEqual(expected, json.loads(result.body)) # Reset the policy expectation self.expect_policy_check('list_env_templates') req = self._get('/templates') result = req.get_response(self.api) del expected['services'] self.assertEqual(200, result.status_code) self.assertEqual({'templates': [expected]}, json.loads(result.body)) # Reset the policy expectation self.expect_policy_check('show_env_template', {'env_template_id': self.uuids[0]}) expected['services'] = services req = self._get('/templates/%s' % self.uuids[0]) result = req.get_response(self.api) self.assertEqual(expected, json.loads(result.body)) def test_add_application_to_template(self): """Create an template, test template.show().""" self._set_policy_rules( {'create_env_template': '@', 'add_application': '@'} ) self.expect_policy_check('create_env_template') fake_now = timeutils.utcnow() timeutils.utcnow.override_time = fake_now services = [ { "instance": { "assignFloatingIp": "true", "keyname": "mykeyname", "image": "cloud-fedora-v3", "flavor": "m1.medium", "?": { "type": "io.murano.resources.Linux", "id": "ef984a74-29a4-45c0-b1dc-2ab9f075732e" } }, "name": "orion", "port": "8080", "?": { "type": "io.murano.apps.apache.Tomcat", "id": "54cea43d-5970-4c73-b9ac-fea656f3c722" } } ] body = { "name": "template_name", } req = self._post('/templates', json.dumps(body)) result = req.get_response(self.api) self.assertEqual(200, result.status_code) body = services req = self._post('/templates/%s/services' % self.uuids[0], json.dumps(body)) result = req.get_response(self.api) self.assertEqual(200, result.status_code) self.assertEqual(services, json.loads(result.body)) req = self._get('/templates/%s/services' % self.uuids[0]) result = req.get_response(self.api) self.assertEqual(200, result.status_code) self.assertEqual(1, len(json.loads(result.body))) service_no_instance = [ { "instance": "ef984a74-29a4-45c0-b1dc-2ab9f075732e", "name": "tomcat", "port": "8080", "?": { "type": "io.murano.apps.apache.Tomcat", "id": "54cea43d-5970-4c73-b9ac-fea656f3c722" } } ] req = self._post('/templates/%s/services' % self.uuids[0], json.dumps(service_no_instance)) result = req.get_response(self.api) self.assertEqual(200, result.status_code) req = self._get('/templates/%s/services' % self.uuids[0]) result = req.get_response(self.api) self.assertEqual(200, result.status_code) self.assertEqual(2, len(json.loads(result.body))) def test_delete_application_in_template(self): """Create an template, test template.show().""" self._set_policy_rules( {'create_env_template': '@', 'delete_env_application': '@'} ) self.expect_policy_check('create_env_template') fake_now = timeutils.utcnow() timeutils.utcnow.override_time = fake_now body = { "name": "mytemplate", "services": [ { "name": "tomcat", "port": "8080", "?": { "type": "io.murano.apps.apache.Tomcat", "id": "54cea43d-5970-4c73-b9ac-fea656f3c722" } } ] } req = self._post('/templates', json.dumps(body)) result = req.get_response(self.api) self.assertEqual(200, result.status_code) req = self._get('/templates/%s/services' % self.uuids[0]) result = req.get_response(self.api) self.assertEqual(200, result.status_code) self.assertEqual(1, len(json.loads(result.body))) service_id = '54cea43d-5970-4c73-b9ac-fea656f3c722' req = self._get('/templates/' + self.uuids[0] + '/services/' + service_id) result = req.get_response(self.api) self.assertEqual(200, result.status_code) req = self._delete('/templates/' + self.uuids[0] + '/services/' + service_id) result = req.get_response(self.api) self.assertEqual(200, result.status_code) req = self._get('/templates/' + self.uuids[0] + '/services/' + service_id) result = req.get_response(self.api) self.assertEqual(404, result.status_code) def test_create_environment(self): """Test that environment is created, session configured.""" opts = [ cfg.StrOpt('config_dir'), cfg.StrOpt('config_file', default='murano.conf'), cfg.StrOpt('project', default='murano'), ] config.CONF.register_opts(opts) self._set_policy_rules( {'create_env_template': '@', 'create_environment': '@'} ) self._create_env_template_no_service() body_env = {'name': 'my_template'} self.expect_policy_check('create_environment', {'env_template_id': self.uuids[0]}) req = self._post('/templates/%s/create-environment' % self.uuids[0], json.dumps(body_env)) session_result = req.get_response(self.api) self.assertEqual(200, session_result.status_code) self.assertIsNotNone(session_result) body_returned = json.loads(session_result.body) self.assertEqual(self.uuids[4], body_returned['session_id']) self.assertEqual(self.uuids[3], body_returned['environment_id']) def test_create_env_with_template_no_services(self): """Test that environment is created and session with template without services. """ opts = [ cfg.StrOpt('config_dir'), cfg.StrOpt('config_file', default='murano.conf'), cfg.StrOpt('project', default='murano'), ] config.CONF.register_opts(opts) self._set_policy_rules( {'create_env_template': '@', 'create_environment': '@'} ) self._create_env_template_no_service() self.expect_policy_check('create_environment', {'env_template_id': self.uuids[0]}) body = {'name': 'my_template'} req = self._post('/templates/%s/create-environment' % self.uuids[0], json.dumps(body)) result = req.get_response(self.api) self.assertIsNotNone(result) self.assertEqual(200, result.status_code) body_returned = json.loads(result.body) self.assertEqual(self.uuids[4], body_returned['session_id']) self.assertEqual(self.uuids[3], body_returned['environment_id']) def test_mallformed_env_body(self): """Check that an illegal temp name results in an HTTPClientError.""" self._set_policy_rules( {'create_env_template': '@', 'create_environment': '@'} ) self. _create_env_template_no_service() self.expect_policy_check('create_environment', {'env_template_id': self.uuids[0]}) body = {'invalid': 'test'} req = self._post('/templates/%s/create-environment' % self.uuids[0], json.dumps(body)) result = req.get_response(self.api) self.assertEqual(400, result.status_code) def test_create_env_notexisting_templatebody(self): """Check that an illegal temp name results in an HTTPClientError.""" self._set_policy_rules( {'create_environment': '@'} ) env_template_id = 'noexisting' self.expect_policy_check('create_environment', {'env_template_id': env_template_id}) body = {'name': 'test'} req = self._post('/templates/%s/create-environment' % env_template_id, json.dumps(body)) result = req.get_response(self.api) self.assertEqual(404, result.status_code) def _create_env_template_no_service(self): self.expect_policy_check('create_env_template') fake_now = timeutils.utcnow() timeutils.utcnow.override_time = fake_now req = self._post('/templates', json.dumps({'name': 'name'})) result = req.get_response(self.api) self.assertEqual(200, result.status_code) def _create_env_template_services(self): fake_now = timeutils.utcnow() timeutils.utcnow.override_time = fake_now self.expect_policy_check('create_env_template') fake_now = timeutils.utcnow() timeutils.utcnow.override_time = fake_now body = { "name": "env_template_name", "services": [ { "instance": { "assignFloatingIp": "true", "keyname": "mykeyname", "image": "cloud-fedora-v3", "flavor": "m1.medium", "?": { "type": "io.murano.resources.Linux", "id": "ef984a74-29a4-45c0-b1dc-2ab9f075732e" } }, "name": "orion", "port": "8080", "?": { "type": "io.murano.apps.apache.Tomcat", "id": "54cea43d-5970-4c73-b9ac-fea656f3c722" } } ] } req = self._post('/templates', json.dumps(body)) req.get_response(self.api)