
Murano does not get keystone endpoint when Keystone is configured to use templated catalog Change-Id: Id568c0a59b2e99dc946b1f2f55f6b233fd6a1b27 Closes-bug: #1514692
528 lines
18 KiB
Python
528 lines
18 KiB
Python
# Copyright (c) 2014 Mirantis, Inc.
|
|
#
|
|
# 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
|
|
import os
|
|
import time
|
|
import uuid
|
|
|
|
import requests
|
|
from tempest import clients
|
|
from tempest.common import credentials_factory as common_creds
|
|
from tempest.common import dynamic_creds
|
|
from tempest import config
|
|
from tempest import test
|
|
from tempest_lib.common import rest_client
|
|
from tempest_lib import exceptions
|
|
|
|
import murano.tests.functional.common.zip_utils_mixin as zip_utils
|
|
|
|
CONF = config.CONF
|
|
|
|
|
|
def generate_name(prefix):
|
|
"""Generate name for objects."""
|
|
suffix = uuid.uuid4().hex[:8]
|
|
return "{0}_{1}".format(prefix, suffix)
|
|
|
|
|
|
class MuranoClient(rest_client.RestClient):
|
|
def __init__(self, auth_provider):
|
|
super(MuranoClient, self).__init__(
|
|
auth_provider,
|
|
'application-catalog',
|
|
CONF.identity.region
|
|
)
|
|
|
|
def get_environments_list(self):
|
|
resp, body = self.get('v1/environments')
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def create_environment(self, name):
|
|
body = {'name': name}
|
|
resp, body = self.post('v1/environments', json.dumps(body))
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def delete_environment(self, environment_id, timeout=180):
|
|
def _is_exist():
|
|
try:
|
|
resp, _ = self.get('v1/environments/{0}'.format(
|
|
environment_id))
|
|
except exceptions.NotFound:
|
|
return False
|
|
return resp.status == 200
|
|
|
|
env_deleted = not _is_exist()
|
|
self.delete('v1/environments/{0}'.format(environment_id))
|
|
|
|
start_time = time.time()
|
|
while env_deleted is not True:
|
|
if timeout and time.time() - start_time > timeout:
|
|
raise Exception('Environment was not deleted')
|
|
time.sleep(5)
|
|
env_deleted = not _is_exist()
|
|
|
|
def update_environment(self, environment_id):
|
|
post_body = '{"name": "%s"}' % ("changed-environment-name")
|
|
|
|
resp, body = self.put('v1/environments/{0}'.format(environment_id),
|
|
post_body)
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def get_environment(self, environment_id):
|
|
resp, body = self.get('v1/environments/{0}'.format(environment_id))
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def create_session(self, environment_id):
|
|
post_body = None
|
|
|
|
resp, body = self.post(
|
|
'v1/environments/{0}/configure'.format(environment_id),
|
|
post_body
|
|
)
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def delete_session(self, environment_id, session_id):
|
|
return self.delete(
|
|
'v1/environments/{0}/sessions/{1}'.format(environment_id,
|
|
session_id))
|
|
|
|
def get_session(self, environment_id, session_id):
|
|
resp, body = self.get(
|
|
'v1/environments/{0}/sessions/{1}'.format(environment_id,
|
|
session_id))
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def deploy_session(self, environment_id, session_id):
|
|
post_body = None
|
|
url = 'v1/environments/{0}/sessions/{1}/deploy'
|
|
resp, _ = self.post(url.format(environment_id, session_id), post_body)
|
|
|
|
return resp
|
|
|
|
def create_service(self, environment_id, session_id, post_body):
|
|
post_body = json.dumps(post_body)
|
|
|
|
headers = self.get_headers()
|
|
headers.update(
|
|
{'X-Configuration-Session': session_id}
|
|
)
|
|
|
|
resp, body = self.post(
|
|
'v1/environments/{0}/services'.format(environment_id),
|
|
post_body,
|
|
headers
|
|
)
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def delete_service(self, environment_id, session_id, service_id):
|
|
headers = self.get_headers()
|
|
headers.update(
|
|
{'X-Configuration-Session': session_id}
|
|
)
|
|
|
|
return self.delete(
|
|
'v1/environments/{0}/services/{1}'.format(environment_id,
|
|
service_id),
|
|
headers
|
|
)
|
|
|
|
def get_services_list(self, environment_id, session_id):
|
|
headers = self.get_headers()
|
|
if session_id:
|
|
headers.update(
|
|
{'X-Configuration-Session': session_id}
|
|
)
|
|
|
|
resp, body = self.get(
|
|
'v1/environments/{0}/services'.format(environment_id),
|
|
headers
|
|
)
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def get_service(self, environment_id, session_id, service_id):
|
|
headers = self.get_headers()
|
|
headers.update(
|
|
{'X-Configuration-Session': session_id}
|
|
)
|
|
|
|
resp, body = self.get(
|
|
'v1/environments/{0}/services/{1}'.format(environment_id,
|
|
service_id),
|
|
headers
|
|
)
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def get_list_packages(self):
|
|
resp, body = self.get('v1/catalog/packages')
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def get_package(self, id):
|
|
resp, body = self.get('v1/catalog/packages/{0}'.format(id))
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def upload_package(self, package_name, body, path=None):
|
|
headers = {'X-Auth-Token': self.auth_provider.get_token()}
|
|
|
|
if not path:
|
|
__location__ = os.path.realpath(os.path.join(
|
|
os.getcwd(), os.path.dirname(__file__)))
|
|
|
|
path = os.path.join(__location__, 'v1/DummyTestApp.zip')
|
|
|
|
files = {'%s' % package_name: open(path, 'rb')}
|
|
|
|
post_body = {'JsonString': json.dumps(body)}
|
|
request_url = '{endpoint}{url}'.format(endpoint=self.base_url,
|
|
url='/v1/catalog/packages')
|
|
|
|
resp = requests.post(request_url, files=files, data=post_body,
|
|
headers=headers)
|
|
|
|
return resp
|
|
|
|
def update_package(self, id, post_body):
|
|
headers = {
|
|
'X-Auth-Token': self.auth_provider.get_token(),
|
|
'content-type': 'application/murano-packages-json-patch'
|
|
}
|
|
|
|
resp, body = self.patch('v1/catalog/packages/{0}'.format(id),
|
|
json.dumps(post_body), headers=headers)
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def delete_package(self, id):
|
|
return self.delete('v1/catalog/packages/{0}'.format(id))
|
|
|
|
def download_package(self, id):
|
|
headers = {
|
|
'X-Auth-Token': self.auth_provider.get_token(),
|
|
'content-type': 'application/octet-stream'
|
|
}
|
|
return self.get('v1/catalog/packages/{0}/download'.format(id),
|
|
headers=headers)
|
|
|
|
def get_ui_definition(self, id):
|
|
headers = {
|
|
'X-Auth-Token': self.auth_provider.get_token(),
|
|
'content-type': 'text/plain'
|
|
}
|
|
return self.get('v1/catalog/packages/{0}/ui'.format(id),
|
|
headers=headers)
|
|
|
|
def get_logo(self, id):
|
|
headers = {
|
|
'X-Auth-Token': self.auth_provider.get_token(),
|
|
'content-type': 'application/octet-stream'
|
|
}
|
|
return self.get('v1/catalog/packages/{0}/logo'.format(id),
|
|
headers=headers)
|
|
|
|
def get_env_templates_list(self):
|
|
"""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, "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}
|
|
body['services'] = [self._get_demo_app()]
|
|
resp, body = self.post('v1/templates', json.dumps(body))
|
|
return resp, json.loads(body)
|
|
|
|
def create_app_in_env_template(self, env_template_name):
|
|
"""Check the creation of an environment template."""
|
|
resp, body = self.post('v1/templates/{0}/services'.
|
|
format(env_template_name),
|
|
json.dumps(self._get_demo_app()))
|
|
return resp, json.loads(body)
|
|
|
|
def get_apps_in_env_template(self, env_template_name):
|
|
"""Check getting information about applications
|
|
in an environment template.
|
|
"""
|
|
resp, body = self.get('v1/templates/{0}/services'.
|
|
format(env_template_name))
|
|
return resp, json.loads(body)
|
|
|
|
def get_app_in_env_template(self, env_template_name, app_name):
|
|
"""Check getting information about an application
|
|
in an environment template.
|
|
"""
|
|
resp, body = self.get('v1/templates/{0}/services/{1}'.
|
|
format(env_template_name, app_name))
|
|
return resp, json.loads(body)
|
|
|
|
def delete_app_in_env_template(self, env_template_name):
|
|
"""Delete an application in an environment template."""
|
|
resp, _ = self.delete('v1/templates/{0}/services/{1}'.
|
|
format(env_template_name, 'ID'))
|
|
return resp
|
|
|
|
def delete_env_template(self, env_template_id):
|
|
"""Check the deletion of an environment template."""
|
|
resp, _ = self.delete('v1/templates/{0}'.format(env_template_id))
|
|
return resp
|
|
|
|
def get_env_template(self, env_template_id):
|
|
"""Check getting information of an environment template."""
|
|
resp, body = self.get('v1/templates/{0}'.format(env_template_id))
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def create_env_from_template(self, env_template_id, env_name):
|
|
"""Check creating an environment from a template."""
|
|
body = {'name': env_name}
|
|
resp, body = self.post('v1/templates/{0}/create-environment'.
|
|
format(env_template_id),
|
|
json.dumps(body))
|
|
return resp, json.loads(body)
|
|
|
|
def _get_demo_app(self):
|
|
return {
|
|
"instance": {
|
|
"assignFloatingIp": "true",
|
|
"keyname": "mykeyname",
|
|
"image": "cloud-fedora-v3",
|
|
"flavor": "m1.medium",
|
|
"?": {
|
|
"type": "io.murano.resources.LinuxMuranoInstance",
|
|
"id": "ef984a74-29a4-45c0-b1dc-2ab9f075732e"
|
|
}
|
|
},
|
|
"name": "orion",
|
|
"port": "8080",
|
|
"?": {
|
|
"type": "io.murano.apps.apache.Tomcat",
|
|
"id": "ID"
|
|
}
|
|
}
|
|
|
|
def list_categories(self):
|
|
resp, body = self.get('v1/catalog/packages/categories')
|
|
return resp, json.loads(body)
|
|
|
|
def create_category(self, name):
|
|
body = {'name': name}
|
|
resp, body = self.post('v1/catalog/categories', json.dumps(body))
|
|
|
|
return resp, json.loads(body)
|
|
|
|
def delete_category(self, id):
|
|
return self.delete('v1/catalog/categories/{0}'.format(id))
|
|
|
|
def get_category(self, id):
|
|
resp, body = self.get('v1/catalog/categories/{0}'.format(id))
|
|
return resp, json.loads(body)
|
|
|
|
|
|
class TestAuth(test.BaseTestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(TestAuth, cls).setUpClass()
|
|
|
|
# If no credentials are provided, the Manager will use those
|
|
# in CONF.identity and generate an auth_provider from them
|
|
cls.creds = common_creds.get_configured_credentials(
|
|
credential_type='identity_admin')
|
|
mgr = clients.Manager(cls.creds)
|
|
cls.client = MuranoClient(mgr.auth_provider)
|
|
|
|
|
|
class TestObjectCreation(TestAuth):
|
|
|
|
def create_app_zip_archive(self, name, relative_path="v1/"):
|
|
location = os.path.realpath(
|
|
os.path.join(os.getcwd(), os.path.dirname(__file__)))
|
|
|
|
path_to_source = os.path.join(location, relative_path)
|
|
|
|
path = zip_utils.ZipUtilsMixin.zip_dir(path_to_source, name)
|
|
self.addCleanup(os.remove, path)
|
|
|
|
return path
|
|
|
|
def upload_package(self, name, body, path):
|
|
resp = self.client.upload_package(name, body, path)
|
|
self.addCleanup(self.client.delete_package, resp.json()['id'])
|
|
|
|
return resp
|
|
|
|
def create_category(self, name):
|
|
resp, body = self.client.create_category(name)
|
|
self.addCleanup(self.client.delete_category, body['id'])
|
|
|
|
return resp, body
|
|
|
|
|
|
class TestCase(TestAuth):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(TestCase, cls).setUpClass()
|
|
|
|
# If no credentials are provided, the Manager will use those
|
|
# in CONF.identity and generate an auth_provider from them
|
|
cls.creds = common_creds.get_configured_credentials(
|
|
credential_type='identity_admin')
|
|
mgr = clients.Manager(cls.creds)
|
|
cls.client = MuranoClient(mgr.auth_provider)
|
|
|
|
def setUp(self):
|
|
super(TestCase, self).setUp()
|
|
|
|
self.environments = []
|
|
self.env_templates = []
|
|
|
|
def tearDown(self):
|
|
super(TestCase, self).tearDown()
|
|
|
|
for environment in self.environments:
|
|
try:
|
|
self.client.delete_environment(environment['id'])
|
|
except exceptions.NotFound:
|
|
pass
|
|
|
|
for env_template in self.env_templates:
|
|
try:
|
|
self.client.delete_env_template(env_template['id'])
|
|
except exceptions.NotFound:
|
|
pass
|
|
|
|
def create_environment(self, name):
|
|
environment = self.client.create_environment(name)[1]
|
|
self.environments.append(environment)
|
|
|
|
return environment
|
|
|
|
def create_env_template(self, name):
|
|
resp, env_template = self.client.create_env_template(name)
|
|
self.env_templates.append(env_template)
|
|
return resp, 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:
|
|
client = self.client
|
|
post_body = {
|
|
"?": {
|
|
"id": uuid.uuid4().hex,
|
|
"type": "io.murano.tests.demoService"
|
|
},
|
|
"availabilityZone": "nova",
|
|
"name": "demo",
|
|
"unitNamingPattern": "host",
|
|
"osImage": {
|
|
"type": "cirros.demo",
|
|
"name": "demo",
|
|
"title": "Demo"
|
|
},
|
|
"units": [{}],
|
|
"flavor": "m1.small",
|
|
"configuration": "standalone"
|
|
}
|
|
|
|
return client.create_service(environment_id,
|
|
session_id,
|
|
post_body)
|
|
|
|
|
|
class NegativeTestCase(TestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super(NegativeTestCase, cls).setUpClass()
|
|
|
|
# If no credentials are provided, the Manager will use those
|
|
# in CONF.identity and generate an auth_provider from them
|
|
admin_creds = common_creds.get_configured_credentials(
|
|
credential_type='identity_admin')
|
|
cls.dynamic_creds = dynamic_creds.DynamicCredentialProvider(
|
|
identity_version='v2', name=cls.__name__, admin_creds=admin_creds)
|
|
creds = cls.dynamic_creds.get_alt_creds()
|
|
mgr = clients.Manager(credentials=creds)
|
|
cls.alt_client = MuranoClient(mgr.auth_provider)
|
|
|
|
@classmethod
|
|
def purge_creds(cls):
|
|
cls.dynamic_creds.clear_creds()
|