Merge "Fix password not strong enough for cmd"
diff --git a/tempest/api/compute/admin/test_floating_ips_bulk.py b/tempest/api/compute/admin/test_floating_ips_bulk.py
index fe05ddb..456363c 100644
--- a/tempest/api/compute/admin/test_floating_ips_bulk.py
+++ b/tempest/api/compute/admin/test_floating_ips_bulk.py
@@ -38,7 +38,7 @@
@classmethod
def resource_setup(cls):
super(FloatingIPsBulkAdminTestJSON, cls).resource_setup()
- cls.ip_range = CONF.compute.floating_ip_range
+ cls.ip_range = CONF.validation.floating_ip_range
cls.verify_unallocated_floating_ip_range(cls.ip_range)
@classmethod
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 2321b4e..aa8ee3f 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -101,13 +101,13 @@
super(BaseV2ComputeTest, cls).resource_setup()
cls.build_interval = CONF.compute.build_interval
cls.build_timeout = CONF.compute.build_timeout
- cls.ssh_user = CONF.compute.ssh_user
cls.image_ref = CONF.compute.image_ref
cls.image_ref_alt = CONF.compute.image_ref_alt
cls.flavor_ref = CONF.compute.flavor_ref
cls.flavor_ref_alt = CONF.compute.flavor_ref_alt
- cls.image_ssh_user = CONF.compute.image_ssh_user
- cls.image_ssh_password = CONF.compute.image_ssh_password
+ cls.ssh_user = CONF.validation.image_ssh_user
+ cls.image_ssh_user = CONF.validation.image_ssh_user
+ cls.image_ssh_password = CONF.validation.image_ssh_password
cls.servers = []
cls.images = []
cls.security_groups = []
diff --git a/tempest/api/identity/admin/v2/test_roles.py b/tempest/api/identity/admin/v2/test_roles.py
index 8702db7..e547bdd 100644
--- a/tempest/api/identity/admin/v2/test_roles.py
+++ b/tempest/api/identity/admin/v2/test_roles.py
@@ -27,7 +27,7 @@
super(RolesTestJSON, cls).resource_setup()
for _ in moves.xrange(5):
role_name = data_utils.rand_name(name='role')
- role = cls.client.create_role(role_name)['role']
+ role = cls.roles_client.create_role(role_name)['role']
cls.data.roles.append(role)
def _get_role_params(self):
@@ -48,7 +48,7 @@
@test.idempotent_id('75d9593f-50b7-4fcf-bd64-e3fb4a278e23')
def test_list_roles(self):
"""Return a list of all roles."""
- body = self.client.list_roles()['roles']
+ body = self.roles_client.list_roles()['roles']
found = [role for role in body if role in self.data.roles]
self.assertTrue(any(found))
self.assertEqual(len(found), len(self.data.roles))
@@ -57,16 +57,16 @@
def test_role_create_delete(self):
"""Role should be created, verified, and deleted."""
role_name = data_utils.rand_name(name='role-test')
- body = self.client.create_role(role_name)['role']
+ body = self.roles_client.create_role(role_name)['role']
self.assertEqual(role_name, body['name'])
- body = self.client.list_roles()['roles']
+ body = self.roles_client.list_roles()['roles']
found = [role for role in body if role['name'] == role_name]
self.assertTrue(any(found))
- body = self.client.delete_role(found[0]['id'])
+ body = self.roles_client.delete_role(found[0]['id'])
- body = self.client.list_roles()['roles']
+ body = self.roles_client.list_roles()['roles']
found = [role for role in body if role['name'] == role_name]
self.assertFalse(any(found))
@@ -76,7 +76,7 @@
self.data.setup_test_role()
role_id = self.data.role['id']
role_name = self.data.role['name']
- body = self.client.show_role(role_id)['role']
+ body = self.roles_client.show_role(role_id)['role']
self.assertEqual(role_id, body['id'])
self.assertEqual(role_name, body['name'])
@@ -84,24 +84,28 @@
def test_assign_user_role(self):
"""Assign a role to a user on a tenant."""
(user, tenant, role) = self._get_role_params()
- self.client.assign_user_role(tenant['id'], user['id'], role['id'])
- roles = self.client.list_user_roles(tenant['id'], user['id'])['roles']
+ self.roles_client.assign_user_role(tenant['id'], user['id'],
+ role['id'])
+ roles = self.roles_client.list_user_roles(tenant['id'],
+ user['id'])['roles']
self.assert_role_in_role_list(role, roles)
@test.idempotent_id('f0b9292c-d3ba-4082-aa6c-440489beef69')
def test_remove_user_role(self):
"""Remove a role assigned to a user on a tenant."""
(user, tenant, role) = self._get_role_params()
- user_role = self.client.assign_user_role(tenant['id'],
- user['id'],
- role['id'])['role']
- self.client.delete_user_role(tenant['id'], user['id'],
- user_role['id'])
+ user_role = self.roles_client.assign_user_role(tenant['id'],
+ user['id'],
+ role['id'])['role']
+ self.roles_client.delete_user_role(tenant['id'], user['id'],
+ user_role['id'])
@test.idempotent_id('262e1e3e-ed71-4edd-a0e5-d64e83d66d05')
def test_list_user_roles(self):
"""List roles assigned to a user on tenant."""
(user, tenant, role) = self._get_role_params()
- self.client.assign_user_role(tenant['id'], user['id'], role['id'])
- roles = self.client.list_user_roles(tenant['id'], user['id'])['roles']
+ self.roles_client.assign_user_role(tenant['id'], user['id'],
+ role['id'])
+ roles = self.roles_client.list_user_roles(tenant['id'],
+ user['id'])['roles']
self.assert_role_in_role_list(role, roles)
diff --git a/tempest/api/identity/admin/v2/test_roles_negative.py b/tempest/api/identity/admin/v2/test_roles_negative.py
index 45c95df..a57163d 100644
--- a/tempest/api/identity/admin/v2/test_roles_negative.py
+++ b/tempest/api/identity/admin/v2/test_roles_negative.py
@@ -37,7 +37,7 @@
def test_list_roles_by_unauthorized_user(self):
# Non-administrator user should not be able to list roles
self.assertRaises(lib_exc.Forbidden,
- self.non_admin_client.list_roles)
+ self.non_admin_roles_client.list_roles)
@test.attr(type=['negative'])
@test.idempotent_id('11a3c7da-df6c-40c2-abc2-badd682edf9f')
@@ -45,14 +45,15 @@
# Request to list roles without a valid token should fail
token = self.client.auth_provider.get_token()
self.client.delete_token(token)
- self.assertRaises(lib_exc.Unauthorized, self.client.list_roles)
+ self.assertRaises(lib_exc.Unauthorized, self.roles_client.list_roles)
self.client.auth_provider.clear_auth()
@test.attr(type=['negative'])
@test.idempotent_id('c0b89e56-accc-4c73-85f8-9c0f866104c1')
def test_role_create_blank_name(self):
# Should not be able to create a role with a blank name
- self.assertRaises(lib_exc.BadRequest, self.client.create_role, '')
+ self.assertRaises(lib_exc.BadRequest, self.roles_client.create_role,
+ '')
@test.attr(type=['negative'])
@test.idempotent_id('585c8998-a8a4-4641-a5dd-abef7a8ced00')
@@ -60,7 +61,7 @@
# Non-administrator user should not be able to create role
role_name = data_utils.rand_name(name='role')
self.assertRaises(lib_exc.Forbidden,
- self.non_admin_client.create_role, role_name)
+ self.non_admin_roles_client.create_role, role_name)
@test.attr(type=['negative'])
@test.idempotent_id('a7edd17a-e34a-4aab-8bb7-fa6f498645b8')
@@ -70,7 +71,7 @@
self.client.delete_token(token)
role_name = data_utils.rand_name(name='role')
self.assertRaises(lib_exc.Unauthorized,
- self.client.create_role, role_name)
+ self.roles_client.create_role, role_name)
self.client.auth_provider.clear_auth()
@test.attr(type=['negative'])
@@ -78,10 +79,10 @@
def test_role_create_duplicate(self):
# Role names should be unique
role_name = data_utils.rand_name(name='role-dup')
- body = self.client.create_role(role_name)['role']
+ body = self.roles_client.create_role(role_name)['role']
role1_id = body.get('id')
- self.addCleanup(self.client.delete_role, role1_id)
- self.assertRaises(lib_exc.Conflict, self.client.create_role,
+ self.addCleanup(self.roles_client.delete_role, role1_id)
+ self.assertRaises(lib_exc.Conflict, self.roles_client.create_role,
role_name)
@test.attr(type=['negative'])
@@ -89,24 +90,24 @@
def test_delete_role_by_unauthorized_user(self):
# Non-administrator user should not be able to delete role
role_name = data_utils.rand_name(name='role')
- body = self.client.create_role(role_name)['role']
+ body = self.roles_client.create_role(role_name)['role']
self.data.roles.append(body)
role_id = body.get('id')
self.assertRaises(lib_exc.Forbidden,
- self.non_admin_client.delete_role, role_id)
+ self.non_admin_roles_client.delete_role, role_id)
@test.attr(type=['negative'])
@test.idempotent_id('44b60b20-70de-4dac-beaf-a3fc2650a16b')
def test_delete_role_request_without_token(self):
# Request to delete role without a valid token should fail
role_name = data_utils.rand_name(name='role')
- body = self.client.create_role(role_name)['role']
+ body = self.roles_client.create_role(role_name)['role']
self.data.roles.append(body)
role_id = body.get('id')
token = self.client.auth_provider.get_token()
self.client.delete_token(token)
self.assertRaises(lib_exc.Unauthorized,
- self.client.delete_role,
+ self.roles_client.delete_role,
role_id)
self.client.auth_provider.clear_auth()
@@ -115,7 +116,7 @@
def test_delete_role_non_existent(self):
# Attempt to delete a non existent role should fail
non_existent_role = str(uuid.uuid4().hex)
- self.assertRaises(lib_exc.NotFound, self.client.delete_role,
+ self.assertRaises(lib_exc.NotFound, self.roles_client.delete_role,
non_existent_role)
@test.attr(type=['negative'])
@@ -125,7 +126,7 @@
# assign a role to user
(user, tenant, role) = self._get_role_params()
self.assertRaises(lib_exc.Forbidden,
- self.non_admin_client.assign_user_role,
+ self.non_admin_roles_client.assign_user_role,
tenant['id'], user['id'], role['id'])
@test.attr(type=['negative'])
@@ -136,7 +137,7 @@
token = self.client.auth_provider.get_token()
self.client.delete_token(token)
self.assertRaises(lib_exc.Unauthorized,
- self.client.assign_user_role, tenant['id'],
+ self.roles_client.assign_user_role, tenant['id'],
user['id'], role['id'])
self.client.auth_provider.clear_auth()
@@ -146,7 +147,7 @@
# Attempt to assign a non existent role to user should fail
(user, tenant, role) = self._get_role_params()
non_existent_role = str(uuid.uuid4().hex)
- self.assertRaises(lib_exc.NotFound, self.client.assign_user_role,
+ self.assertRaises(lib_exc.NotFound, self.roles_client.assign_user_role,
tenant['id'], user['id'], non_existent_role)
@test.attr(type=['negative'])
@@ -155,7 +156,7 @@
# Attempt to assign a role on a non existent tenant should fail
(user, tenant, role) = self._get_role_params()
non_existent_tenant = str(uuid.uuid4().hex)
- self.assertRaises(lib_exc.NotFound, self.client.assign_user_role,
+ self.assertRaises(lib_exc.NotFound, self.roles_client.assign_user_role,
non_existent_tenant, user['id'], role['id'])
@test.attr(type=['negative'])
@@ -163,8 +164,9 @@
def test_assign_duplicate_user_role(self):
# Duplicate user role should not get assigned
(user, tenant, role) = self._get_role_params()
- self.client.assign_user_role(tenant['id'], user['id'], role['id'])
- self.assertRaises(lib_exc.Conflict, self.client.assign_user_role,
+ self.roles_client.assign_user_role(tenant['id'], user['id'],
+ role['id'])
+ self.assertRaises(lib_exc.Conflict, self.roles_client.assign_user_role,
tenant['id'], user['id'], role['id'])
@test.attr(type=['negative'])
@@ -173,11 +175,11 @@
# Non-administrator user should not be authorized to
# remove a user's role
(user, tenant, role) = self._get_role_params()
- self.client.assign_user_role(tenant['id'],
- user['id'],
- role['id'])
+ self.roles_client.assign_user_role(tenant['id'],
+ user['id'],
+ role['id'])
self.assertRaises(lib_exc.Forbidden,
- self.non_admin_client.delete_user_role,
+ self.non_admin_roles_client.delete_user_role,
tenant['id'], user['id'], role['id'])
@test.attr(type=['negative'])
@@ -185,13 +187,13 @@
def test_remove_user_role_request_without_token(self):
# Request to remove a user's role without a valid token
(user, tenant, role) = self._get_role_params()
- self.client.assign_user_role(tenant['id'],
- user['id'],
- role['id'])
+ self.roles_client.assign_user_role(tenant['id'],
+ user['id'],
+ role['id'])
token = self.client.auth_provider.get_token()
self.client.delete_token(token)
self.assertRaises(lib_exc.Unauthorized,
- self.client.delete_user_role, tenant['id'],
+ self.roles_client.delete_user_role, tenant['id'],
user['id'], role['id'])
self.client.auth_provider.clear_auth()
@@ -200,11 +202,11 @@
def test_remove_user_role_non_existent_role(self):
# Attempt to delete a non existent role from a user should fail
(user, tenant, role) = self._get_role_params()
- self.client.assign_user_role(tenant['id'],
- user['id'],
- role['id'])
+ self.roles_client.assign_user_role(tenant['id'],
+ user['id'],
+ role['id'])
non_existent_role = str(uuid.uuid4().hex)
- self.assertRaises(lib_exc.NotFound, self.client.delete_user_role,
+ self.assertRaises(lib_exc.NotFound, self.roles_client.delete_user_role,
tenant['id'], user['id'], non_existent_role)
@test.attr(type=['negative'])
@@ -212,11 +214,11 @@
def test_remove_user_role_non_existent_tenant(self):
# Attempt to remove a role from a non existent tenant should fail
(user, tenant, role) = self._get_role_params()
- self.client.assign_user_role(tenant['id'],
- user['id'],
- role['id'])
+ self.roles_client.assign_user_role(tenant['id'],
+ user['id'],
+ role['id'])
non_existent_tenant = str(uuid.uuid4().hex)
- self.assertRaises(lib_exc.NotFound, self.client.delete_user_role,
+ self.assertRaises(lib_exc.NotFound, self.roles_client.delete_user_role,
non_existent_tenant, user['id'], role['id'])
@test.attr(type=['negative'])
@@ -225,10 +227,11 @@
# Non-administrator user should not be authorized to list
# a user's roles
(user, tenant, role) = self._get_role_params()
- self.client.assign_user_role(tenant['id'], user['id'], role['id'])
+ self.roles_client.assign_user_role(tenant['id'], user['id'],
+ role['id'])
self.assertRaises(lib_exc.Forbidden,
- self.non_admin_client.list_user_roles, tenant['id'],
- user['id'])
+ self.non_admin_roles_client.list_user_roles,
+ tenant['id'], user['id'])
@test.attr(type=['negative'])
@test.idempotent_id('682adfb2-fd5f-4b0a-a9ca-322e9bebb907')
@@ -239,7 +242,7 @@
self.client.delete_token(token)
try:
self.assertRaises(lib_exc.Unauthorized,
- self.client.list_user_roles, tenant['id'],
+ self.roles_client.list_user_roles, tenant['id'],
user['id'])
finally:
self.client.auth_provider.clear_auth()
diff --git a/tempest/api/identity/admin/v2/test_tokens.py b/tempest/api/identity/admin/v2/test_tokens.py
index 0daa66d..e752b02 100644
--- a/tempest/api/identity/admin/v2/test_tokens.py
+++ b/tempest/api/identity/admin/v2/test_tokens.py
@@ -77,15 +77,15 @@
# Create a role
role_name = data_utils.rand_name(name='role')
- role = self.client.create_role(role_name)['role']
+ role = self.roles_client.create_role(role_name)['role']
self.data.roles.append(role)
# Grant the user the role on the tenants.
- self.client.assign_user_role(tenant1['id'], user['id'],
- role['id'])
+ self.roles_client.assign_user_role(tenant1['id'], user['id'],
+ role['id'])
- self.client.assign_user_role(tenant2['id'], user['id'],
- role['id'])
+ self.roles_client.assign_user_role(tenant2['id'], user['id'],
+ role['id'])
# Get an unscoped token.
body = self.token_client.auth(user_name, user_password)
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index 9cf1ce0..2e9714e 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -170,8 +170,8 @@
user_ids = list()
fetched_user_ids = list()
user_ids.append(user['id'])
- role = self.client.assign_user_role(tenant['id'], user['id'],
- role['id'])['role']
+ role = self.roles_client.assign_user_role(tenant['id'], user['id'],
+ role['id'])['role']
alt_user2 = data_utils.rand_name('second_user')
alt_password2 = data_utils.rand_password()
@@ -180,9 +180,9 @@
'user2@123')['user']
user_ids.append(second_user['id'])
self.data.users.append(second_user)
- role = self.client.assign_user_role(tenant['id'],
- second_user['id'],
- role['id'])['role']
+ role = self.roles_client.assign_user_role(tenant['id'],
+ second_user['id'],
+ role['id'])['role']
# List of users with roles for the respective tenant ID
body = (self.tenants_client.list_tenant_users(self.data.tenant['id'])
['users'])
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 8359b8f..1a4c8bb 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -56,7 +56,7 @@
@classmethod
def get_role_by_name(cls, name):
- roles = cls.client.list_roles()['roles']
+ roles = cls.roles_client.list_roles()['roles']
role = [r for r in roles if r['name'] == name]
if len(role) > 0:
return role[0]
@@ -76,6 +76,7 @@
cls.non_admin_client = cls.os.identity_public_client
cls.non_admin_token_client = cls.os.token_client
cls.non_admin_tenants_client = cls.os.tenants_public_client
+ cls.non_admin_roles_client = cls.os.roles_public_client
@classmethod
def resource_setup(cls):
@@ -98,11 +99,14 @@
cls.token_client = cls.os_adm.token_client
cls.tenants_client = cls.os_adm.tenants_client
cls.non_admin_tenants_client = cls.os.tenants_client
+ cls.roles_client = cls.os_adm.roles_client
+ cls.non_admin_roles_client = cls.os.roles_client
@classmethod
def resource_setup(cls):
super(BaseIdentityV2AdminTest, cls).resource_setup()
- cls.data = DataGenerator(cls.client, cls.tenants_client)
+ cls.data = DataGenerator(cls.client, cls.tenants_client,
+ cls.roles_client)
@classmethod
def resource_cleanup(cls):
@@ -187,10 +191,11 @@
class DataGenerator(object):
- def __init__(self, client, tenants_client=None):
+ def __init__(self, client, tenants_client=None, roles_client=None):
self.client = client
# TODO(dmellado) split Datagenerator for v2 and v3
self.tenants_client = tenants_client
+ self.roles_client = roles_client
self.users = []
self.tenants = []
self.roles = []
@@ -232,7 +237,7 @@
def setup_test_role(self):
"""Set up a test role."""
self.test_role = data_utils.rand_name('role')
- self.role = self.client.create_role(self.test_role)['role']
+ self.role = self.roles_client.create_role(self.test_role)['role']
self.roles.append(self.role)
def setup_test_v3_user(self):
@@ -294,7 +299,7 @@
for tenant in self.tenants:
self._try_wrapper(self.tenants_client.delete_tenant, tenant)
for role in self.roles:
- self._try_wrapper(self.client.delete_role, role)
+ self._try_wrapper(self.roles_client.delete_role, role)
for v3_user in self.v3_users:
self._try_wrapper(self.client.delete_user, v3_user)
for v3_project in self.projects:
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index da0ce83..c3205ce 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -70,8 +70,10 @@
container_format = kwargs.pop('container_format')
disk_format = kwargs.pop('disk_format')
- image = cls.client.create_image(name, container_format,
- disk_format, **kwargs)
+ image = cls.client.create_image(name=name,
+ container_format=container_format,
+ disk_format=disk_format,
+ **kwargs)
# Image objects returned by the v1 client have the image
# data inside a dict that is keyed against 'image'.
if 'image' in image:
@@ -156,7 +158,7 @@
def _create_image(self):
name = data_utils.rand_name('image')
- image = self.os_img_client.create_image(name,
+ image = self.os_img_client.create_image(name=name,
container_format='bare',
disk_format='raw')
image_id = image['id']
diff --git a/tempest/api/image/v2/test_images_negative.py b/tempest/api/image/v2/test_images_negative.py
index 71c8c7a..485942e 100644
--- a/tempest/api/image/v2/test_images_negative.py
+++ b/tempest/api/image/v2/test_images_negative.py
@@ -90,10 +90,12 @@
def test_register_with_invalid_container_format(self):
# Negative tests for invalid data supplied to POST /images
self.assertRaises(lib_exc.BadRequest, self.client.create_image,
- 'test', 'wrong', 'vhd')
+ name='test', container_format='wrong',
+ disk_format='vhd')
@test.attr(type=['negative'])
@test.idempotent_id('70c6040c-5a97-4111-9e13-e73665264ce1')
def test_register_with_invalid_disk_format(self):
self.assertRaises(lib_exc.BadRequest, self.client.create_image,
- 'test', 'bare', 'wrong')
+ name='test', container_format='bare',
+ disk_format='wrong')
diff --git a/tempest/api/network/admin/test_agent_management.py b/tempest/api/network/admin/test_agent_management.py
index c5d0d57..64802aa 100644
--- a/tempest/api/network/admin/test_agent_management.py
+++ b/tempest/api/network/admin/test_agent_management.py
@@ -63,7 +63,7 @@
# one to avoid the negative effect.
agent_status = {'admin_state_up': origin_status}
body = self.admin_client.update_agent(agent_id=self.agent['id'],
- agent_info=agent_status)
+ agent=agent_status)
updated_status = body['agent']['admin_state_up']
self.assertEqual(origin_status, updated_status)
@@ -73,7 +73,7 @@
description = 'description for update agent.'
agent_description = {'description': description}
body = self.admin_client.update_agent(agent_id=self.agent['id'],
- agent_info=agent_description)
+ agent=agent_description)
self.addCleanup(self._restore_agent)
updated_description = body['agent']['description']
self.assertEqual(updated_description, description)
@@ -84,4 +84,4 @@
description = self.agent['description'] or ''
origin_agent = {'description': description}
self.admin_client.update_agent(agent_id=self.agent['id'],
- agent_info=origin_agent)
+ agent=origin_agent)
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index ed191b6..406ad44 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -301,7 +301,7 @@
test_routes.sort(key=lambda x: x['destination'])
extra_route = self.client.update_extra_routes(router['id'],
- test_routes)
+ routes=test_routes)
show_body = self.client.show_router(router['id'])
# Assert the number of routes
self.assertEqual(routes_num, len(extra_route['router']['routes']))
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py
index bbd01f0..8b617ac 100644
--- a/tempest/api/telemetry/base.py
+++ b/tempest/api/telemetry/base.py
@@ -77,7 +77,7 @@
@classmethod
def create_image(cls, client):
body = client.create_image(
- data_utils.rand_name('image'), container_format='bare',
+ name=data_utils.rand_name('image'), container_format='bare',
disk_format='raw', visibility='private')
# TODO(jswarren) Move ['image'] up to initial body value assignment
# once both v1 and v2 glance clients include the full response
diff --git a/tempest/clients.py b/tempest/clients.py
index 74f8684..a837ce1 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -89,6 +89,8 @@
DatabaseVersionsClient
from tempest.services.identity.v2.json.identity_client import \
IdentityClient
+from tempest.services.identity.v2.json.roles_client import \
+ RolesClient
from tempest.services.identity.v2.json.tenants_client import \
TenantsClient
from tempest.services.identity.v3.json.credentials_client import \
@@ -437,6 +439,8 @@
**params_v2_admin)
self.tenants_client = TenantsClient(self.auth_provider,
**params_v2_admin)
+ self.roles_client = RolesClient(self.auth_provider,
+ **params_v2_admin)
params_v2_public = params.copy()
params_v2_public['endpoint_type'] = (
CONF.identity.v2_public_endpoint_type)
@@ -445,6 +449,8 @@
**params_v2_public)
self.tenants_public_client = TenantsClient(self.auth_provider,
**params_v2_public)
+ self.roles_public_client = RolesClient(self.auth_provider,
+ **params_v2_public)
params_v3 = params.copy()
params_v3['endpoint_type'] = CONF.identity.v3_endpoint_type
# Clients below use the endpoint type of Keystone API v3
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 2a8fcd3..b90ee04 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -93,6 +93,7 @@
from tempest import config
from tempest import exceptions as exc
from tempest.services.identity.v2.json import identity_client
+from tempest.services.identity.v2.json import roles_client
from tempest.services.identity.v2.json import tenants_client
from tempest.services.network.json import network_client
from tempest.services.network.json import networks_client
@@ -146,6 +147,13 @@
endpoint_type='adminURL',
**params
)
+ roles_admin = roles_client.RolesClient(
+ _auth,
+ CONF.identity.catalog_type,
+ CONF.identity.region,
+ endpoint_type='adminURL',
+ **params
+ )
network_admin = None
networks_admin = None
subnets_admin = None
@@ -171,14 +179,14 @@
CONF.network.region or CONF.identity.region,
endpoint_type='adminURL',
**params)
- return (identity_admin, tenants_admin, neutron_iso_networks, network_admin,
- networks_admin, subnets_admin)
+ return (identity_admin, tenants_admin, roles_admin, neutron_iso_networks,
+ network_admin, networks_admin, subnets_admin)
def create_resources(opts, resources):
- (identity_admin, tenants_admin, neutron_iso_networks,
+ (identity_admin, tenants_admin, roles_admin, neutron_iso_networks,
network_admin, networks_admin, subnets_admin) = get_admin_clients(opts)
- roles = identity_admin.list_roles()['roles']
+ roles = roles_admin.list_roles()['roles']
for u in resources['users']:
u['role_ids'] = []
for r in u.get('roles', ()):
@@ -240,7 +248,7 @@
continue
for r in u['role_ids']:
try:
- identity_admin.assign_user_role(tenant['id'], user['id'], r)
+ roles_admin.assign_user_role(tenant['id'], user['id'], r)
except tempest_lib.exceptions.Conflict:
# don't care if it's already assigned
pass
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index 1c8ddcb..3c32d48 100644
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -177,6 +177,7 @@
def _init_admin_ids(self):
id_cl = self.admin_mgr.identity_client
+ rl_cl = self.admin_mgr.roles_client
tenant = identity.get_tenant_by_name(id_cl,
CONF.auth.admin_tenant_name)
@@ -186,7 +187,7 @@
CONF.auth.admin_username)
self.admin_id = user['id']
- roles = id_cl.list_roles()['roles']
+ roles = rl_cl.list_roles()['roles']
for role in roles:
if role['name'] == CONF.identity.admin_role:
self.admin_role_id = role['id']
@@ -221,8 +222,9 @@
def _add_admin(self, tenant_id):
id_cl = self.admin_mgr.identity_client
+ rl_cl = self.admin_mgr.roles_client
needs_role = True
- roles = id_cl.list_user_roles(tenant_id, self.admin_id)['roles']
+ roles = rl_cl.list_user_roles(tenant_id, self.admin_id)['roles']
for role in roles:
if role['id'] == self.admin_role_id:
needs_role = False
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index b5b78c6..032b8b4 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -857,10 +857,13 @@
class RoleService(IdentityService):
+ def __init__(self, manager, **kwargs):
+ super(RoleService, self).__init__(kwargs)
+ self.client = manager.roles_client
+
def list(self):
- client = self.client
try:
- roles = client.list_roles()['roles']
+ roles = self.client.list_roles()['roles']
# reconcile roles with saved state and never list admin role
if not self.is_save_state:
roles = [role for role in roles if
@@ -874,11 +877,10 @@
return []
def delete(self):
- client = self.client
roles = self.list()
for role in roles:
try:
- client.delete_role(role['id'])
+ self.client.delete_role(role['id'])
except Exception:
LOG.exception("Delete Role exception.")
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 826d8e8..cdd0044 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -128,6 +128,7 @@
from tempest.services.compute.json import security_group_rules_client
from tempest.services.compute.json import servers_client
from tempest.services.identity.v2.json import identity_client
+from tempest.services.identity.v2.json import roles_client
from tempest.services.identity.v2.json import tenants_client
from tempest.services.image.v2.json import images_client
from tempest.services.network.json import network_client
@@ -206,6 +207,12 @@
CONF.identity.region,
endpoint_type='adminURL',
**default_params_with_timeout_values)
+ self.roles = roles_client.RolesClient(
+ _auth,
+ CONF.identity.catalog_type,
+ CONF.identity.region,
+ endpoint_type='adminURL',
+ **default_params_with_timeout_values)
self.servers = servers_client.ServersClient(_auth,
**compute_params)
self.flavors = flavors_client.FlavorsClient(_auth,
@@ -339,11 +346,11 @@
def _assign_swift_role(user, swift_role):
admin = keystone_admin()
- roles = admin.identity.list_roles()
+ roles = admin.roles.list_roles()
role = next(r for r in roles if r['name'] == swift_role)
LOG.debug(USERS[user])
try:
- admin.identity.assign_user_role(
+ admin.roles.assign_user_role(
USERS[user]['tenant_id'],
USERS[user]['id'],
role['id'])
@@ -492,24 +499,26 @@
for network_name, body in found['addresses'].items():
for addr in body:
ip = addr['addr']
- # If floatingip_for_ssh is at True, it's assumed
- # you want to use the floating IP to reach the server,
- # fallback to fixed IP, then other type.
+ # Use floating IP, fixed IP or other type to
+ # reach the server.
# This is useful in multi-node environment.
- if CONF.compute.use_floatingip_for_ssh:
+ if CONF.validation.connect_method == 'floating':
if addr.get('OS-EXT-IPS:type',
'floating') == 'floating':
self._ping_ip(ip, 60)
_floating_is_alive = True
- elif addr.get('OS-EXT-IPS:type', 'fixed') == 'fixed':
- namespace = _get_router_namespace(client,
- network_name)
- self._ping_ip(ip, 60, namespace)
+ elif CONF.validation.connect_method == 'fixed':
+ if addr.get('OS-EXT-IPS:type',
+ 'fixed') == 'fixed':
+ namespace = _get_router_namespace(client,
+ network_name)
+ self._ping_ip(ip, 60, namespace)
else:
self._ping_ip(ip, 60)
- # if floatingip_for_ssh is at True, validate found a
- # floating IP and ping worked.
- if CONF.compute.use_floatingip_for_ssh:
+ # If CONF.validation.connect_method is floating, validate
+ # that the floating IP is attached to the server and the
+ # the server is pingable.
+ if CONF.validation.connect_method == 'floating':
self.assertTrue(_floating_is_alive,
"Server %s has no floating IP." %
server['name'])
@@ -903,7 +912,7 @@
# create security group(s) after server spawning
for secgroup in server['secgroups']:
client.servers.add_security_group(server_id, name=secgroup)
- if CONF.compute.use_floatingip_for_ssh:
+ if CONF.validation.connect_method == 'floating':
floating_ip_pool = server.get('floating_ip_pool')
floating_ip = client.floating_ips.create_floating_ip(
pool_name=floating_ip_pool)['floating_ip']
diff --git a/tempest/common/cred_client.py b/tempest/common/cred_client.py
index 94515dc..a33732e 100644
--- a/tempest/common/cred_client.py
+++ b/tempest/common/cred_client.py
@@ -31,12 +31,14 @@
admin credentials used for generating credentials.
"""
- def __init__(self, identity_client, projects_client=None):
+ def __init__(self, identity_client, projects_client=None,
+ roles_client=None):
# The client implies version and credentials
self.identity_client = identity_client
# this is temporary until the v3 project client is
# separated, then projects_client will become mandatory
self.projects_client = projects_client or identity_client
+ self.roles_client = roles_client or identity_client
def create_user(self, username, password, project, email):
user = self.identity_client.create_user(
@@ -59,7 +61,7 @@
def create_user_role(self, role_name):
if not self._check_role_exists(role_name):
- self.identity_client.create_role(role_name)
+ self.roles_client.create_role(role_name)
def assign_user_role(self, user, project, role_name):
role = self._check_role_exists(role_name)
@@ -67,8 +69,8 @@
msg = 'No "%s" role found' % role_name
raise lib_exc.NotFound(msg)
try:
- self.identity_client.assign_user_role(project['id'], user['id'],
- role['id'])
+ self.roles_client.assign_user_role(project['id'], user['id'],
+ role['id'])
except lib_exc.Conflict:
LOG.debug("Role %s already assigned on project %s for user %s" % (
role['id'], project['id'], user['id']))
@@ -88,14 +90,16 @@
self.identity_client.delete_user(user_id)
def _list_roles(self):
- roles = self.identity_client.list_roles()['roles']
+ roles = self.roles_client.list_roles()['roles']
return roles
class V2CredsClient(CredsClient):
- def __init__(self, identity_client, projects_client):
- super(V2CredsClient, self).__init__(identity_client, projects_client)
+ def __init__(self, identity_client, projects_client, roles_client):
+ super(V2CredsClient, self).__init__(identity_client,
+ projects_client,
+ roles_client)
def create_project(self, name, description):
tenant = self.projects_client.create_tenant(
@@ -160,8 +164,9 @@
def get_creds_client(identity_client,
projects_client=None,
+ roles_client=None,
project_domain_name=None):
if isinstance(identity_client, v2_identity.IdentityClient):
- return V2CredsClient(identity_client, projects_client)
+ return V2CredsClient(identity_client, projects_client, roles_client)
else:
return V3CredsClient(identity_client, project_domain_name)
diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py
index 95dcafc..5d290d4 100644
--- a/tempest/common/credentials_factory.py
+++ b/tempest/common/credentials_factory.py
@@ -11,8 +11,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import os
-
from oslo_concurrency import lockutils
from oslo_log import log as logging
from tempest_lib import auth
@@ -170,8 +168,7 @@
admin_creds=admin_creds,
**_get_dynamic_provider_params())
else:
- if (CONF.auth.test_accounts_file and
- os.path.isfile(CONF.auth.test_accounts_file)):
+ if CONF.auth.test_accounts_file:
# Most params are not relevant for pre-created accounts
return preprov_creds.PreProvisionedCredentialProvider(
name=name, identity_version=identity_version,
@@ -193,8 +190,7 @@
if CONF.auth.use_dynamic_credentials:
return is_admin
# Check whether test accounts file has the admin specified or not
- elif (CONF.auth.test_accounts_file and
- os.path.isfile(CONF.auth.test_accounts_file)):
+ elif CONF.auth.test_accounts_file:
check_accounts = preprov_creds.PreProvisionedCredentialProvider(
identity_version=identity_version, name='check_admin',
**_get_preprov_provider_params())
@@ -219,8 +215,7 @@
if CONF.auth.use_dynamic_credentials:
return True
# Check whether test accounts file has the admin specified or not
- if (CONF.auth.test_accounts_file and
- os.path.isfile(CONF.auth.test_accounts_file)):
+ if CONF.auth.test_accounts_file:
check_accounts = preprov_creds.PreProvisionedCredentialProvider(
identity_version=identity_version, name='check_alt',
**_get_preprov_provider_params())
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index 813d94f..c52aa41 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -58,6 +58,7 @@
self.ports = []
self.default_admin_creds = admin_creds
(self.identity_admin_client, self.tenants_admin_client,
+ self.roles_admin_client,
self.network_admin_client,
self.networks_admin_client,
self.subnets_admin_client,
@@ -72,6 +73,7 @@
self.creds_client = cred_client.get_creds_client(
self.identity_admin_client,
self.tenants_admin_client,
+ self.roles_admin_client,
self.creds_domain_name)
def _get_admin_clients(self):
@@ -83,10 +85,11 @@
"""
os = clients.Manager(self.default_admin_creds)
if self.identity_version == 'v2':
- return (os.identity_client, os.tenants_client, os.network_client,
- os.networks_client, os.subnets_client, os.ports_client)
+ return (os.identity_client, os.tenants_client, os.roles_client,
+ os.network_client, os.networks_client, os.subnets_client,
+ os.ports_client)
else:
- return (os.identity_v3_client, None, os.network_client,
+ return (os.identity_v3_client, None, None, os.network_client,
os.networks_client, os.subnets_client, os.ports_client)
def _create_creds(self, suffix="", admin=False, roles=None):
diff --git a/tempest/common/preprov_creds.py b/tempest/common/preprov_creds.py
index 74cc3f0..34af31e 100644
--- a/tempest/common/preprov_creds.py
+++ b/tempest/common/preprov_creds.py
@@ -31,8 +31,13 @@
def read_accounts_yaml(path):
- with open(path, 'r') as yaml_file:
- accounts = yaml.load(yaml_file)
+ try:
+ with open(path, 'r') as yaml_file:
+ accounts = yaml.load(yaml_file)
+ except IOError:
+ raise exceptions.InvalidConfiguration(
+ 'The path for the test accounts file: %s '
+ 'could not be found' % path)
return accounts
@@ -74,7 +79,7 @@
identity_version=identity_version, name=name,
admin_role=admin_role, credentials_domain=credentials_domain)
self.test_accounts_file = test_accounts_file
- if test_accounts_file and os.path.isfile(test_accounts_file):
+ if test_accounts_file:
accounts = read_accounts_yaml(self.test_accounts_file)
self.use_default_creds = False
else:
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 025b79f..b76c356 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -31,7 +31,7 @@
# NOTE(afazekas): It should always get an address instead of server
def __init__(self, server, username, password=None, pkey=None):
ssh_timeout = CONF.validation.ssh_timeout
- network = CONF.compute.network_for_ssh
+ network = CONF.validation.network_for_ssh
ip_version = CONF.validation.ip_version_for_ssh
connect_timeout = CONF.validation.connect_timeout
if isinstance(server, six.string_types):
@@ -51,7 +51,7 @@
def exec_command(self, cmd):
# Shell options below add more clearness on failures,
# path is extended for some non-cirros guest oses (centos7)
- cmd = CONF.compute.ssh_shell_prologue + " " + cmd
+ cmd = CONF.validation.ssh_shell_prologue + " " + cmd
LOG.debug("Remote command: %s" % cmd)
return self.ssh_client.exec_command(cmd)
@@ -73,7 +73,7 @@
return output.split()[1]
def get_number_of_vcpus(self):
- output = self.exec_command('grep -c processor /proc/cpuinfo')
+ output = self.exec_command('grep -c ^processor /proc/cpuinfo')
return int(output)
def get_partitions(self):
@@ -94,8 +94,8 @@
cmd = 'sudo sh -c "echo \\"%s\\" >/dev/console"' % message
return self.exec_command(cmd)
- def ping_host(self, host, count=CONF.compute.ping_count,
- size=CONF.compute.ping_size, nic=None):
+ def ping_host(self, host, count=CONF.validation.ping_count,
+ size=CONF.validation.ping_size, nic=None):
addr = netaddr.IPAddress(host)
cmd = 'ping6' if addr.version == 6 else 'ping'
if nic:
diff --git a/tempest/config.py b/tempest/config.py
index a6212fb..a4ae966 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -17,9 +17,10 @@
import logging as std_logging
import os
+import tempfile
+from oslo_concurrency import lockutils
from oslo_config import cfg
-
from oslo_log import log as logging
from tempest.test_discover import plugins
@@ -231,12 +232,6 @@
cfg.StrOpt('flavor_ref_alt',
default="2",
help='Valid secondary flavor to be used in tests.'),
- cfg.StrOpt('image_ssh_user',
- default="root",
- help="User name used to authenticate to an instance."),
- cfg.StrOpt('image_ssh_password',
- default="password",
- help="Password used to authenticate to an instance."),
cfg.IntOpt('build_interval',
default=1,
help="Time in seconds between build status checks."),
@@ -245,41 +240,6 @@
help="Timeout in seconds to wait for an instance to build. "
"Other services that do not define build_timeout will "
"inherit this value."),
- cfg.StrOpt('ssh_shell_prologue',
- default="set -eu -o pipefail; PATH=$$PATH:/sbin;",
- help="Shell fragments to use before executing a command "
- "when sshing to a guest."),
- cfg.StrOpt('ssh_auth_method',
- default='keypair',
- choices=('keypair', 'configured', 'adminpass', 'disabled'),
- help="Auth method used for authenticate to the instance. "
- "Valid choices are: keypair, configured, adminpass "
- "and disabled. "
- "Keypair: start the servers with a ssh keypair. "
- "Configured: use the configured user and password. "
- "Adminpass: use the injected adminPass. "
- "Disabled: avoid using ssh when it is an option."),
- cfg.StrOpt('ssh_connect_method',
- default='floating',
- choices=('fixed', 'floating'),
- help="How to connect to the instance? "
- "fixed: using the first ip belongs the fixed network "
- "floating: creating and using a floating ip."),
- cfg.StrOpt('ssh_user',
- default='root',
- help="User name used to authenticate to an instance."),
- cfg.IntOpt('ping_timeout',
- default=120,
- help="Timeout in seconds to wait for ping to "
- "succeed."),
- cfg.IntOpt('ping_size',
- default=56,
- help="The packet size for ping packets originating "
- "from remote linux hosts"),
- cfg.IntOpt('ping_count',
- default=1,
- help="The number of ping packets originating from remote "
- "linux hosts"),
cfg.IntOpt('ready_wait',
default=0,
help="Additional wait time for clean state, when there is "
@@ -291,13 +251,6 @@
"servers if tempest does not create a network or a "
"network is not specified elsewhere. It may be used for "
"ssh validation only if floating IPs are disabled."),
- cfg.StrOpt('network_for_ssh',
- default='public',
- help="Network used for SSH connections. Ignored if "
- "use_floatingip_for_ssh=true or run_validation=false."),
- cfg.BoolOpt('use_floatingip_for_ssh',
- default=True,
- help="Does SSH use Floating IPs?"),
cfg.StrOpt('catalog_type',
default='compute',
help="Catalog type of the Compute service."),
@@ -323,12 +276,6 @@
'when shelved. This time should be the same as the time '
'of nova.conf, and some tests will run for as long as the '
'time.'),
- cfg.StrOpt('floating_ip_range',
- default='10.0.0.0/29',
- help='Unallocated floating IP range, which will be used to '
- 'test the floating IP bulk feature for CRUD operation. '
- 'This block must not overlap an existing floating IP '
- 'pool.'),
cfg.IntOpt('min_compute_nodes',
default=1,
help=('The minimum number of compute nodes expected. This will '
@@ -672,9 +619,7 @@
cfg.BoolOpt('run_validation',
default=False,
help='Enable ssh on created servers and creation of additional'
- ' validation resources to enable remote access',
- deprecated_opts=[cfg.DeprecatedOpt('run_ssh',
- group='compute')]),
+ ' validation resources to enable remote access'),
cfg.BoolOpt('security_group',
default=True,
help='Enable/disable security groups.'),
@@ -686,31 +631,77 @@
choices=['fixed', 'floating'],
help='Default IP type used for validation: '
'-fixed: uses the first IP belonging to the fixed network '
- '-floating: creates and uses a floating IP'),
+ '-floating: creates and uses a floating IP',
+ deprecated_opts=[cfg.DeprecatedOpt('use_floatingip_for_ssh',
+ group='compute')]),
cfg.StrOpt('auth_method',
default='keypair',
choices=['keypair'],
help='Default authentication method to the instance. '
'Only ssh via keypair is supported for now. '
- 'Additional methods will be handled in a separate spec.'),
+ 'Additional methods will be handled in a separate spec.',
+ deprecated_opts=[cfg.DeprecatedOpt('ssh_auth_method',
+ group='compute')]),
cfg.IntOpt('ip_version_for_ssh',
default=4,
- help='Default IP version for ssh connections.',
- deprecated_opts=[cfg.DeprecatedOpt('ip_version_for_ssh',
- group='compute')]),
+ help='Default IP version for ssh connections.'),
cfg.IntOpt('ping_timeout',
default=120,
- help='Timeout in seconds to wait for ping to succeed.'),
+ help='Timeout in seconds to wait for ping to succeed.',
+ deprecated_opts=[cfg.DeprecatedOpt('ping_timeout',
+ group='compute')]),
cfg.IntOpt('connect_timeout',
default=60,
help='Timeout in seconds to wait for the TCP connection to be '
- 'successful.',
- deprecated_opts=[cfg.DeprecatedOpt('ssh_channel_timeout',
- group='compute')]),
+ 'successful.'),
cfg.IntOpt('ssh_timeout',
default=300,
- help='Timeout in seconds to wait for the ssh banner.',
- deprecated_opts=[cfg.DeprecatedOpt('ssh_timeout',
+ help='Timeout in seconds to wait for the ssh banner.'),
+ cfg.StrOpt('image_ssh_user',
+ default="root",
+ help="User name used to authenticate to an instance.",
+ deprecated_opts=[cfg.DeprecatedOpt('image_ssh_user',
+ group='compute'),
+ cfg.DeprecatedOpt('ssh_user',
+ group='compute'),
+ cfg.DeprecatedOpt('ssh_user',
+ group='scenario')]),
+ cfg.StrOpt('image_ssh_password',
+ default="password",
+ help="Password used to authenticate to an instance.",
+ deprecated_opts=[cfg.DeprecatedOpt('image_ssh_password',
+ group='compute')]),
+ cfg.StrOpt('ssh_shell_prologue',
+ default="set -eu -o pipefail; PATH=$$PATH:/sbin;",
+ help="Shell fragments to use before executing a command "
+ "when sshing to a guest.",
+ deprecated_opts=[cfg.DeprecatedOpt('ssh_shell_prologue',
+ group='compute')]),
+ cfg.IntOpt('ping_size',
+ default=56,
+ help="The packet size for ping packets originating "
+ "from remote linux hosts",
+ deprecated_opts=[cfg.DeprecatedOpt('ping_size',
+ group='compute')]),
+ cfg.IntOpt('ping_count',
+ default=1,
+ help="The number of ping packets originating from remote "
+ "linux hosts",
+ deprecated_opts=[cfg.DeprecatedOpt('ping_count',
+ group='compute')]),
+ cfg.StrOpt('floating_ip_range',
+ default='10.0.0.0/29',
+ help='Unallocated floating IP range, which will be used to '
+ 'test the floating IP bulk feature for CRUD operation. '
+ 'This block must not overlap an existing floating IP '
+ 'pool.',
+ deprecated_opts=[cfg.DeprecatedOpt('floating_ip_range',
+ group='compute')]),
+ cfg.StrOpt('network_for_ssh',
+ default='public',
+ help="Network used for SSH connections. Ignored if "
+ "use_floatingip_for_ssh=true or run_validation=false.",
+ deprecated_opts=[cfg.DeprecatedOpt('network_for_ssh',
group='compute')]),
]
@@ -1126,9 +1117,6 @@
cfg.StrOpt('aki_img_file',
default='cirros-0.3.1-x86_64-vmlinuz',
help='AKI image file name'),
- cfg.StrOpt('ssh_user',
- default='cirros',
- help='ssh username for the image file'),
cfg.IntOpt(
'large_ops_number',
default=0,
@@ -1406,6 +1394,7 @@
_CONF.set_default('alt_domain_name',
self.auth.default_credentials_domain_name,
group='identity')
+ logging.tempest_set_log_file('tempest.log')
def __init__(self, parse_conf=True, config_path=None):
"""Initialize a configuration from a conf directory and conf file."""
@@ -1462,6 +1451,8 @@
def __getattr__(self, attr):
if not self._config:
self._fix_log_levels()
+ lock_dir = os.path.join(tempfile.gettempdir(), 'tempest-lock')
+ lockutils.set_defaults(lock_dir)
self._config = TempestConfigPrivate(config_path=self._path)
return getattr(self._config, attr)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 3e6a947..c2159c3 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -359,7 +359,7 @@
if isinstance(server_or_ip, six.string_types):
ip = server_or_ip
else:
- addrs = server_or_ip['addresses'][CONF.compute.network_for_ssh]
+ addrs = server_or_ip['addresses'][CONF.validation.network_for_ssh]
try:
ip = (addr['addr'] for addr in addrs if
netaddr.valid_ipv4(addr['addr'])).next()
@@ -368,7 +368,7 @@
"remote server.")
if username is None:
- username = CONF.scenario.ssh_user
+ username = CONF.validation.image_ssh_user
# Set this with 'keypair' or others to log in with keypair or
# username/password.
if CONF.validation.auth_method == 'keypair':
@@ -376,7 +376,7 @@
if private_key is None:
private_key = self.keypair['private_key']
else:
- password = CONF.compute.image_ssh_password
+ password = CONF.validation.image_ssh_password
private_key = None
linux_client = remote_client.RemoteClient(ip, username,
pkey=private_key,
@@ -812,8 +812,9 @@
def _get_server_port_id_and_ip4(self, server, ip_addr=None):
ports = self._list_ports(device_id=server['id'], status='ACTIVE',
fixed_ip=ip_addr)
- # it might happen here that this port has more then one ip address
- # as in case of dual stack- when this port is created on 2 subnets
+ # A port can have more then one IP address in some cases.
+ # If the network is dual-stack (IPv4 + IPv6), this port is associated
+ # with 2 subnets
port_map = [(p["id"], fxip["ip_address"])
for p in ports
for fxip in p["fixed_ips"]
@@ -1095,7 +1096,7 @@
return rules
def _ssh_to_server(self, server, private_key):
- ssh_login = CONF.compute.image_ssh_user
+ ssh_login = CONF.validation.image_ssh_user
return self.get_remote_client(server,
username=ssh_login,
private_key=private_key)
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 8aac98e..d6dd6f3 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -74,7 +74,7 @@
def _check_network_connectivity(self, server, keypair, floating_ip,
should_connect=True):
- username = CONF.compute.image_ssh_user
+ username = CONF.validation.image_ssh_user
private_key = keypair['private_key']
self._check_tenant_network_connectivity(
server, username, private_key,
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 20ccc59..44942b0 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -172,7 +172,7 @@
return self.keypairs[server['key_name']]['private_key']
def _check_tenant_network_connectivity(self):
- ssh_login = CONF.compute.image_ssh_user
+ ssh_login = CONF.validation.image_ssh_user
for server in self.servers:
# call the common method in the parent class
super(TestNetworkBasicOps, self).\
@@ -195,7 +195,7 @@
:param should_check_floating_ip_status: bool. should status of
floating_ip be checked or not
"""
- ssh_login = CONF.compute.image_ssh_user
+ ssh_login = CONF.validation.image_ssh_user
floating_ip, server = self.floating_ip_tuple
ip_address = floating_ip.floating_ip_address
private_key = None
@@ -744,20 +744,28 @@
def test_port_security_macspoofing_port(self):
"""Tests port_security extension enforces mac spoofing
- 1. create a new network
- 2. connect VM to new network
- 4. check VM can ping new network DHCP port
- 5. spoof mac on new new network interface
- 6. check Neutron enforces mac spoofing and blocks pings via spoofed
- interface
- 7. disable port-security on the spoofed port
- 8. check Neutron allows pings via spoofed interface
+ Neutron security groups always apply anti-spoof rules on the VMs. This
+ allows traffic to originate and terminate at the VM as expected, but
+ prevents traffic to pass through the VM. Anti-spoof rules are not
+ required in cases where the VM routes traffic through it.
+
+ The test steps are :
+ 1. Create a new network.
+ 2. Connect (hotplug) the VM to a new network.
+ 3. Check the VM can ping the DHCP interface of this network.
+ 4. Spoof the mac address of the new VM interface.
+ 5. Check the Security Group enforces mac spoofing and blocks pings via
+ spoofed interface (VM cannot ping the DHCP interface).
+ 6. Disable port-security of the spoofed port- set the flag to false.
+ 7. Retest 3rd step and check that the Security Group allows pings via
+ the spoofed interface.
"""
+
spoof_mac = "00:00:00:00:00:01"
# Create server
self._setup_network_and_servers()
- self.check_public_network_connectivity(should_connect=False)
+ self.check_public_network_connectivity(should_connect=True)
self._create_new_network()
self._hotplug_server()
fip, server = self.floating_ip_tuple
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index d6ad46a..40c7680 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -114,7 +114,7 @@
return ips
def prepare_server(self, networks=None):
- username = CONF.compute.image_ssh_user
+ username = CONF.validation.image_ssh_user
networks = networks or [self.network]
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index e266dc2..4e5a1e0 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -512,7 +512,7 @@
tenant = self.primary_tenant
ip = self._get_server_ip(tenant.access_point,
floating=self.floating_ip_access)
- ssh_login = CONF.compute.image_ssh_user
+ ssh_login = CONF.validation.image_ssh_user
private_key = tenant.keypair['private_key']
self.check_vm_connectivity(ip,
should_connect=False)
diff --git a/tempest/services/identity/v2/json/identity_client.py b/tempest/services/identity/v2/json/identity_client.py
index f80e22d..54596be 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -26,60 +26,6 @@
body = json.loads(body)
return service_client.ResponseBody(resp, body)
- def create_role(self, name):
- """Create a role."""
- post_body = {
- 'name': name,
- }
- post_body = json.dumps({'role': post_body})
- resp, body = self.post('OS-KSADM/roles', post_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def show_role(self, role_id):
- """Get a role by its id."""
- resp, body = self.get('OS-KSADM/roles/%s' % role_id)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def delete_role(self, role_id):
- """Delete a role."""
- resp, body = self.delete('OS-KSADM/roles/%s' % str(role_id))
- self.expected_success(204, resp.status)
- return resp, body
-
- def list_user_roles(self, tenant_id, user_id):
- """Returns a list of roles assigned to a user for a tenant."""
- url = '/tenants/%s/users/%s/roles' % (tenant_id, user_id)
- resp, body = self.get(url)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def assign_user_role(self, tenant_id, user_id, role_id):
- """Add roles to a user on a tenant."""
- resp, body = self.put('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
- (tenant_id, user_id, role_id), "")
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
- def delete_user_role(self, tenant_id, user_id, role_id):
- """Removes a role assignment for a user on a tenant."""
- resp, body = self.delete('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
- (tenant_id, user_id, role_id))
- self.expected_success(204, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def list_roles(self):
- """Returns roles."""
- resp, body = self.get('OS-KSADM/roles')
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBody(resp, body)
-
def create_user(self, name, password, tenant_id, email, **kwargs):
"""Create a user."""
post_body = {
diff --git a/tempest/services/identity/v2/json/roles_client.py b/tempest/services/identity/v2/json/roles_client.py
new file mode 100644
index 0000000..de8f9cb
--- /dev/null
+++ b/tempest/services/identity/v2/json/roles_client.py
@@ -0,0 +1,73 @@
+# 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.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.common import service_client
+
+
+class RolesClient(service_client.ServiceClient):
+ api_version = "v2.0"
+
+ def create_role(self, name):
+ """Create a role."""
+ post_body = {
+ 'name': name,
+ }
+ post_body = json.dumps({'role': post_body})
+ resp, body = self.post('OS-KSADM/roles', post_body)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def show_role(self, role_id):
+ """Get a role by its id."""
+ resp, body = self.get('OS-KSADM/roles/%s' % role_id)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def delete_role(self, role_id):
+ """Delete a role."""
+ resp, body = self.delete('OS-KSADM/roles/%s' % str(role_id))
+ self.expected_success(204, resp.status)
+ return resp, body
+
+ def list_user_roles(self, tenant_id, user_id):
+ """Returns a list of roles assigned to a user for a tenant."""
+ url = '/tenants/%s/users/%s/roles' % (tenant_id, user_id)
+ resp, body = self.get(url)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def assign_user_role(self, tenant_id, user_id, role_id):
+ """Add roles to a user on a tenant."""
+ resp, body = self.put('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
+ (tenant_id, user_id, role_id), "")
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def delete_user_role(self, tenant_id, user_id, role_id):
+ """Removes a role assignment for a user on a tenant."""
+ resp, body = self.delete('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
+ (tenant_id, user_id, role_id))
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp, body)
+
+ def list_roles(self):
+ """Returns roles."""
+ resp, body = self.get('OS-KSADM/roles')
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/image/v2/json/images_client.py b/tempest/services/image/v2/json/images_client.py
index 44062ea..72b203a 100644
--- a/tempest/services/image/v2/json/images_client.py
+++ b/tempest/services/image/v2/json/images_client.py
@@ -55,6 +55,11 @@
return self._http
def update_image(self, image_id, patch):
+ """Update an image.
+
+ Available params: see http://developer.openstack.org/
+ api-ref-image-v2.html#updateImage-v2
+ """
data = json.dumps(patch)
headers = {"Content-Type": "application/openstack-images-v2.0"
"-json-patch"}
@@ -63,21 +68,13 @@
body = json.loads(body)
return service_client.ResponseBody(resp, body)
- def create_image(self, name, container_format, disk_format, **kwargs):
- params = {
- "name": name,
- "container_format": container_format,
- "disk_format": disk_format,
- }
+ def create_image(self, **kwargs):
+ """Create an image.
- for option in kwargs:
- value = kwargs.get(option)
- if isinstance(value, dict) or isinstance(value, tuple):
- params.update(value)
- else:
- params[option] = value
-
- data = json.dumps(params)
+ Available params: see http://developer.openstack.org/
+ api-ref-image-v2.html#createImage-v2
+ """
+ data = json.dumps(kwargs)
resp, body = self.post('v2/images', data)
self.expected_success(201, resp.status)
body = json.loads(body)
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 459891f..6e3b0fe 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -240,15 +240,18 @@
uri = '/ports?device_id=%s' % uuid
return self.list_resources(uri)
- def update_agent(self, agent_id, agent_info):
+ def update_agent(self, agent_id, **kwargs):
"""Update agent
:param agent_info: Agent update information.
E.g {"admin_state_up": True}
"""
+ # TODO(piyush): Current api-site doesn't contain this API description.
+ # After fixing the api-site, we need to fix here also for putting the
+ # link to api-site.
+ # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1526673
uri = '/agents/%s' % agent_id
- agent = {"agent": agent_info}
- return self.update_resource(uri, agent)
+ return self.update_resource(uri, kwargs)
def show_agent(self, agent_id, **fields):
uri = '/agents/%s' % agent_id
@@ -270,6 +273,7 @@
# TODO(piyush): Current api-site doesn't contain this API description.
# After fixing the api-site, we need to fix here also for putting the
# link to api-site.
+ # LP: https://bugs.launchpad.net/openstack-api-site/+bug/1526670
uri = '/agents/%s/l3-routers' % agent_id
return self.create_resource(uri, kwargs)
@@ -290,13 +294,14 @@
network_id)
return self.delete_resource(uri)
- def update_extra_routes(self, router_id, routes):
+ def update_extra_routes(self, router_id, **kwargs):
+ """Update Extra routes.
+
+ Available params: see http://developer.openstack.org/
+ api-ref-networking-v2-ext.html#updateExtraRoutes
+ """
uri = '/routers/%s' % router_id
- put_body = {
- 'router': {
- 'routes': routes
- }
- }
+ put_body = {'router': kwargs}
return self.update_resource(uri, put_body)
def delete_extra_routes(self, router_id):
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index 2a23291..8bbbfc4 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -161,7 +161,7 @@
self._create_sec_group()
self._create_keypair()
private_key = self.key['private_key']
- username = CONF.compute.image_ssh_user
+ username = CONF.validation.image_ssh_user
self.remote_client = remote_client.RemoteClient(self.floating['ip'],
username,
pkey=private_key)
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index cac848b..a550d71 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -147,11 +147,13 @@
if CONF.identity.auth_version == 'v2':
identity_client = admin_manager.identity_client
projects_client = admin_manager.tenants_client
+ roles_client = admin_manager.roles_client
else:
identity_client = admin_manager.identity_v3_client
projects_client = None
+ roles_client = None
credentials_client = cred_client.get_creds_client(
- identity_client, projects_client)
+ identity_client, projects_client, roles_client)
project = credentials_client.create_project(
name=tenant_name, description=tenant_name)
user = credentials_client.create_user(username, password,
diff --git a/tempest/test.py b/tempest/test.py
index 8e961f4..407df3b 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -437,9 +437,11 @@
if CONF.identity.auth_version == 'v2':
client = self.os_admin.identity_client
project_client = self.os_admin.tenants_client
+ roles_client = self.os_admin.roles_client
else:
client = self.os_admin.identity_v3_client
project_client = None
+ roles_client = None
try:
domain = client.auth_provider.credentials.project_domain_name
@@ -447,6 +449,7 @@
domain = 'Default'
return cred_client.get_creds_client(client, project_client,
+ roles_client,
project_domain_name=domain)
@classmethod
diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py
index 10acd14..d520985 100644
--- a/tempest/tests/common/test_dynamic_creds.py
+++ b/tempest/tests/common/test_dynamic_creds.py
@@ -24,6 +24,8 @@
from tempest import exceptions
from tempest.services.identity.v2.json import identity_client as \
json_iden_client
+from tempest.services.identity.v2.json import roles_client as \
+ json_roles_client
from tempest.services.identity.v2.json import tenants_client as \
json_tenants_client
from tempest.services.network.json import network_client as json_network_client
@@ -84,7 +86,7 @@
def _mock_list_roles(self, id, name):
roles_fix = self.useFixture(mockpatch.PatchObject(
- json_iden_client.IdentityClient,
+ json_roles_client.RolesClient,
'list_roles',
return_value=(service_client.ResponseBody
(200,
@@ -95,7 +97,7 @@
def _mock_list_2_roles(self):
roles_fix = self.useFixture(mockpatch.PatchObject(
- json_iden_client.IdentityClient,
+ json_roles_client.RolesClient,
'list_roles',
return_value=(service_client.ResponseBody
(200,
@@ -106,7 +108,7 @@
def _mock_assign_user_role(self):
tenant_fix = self.useFixture(mockpatch.PatchObject(
- json_iden_client.IdentityClient,
+ json_roles_client.RolesClient,
'assign_user_role',
return_value=(service_client.ResponseBody
(200, {}))))
@@ -114,7 +116,7 @@
def _mock_list_role(self):
roles_fix = self.useFixture(mockpatch.PatchObject(
- json_iden_client.IdentityClient,
+ json_roles_client.RolesClient,
'list_roles',
return_value=(service_client.ResponseBody
(200, {'roles': [{'id': '1',
@@ -178,11 +180,11 @@
self._mock_user_create('1234', 'fake_admin_user')
self._mock_tenant_create('1234', 'fake_admin_tenant')
- user_mock = mock.patch.object(json_iden_client.IdentityClient,
+ user_mock = mock.patch.object(json_roles_client.RolesClient,
'assign_user_role')
user_mock.start()
self.addCleanup(user_mock.stop)
- with mock.patch.object(json_iden_client.IdentityClient,
+ with mock.patch.object(json_roles_client.RolesClient,
'assign_user_role') as user_mock:
admin_creds = creds.get_admin_creds()
user_mock.assert_has_calls([
@@ -201,11 +203,11 @@
self._mock_user_create('1234', 'fake_role_user')
self._mock_tenant_create('1234', 'fake_role_tenant')
- user_mock = mock.patch.object(json_iden_client.IdentityClient,
+ user_mock = mock.patch.object(json_roles_client.RolesClient,
'assign_user_role')
user_mock.start()
self.addCleanup(user_mock.stop)
- with mock.patch.object(json_iden_client.IdentityClient,
+ with mock.patch.object(json_roles_client.RolesClient,
'assign_user_role') as user_mock:
role_creds = creds.get_creds_by_roles(
roles=['role1', 'role2'])
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
index e596aab..9c2b99e 100644
--- a/tempest/tests/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -29,7 +29,7 @@
self.useFixture(fake_config.ConfigFixture())
self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
cfg.CONF.set_default('ip_version_for_ssh', 4, group='validation')
- cfg.CONF.set_default('network_for_ssh', 'public', group='compute')
+ cfg.CONF.set_default('network_for_ssh', 'public', group='validation')
cfg.CONF.set_default('connect_timeout', 1, group='validation')
self.conn = remote_client.RemoteClient('127.0.0.1', 'user', 'pass')
@@ -79,7 +79,7 @@
def test_get_number_of_vcpus(self):
self.ssh_mock.mock.exec_command.return_value = '16'
self.assertEqual(self.conn.get_number_of_vcpus(), 16)
- self._assert_exec_called_with('grep -c processor /proc/cpuinfo')
+ self._assert_exec_called_with('grep -c ^processor /proc/cpuinfo')
def test_get_partitions(self):
proc_partitions = """major minor #blocks name
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 6c1b362..8fe9406 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -280,7 +280,7 @@
# NOTE(afazekas): it may be reports available before it is available
ssh = remote_client.RemoteClient(address.public_ip,
- CONF.compute.ssh_user,
+ CONF.validation.image_ssh_user,
pkey=self.keypair.material)
text = data_utils.rand_name("Pattern text for console output")
try: