688 lines
25 KiB
Python
688 lines
25 KiB
Python
#!/usr/bin/env python3
|
|
|
|
# Copyright 2018 Canonical Ltd.
|
|
#
|
|
# 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.
|
|
|
|
"""Encapsulating `neutron-openvswitch` testing."""
|
|
|
|
|
|
import logging
|
|
import tenacity
|
|
import unittest
|
|
|
|
import zaza
|
|
import zaza.openstack.charm_tests.glance.setup as glance_setup
|
|
import zaza.openstack.charm_tests.nova.utils as nova_utils
|
|
import zaza.openstack.charm_tests.test_utils as test_utils
|
|
import zaza.openstack.configure.guest as guest
|
|
import zaza.openstack.utilities.openstack as openstack_utils
|
|
|
|
|
|
class NeutronGatewayTest(test_utils.OpenStackBaseTest):
|
|
"""Test basic Neutron Gateway Charm functionality."""
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
"""Run class setup for running Neutron Gateway tests."""
|
|
super(NeutronGatewayTest, cls).setUpClass()
|
|
cls.current_os_release = openstack_utils.get_os_release()
|
|
cls.services = cls._get_services()
|
|
|
|
bionic_stein = openstack_utils.get_os_release('bionic_stein')
|
|
|
|
cls.pgrep_full = (True if cls.current_os_release >= bionic_stein
|
|
else False)
|
|
|
|
def test_900_restart_on_config_change(self):
|
|
"""Checking restart happens on config change.
|
|
|
|
Change disk format and assert then change propagates to the correct
|
|
file and that services are restarted as a result
|
|
"""
|
|
# Expected default and alternate values
|
|
current_value = zaza.model.get_application_config(
|
|
'neutron-gateway')['debug']['value']
|
|
new_value = str(not bool(current_value)).title()
|
|
current_value = str(current_value).title()
|
|
|
|
set_default = {'debug': current_value}
|
|
set_alternate = {'debug': new_value}
|
|
default_entry = {'DEFAULT': {'debug': [current_value]}}
|
|
alternate_entry = {'DEFAULT': {'debug': [new_value]}}
|
|
|
|
# Config file affected by juju set config change
|
|
conf_file = '/etc/neutron/neutron.conf'
|
|
|
|
# Make config change, check for service restarts
|
|
logging.info(
|
|
'Setting verbose on neutron-api {}'.format(set_alternate))
|
|
self.restart_on_changed(
|
|
conf_file,
|
|
set_default,
|
|
set_alternate,
|
|
default_entry,
|
|
alternate_entry,
|
|
self.services,
|
|
pgrep_full=self.pgrep_full)
|
|
|
|
def test_910_pause_and_resume(self):
|
|
"""Run pause and resume tests.
|
|
|
|
Pause service and check services are stopped then resume and check
|
|
they are started
|
|
"""
|
|
with self.pause_resume(
|
|
self.services,
|
|
pgrep_full=self.pgrep_full):
|
|
logging.info("Testing pause resume")
|
|
|
|
def test_920_change_aa_profile(self):
|
|
"""Test changing the Apparmor profile mode."""
|
|
services = ['neutron-openvswitch-agent',
|
|
'neutron-dhcp-agent',
|
|
'neutron-l3-agent',
|
|
'neutron-metadata-agent',
|
|
'neutron-metering-agent']
|
|
|
|
set_default = {'aa-profile-mode': 'disable'}
|
|
set_alternate = {'aa-profile-mode': 'complain'}
|
|
|
|
mtime = zaza.model.get_unit_time(
|
|
self.lead_unit,
|
|
model_name=self.model_name)
|
|
logging.debug('Remote unit timestamp {}'.format(mtime))
|
|
|
|
with self.config_change(set_default, set_alternate):
|
|
for unit in zaza.model.get_units('neutron-gateway',
|
|
model_name=self.model_name):
|
|
logging.info('Checking number of profiles in complain '
|
|
'mode in {}'.format(unit.entity_id))
|
|
run = zaza.model.run_on_unit(
|
|
unit.entity_id,
|
|
'aa-status --complaining',
|
|
model_name=self.model_name)
|
|
output = run['Stdout']
|
|
self.assertTrue(int(output) >= len(services))
|
|
|
|
@classmethod
|
|
def _get_services(cls):
|
|
"""
|
|
Return the services expected in Neutron Gateway.
|
|
|
|
:returns: A list of services
|
|
:rtype: list[str]
|
|
"""
|
|
services = ['neutron-dhcp-agent',
|
|
'neutron-metadata-agent',
|
|
'neutron-metering-agent',
|
|
'neutron-openvswitch-agent']
|
|
|
|
trusty_icehouse = openstack_utils.get_os_release('trusty_icehouse')
|
|
xenial_newton = openstack_utils.get_os_release('xenial_newton')
|
|
bionic_train = openstack_utils.get_os_release('bionic_train')
|
|
|
|
if cls.current_os_release <= trusty_icehouse:
|
|
services.append('neutron-vpn-agent')
|
|
if cls.current_os_release < xenial_newton:
|
|
services.append('neutron-lbaas-agent')
|
|
if xenial_newton <= cls.current_os_release < bionic_train:
|
|
services.append('neutron-lbaasv2-agent')
|
|
|
|
return services
|
|
|
|
|
|
class NeutronApiTest(test_utils.OpenStackBaseTest):
|
|
"""Test basic Neutron API Charm functionality."""
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
"""Run class setup for running Neutron Gateway tests."""
|
|
super(NeutronApiTest, cls).setUpClass()
|
|
cls.current_os_release = openstack_utils.get_os_release()
|
|
|
|
# set up clients
|
|
cls.neutron_client = (
|
|
openstack_utils.get_neutron_session_client(cls.keystone_session))
|
|
|
|
def test_400_create_network(self):
|
|
"""Create a network, verify that it exists, and then delete it."""
|
|
logging.debug('Creating neutron network...')
|
|
self.neutron_client.format = 'json'
|
|
net_name = 'test_net'
|
|
|
|
# Verify that the network doesn't exist
|
|
networks = self.neutron_client.list_networks(name=net_name)
|
|
net_count = len(networks['networks'])
|
|
assert net_count == 0, (
|
|
"Expected zero networks, found {}".format(net_count))
|
|
|
|
# Create a network and verify that it exists
|
|
network = {'name': net_name}
|
|
self.neutron_client.create_network({'network': network})
|
|
|
|
networks = self.neutron_client.list_networks(name=net_name)
|
|
logging.debug('Networks: {}'.format(networks))
|
|
net_len = len(networks['networks'])
|
|
assert net_len == 1, (
|
|
"Expected 1 network, found {}".format(net_len))
|
|
|
|
logging.debug('Confirming new neutron network...')
|
|
network = networks['networks'][0]
|
|
assert network['name'] == net_name, "network ext_net not found"
|
|
|
|
# Cleanup
|
|
logging.debug('Deleting neutron network...')
|
|
self.neutron_client.delete_network(network['id'])
|
|
|
|
def test_401_enable_qos(self):
|
|
"""Check qos settings set via neutron-api charm."""
|
|
if (self.current_os_release >=
|
|
openstack_utils.get_os_release('trusty_mitaka')):
|
|
logging.info('running qos check')
|
|
|
|
with self.config_change(
|
|
{'enable-qos': 'False'},
|
|
{'enable-qos': 'True'},
|
|
application_name="neutron-api"):
|
|
|
|
self._validate_openvswitch_agent_qos()
|
|
|
|
def test_900_restart_on_config_change(self):
|
|
"""Checking restart happens on config change.
|
|
|
|
Change disk format and assert then change propagates to the correct
|
|
file and that services are restarted as a result
|
|
"""
|
|
# Expected default and alternate values
|
|
current_value = zaza.model.get_application_config(
|
|
'neutron-api')['debug']['value']
|
|
new_value = str(not bool(current_value)).title()
|
|
current_value = str(current_value).title()
|
|
|
|
set_default = {'debug': current_value}
|
|
set_alternate = {'debug': new_value}
|
|
default_entry = {'DEFAULT': {'debug': [current_value]}}
|
|
alternate_entry = {'DEFAULT': {'debug': [new_value]}}
|
|
|
|
# Config file affected by juju set config change
|
|
conf_file = '/etc/neutron/neutron.conf'
|
|
|
|
# Make config change, check for service restarts
|
|
logging.info(
|
|
'Setting verbose on neutron-api {}'.format(set_alternate))
|
|
bionic_stein = openstack_utils.get_os_release('bionic_stein')
|
|
if openstack_utils.get_os_release() >= bionic_stein:
|
|
pgrep_full = True
|
|
else:
|
|
pgrep_full = False
|
|
self.restart_on_changed(
|
|
conf_file,
|
|
set_default,
|
|
set_alternate,
|
|
default_entry,
|
|
alternate_entry,
|
|
['neutron-server'],
|
|
pgrep_full=pgrep_full)
|
|
|
|
def test_901_pause_resume(self):
|
|
"""Run pause and resume tests.
|
|
|
|
Pause service and check services are stopped then resume and check
|
|
they are started
|
|
"""
|
|
bionic_stein = openstack_utils.get_os_release('bionic_stein')
|
|
if openstack_utils.get_os_release() >= bionic_stein:
|
|
pgrep_full = True
|
|
else:
|
|
pgrep_full = False
|
|
with self.pause_resume(
|
|
["neutron-server", "apache2", "haproxy"],
|
|
pgrep_full=pgrep_full):
|
|
logging.info("Testing pause resume")
|
|
|
|
@tenacity.retry(wait=tenacity.wait_exponential(min=5, max=60))
|
|
def _validate_openvswitch_agent_qos(self):
|
|
"""Validate that the qos extension is enabled in the ovs agent."""
|
|
# obtain the dhcp agent to identify the neutron-gateway host
|
|
dhcp_agent = self.neutron_client.list_agents(
|
|
binary='neutron-dhcp-agent')['agents'][0]
|
|
neutron_gw_host = dhcp_agent['host']
|
|
logging.debug('neutron gw host: {}'.format(neutron_gw_host))
|
|
|
|
# check extensions on the ovs agent to validate qos
|
|
ovs_agent = self.neutron_client.list_agents(
|
|
binary='neutron-openvswitch-agent',
|
|
host=neutron_gw_host)['agents'][0]
|
|
|
|
self.assertIn('qos', ovs_agent['configurations']['extensions'])
|
|
|
|
|
|
class SecurityTest(test_utils.OpenStackBaseTest):
|
|
"""Neutron Security Tests."""
|
|
|
|
def test_security_checklist(self):
|
|
"""Verify expected state with security-checklist."""
|
|
expected_failures = []
|
|
expected_passes = [
|
|
'validate-file-ownership',
|
|
'validate-file-permissions',
|
|
]
|
|
expected_to_pass = True
|
|
|
|
# override settings depending on application name so we can reuse
|
|
# the class for multiple charms
|
|
if self.application_name == 'neutron-api':
|
|
tls_checks = [
|
|
'validate-uses-tls-for-keystone',
|
|
]
|
|
|
|
expected_failures = [
|
|
'validate-enables-tls', # LP: #1851610
|
|
]
|
|
|
|
expected_passes.append('validate-uses-keystone')
|
|
|
|
if zaza.model.get_relation_id(
|
|
'neutron-api',
|
|
'vault',
|
|
remote_interface_name='certificates'):
|
|
expected_passes.extend(tls_checks)
|
|
else:
|
|
expected_failures.extend(tls_checks)
|
|
|
|
expected_to_pass = False
|
|
|
|
for unit in zaza.model.get_units(self.application_name,
|
|
model_name=self.model_name):
|
|
logging.info('Running `security-checklist` action'
|
|
' on unit {}'.format(unit.entity_id))
|
|
test_utils.audit_assertions(
|
|
zaza.model.run_action(
|
|
unit.entity_id,
|
|
'security-checklist',
|
|
model_name=self.model_name,
|
|
action_params={}),
|
|
expected_passes,
|
|
expected_failures,
|
|
expected_to_pass=expected_to_pass)
|
|
|
|
|
|
class NeutronOpenvSwitchTest(test_utils.OpenStackBaseTest):
|
|
"""Test basic Neutron Openvswitch Charm functionality."""
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
"""Run class setup for running Neutron Openvswitch tests."""
|
|
super(NeutronOpenvSwitchTest, cls).setUpClass()
|
|
|
|
cls.current_os_release = openstack_utils.get_os_release()
|
|
|
|
cls.compute_unit = zaza.model.get_units('nova-compute')[0]
|
|
cls.neutron_api_unit = zaza.model.get_units('neutron-api')[0]
|
|
cls.n_ovs_unit = zaza.model.get_units('neutron-openvswitch')[0]
|
|
|
|
cls.bionic_stein = openstack_utils.get_os_release('bionic_stein')
|
|
cls.trusty_mitaka = openstack_utils.get_os_release('trusty_mitaka')
|
|
|
|
if cls.current_os_release >= cls.bionic_stein:
|
|
cls.pgrep_full = True
|
|
else:
|
|
cls.pgrep_full = False
|
|
|
|
# set up client
|
|
cls.neutron_client = (
|
|
openstack_utils.get_neutron_session_client(cls.keystone_session))
|
|
|
|
def test_101_neutron_sriov_config(self):
|
|
"""Verify data in the sriov agent config file."""
|
|
trusty_kilo = openstack_utils.get_os_release('trusty_kilo')
|
|
if self.current_os_release < trusty_kilo:
|
|
logging.debug('Skipping test, sriov agent not supported on < '
|
|
'trusty/kilo')
|
|
return
|
|
|
|
zaza.model.set_application_config(
|
|
self.application_name,
|
|
{'enable-sriov': 'True'})
|
|
|
|
zaza.model.wait_for_application_states()
|
|
|
|
self._check_settings_in_config(
|
|
self.application_name,
|
|
'sriov-device-mappings',
|
|
'physical_device_mappings',
|
|
['', 'physnet42:eth42'],
|
|
'sriov_nic',
|
|
'/etc/neutron/plugins/ml2/sriov_agent.ini')
|
|
|
|
# the CI environment does not expose an actual SR-IOV NIC to the
|
|
# functional tests. consequently the neutron-sriov agent will not
|
|
# run, and the charm will update its status as such. this will prevent
|
|
# the success of pause/resume test.
|
|
#
|
|
# disable sriov after validation of config file is complete.
|
|
logging.info('Disabling SR-IOV after verifying config file data...')
|
|
|
|
zaza.model.set_application_config(
|
|
self.application_name,
|
|
{'enable-sriov': 'False'})
|
|
|
|
logging.info('Waiting for config-changes to complete...')
|
|
zaza.model.wait_for_application_states()
|
|
|
|
logging.debug('OK')
|
|
|
|
def _check_settings_in_config(self, service, charm_key,
|
|
config_file_key, vpair,
|
|
section, conf_file):
|
|
|
|
set_default = {charm_key: vpair[0]}
|
|
set_alternate = {charm_key: vpair[1]}
|
|
app_name = service
|
|
|
|
expected = {
|
|
section: {
|
|
config_file_key: [vpair[1]],
|
|
},
|
|
}
|
|
|
|
with self.config_change(set_default,
|
|
set_alternate,
|
|
application_name=app_name):
|
|
zaza.model.block_until_oslo_config_entries_match(
|
|
self.application_name,
|
|
conf_file,
|
|
expected,
|
|
)
|
|
logging.debug('OK')
|
|
|
|
def test_201_l2pop_propagation(self):
|
|
"""Verify that l2pop setting propagates to neutron-ovs."""
|
|
self._check_settings_in_config(
|
|
'neutron-api',
|
|
'l2-population',
|
|
'l2_population',
|
|
['False', 'True'],
|
|
'agent',
|
|
'/etc/neutron/plugins/ml2/openvswitch_agent.ini')
|
|
|
|
def test_202_nettype_propagation(self):
|
|
"""Verify that nettype setting propagates to neutron-ovs."""
|
|
self._check_settings_in_config(
|
|
'neutron-api',
|
|
'overlay-network-type',
|
|
'tunnel_types',
|
|
['vxlan', 'gre'],
|
|
'agent',
|
|
'/etc/neutron/plugins/ml2/openvswitch_agent.ini')
|
|
|
|
def test_301_secgroup_propagation_local_override(self):
|
|
"""Verify disable-security-groups overrides what neutron-api says."""
|
|
if self.current_os_release >= self.trusty_mitaka:
|
|
conf_file = "/etc/neutron/plugins/ml2/openvswitch_agent.ini"
|
|
else:
|
|
conf_file = "/etc/neutron/plugins/ml2/ml2_conf.ini"
|
|
|
|
zaza.model.set_application_config(
|
|
'neutron-api',
|
|
{'neutron-security-groups': 'True'})
|
|
zaza.model.set_application_config(
|
|
'neutron-openvswitch',
|
|
{'disable-security-groups': 'True'})
|
|
|
|
zaza.model.wait_for_application_states()
|
|
|
|
expected = {
|
|
'securitygroup': {
|
|
'enable_security_group': ['False'],
|
|
},
|
|
}
|
|
|
|
zaza.model.block_until_oslo_config_entries_match(
|
|
self.application_name,
|
|
conf_file,
|
|
expected,
|
|
)
|
|
|
|
logging.info('Restoring to default configuration...')
|
|
zaza.model.set_application_config(
|
|
'neutron-openvswitch',
|
|
{'disable-security-groups': 'False'})
|
|
zaza.model.set_application_config(
|
|
'neutron-api',
|
|
{'neutron-security-groups': 'False'})
|
|
|
|
zaza.model.wait_for_application_states()
|
|
|
|
def test_401_restart_on_config_change(self):
|
|
"""Verify that the specified services are restarted.
|
|
|
|
When the config is changed we need to make sure that the services are
|
|
restarted.
|
|
"""
|
|
self.restart_on_changed(
|
|
'/etc/neutron/neutron.conf',
|
|
{'debug': 'false'},
|
|
{'debug': 'true'},
|
|
{'DEFAULT': {'debug': ['False']}},
|
|
{'DEFAULT': {'debug': ['True']}},
|
|
['neutron-openvswitch-agent'],
|
|
pgrep_full=self.pgrep_full)
|
|
|
|
def test_501_enable_qos(self):
|
|
"""Check qos settings set via neutron-api charm."""
|
|
if self.current_os_release < self.trusty_mitaka:
|
|
logging.debug('Skipping test')
|
|
return
|
|
|
|
set_default = {'enable-qos': 'false'}
|
|
set_alternate = {'enable-qos': 'true'}
|
|
app_name = 'neutron-api'
|
|
|
|
conf_file = '/etc/neutron/plugins/ml2/openvswitch_agent.ini'
|
|
expected = {
|
|
'agent': {
|
|
'extensions': ['qos'],
|
|
},
|
|
}
|
|
|
|
with self.config_change(set_default,
|
|
set_alternate,
|
|
application_name=app_name):
|
|
zaza.model.block_until_oslo_config_entries_match(
|
|
self.application_name,
|
|
conf_file,
|
|
expected,
|
|
)
|
|
logging.debug('OK')
|
|
|
|
def test_901_pause_and_resume(self):
|
|
"""Run pause and resume tests.
|
|
|
|
Pause service and check services are stopped then resume and check
|
|
they are started
|
|
"""
|
|
with self.pause_resume(['neutron-openvswitch-agent'],
|
|
pgrep_full=self.pgrep_full):
|
|
logging.info('Testing pause resume')
|
|
|
|
|
|
class NeutronNetworkingTest(unittest.TestCase):
|
|
"""Ensure that openstack instances have valid networking."""
|
|
|
|
RESOURCE_PREFIX = 'zaza-neutrontests'
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
"""Run class setup for running Neutron API Networking tests."""
|
|
cls.keystone_session = (
|
|
openstack_utils.get_overcloud_keystone_session())
|
|
cls.nova_client = (
|
|
openstack_utils.get_nova_session_client(cls.keystone_session))
|
|
# NOTE(fnordahl): in the event of a test failure we do not want to run
|
|
# tear down code as it will make debugging a problem virtually
|
|
# impossible. To alleviate each test method will set the
|
|
# `run_tearDown` instance variable at the end which will let us run
|
|
# tear down only when there were no failure.
|
|
cls.run_tearDown = False
|
|
|
|
@classmethod
|
|
def tearDown(cls):
|
|
"""Remove test resources."""
|
|
if cls.run_tearDown:
|
|
logging.info('Running teardown')
|
|
for server in cls.nova_client.servers.list():
|
|
if server.name.startswith(cls.RESOURCE_PREFIX):
|
|
openstack_utils.delete_resource(
|
|
cls.nova_client.servers,
|
|
server.id,
|
|
msg="server")
|
|
|
|
def test_instances_have_networking(self):
|
|
"""Validate North/South and East/West networking."""
|
|
guest.launch_instance(
|
|
glance_setup.LTS_IMAGE_NAME,
|
|
vm_name='{}-ins-1'.format(self.RESOURCE_PREFIX))
|
|
guest.launch_instance(
|
|
glance_setup.LTS_IMAGE_NAME,
|
|
vm_name='{}-ins-2'.format(self.RESOURCE_PREFIX))
|
|
|
|
instance_1 = self.nova_client.servers.find(
|
|
name='{}-ins-1'.format(self.RESOURCE_PREFIX))
|
|
|
|
instance_2 = self.nova_client.servers.find(
|
|
name='{}-ins-2'.format(self.RESOURCE_PREFIX))
|
|
|
|
def verify(stdin, stdout, stderr):
|
|
"""Validate that the SSH command exited 0."""
|
|
self.assertEqual(stdout.channel.recv_exit_status(), 0)
|
|
|
|
# Verify network from 1 to 2
|
|
self.validate_instance_can_reach_other(instance_1, instance_2, verify)
|
|
|
|
# Verify network from 2 to 1
|
|
self.validate_instance_can_reach_other(instance_2, instance_1, verify)
|
|
|
|
# Validate tenant to external network routing
|
|
self.validate_instance_can_reach_router(instance_1, verify)
|
|
self.validate_instance_can_reach_router(instance_2, verify)
|
|
|
|
# If we get here, it means the tests passed
|
|
self.run_tearDown = True
|
|
|
|
@tenacity.retry(wait=tenacity.wait_exponential(multiplier=1, max=60),
|
|
reraise=True, stop=tenacity.stop_after_attempt(8))
|
|
def validate_instance_can_reach_other(self,
|
|
instance_1,
|
|
instance_2,
|
|
verify):
|
|
"""
|
|
Validate that an instance can reach a fixed and floating of another.
|
|
|
|
:param instance_1: The instance to check networking from
|
|
:type instance_1: nova_client.Server
|
|
|
|
:param instance_2: The instance to check networking from
|
|
:type instance_2: nova_client.Server
|
|
"""
|
|
floating_1 = floating_ips_from_instance(instance_1)[0]
|
|
floating_2 = floating_ips_from_instance(instance_2)[0]
|
|
address_2 = fixed_ips_from_instance(instance_2)[0]
|
|
|
|
username = guest.boot_tests['bionic']['username']
|
|
password = guest.boot_tests['bionic'].get('password')
|
|
privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME)
|
|
|
|
openstack_utils.ssh_command(
|
|
username, floating_1, 'instance-1',
|
|
'ping -c 1 {}'.format(address_2),
|
|
password=password, privkey=privkey, verify=verify)
|
|
|
|
openstack_utils.ssh_command(
|
|
username, floating_1, 'instance-1',
|
|
'ping -c 1 {}'.format(floating_2),
|
|
password=password, privkey=privkey, verify=verify)
|
|
|
|
@tenacity.retry(wait=tenacity.wait_exponential(multiplier=1, max=60),
|
|
reraise=True, stop=tenacity.stop_after_attempt(8))
|
|
def validate_instance_can_reach_router(self, instance, verify):
|
|
"""
|
|
Validate that an instance can reach it's primary gateway.
|
|
|
|
We make the assumption that the router's IP is 192.168.0.1
|
|
as that's the network that is setup in
|
|
neutron.setup.basic_overcloud_network which is used in all
|
|
Zaza Neutron validations.
|
|
|
|
:param instance: The instance to check networking from
|
|
:type instance: nova_client.Server
|
|
"""
|
|
address = floating_ips_from_instance(instance)[0]
|
|
|
|
username = guest.boot_tests['bionic']['username']
|
|
password = guest.boot_tests['bionic'].get('password')
|
|
privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME)
|
|
|
|
openstack_utils.ssh_command(
|
|
username, address, 'instance', 'ping -c 1 192.168.0.1',
|
|
password=password, privkey=privkey, verify=verify)
|
|
pass
|
|
|
|
|
|
def floating_ips_from_instance(instance):
|
|
"""
|
|
Retrieve floating IPs from an instance.
|
|
|
|
:param instance: The instance to fetch floating IPs from
|
|
:type instance: nova_client.Server
|
|
|
|
:returns: A list of floating IPs for the specified server
|
|
:rtype: list[str]
|
|
"""
|
|
return ips_from_instance(instance, 'floating')
|
|
|
|
|
|
def fixed_ips_from_instance(instance):
|
|
"""
|
|
Retrieve fixed IPs from an instance.
|
|
|
|
:param instance: The instance to fetch fixed IPs from
|
|
:type instance: nova_client.Server
|
|
|
|
:returns: A list of fixed IPs for the specified server
|
|
:rtype: list[str]
|
|
"""
|
|
return ips_from_instance(instance, 'fixed')
|
|
|
|
|
|
def ips_from_instance(instance, ip_type):
|
|
"""
|
|
Retrieve IPs of a certain type from an instance.
|
|
|
|
:param instance: The instance to fetch IPs from
|
|
:type instance: nova_client.Server
|
|
:param ip_type: the type of IP to fetch, floating or fixed
|
|
:type ip_type: str
|
|
|
|
:returns: A list of IPs for the specified server
|
|
:rtype: list[str]
|
|
"""
|
|
if ip_type not in ['floating', 'fixed']:
|
|
raise RuntimeError(
|
|
"Only 'floating' and 'fixed' are valid IP types to search for"
|
|
)
|
|
return list([
|
|
ip['addr'] for ip in instance.addresses['private']
|
|
if ip['OS-EXT-IPS:type'] == ip_type])
|