Consolidate the ssh code
The entire mechanism for ssh validation is a mess. The fact that there is a parameter which is server_or_ip, so you never know if it's an object or an address, and that every one of 7 layers need to handle either case, makes doing any enhancements here for failure detection impossible. This change implements a get_server_ip method that gets the fixed or floating IP address before passing it to the remote client. Change-Id: I76d818bf9e1bd26b1e499464fc9213764afee279
This commit is contained in:
parent
5576f740b2
commit
20e9861d51
|
@ -23,6 +23,7 @@ from tempest.common import compute
|
|||
from tempest.common.utils import data_utils
|
||||
from tempest.common import waiters
|
||||
from tempest import config
|
||||
from tempest import exceptions
|
||||
import tempest.test
|
||||
|
||||
CONF = config.CONF
|
||||
|
@ -356,16 +357,19 @@ class BaseV2ComputeTest(api_version_utils.BaseMicroversionTest,
|
|||
def get_server_ip(cls, server):
|
||||
"""Get the server fixed or floating IP.
|
||||
|
||||
For the floating IP, the address created by the validation resources
|
||||
is returned.
|
||||
For the fixed IP, the server is returned and the current mechanism of
|
||||
address extraction in the remote_client is followed.
|
||||
Based on the configuration we're in, return a correct ip
|
||||
address for validating that a guest is up.
|
||||
"""
|
||||
if CONF.validation.connect_method == 'floating':
|
||||
ip_or_server = cls.validation_resources['floating_ip']['ip']
|
||||
return cls.validation_resources['floating_ip']['ip']
|
||||
elif CONF.validation.connect_method == 'fixed':
|
||||
ip_or_server = server
|
||||
return ip_or_server
|
||||
addresses = server['addresses'][CONF.validation.network_for_ssh]
|
||||
for address in addresses:
|
||||
if address['version'] == CONF.validation.ip_version_for_ssh:
|
||||
return address['addr']
|
||||
raise exceptions.ServerUnreachable()
|
||||
else:
|
||||
raise exceptions.InvalidConfiguration()
|
||||
|
||||
|
||||
class BaseV2ComputeAdminTest(BaseV2ComputeTest):
|
||||
|
|
|
@ -15,7 +15,6 @@ import re
|
|||
import time
|
||||
|
||||
from oslo_log import log as logging
|
||||
import six
|
||||
from tempest_lib.common import ssh
|
||||
|
||||
from tempest import config
|
||||
|
@ -28,22 +27,10 @@ LOG = logging.getLogger(__name__)
|
|||
|
||||
class RemoteClient(object):
|
||||
|
||||
# NOTE(afazekas): It should always get an address instead of server
|
||||
def __init__(self, server, username, password=None, pkey=None):
|
||||
def __init__(self, ip_address, username, password=None, pkey=None):
|
||||
ssh_timeout = CONF.validation.ssh_timeout
|
||||
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):
|
||||
ip_address = server
|
||||
else:
|
||||
addresses = server['addresses'][network]
|
||||
for address in addresses:
|
||||
if address['version'] == ip_version:
|
||||
ip_address = address['addr']
|
||||
break
|
||||
else:
|
||||
raise exceptions.ServerUnreachable()
|
||||
|
||||
self.ssh_client = ssh.Client(ip_address, username, password,
|
||||
ssh_timeout, pkey=pkey,
|
||||
channel_timeout=connect_timeout)
|
||||
|
|
|
@ -352,25 +352,15 @@ class ScenarioTest(tempest.test.BaseTestCase):
|
|||
|
||||
return secgroup
|
||||
|
||||
def get_remote_client(self, server_or_ip, username=None, private_key=None):
|
||||
def get_remote_client(self, ip_address, username=None, private_key=None):
|
||||
"""Get a SSH client to a remote server
|
||||
|
||||
@param server_or_ip a server object as returned by Tempest compute
|
||||
client or an IP address to connect to
|
||||
@param ip_address the server floating or fixed IP address to use
|
||||
for ssh validation
|
||||
@param username name of the Linux account on the remote server
|
||||
@param private_key the SSH private key to use
|
||||
@return a RemoteClient object
|
||||
"""
|
||||
if isinstance(server_or_ip, six.string_types):
|
||||
ip = server_or_ip
|
||||
else:
|
||||
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()
|
||||
except StopIteration:
|
||||
raise lib_exc.NotFound("No IPv4 addresses to use for SSH to "
|
||||
"remote server.")
|
||||
|
||||
if username is None:
|
||||
username = CONF.validation.image_ssh_user
|
||||
|
@ -383,14 +373,15 @@ class ScenarioTest(tempest.test.BaseTestCase):
|
|||
else:
|
||||
password = CONF.validation.image_ssh_password
|
||||
private_key = None
|
||||
linux_client = remote_client.RemoteClient(ip, username,
|
||||
linux_client = remote_client.RemoteClient(ip_address, username,
|
||||
pkey=private_key,
|
||||
password=password)
|
||||
try:
|
||||
linux_client.validate_authentication()
|
||||
except Exception as e:
|
||||
message = ('Initializing SSH connection to %(ip)s failed. '
|
||||
'Error: %(error)s' % {'ip': ip, 'error': e})
|
||||
'Error: %(error)s' % {'ip_address': ip_address,
|
||||
'error': e})
|
||||
caller = misc_utils.find_test_caller()
|
||||
if caller:
|
||||
message = '(%s) %s' % (caller, message)
|
||||
|
@ -628,9 +619,9 @@ class ScenarioTest(tempest.test.BaseTestCase):
|
|||
floating_ip['ip'], thing['id'])
|
||||
return floating_ip
|
||||
|
||||
def create_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt',
|
||||
def create_timestamp(self, ip_address, dev_name=None, mount_path='/mnt',
|
||||
private_key=None):
|
||||
ssh_client = self.get_remote_client(server_or_ip,
|
||||
ssh_client = self.get_remote_client(ip_address,
|
||||
private_key=private_key)
|
||||
if dev_name is not None:
|
||||
ssh_client.make_fs(dev_name)
|
||||
|
@ -643,9 +634,9 @@ class ScenarioTest(tempest.test.BaseTestCase):
|
|||
ssh_client.umount(mount_path)
|
||||
return timestamp
|
||||
|
||||
def get_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt',
|
||||
def get_timestamp(self, ip_address, dev_name=None, mount_path='/mnt',
|
||||
private_key=None):
|
||||
ssh_client = self.get_remote_client(server_or_ip,
|
||||
ssh_client = self.get_remote_client(ip_address,
|
||||
private_key=private_key)
|
||||
if dev_name is not None:
|
||||
ssh_client.mount(dev_name, mount_path)
|
||||
|
@ -655,12 +646,25 @@ class ScenarioTest(tempest.test.BaseTestCase):
|
|||
ssh_client.umount(mount_path)
|
||||
return timestamp
|
||||
|
||||
def get_server_or_ip(self, server):
|
||||
def get_server_ip(self, server):
|
||||
"""Get the server fixed or floating IP.
|
||||
|
||||
Based on the configuration we're in, return a correct ip
|
||||
address for validating that a guest is up.
|
||||
"""
|
||||
if CONF.validation.connect_method == 'floating':
|
||||
ip = self.create_floating_ip(server)['ip']
|
||||
# The tests calling this method don't have a floating IP
|
||||
# and can't make use of the validattion resources. So the
|
||||
# method is creating the floating IP there.
|
||||
return self.create_floating_ip(server)['ip']
|
||||
elif CONF.validation.connect_method == 'fixed':
|
||||
addresses = server['addresses'][CONF.validation.network_for_ssh]
|
||||
for address in addresses:
|
||||
if address['version'] == CONF.validation.ip_version_for_ssh:
|
||||
return address['addr']
|
||||
raise exceptions.ServerUnreachable()
|
||||
else:
|
||||
ip = server
|
||||
return ip
|
||||
raise exceptions.InvalidConfiguration()
|
||||
|
||||
|
||||
class NetworkScenarioTest(ScenarioTest):
|
||||
|
@ -1316,13 +1320,6 @@ class BaremetalScenarioTest(ScenarioTest):
|
|||
def add_keypair(self):
|
||||
self.keypair = self.create_keypair()
|
||||
|
||||
def verify_connectivity(self, ip=None):
|
||||
if ip:
|
||||
dest = self.get_remote_client(ip)
|
||||
else:
|
||||
dest = self.get_remote_client(self.instance)
|
||||
dest.validate_authentication()
|
||||
|
||||
def boot_instance(self):
|
||||
self.instance = self.create_server(
|
||||
key_name=self.keypair['name'])
|
||||
|
|
|
@ -112,12 +112,9 @@ class BaremetalBasicOps(manager.BaremetalScenarioTest):
|
|||
self.add_keypair()
|
||||
self.boot_instance()
|
||||
self.validate_ports()
|
||||
self.verify_connectivity()
|
||||
if CONF.validation.connect_method == 'floating':
|
||||
floating_ip = self.create_floating_ip(self.instance)['ip']
|
||||
self.verify_connectivity(ip=floating_ip)
|
||||
|
||||
vm_client = self.get_remote_client(self.instance)
|
||||
ip_address = self.get_server_ip(self.instance)
|
||||
self.get_remote_client(ip_address).validate_authentication()
|
||||
vm_client = self.get_remote_client(ip_address)
|
||||
|
||||
# We expect the ephemeral partition to be mounted on /mnt and to have
|
||||
# the same size as our flavor definition.
|
||||
|
@ -126,6 +123,6 @@ class BaremetalBasicOps(manager.BaremetalScenarioTest):
|
|||
self.verify_partition(vm_client, 'ephemeral0', '/mnt', eph_size)
|
||||
# Create the test file
|
||||
self.create_timestamp(
|
||||
floating_ip, private_key=self.keypair['private_key'])
|
||||
ip_address, private_key=self.keypair['private_key'])
|
||||
|
||||
self.terminate_instance()
|
||||
|
|
|
@ -124,7 +124,7 @@ class TestGettingAddress(manager.NetworkScenarioTest):
|
|||
fip = self.create_floating_ip(thing=srv)
|
||||
ips = self.define_server_ips(srv=srv)
|
||||
ssh = self.get_remote_client(
|
||||
server_or_ip=fip.floating_ip_address,
|
||||
ip_address=fip.floating_ip_address,
|
||||
username=username)
|
||||
return ssh, ips, srv["id"]
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ class TestServerBasicOps(manager.ScenarioTest):
|
|||
self.fip = self.create_floating_ip(self.instance)['ip']
|
||||
# Check ssh
|
||||
self.ssh_client = self.get_remote_client(
|
||||
server_or_ip=self.fip,
|
||||
ip_address=self.fip,
|
||||
username=self.image_utils.ssh_user(self.image_ref),
|
||||
private_key=keypair['private_key'])
|
||||
|
||||
|
|
|
@ -80,7 +80,7 @@ class TestShelveInstance(manager.ScenarioTest):
|
|||
security_groups=security_groups,
|
||||
wait_until='ACTIVE')
|
||||
|
||||
instance_ip = self.get_server_or_ip(server)
|
||||
instance_ip = self.get_server_ip(server)
|
||||
timestamp = self.create_timestamp(instance_ip,
|
||||
private_key=keypair['private_key'])
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class TestSnapshotPattern(manager.ScenarioTest):
|
|||
security_groups=[{'name': security_group['name']}],
|
||||
wait_until='ACTIVE')
|
||||
|
||||
instance_ip = self.get_server_or_ip(server)
|
||||
instance_ip = self.get_server_ip(server)
|
||||
timestamp = self.create_timestamp(instance_ip,
|
||||
private_key=keypair['private_key'])
|
||||
|
||||
|
@ -67,7 +67,7 @@ class TestSnapshotPattern(manager.ScenarioTest):
|
|||
wait_until='ACTIVE')
|
||||
|
||||
# check the existence of the timestamp file in the second instance
|
||||
server_from_snapshot_ip = self.get_server_or_ip(server_from_snapshot)
|
||||
server_from_snapshot_ip = self.get_server_ip(server_from_snapshot)
|
||||
timestamp2 = self.get_timestamp(server_from_snapshot_ip,
|
||||
private_key=keypair['private_key'])
|
||||
self.assertEqual(timestamp, timestamp2)
|
||||
|
|
|
@ -80,9 +80,9 @@ class TestStampPattern(manager.ScenarioTest):
|
|||
self.assertEqual(snapshot_name, snapshot['display_name'])
|
||||
return snapshot
|
||||
|
||||
def _wait_for_volume_available_on_the_system(self, server_or_ip,
|
||||
def _wait_for_volume_available_on_the_system(self, ip_address,
|
||||
private_key):
|
||||
ssh = self.get_remote_client(server_or_ip, private_key=private_key)
|
||||
ssh = self.get_remote_client(ip_address, private_key=private_key)
|
||||
|
||||
def _func():
|
||||
part = ssh.get_partitions()
|
||||
|
@ -113,7 +113,7 @@ class TestStampPattern(manager.ScenarioTest):
|
|||
wait_until='ACTIVE')
|
||||
|
||||
# create and add floating IP to server1
|
||||
ip_for_server = self.get_server_or_ip(server)
|
||||
ip_for_server = self.get_server_ip(server)
|
||||
|
||||
self.nova_volume_attach(server, volume)
|
||||
self._wait_for_volume_available_on_the_system(ip_for_server,
|
||||
|
@ -140,7 +140,7 @@ class TestStampPattern(manager.ScenarioTest):
|
|||
security_groups=security_group)
|
||||
|
||||
# create and add floating IP to server_from_snapshot
|
||||
ip_for_snapshot = self.get_server_or_ip(server_from_snapshot)
|
||||
ip_for_snapshot = self.get_server_ip(server_from_snapshot)
|
||||
|
||||
# attach volume2 to instance2
|
||||
self.nova_volume_attach(server_from_snapshot, volume_from_snapshot)
|
||||
|
|
|
@ -114,7 +114,7 @@ class TestVolumeBootPattern(manager.ScenarioTest):
|
|||
keypair, security_group)
|
||||
|
||||
# write content to volume on instance
|
||||
ip_instance_1st = self.get_server_or_ip(instance_1st)
|
||||
ip_instance_1st = self.get_server_ip(instance_1st)
|
||||
timestamp = self.create_timestamp(ip_instance_1st,
|
||||
private_key=keypair['private_key'])
|
||||
|
||||
|
@ -126,7 +126,7 @@ class TestVolumeBootPattern(manager.ScenarioTest):
|
|||
keypair, security_group)
|
||||
|
||||
# check the content of written file
|
||||
ip_instance_2nd = self.get_server_or_ip(instance_2nd)
|
||||
ip_instance_2nd = self.get_server_ip(instance_2nd)
|
||||
timestamp2 = self.get_timestamp(ip_instance_2nd,
|
||||
private_key=keypair['private_key'])
|
||||
self.assertEqual(timestamp, timestamp2)
|
||||
|
@ -141,7 +141,7 @@ class TestVolumeBootPattern(manager.ScenarioTest):
|
|||
keypair, security_group))
|
||||
|
||||
# check the content of written file
|
||||
server_from_snapshot_ip = self.get_server_or_ip(server_from_snapshot)
|
||||
server_from_snapshot_ip = self.get_server_ip(server_from_snapshot)
|
||||
timestamp3 = self.get_timestamp(server_from_snapshot_ip,
|
||||
private_key=keypair['private_key'])
|
||||
self.assertEqual(timestamp, timestamp3)
|
||||
|
|
Loading…
Reference in New Issue