Enable xenial/queens amulet testing
Update amulet tests to enable xenial/queens testing; refactor to use new amulet helpers for v2/v3 defaults switch@queens or later. Change-Id: I09085384db6b47e7bd80a6024c170115fc936680
This commit is contained in:
parent
9baae6cb89
commit
ca525ceb81
@ -5,5 +5,6 @@
|
||||
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
|
||||
<path>/swift-storage/hooks</path>
|
||||
<path>/swift-storage/unit_tests</path>
|
||||
<path>/${PROJECT_DIR_NAME}/tests</path>
|
||||
</pydev_pathproperty>
|
||||
</pydev_project>
|
||||
|
@ -21,6 +21,9 @@ from collections import OrderedDict
|
||||
from charmhelpers.contrib.amulet.deployment import (
|
||||
AmuletDeployment
|
||||
)
|
||||
from charmhelpers.contrib.openstack.amulet.utils import (
|
||||
OPENSTACK_RELEASES_PAIRS
|
||||
)
|
||||
|
||||
DEBUG = logging.DEBUG
|
||||
ERROR = logging.ERROR
|
||||
@ -271,11 +274,8 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
||||
release.
|
||||
"""
|
||||
# Must be ordered by OpenStack release (not by Ubuntu release):
|
||||
(self.trusty_icehouse, self.trusty_kilo, self.trusty_liberty,
|
||||
self.trusty_mitaka, self.xenial_mitaka, self.xenial_newton,
|
||||
self.yakkety_newton, self.xenial_ocata, self.zesty_ocata,
|
||||
self.xenial_pike, self.artful_pike, self.xenial_queens,
|
||||
self.bionic_queens,) = range(13)
|
||||
for i, os_pair in enumerate(OPENSTACK_RELEASES_PAIRS):
|
||||
setattr(self, os_pair, i)
|
||||
|
||||
releases = {
|
||||
('trusty', None): self.trusty_icehouse,
|
||||
|
@ -50,6 +50,13 @@ ERROR = logging.ERROR
|
||||
|
||||
NOVA_CLIENT_VERSION = "2"
|
||||
|
||||
OPENSTACK_RELEASES_PAIRS = [
|
||||
'trusty_icehouse', 'trusty_kilo', 'trusty_liberty',
|
||||
'trusty_mitaka', 'xenial_mitaka', 'xenial_newton',
|
||||
'yakkety_newton', 'xenial_ocata', 'zesty_ocata',
|
||||
'xenial_pike', 'artful_pike', 'xenial_queens',
|
||||
'bionic_queens']
|
||||
|
||||
|
||||
class OpenStackAmuletUtils(AmuletUtils):
|
||||
"""OpenStack amulet utilities.
|
||||
@ -63,7 +70,34 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||
super(OpenStackAmuletUtils, self).__init__(log_level)
|
||||
|
||||
def validate_endpoint_data(self, endpoints, admin_port, internal_port,
|
||||
public_port, expected):
|
||||
public_port, expected, openstack_release=None):
|
||||
"""Validate endpoint data. Pick the correct validator based on
|
||||
OpenStack release. Expected data should be in the v2 format:
|
||||
{
|
||||
'id': id,
|
||||
'region': region,
|
||||
'adminurl': adminurl,
|
||||
'internalurl': internalurl,
|
||||
'publicurl': publicurl,
|
||||
'service_id': service_id}
|
||||
|
||||
"""
|
||||
validation_function = self.validate_v2_endpoint_data
|
||||
xenial_queens = OPENSTACK_RELEASES_PAIRS.index('xenial_queens')
|
||||
if openstack_release and openstack_release >= xenial_queens:
|
||||
validation_function = self.validate_v3_endpoint_data
|
||||
expected = {
|
||||
'id': expected['id'],
|
||||
'region': expected['region'],
|
||||
'region_id': 'RegionOne',
|
||||
'url': self.valid_url,
|
||||
'interface': self.not_null,
|
||||
'service_id': expected['service_id']}
|
||||
return validation_function(endpoints, admin_port, internal_port,
|
||||
public_port, expected)
|
||||
|
||||
def validate_v2_endpoint_data(self, endpoints, admin_port, internal_port,
|
||||
public_port, expected):
|
||||
"""Validate endpoint data.
|
||||
|
||||
Validate actual endpoint data vs expected endpoint data. The ports
|
||||
@ -141,7 +175,86 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||
if len(found) != expected_num_eps:
|
||||
return 'Unexpected number of endpoints found'
|
||||
|
||||
def validate_svc_catalog_endpoint_data(self, expected, actual):
|
||||
def convert_svc_catalog_endpoint_data_to_v3(self, ep_data):
|
||||
"""Convert v2 endpoint data into v3.
|
||||
|
||||
{
|
||||
'service_name1': [
|
||||
{
|
||||
'adminURL': adminURL,
|
||||
'id': id,
|
||||
'region': region.
|
||||
'publicURL': publicURL,
|
||||
'internalURL': internalURL
|
||||
}],
|
||||
'service_name2': [
|
||||
{
|
||||
'adminURL': adminURL,
|
||||
'id': id,
|
||||
'region': region.
|
||||
'publicURL': publicURL,
|
||||
'internalURL': internalURL
|
||||
}],
|
||||
}
|
||||
"""
|
||||
self.log.warn("Endpoint ID and Region ID validation is limited to not "
|
||||
"null checks after v2 to v3 conversion")
|
||||
for svc in ep_data.keys():
|
||||
assert len(ep_data[svc]) == 1, "Unknown data format"
|
||||
svc_ep_data = ep_data[svc][0]
|
||||
ep_data[svc] = [
|
||||
{
|
||||
'url': svc_ep_data['adminURL'],
|
||||
'interface': 'admin',
|
||||
'region': svc_ep_data['region'],
|
||||
'region_id': self.not_null,
|
||||
'id': self.not_null},
|
||||
{
|
||||
'url': svc_ep_data['publicURL'],
|
||||
'interface': 'public',
|
||||
'region': svc_ep_data['region'],
|
||||
'region_id': self.not_null,
|
||||
'id': self.not_null},
|
||||
{
|
||||
'url': svc_ep_data['internalURL'],
|
||||
'interface': 'internal',
|
||||
'region': svc_ep_data['region'],
|
||||
'region_id': self.not_null,
|
||||
'id': self.not_null}]
|
||||
return ep_data
|
||||
|
||||
def validate_svc_catalog_endpoint_data(self, expected, actual,
|
||||
openstack_release=None):
|
||||
"""Validate service catalog endpoint data. Pick the correct validator
|
||||
for the OpenStack version. Expected data should be in the v2 format:
|
||||
{
|
||||
'service_name1': [
|
||||
{
|
||||
'adminURL': adminURL,
|
||||
'id': id,
|
||||
'region': region.
|
||||
'publicURL': publicURL,
|
||||
'internalURL': internalURL
|
||||
}],
|
||||
'service_name2': [
|
||||
{
|
||||
'adminURL': adminURL,
|
||||
'id': id,
|
||||
'region': region.
|
||||
'publicURL': publicURL,
|
||||
'internalURL': internalURL
|
||||
}],
|
||||
}
|
||||
|
||||
"""
|
||||
validation_function = self.validate_v2_svc_catalog_endpoint_data
|
||||
xenial_queens = OPENSTACK_RELEASES_PAIRS.index('xenial_queens')
|
||||
if openstack_release and openstack_release >= xenial_queens:
|
||||
validation_function = self.validate_v3_svc_catalog_endpoint_data
|
||||
expected = self.convert_svc_catalog_endpoint_data_to_v3(expected)
|
||||
return validation_function(expected, actual)
|
||||
|
||||
def validate_v2_svc_catalog_endpoint_data(self, expected, actual):
|
||||
"""Validate service catalog endpoint data.
|
||||
|
||||
Validate a list of actual service catalog endpoints vs a list of
|
||||
@ -367,13 +480,36 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||
project_domain_name=None, project_name=None):
|
||||
"""Authenticate with Keystone"""
|
||||
self.log.debug('Authenticating with keystone...')
|
||||
port = 5000
|
||||
if admin_port:
|
||||
port = 35357
|
||||
base_ep = "http://{}:{}".format(keystone_ip.strip().decode('utf-8'),
|
||||
port)
|
||||
if not api_version or api_version == 2:
|
||||
ep = base_ep + "/v2.0"
|
||||
if not api_version:
|
||||
api_version = 2
|
||||
sess, auth = self.get_keystone_session(
|
||||
keystone_ip=keystone_ip,
|
||||
username=username,
|
||||
password=password,
|
||||
api_version=api_version,
|
||||
admin_port=admin_port,
|
||||
user_domain_name=user_domain_name,
|
||||
domain_name=domain_name,
|
||||
project_domain_name=project_domain_name,
|
||||
project_name=project_name
|
||||
)
|
||||
if api_version == 2:
|
||||
client = keystone_client.Client(session=sess)
|
||||
else:
|
||||
client = keystone_client_v3.Client(session=sess)
|
||||
# This populates the client.service_catalog
|
||||
client.auth_ref = auth.get_access(sess)
|
||||
return client
|
||||
|
||||
def get_keystone_session(self, keystone_ip, username, password,
|
||||
api_version=False, admin_port=False,
|
||||
user_domain_name=None, domain_name=None,
|
||||
project_domain_name=None, project_name=None):
|
||||
"""Return a keystone session object"""
|
||||
ep = self.get_keystone_endpoint(keystone_ip,
|
||||
api_version=api_version,
|
||||
admin_port=admin_port)
|
||||
if api_version == 2:
|
||||
auth = v2.Password(
|
||||
username=username,
|
||||
password=password,
|
||||
@ -381,12 +517,7 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||
auth_url=ep
|
||||
)
|
||||
sess = keystone_session.Session(auth=auth)
|
||||
client = keystone_client.Client(session=sess)
|
||||
# This populates the client.service_catalog
|
||||
client.auth_ref = auth.get_access(sess)
|
||||
return client
|
||||
else:
|
||||
ep = base_ep + "/v3"
|
||||
auth = v3.Password(
|
||||
user_domain_name=user_domain_name,
|
||||
username=username,
|
||||
@ -397,10 +528,57 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||
auth_url=ep
|
||||
)
|
||||
sess = keystone_session.Session(auth=auth)
|
||||
client = keystone_client_v3.Client(session=sess)
|
||||
# This populates the client.service_catalog
|
||||
client.auth_ref = auth.get_access(sess)
|
||||
return client
|
||||
return (sess, auth)
|
||||
|
||||
def get_keystone_endpoint(self, keystone_ip, api_version=None,
|
||||
admin_port=False):
|
||||
"""Return keystone endpoint"""
|
||||
port = 5000
|
||||
if admin_port:
|
||||
port = 35357
|
||||
base_ep = "http://{}:{}".format(keystone_ip.strip().decode('utf-8'),
|
||||
port)
|
||||
if api_version == 2:
|
||||
ep = base_ep + "/v2.0"
|
||||
else:
|
||||
ep = base_ep + "/v3"
|
||||
return ep
|
||||
|
||||
def get_default_keystone_session(self, keystone_sentry,
|
||||
openstack_release=None):
|
||||
"""Return a keystone session object and client object assuming standard
|
||||
default settings
|
||||
|
||||
Example call in amulet tests:
|
||||
self.keystone_session, self.keystone = u.get_default_keystone_session(
|
||||
self.keystone_sentry,
|
||||
openstack_release=self._get_openstack_release())
|
||||
|
||||
The session can then be used to auth other clients:
|
||||
neutronclient.Client(session=session)
|
||||
aodh_client.Client(session=session)
|
||||
eyc
|
||||
"""
|
||||
self.log.debug('Authenticating keystone admin...')
|
||||
api_version = 2
|
||||
client_class = keystone_client.Client
|
||||
# 11 => xenial_queens
|
||||
if openstack_release and openstack_release >= 11:
|
||||
api_version = 3
|
||||
client_class = keystone_client_v3.Client
|
||||
keystone_ip = keystone_sentry.info['public-address']
|
||||
session, auth = self.get_keystone_session(
|
||||
keystone_ip,
|
||||
api_version=api_version,
|
||||
username='admin',
|
||||
password='openstack',
|
||||
project_name='admin',
|
||||
user_domain_name='admin_domain',
|
||||
project_domain_name='admin_domain')
|
||||
client = client_class(session=session)
|
||||
# This populates the client.service_catalog
|
||||
client.auth_ref = auth.get_access(session)
|
||||
return session, client
|
||||
|
||||
def authenticate_keystone_admin(self, keystone_sentry, user, password,
|
||||
tenant=None, api_version=None,
|
||||
|
@ -384,6 +384,7 @@ class IdentityServiceContext(OSContextGenerator):
|
||||
# so a missing value just indicates keystone needs
|
||||
# upgrading
|
||||
ctxt['admin_tenant_id'] = rdata.get('service_tenant_id')
|
||||
ctxt['admin_domain_id'] = rdata.get('service_domain_id')
|
||||
return ctxt
|
||||
|
||||
return {}
|
||||
|
@ -15,6 +15,9 @@
|
||||
import amulet
|
||||
import swiftclient
|
||||
|
||||
import keystoneclient
|
||||
from keystoneclient.v3 import client as keystone_client_v3
|
||||
|
||||
from charmhelpers.contrib.openstack.amulet.deployment import (
|
||||
OpenStackAmuletDeployment
|
||||
)
|
||||
@ -121,46 +124,105 @@ class SwiftStorageBasicDeployment(OpenStackAmuletDeployment):
|
||||
self._get_openstack_release_string()))
|
||||
|
||||
# Authenticate admin with keystone
|
||||
self.keystone = u.authenticate_keystone_admin(self.keystone_sentry,
|
||||
user='admin',
|
||||
password='openstack',
|
||||
tenant='admin')
|
||||
self.keystone_session, self.keystone = (
|
||||
u.get_default_keystone_session(self.keystone_sentry,
|
||||
self._get_openstack_release())
|
||||
)
|
||||
|
||||
# Authenticate admin with glance endpoint
|
||||
self.glance = u.authenticate_glance_admin(self.keystone)
|
||||
|
||||
# Authenticate swift user
|
||||
keystone_ip = self.keystone_sentry.info['public-address']
|
||||
keystone_relation = self.keystone_sentry.relation(
|
||||
'identity-service', 'swift-proxy:identity-service')
|
||||
ep = self.keystone.service_catalog.url_for(service_type='identity',
|
||||
interface='publicURL')
|
||||
self.swift = swiftclient.Connection(
|
||||
authurl=ep,
|
||||
user=keystone_relation['service_username'],
|
||||
key=keystone_relation['service_password'],
|
||||
tenant_name=keystone_relation['service_tenant'],
|
||||
auth_version='2.0')
|
||||
|
||||
# Create a demo tenant/role/user
|
||||
self.demo_tenant = 'demoTenant'
|
||||
self.demo_role = 'demoRole'
|
||||
self.demo_user = 'demoUser'
|
||||
self.demo_project = 'demoProject'
|
||||
self.demo_domain = 'demoDomain'
|
||||
|
||||
if self._get_openstack_release() >= self.xenial_queens:
|
||||
self.create_users_v3()
|
||||
self.demo_user_session, _ = u.get_keystone_session(
|
||||
keystone_ip,
|
||||
self.demo_user,
|
||||
'password',
|
||||
api_version=3,
|
||||
user_domain_name=self.demo_domain,
|
||||
project_domain_name=self.demo_domain,
|
||||
project_name=self.demo_project
|
||||
)
|
||||
self.keystone_demo = keystone_client_v3.Client(
|
||||
session=self.demo_user_session)
|
||||
self.service_session, _ = u.get_keystone_session(
|
||||
keystone_ip,
|
||||
keystone_relation['service_username'],
|
||||
keystone_relation['service_password'],
|
||||
api_version=3,
|
||||
user_domain_name=keystone_relation['service_domain'],
|
||||
project_domain_name=keystone_relation['service_domain'],
|
||||
project_name=keystone_relation['service_tenant']
|
||||
)
|
||||
else:
|
||||
self.create_users_v2()
|
||||
# Authenticate demo user with keystone
|
||||
self.keystone_demo = \
|
||||
u.authenticate_keystone_user(
|
||||
self.keystone, user=self.demo_user,
|
||||
password='password',
|
||||
tenant=self.demo_tenant)
|
||||
self.service_session, _ = u.get_keystone_session(
|
||||
keystone_ip,
|
||||
keystone_relation['service_username'],
|
||||
keystone_relation['service_password'],
|
||||
api_version=2,
|
||||
project_name=keystone_relation['service_tenant']
|
||||
)
|
||||
self.swift = swiftclient.Connection(session=self.service_session)
|
||||
|
||||
def create_users_v3(self):
|
||||
try:
|
||||
self.keystone.projects.find(name=self.demo_project)
|
||||
except keystoneclient.exceptions.NotFound:
|
||||
domain = self.keystone.domains.create(
|
||||
self.demo_domain,
|
||||
description='Demo Domain',
|
||||
enabled=True
|
||||
)
|
||||
project = self.keystone.projects.create(
|
||||
self.demo_project,
|
||||
domain,
|
||||
description='Demo Project',
|
||||
enabled=True,
|
||||
)
|
||||
user = self.keystone.users.create(
|
||||
self.demo_user,
|
||||
domain=domain.id,
|
||||
project=self.demo_project,
|
||||
password='password',
|
||||
email='demov3@demo.com',
|
||||
description='Demo',
|
||||
enabled=True)
|
||||
role = self.keystone.roles.find(name='Admin')
|
||||
self.keystone.roles.grant(
|
||||
role.id,
|
||||
user=user.id,
|
||||
project=project.id)
|
||||
|
||||
def create_users_v2(self):
|
||||
if not u.tenant_exists(self.keystone, self.demo_tenant):
|
||||
tenant = self.keystone.tenants.create(tenant_name=self.demo_tenant,
|
||||
description='demo tenant',
|
||||
enabled=True)
|
||||
|
||||
self.keystone.roles.create(name=self.demo_role)
|
||||
self.keystone.users.create(name=self.demo_user,
|
||||
password='password',
|
||||
tenant_id=tenant.id,
|
||||
email='demo@demo.com')
|
||||
|
||||
# Authenticate demo user with keystone
|
||||
self.keystone_demo = \
|
||||
u.authenticate_keystone_user(self.keystone, user=self.demo_user,
|
||||
password='password',
|
||||
tenant=self.demo_tenant)
|
||||
|
||||
def test_100_services(self):
|
||||
"""Verify the expected services are running on the corresponding
|
||||
service units."""
|
||||
@ -193,36 +255,6 @@ class SwiftStorageBasicDeployment(OpenStackAmuletDeployment):
|
||||
if ret:
|
||||
amulet.raise_status(amulet.FAIL, msg=ret)
|
||||
|
||||
def test_102_users(self):
|
||||
"""Verify all existing roles."""
|
||||
u.log.debug('Checking keystone users...')
|
||||
user1 = {'name': 'demoUser',
|
||||
'enabled': True,
|
||||
'tenantId': u.not_null,
|
||||
'id': u.not_null,
|
||||
'email': 'demo@demo.com'}
|
||||
user2 = {'name': 'admin',
|
||||
'enabled': True,
|
||||
'tenantId': u.not_null,
|
||||
'id': u.not_null,
|
||||
'email': 'juju@localhost'}
|
||||
user3 = {'name': 'glance',
|
||||
'enabled': True,
|
||||
'tenantId': u.not_null,
|
||||
'id': u.not_null,
|
||||
'email': u'juju@localhost'}
|
||||
user4 = {'name': 's3_swift',
|
||||
'enabled': True,
|
||||
'tenantId': u.not_null,
|
||||
'id': u.not_null,
|
||||
'email': u'juju@localhost'}
|
||||
expected = [user1, user2, user3, user4]
|
||||
actual = self.keystone.users.list()
|
||||
|
||||
ret = u.validate_user_data(expected, actual)
|
||||
if ret:
|
||||
amulet.raise_status(amulet.FAIL, msg=ret)
|
||||
|
||||
def test_104_keystone_service_catalog(self):
|
||||
"""Verify that the service catalog endpoint data is valid."""
|
||||
u.log.debug('Checking keystone service catalog...')
|
||||
@ -234,30 +266,15 @@ class SwiftStorageBasicDeployment(OpenStackAmuletDeployment):
|
||||
|
||||
expected = {'image': [endpoint_id], 'object-store': [endpoint_id],
|
||||
'identity': [endpoint_id], 's3': [endpoint_id]}
|
||||
actual = self.keystone_demo.service_catalog.get_endpoints()
|
||||
actual = self.keystone.service_catalog.get_endpoints()
|
||||
|
||||
ret = u.validate_svc_catalog_endpoint_data(expected, actual)
|
||||
ret = u.validate_svc_catalog_endpoint_data(
|
||||
expected, actual,
|
||||
openstack_release=self._get_openstack_release()
|
||||
)
|
||||
if ret:
|
||||
amulet.raise_status(amulet.FAIL, msg=ret)
|
||||
|
||||
def test_106_swift_object_store_endpoint(self):
|
||||
"""Verify the swift object-store endpoint data."""
|
||||
u.log.debug('Checking keystone endpoint for swift object store...')
|
||||
endpoints = self.keystone.endpoints.list()
|
||||
admin_port = internal_port = public_port = '8080'
|
||||
expected = {'id': u.not_null,
|
||||
'region': 'RegionOne',
|
||||
'adminurl': u.valid_url,
|
||||
'internalurl': u.valid_url,
|
||||
'publicurl': u.valid_url,
|
||||
'service_id': u.not_null}
|
||||
|
||||
ret = u.validate_endpoint_data(endpoints, admin_port, internal_port,
|
||||
public_port, expected)
|
||||
if ret:
|
||||
message = 'object-store endpoint: {}'.format(ret)
|
||||
amulet.raise_status(amulet.FAIL, msg=message)
|
||||
|
||||
def test_200_swift_storage_swift_storage_relation(self):
|
||||
"""Verify the swift-storage to swift-proxy swift-storage relation
|
||||
data."""
|
||||
|
@ -21,6 +21,9 @@ from collections import OrderedDict
|
||||
from charmhelpers.contrib.amulet.deployment import (
|
||||
AmuletDeployment
|
||||
)
|
||||
from charmhelpers.contrib.openstack.amulet.utils import (
|
||||
OPENSTACK_RELEASES_PAIRS
|
||||
)
|
||||
|
||||
DEBUG = logging.DEBUG
|
||||
ERROR = logging.ERROR
|
||||
@ -271,11 +274,8 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
||||
release.
|
||||
"""
|
||||
# Must be ordered by OpenStack release (not by Ubuntu release):
|
||||
(self.trusty_icehouse, self.trusty_kilo, self.trusty_liberty,
|
||||
self.trusty_mitaka, self.xenial_mitaka, self.xenial_newton,
|
||||
self.yakkety_newton, self.xenial_ocata, self.zesty_ocata,
|
||||
self.xenial_pike, self.artful_pike, self.xenial_queens,
|
||||
self.bionic_queens,) = range(13)
|
||||
for i, os_pair in enumerate(OPENSTACK_RELEASES_PAIRS):
|
||||
setattr(self, os_pair, i)
|
||||
|
||||
releases = {
|
||||
('trusty', None): self.trusty_icehouse,
|
||||
|
@ -50,6 +50,13 @@ ERROR = logging.ERROR
|
||||
|
||||
NOVA_CLIENT_VERSION = "2"
|
||||
|
||||
OPENSTACK_RELEASES_PAIRS = [
|
||||
'trusty_icehouse', 'trusty_kilo', 'trusty_liberty',
|
||||
'trusty_mitaka', 'xenial_mitaka', 'xenial_newton',
|
||||
'yakkety_newton', 'xenial_ocata', 'zesty_ocata',
|
||||
'xenial_pike', 'artful_pike', 'xenial_queens',
|
||||
'bionic_queens']
|
||||
|
||||
|
||||
class OpenStackAmuletUtils(AmuletUtils):
|
||||
"""OpenStack amulet utilities.
|
||||
@ -63,7 +70,34 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||
super(OpenStackAmuletUtils, self).__init__(log_level)
|
||||
|
||||
def validate_endpoint_data(self, endpoints, admin_port, internal_port,
|
||||
public_port, expected):
|
||||
public_port, expected, openstack_release=None):
|
||||
"""Validate endpoint data. Pick the correct validator based on
|
||||
OpenStack release. Expected data should be in the v2 format:
|
||||
{
|
||||
'id': id,
|
||||
'region': region,
|
||||
'adminurl': adminurl,
|
||||
'internalurl': internalurl,
|
||||
'publicurl': publicurl,
|
||||
'service_id': service_id}
|
||||
|
||||
"""
|
||||
validation_function = self.validate_v2_endpoint_data
|
||||
xenial_queens = OPENSTACK_RELEASES_PAIRS.index('xenial_queens')
|
||||
if openstack_release and openstack_release >= xenial_queens:
|
||||
validation_function = self.validate_v3_endpoint_data
|
||||
expected = {
|
||||
'id': expected['id'],
|
||||
'region': expected['region'],
|
||||
'region_id': 'RegionOne',
|
||||
'url': self.valid_url,
|
||||
'interface': self.not_null,
|
||||
'service_id': expected['service_id']}
|
||||
return validation_function(endpoints, admin_port, internal_port,
|
||||
public_port, expected)
|
||||
|
||||
def validate_v2_endpoint_data(self, endpoints, admin_port, internal_port,
|
||||
public_port, expected):
|
||||
"""Validate endpoint data.
|
||||
|
||||
Validate actual endpoint data vs expected endpoint data. The ports
|
||||
@ -141,7 +175,86 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||
if len(found) != expected_num_eps:
|
||||
return 'Unexpected number of endpoints found'
|
||||
|
||||
def validate_svc_catalog_endpoint_data(self, expected, actual):
|
||||
def convert_svc_catalog_endpoint_data_to_v3(self, ep_data):
|
||||
"""Convert v2 endpoint data into v3.
|
||||
|
||||
{
|
||||
'service_name1': [
|
||||
{
|
||||
'adminURL': adminURL,
|
||||
'id': id,
|
||||
'region': region.
|
||||
'publicURL': publicURL,
|
||||
'internalURL': internalURL
|
||||
}],
|
||||
'service_name2': [
|
||||
{
|
||||
'adminURL': adminURL,
|
||||
'id': id,
|
||||
'region': region.
|
||||
'publicURL': publicURL,
|
||||
'internalURL': internalURL
|
||||
}],
|
||||
}
|
||||
"""
|
||||
self.log.warn("Endpoint ID and Region ID validation is limited to not "
|
||||
"null checks after v2 to v3 conversion")
|
||||
for svc in ep_data.keys():
|
||||
assert len(ep_data[svc]) == 1, "Unknown data format"
|
||||
svc_ep_data = ep_data[svc][0]
|
||||
ep_data[svc] = [
|
||||
{
|
||||
'url': svc_ep_data['adminURL'],
|
||||
'interface': 'admin',
|
||||
'region': svc_ep_data['region'],
|
||||
'region_id': self.not_null,
|
||||
'id': self.not_null},
|
||||
{
|
||||
'url': svc_ep_data['publicURL'],
|
||||
'interface': 'public',
|
||||
'region': svc_ep_data['region'],
|
||||
'region_id': self.not_null,
|
||||
'id': self.not_null},
|
||||
{
|
||||
'url': svc_ep_data['internalURL'],
|
||||
'interface': 'internal',
|
||||
'region': svc_ep_data['region'],
|
||||
'region_id': self.not_null,
|
||||
'id': self.not_null}]
|
||||
return ep_data
|
||||
|
||||
def validate_svc_catalog_endpoint_data(self, expected, actual,
|
||||
openstack_release=None):
|
||||
"""Validate service catalog endpoint data. Pick the correct validator
|
||||
for the OpenStack version. Expected data should be in the v2 format:
|
||||
{
|
||||
'service_name1': [
|
||||
{
|
||||
'adminURL': adminURL,
|
||||
'id': id,
|
||||
'region': region.
|
||||
'publicURL': publicURL,
|
||||
'internalURL': internalURL
|
||||
}],
|
||||
'service_name2': [
|
||||
{
|
||||
'adminURL': adminURL,
|
||||
'id': id,
|
||||
'region': region.
|
||||
'publicURL': publicURL,
|
||||
'internalURL': internalURL
|
||||
}],
|
||||
}
|
||||
|
||||
"""
|
||||
validation_function = self.validate_v2_svc_catalog_endpoint_data
|
||||
xenial_queens = OPENSTACK_RELEASES_PAIRS.index('xenial_queens')
|
||||
if openstack_release and openstack_release >= xenial_queens:
|
||||
validation_function = self.validate_v3_svc_catalog_endpoint_data
|
||||
expected = self.convert_svc_catalog_endpoint_data_to_v3(expected)
|
||||
return validation_function(expected, actual)
|
||||
|
||||
def validate_v2_svc_catalog_endpoint_data(self, expected, actual):
|
||||
"""Validate service catalog endpoint data.
|
||||
|
||||
Validate a list of actual service catalog endpoints vs a list of
|
||||
@ -367,13 +480,36 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||
project_domain_name=None, project_name=None):
|
||||
"""Authenticate with Keystone"""
|
||||
self.log.debug('Authenticating with keystone...')
|
||||
port = 5000
|
||||
if admin_port:
|
||||
port = 35357
|
||||
base_ep = "http://{}:{}".format(keystone_ip.strip().decode('utf-8'),
|
||||
port)
|
||||
if not api_version or api_version == 2:
|
||||
ep = base_ep + "/v2.0"
|
||||
if not api_version:
|
||||
api_version = 2
|
||||
sess, auth = self.get_keystone_session(
|
||||
keystone_ip=keystone_ip,
|
||||
username=username,
|
||||
password=password,
|
||||
api_version=api_version,
|
||||
admin_port=admin_port,
|
||||
user_domain_name=user_domain_name,
|
||||
domain_name=domain_name,
|
||||
project_domain_name=project_domain_name,
|
||||
project_name=project_name
|
||||
)
|
||||
if api_version == 2:
|
||||
client = keystone_client.Client(session=sess)
|
||||
else:
|
||||
client = keystone_client_v3.Client(session=sess)
|
||||
# This populates the client.service_catalog
|
||||
client.auth_ref = auth.get_access(sess)
|
||||
return client
|
||||
|
||||
def get_keystone_session(self, keystone_ip, username, password,
|
||||
api_version=False, admin_port=False,
|
||||
user_domain_name=None, domain_name=None,
|
||||
project_domain_name=None, project_name=None):
|
||||
"""Return a keystone session object"""
|
||||
ep = self.get_keystone_endpoint(keystone_ip,
|
||||
api_version=api_version,
|
||||
admin_port=admin_port)
|
||||
if api_version == 2:
|
||||
auth = v2.Password(
|
||||
username=username,
|
||||
password=password,
|
||||
@ -381,12 +517,7 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||
auth_url=ep
|
||||
)
|
||||
sess = keystone_session.Session(auth=auth)
|
||||
client = keystone_client.Client(session=sess)
|
||||
# This populates the client.service_catalog
|
||||
client.auth_ref = auth.get_access(sess)
|
||||
return client
|
||||
else:
|
||||
ep = base_ep + "/v3"
|
||||
auth = v3.Password(
|
||||
user_domain_name=user_domain_name,
|
||||
username=username,
|
||||
@ -397,10 +528,57 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||
auth_url=ep
|
||||
)
|
||||
sess = keystone_session.Session(auth=auth)
|
||||
client = keystone_client_v3.Client(session=sess)
|
||||
# This populates the client.service_catalog
|
||||
client.auth_ref = auth.get_access(sess)
|
||||
return client
|
||||
return (sess, auth)
|
||||
|
||||
def get_keystone_endpoint(self, keystone_ip, api_version=None,
|
||||
admin_port=False):
|
||||
"""Return keystone endpoint"""
|
||||
port = 5000
|
||||
if admin_port:
|
||||
port = 35357
|
||||
base_ep = "http://{}:{}".format(keystone_ip.strip().decode('utf-8'),
|
||||
port)
|
||||
if api_version == 2:
|
||||
ep = base_ep + "/v2.0"
|
||||
else:
|
||||
ep = base_ep + "/v3"
|
||||
return ep
|
||||
|
||||
def get_default_keystone_session(self, keystone_sentry,
|
||||
openstack_release=None):
|
||||
"""Return a keystone session object and client object assuming standard
|
||||
default settings
|
||||
|
||||
Example call in amulet tests:
|
||||
self.keystone_session, self.keystone = u.get_default_keystone_session(
|
||||
self.keystone_sentry,
|
||||
openstack_release=self._get_openstack_release())
|
||||
|
||||
The session can then be used to auth other clients:
|
||||
neutronclient.Client(session=session)
|
||||
aodh_client.Client(session=session)
|
||||
eyc
|
||||
"""
|
||||
self.log.debug('Authenticating keystone admin...')
|
||||
api_version = 2
|
||||
client_class = keystone_client.Client
|
||||
# 11 => xenial_queens
|
||||
if openstack_release and openstack_release >= 11:
|
||||
api_version = 3
|
||||
client_class = keystone_client_v3.Client
|
||||
keystone_ip = keystone_sentry.info['public-address']
|
||||
session, auth = self.get_keystone_session(
|
||||
keystone_ip,
|
||||
api_version=api_version,
|
||||
username='admin',
|
||||
password='openstack',
|
||||
project_name='admin',
|
||||
user_domain_name='admin_domain',
|
||||
project_domain_name='admin_domain')
|
||||
client = client_class(session=session)
|
||||
# This populates the client.service_catalog
|
||||
client.auth_ref = auth.get_access(session)
|
||||
return session, client
|
||||
|
||||
def authenticate_keystone_admin(self, keystone_sentry, user, password,
|
||||
tenant=None, api_version=None,
|
||||
|
Loading…
x
Reference in New Issue
Block a user