Use Ubuntu server with a working trunk VLAN subport
- It adds default vlan_id neutron config option - Add a VLAN device to customized Ubuntu image configured to use DHCP - Make Ubuntu server to use a working trunk VLAN subport connected to a new special network - It pings such VLAN server port from a special CirrOS server connected to the new special network - It fixes existing trunk test by providing a proven working vlan connection. Change-Id: I07053dd264f26e7b3959f4ab1c7a6e054a702e77
This commit is contained in:
parent
094d3c0826
commit
4a275f1625
@ -65,15 +65,9 @@ OPTIONS = [
|
||||
cfg.IntOpt('dscp_mark',
|
||||
default=40,
|
||||
help="The DSCP marking value for the QoS Policy Rule"),
|
||||
cfg.StrOpt('trunk_subport_segmentation_type',
|
||||
default='vlan',
|
||||
help="Trunk subport segmentation type"),
|
||||
cfg.IntOpt('trunk_subport_segmentation_id',
|
||||
cfg.IntOpt('vlan_id',
|
||||
default=101,
|
||||
help="Trunk subport segmentation ID"),
|
||||
cfg.StrOpt('trunk_subport_subnet_cidr',
|
||||
default='192.168.101.0/24',
|
||||
help="The CIDR block for trunk subport subnet")
|
||||
help="VLAN trunk subport segmentation ID"),
|
||||
]
|
||||
|
||||
|
||||
|
@ -25,12 +25,13 @@ from tobiko.openstack.stacks import _nova
|
||||
from tobiko.openstack.stacks import _octavia
|
||||
from tobiko.openstack.stacks import _qos
|
||||
from tobiko.openstack.stacks import _ubuntu
|
||||
from tobiko.openstack.stacks import _vlan
|
||||
|
||||
|
||||
CentosFlavorStackFixture = _centos.CentosFlavorStackFixture
|
||||
CentosImageFixture = _centos.CentosImageFixture
|
||||
CentosServerStackFixture = _centos.CentosServerStackFixture
|
||||
Centos7ServerStackFixture = _centos.Centos7ServerStackFixture
|
||||
CentosTrunkServerStackFixture = _centos.CentosTrunkServerStackFixture
|
||||
|
||||
CirrosFlavorStackFixture = _cirros.CirrosFlavorStackFixture
|
||||
CirrosImageFixture = _cirros.CirrosImageFixture
|
||||
@ -52,7 +53,6 @@ FedoraServerStackFixture = _fedora.FedoraServerStackFixture
|
||||
RedHatFlavorStackFixture = _redhat.RedHatFlavorStackFixture
|
||||
RhelImageFixture = _redhat.RhelImageFixture
|
||||
RedHatServerStackFixture = _redhat.RedHatServerStackFixture
|
||||
RedHatTrunkServerStackFixture = _redhat.RedHatTrunkServerStackFixture
|
||||
|
||||
L3haNetworkStackFixture = _l3ha.L3haNetworkStackFixture
|
||||
L3haServerStackFixture = _l3ha.L3haServerStackFixture
|
||||
@ -80,6 +80,16 @@ ServerGroupStackFixture = _nova.ServerGroupStackFixture
|
||||
AffinityServerGroupStackFixture = _nova.AffinityServerGroupStackFixture
|
||||
AntiAffinityServerGroupStackFixture = _nova.AntiAffinityServerGroupStackFixture
|
||||
|
||||
OctaviaLoadbalancerStackFixture = _octavia.OctaviaLoadbalancerStackFixture
|
||||
OctaviaListenerStackFixture = _octavia.OctaviaListenerStackFixture
|
||||
OctaviaPoolStackFixture = _octavia.OctaviaPoolStackFixture
|
||||
OctaviaMemberServerStackFixture = _octavia.OctaviaMemberServerStackFixture
|
||||
OctaviaServerStackFixture = _octavia.OctaviaServerStackFixture
|
||||
OctaviaClientServerStackFixture = _octavia.OctaviaClientServerStackFixture
|
||||
OctaviaOtherServerStackFixture = _octavia.OctaviaOtherServerStackFixture
|
||||
OctaviaOtherMemberServerStackFixture = (
|
||||
_octavia.OctaviaOtherMemberServerStackFixture)
|
||||
|
||||
QosNetworkStackFixture = _qos.QosNetworkStackFixture
|
||||
QosPolicyStackFixture = _qos.QosPolicyStackFixture
|
||||
QosServerStackFixture = _qos.QosServerStackFixture
|
||||
@ -91,12 +101,5 @@ UbuntuServerStackFixture = _ubuntu.UbuntuServerStackFixture
|
||||
UbuntuMinimalServerStackFixture = _ubuntu.UbuntuMinimalServerStackFixture
|
||||
UbuntuExternalServerStackFixture = _ubuntu.UbuntuExternalServerStackFixture
|
||||
|
||||
OctaviaLoadbalancerStackFixture = _octavia.OctaviaLoadbalancerStackFixture
|
||||
OctaviaListenerStackFixture = _octavia.OctaviaListenerStackFixture
|
||||
OctaviaPoolStackFixture = _octavia.OctaviaPoolStackFixture
|
||||
OctaviaMemberServerStackFixture = _octavia.OctaviaMemberServerStackFixture
|
||||
OctaviaServerStackFixture = _octavia.OctaviaServerStackFixture
|
||||
OctaviaClientServerStackFixture = _octavia.OctaviaClientServerStackFixture
|
||||
OctaviaOtherServerStackFixture = _octavia.OctaviaOtherServerStackFixture
|
||||
OctaviaOtherMemberServerStackFixture = (
|
||||
_octavia.OctaviaOtherMemberServerStackFixture)
|
||||
VlanNetworkStackFixture = _vlan.VlanNetworkStackFixture
|
||||
VlanProxyServerStackFixture = _vlan.VlanProxyServerStackFixture
|
||||
|
@ -71,27 +71,3 @@ class Centos7ServerStackFixture(CentosServerStackFixture):
|
||||
|
||||
#: Glance image used to create a Nova server instance
|
||||
image_fixture = tobiko.required_setup_fixture(Centos7ImageFixture)
|
||||
|
||||
|
||||
class CentosTrunkServerStackFixture(
|
||||
CentosServerStackFixture, _nova.TrunkServerStackFixture):
|
||||
|
||||
interface = 'eth0'
|
||||
|
||||
@property
|
||||
def user_data(self):
|
||||
return ("#cloud-config\n"
|
||||
"write_files:\n"
|
||||
"- path: {path}/ifcfg-{interface}.{index}\n"
|
||||
" owner: \"root\"\n"
|
||||
" permissions: \"777\"\n"
|
||||
" content: |\n"
|
||||
" DEVICE=\"{interface}.{index}\"\n"
|
||||
" BOOTPROTO=\"none\"\n"
|
||||
" ONBOOT=\"yes\"\n"
|
||||
" VLAN=\"yes\"\n"
|
||||
" PERSISTENT_DHCLIENT=\"no\"\n"
|
||||
"runcmd:\n"
|
||||
"- [ sh, -c , \"systemctl restart NetworkManager\" ]".format(
|
||||
path='/etc/sysconfig/network-scripts/',
|
||||
interface=self.interface, index=self.trunk_subport_vlan))
|
||||
|
@ -13,7 +13,6 @@
|
||||
# under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import tobiko
|
||||
from tobiko import config
|
||||
from tobiko.openstack import glance
|
||||
from tobiko.openstack.stacks import _nova
|
||||
|
@ -218,6 +218,8 @@ class ServerStackFixture(heat.HeatStackFixture, abc.ABC):
|
||||
def fixed_ipv6(self):
|
||||
return self.find_fixed_ip(ip_version=6)
|
||||
|
||||
has_vlan = False
|
||||
|
||||
#: Schedule on different host that this Nova server instance ID
|
||||
different_host = None
|
||||
|
||||
@ -355,6 +357,12 @@ class ServerStackFixture(heat.HeatStackFixture, abc.ABC):
|
||||
requirements['cores'] += (self.flavor_stack.vcpus or 1)
|
||||
return requirements
|
||||
|
||||
@property
|
||||
def neutron_required_quota_set(self) -> typing.Dict[str, int]:
|
||||
requirements = super().neutron_required_quota_set
|
||||
requirements['port'] += 1
|
||||
return requirements
|
||||
|
||||
def assert_is_reachable(self):
|
||||
ping.assert_reachable_hosts([self.ip_address])
|
||||
|
||||
@ -535,11 +543,3 @@ class AntiAffinityServerGroupStackFixture(tobiko.SharedFixture):
|
||||
@property
|
||||
def scheduler_group(self):
|
||||
return self.server_group_stack.anti_affinity_server_group_id
|
||||
|
||||
|
||||
@neutron.skip_if_missing_networking_extensions('trunk')
|
||||
class TrunkServerStackFixture(CloudInitServerStackFixture):
|
||||
has_trunk = True
|
||||
segmentation_id = CONF.tobiko.neutron.trunk_subport_segmentation_id
|
||||
segmentation_type = CONF.tobiko.neutron.trunk_subport_segmentation_type
|
||||
trunk_subport_cidr = CONF.tobiko.neutron.trunk_subport_subnet_cidr
|
||||
|
@ -86,8 +86,3 @@ class RedHatServerStackFixture(_centos.CentosServerStackFixture):
|
||||
|
||||
#: Flavor used to create a Nova server instance
|
||||
flavor_stack = tobiko.required_setup_fixture(RedHatFlavorStackFixture)
|
||||
|
||||
|
||||
class RedHatTrunkServerStackFixture(
|
||||
RedHatServerStackFixture, _centos.CentosTrunkServerStackFixture):
|
||||
pass
|
||||
|
@ -15,10 +15,13 @@ from __future__ import absolute_import
|
||||
|
||||
import typing
|
||||
|
||||
import yaml
|
||||
|
||||
import tobiko
|
||||
from tobiko import config
|
||||
from tobiko.openstack import glance
|
||||
from tobiko.openstack.stacks import _nova
|
||||
from tobiko.openstack.stacks import _vlan
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
@ -71,6 +74,7 @@ class UbuntuImageFixture(UbuntuMinimalImageFixture,
|
||||
- ping
|
||||
- ncat
|
||||
- nginx
|
||||
- vlan
|
||||
|
||||
The image will also have below running services:
|
||||
- nginx HTTP server listening on TCP port 80
|
||||
@ -86,8 +90,10 @@ class UbuntuImageFixture(UbuntuMinimalImageFixture,
|
||||
def install_packages(self) -> typing.List[str]:
|
||||
return super().install_packages + ['iperf3',
|
||||
'iputils-ping',
|
||||
'nano',
|
||||
'ncat',
|
||||
'nginx']
|
||||
'nginx',
|
||||
'vlan']
|
||||
|
||||
# port of running HTTP server
|
||||
http_port = 80
|
||||
@ -103,8 +109,44 @@ class UbuntuImageFixture(UbuntuMinimalImageFixture,
|
||||
'> /etc/systemd/system/iperf3-server@.service')
|
||||
run_commands.append(
|
||||
f"systemctl enable iperf3-server@{self.iperf3_port}")
|
||||
run_commands.append('echo "8021q" >> /etc/modules')
|
||||
return run_commands
|
||||
|
||||
@property
|
||||
def ethernet_device(self) -> str:
|
||||
return 'ens3'
|
||||
|
||||
@property
|
||||
def vlan_id(self) -> int:
|
||||
return tobiko.tobiko_config().neutron.vlan_id
|
||||
|
||||
@property
|
||||
def vlan_device(self) -> str:
|
||||
return f'vlan{self.vlan_id}'
|
||||
|
||||
@property
|
||||
def vlan_config(self) -> typing.Dict[str, typing.Any]:
|
||||
return {
|
||||
'network': {
|
||||
'version': 2,
|
||||
'vlans': {
|
||||
self.vlan_device: {
|
||||
'link': self.ethernet_device,
|
||||
'dhcp4': True,
|
||||
'dhcp6': True,
|
||||
'id': self.vlan_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@property
|
||||
def write_files(self) -> typing.Dict[str, str]:
|
||||
write_files = super().write_files
|
||||
write_files['/etc/netplan/75-tobiko-vlan.yaml'] = yaml.dump(
|
||||
self.vlan_config)
|
||||
return write_files
|
||||
|
||||
|
||||
class UbuntuFlavorStackFixture(_nova.FlavorStackFixture):
|
||||
ram = 128
|
||||
@ -120,7 +162,8 @@ class UbuntuMinimalServerStackFixture(_nova.CloudInitServerStackFixture):
|
||||
flavor_stack = tobiko.required_setup_fixture(UbuntuFlavorStackFixture)
|
||||
|
||||
|
||||
class UbuntuServerStackFixture(UbuntuMinimalServerStackFixture):
|
||||
class UbuntuServerStackFixture(UbuntuMinimalServerStackFixture,
|
||||
_vlan.VlanServerStackFixture):
|
||||
"""Ubuntu server running an HTTP server
|
||||
|
||||
The server has additional commands compared to the minimal one:
|
||||
@ -140,6 +183,14 @@ class UbuntuServerStackFixture(UbuntuMinimalServerStackFixture):
|
||||
def iperf3_port(self) -> int:
|
||||
return self.image_fixture.iperf3_port
|
||||
|
||||
@property
|
||||
def vlan_id(self) -> int:
|
||||
return self.image_fixture.vlan_id
|
||||
|
||||
@property
|
||||
def vlan_device(self) -> str:
|
||||
return self.image_fixture.vlan_device
|
||||
|
||||
|
||||
class UbuntuExternalServerStackFixture(UbuntuServerStackFixture,
|
||||
_nova.ExternalServerStackFixture):
|
||||
|
108
tobiko/openstack/stacks/_vlan.py
Normal file
108
tobiko/openstack/stacks/_vlan.py
Normal file
@ -0,0 +1,108 @@
|
||||
# Copyright (c) 2021 Red Hat, Inc.
|
||||
#
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 __future__ import absolute_import
|
||||
|
||||
import abc
|
||||
import typing
|
||||
|
||||
import netaddr
|
||||
|
||||
import tobiko
|
||||
from tobiko import config
|
||||
from tobiko.shell import ping
|
||||
from tobiko.shell import ssh
|
||||
from tobiko.openstack import neutron
|
||||
from tobiko.openstack.stacks import _cirros
|
||||
from tobiko.openstack.stacks import _neutron
|
||||
from tobiko.openstack.stacks import _nova
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class VlanNetworkStackFixture(_neutron.NetworkStackFixture):
|
||||
pass
|
||||
|
||||
|
||||
class VlanProxyServerStackFixture(_cirros.CirrosServerStackFixture):
|
||||
network_stack = tobiko.required_fixture(VlanNetworkStackFixture)
|
||||
|
||||
|
||||
@neutron.skip_if_missing_networking_extensions('trunk')
|
||||
class VlanServerStackFixture(_nova.ServerStackFixture, abc.ABC):
|
||||
|
||||
has_vlan = True
|
||||
|
||||
#: stack with the newtwork where the trunk support is attached
|
||||
vlan_network_stack = tobiko.required_fixture(VlanNetworkStackFixture)
|
||||
|
||||
@property
|
||||
def vlan_id(self) -> int:
|
||||
return CONF.tobiko.neutron.vlan_id
|
||||
|
||||
@property
|
||||
def vlan_network(self) -> str:
|
||||
return self.vlan_network_stack.network_id
|
||||
|
||||
@property
|
||||
def vlan_fixed_ipv4(self):
|
||||
return self.find_vlan_fixed_ip(ip_version=4)
|
||||
|
||||
@property
|
||||
def vlan_fixed_ipv6(self):
|
||||
return self.find_vlan_fixed_ip(ip_version=6)
|
||||
|
||||
def find_vlan_fixed_ip(self,
|
||||
ip_version: int = None,
|
||||
unique=False) -> netaddr.IPAddress:
|
||||
vlan_ips = self.list_vlan_fixed_ips(ip_version=ip_version)
|
||||
if unique:
|
||||
return vlan_ips.unique
|
||||
else:
|
||||
return vlan_ips.first
|
||||
|
||||
def list_vlan_fixed_ips(self,
|
||||
ip_version: int = None) \
|
||||
-> tobiko.Selection[netaddr.IPAddress]:
|
||||
fixed_ips: tobiko.Selection[netaddr.IPAddress] = tobiko.Selection(
|
||||
netaddr.IPAddress(fixed_ip['ip_address'])
|
||||
for fixed_ip in self.vlan_fixed_ips)
|
||||
if ip_version is not None:
|
||||
fixed_ips = fixed_ips.with_attributes(version=ip_version)
|
||||
return fixed_ips
|
||||
|
||||
@property
|
||||
def vlan_ssh_proxy_client(self) -> ssh.SSHClientType:
|
||||
return tobiko.setup_fixture(VlanProxyServerStackFixture).ssh_client
|
||||
|
||||
def assert_vlan_is_reachable(self,
|
||||
ip_version: int = None):
|
||||
fixed_ips = self.list_vlan_fixed_ips(ip_version=ip_version)
|
||||
ping.assert_reachable_hosts(fixed_ips,
|
||||
ssh_client=self.vlan_ssh_proxy_client)
|
||||
|
||||
def assert_vlan_is_unreachable(self,
|
||||
ip_version: int = None):
|
||||
fixed_ips = self.list_vlan_fixed_ips(ip_version=ip_version)
|
||||
ping.assert_unreachable_hosts(fixed_ips,
|
||||
ssh_client=self.vlan_ssh_proxy_client)
|
||||
|
||||
@property
|
||||
def neutron_required_quota_set(self) -> typing.Dict[str, int]:
|
||||
requirements = super().neutron_required_quota_set
|
||||
requirements['port'] += 1
|
||||
requirements['trunk'] += 1
|
||||
return requirements
|
@ -72,23 +72,19 @@ parameters:
|
||||
default: ''
|
||||
description: Optional user_data to be passed to the server
|
||||
|
||||
has_trunk:
|
||||
has_vlan:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
trunk_subport_cidr:
|
||||
vlan_network:
|
||||
type: string
|
||||
description: Network ID where vlan trunk support is attached
|
||||
default: ''
|
||||
|
||||
segmentation_type:
|
||||
type: string
|
||||
description: Segmentation type for trunk subport
|
||||
default: ''
|
||||
|
||||
segmentation_id:
|
||||
vlan_id:
|
||||
type: number
|
||||
description: Segmentation ID for trunk subport
|
||||
default: 0
|
||||
description: Segmentation ID for vlan trunk subport
|
||||
default: 101
|
||||
|
||||
conditions:
|
||||
|
||||
@ -98,8 +94,8 @@ conditions:
|
||||
use_extra_dhcp_opts:
|
||||
get_param: use_extra_dhcp_opts
|
||||
|
||||
has_trunk:
|
||||
get_param: has_trunk
|
||||
has_vlan:
|
||||
get_param: has_vlan
|
||||
|
||||
resources:
|
||||
|
||||
@ -154,34 +150,26 @@ resources:
|
||||
floating_network: {get_param: floating_network}
|
||||
port_id: {get_resource: port}
|
||||
|
||||
trunk_subport_network:
|
||||
type: OS::Neutron::Net
|
||||
condition: has_trunk
|
||||
|
||||
trunk_subport_subnet:
|
||||
type: OS::Neutron::Subnet
|
||||
condition: has_trunk
|
||||
properties:
|
||||
network: {get_resource: trunk_subport_network}
|
||||
cidr: {get_param: trunk_subport_cidr}
|
||||
|
||||
trunk_subport:
|
||||
vlan_port:
|
||||
type: OS::Neutron::Port
|
||||
condition: has_trunk
|
||||
description: Vlan trunk subport
|
||||
condition: has_vlan
|
||||
properties:
|
||||
network: {get_resource: trunk_subport_network}
|
||||
network: {get_param: vlan_network}
|
||||
mac_address: {get_attr: [port, mac_address]}
|
||||
port_security_enabled: {get_param: port_security_enabled}
|
||||
security_groups: {get_param: security_groups}
|
||||
|
||||
trunk:
|
||||
type: OS::Neutron::Trunk
|
||||
description: Trunk port connected to the server
|
||||
condition: has_trunk
|
||||
description: Trunk connected to the server port
|
||||
condition: has_vlan
|
||||
properties:
|
||||
port: {get_resource: port}
|
||||
sub_ports:
|
||||
- {port: {get_resource: trunk_subport},
|
||||
segmentation_type: {get_param: segmentation_type},
|
||||
segmentation_id: {get_param: segmentation_id}}
|
||||
- port: {get_resource: vlan_port}
|
||||
segmentation_type: vlan
|
||||
segmentation_id: {get_param: vlan_id}
|
||||
|
||||
outputs:
|
||||
|
||||
@ -208,3 +196,12 @@ outputs:
|
||||
|
||||
port_id:
|
||||
value: {get_resource: port}
|
||||
|
||||
vlan_port_id:
|
||||
value: {get_resource: vlan_port}
|
||||
condition: has_vlan
|
||||
|
||||
vlan_fixed_ips:
|
||||
description: fixed IP addresses of server vlan port
|
||||
value: {get_attr: [vlan_port, fixed_ips]}
|
||||
condition: has_vlan
|
||||
|
@ -76,6 +76,22 @@ def list_ip_addresses(ip_version: int = None,
|
||||
return ips
|
||||
|
||||
|
||||
def find_ip_address(ip_version: int = None,
|
||||
device: str = None,
|
||||
scope: str = None,
|
||||
unique: bool = False,
|
||||
**execute_params) -> \
|
||||
netaddr.IPAddress:
|
||||
ips = list_ip_addresses(ip_version=ip_version,
|
||||
device=device,
|
||||
scope=scope,
|
||||
**execute_params)
|
||||
if unique:
|
||||
return ips.unique
|
||||
else:
|
||||
return ips.first
|
||||
|
||||
|
||||
def parse_ip_address(text: str) -> typing.Tuple[netaddr.IPAddress, int]:
|
||||
if '/' in text:
|
||||
# Remove netmask prefix length
|
||||
|
68
tobiko/tests/functional/openstack/stacks/test_vlan.py
Normal file
68
tobiko/tests/functional/openstack/stacks/test_vlan.py
Normal file
@ -0,0 +1,68 @@
|
||||
# Copyright (c) 2019 Red Hat, Inc.
|
||||
#
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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 __future__ import absolute_import
|
||||
|
||||
import testtools
|
||||
|
||||
import tobiko
|
||||
from tobiko.openstack import stacks
|
||||
from tobiko.shell import ip
|
||||
from tobiko.tests.functional.openstack.stacks import test_cirros
|
||||
|
||||
|
||||
class VlanProxyServerStackTest(test_cirros.CirrosServerStackTest):
|
||||
|
||||
#: Stack of resources with a server attached to a floating IP
|
||||
stack = tobiko.required_fixture(stacks.VlanProxyServerStackFixture)
|
||||
|
||||
|
||||
class UbuntuVlanServerTest(testtools.TestCase):
|
||||
|
||||
#: Stack of resources with a server attached to a floating IP
|
||||
stack = tobiko.required_fixture(stacks.UbuntuServerStackFixture)
|
||||
|
||||
def test_vlan_ipv4_fixed_ip(self):
|
||||
self._test_vlan_fixed_ip(ip_version=4)
|
||||
|
||||
def test_vlan_ipv6_fixed_ip(self):
|
||||
self._test_vlan_fixed_ip(ip_version=6)
|
||||
|
||||
def _test_vlan_fixed_ip(self, ip_version: int):
|
||||
expected_ip = self.get_vlan_fixed_ip(ip_version=ip_version)
|
||||
for attempt in tobiko.retry(timeout=600.,
|
||||
interval=10.):
|
||||
try:
|
||||
actual_ip = ip.find_ip_address(
|
||||
device=self.stack.vlan_device,
|
||||
ip_version=ip_version,
|
||||
ssh_client=self.stack.ssh_client,
|
||||
scope='global',
|
||||
unique=True)
|
||||
except tobiko.ObjectNotFound:
|
||||
attempt.check_limits()
|
||||
else:
|
||||
break
|
||||
else:
|
||||
raise RuntimeError('Broken retry loop')
|
||||
self.assertEqual(expected_ip, actual_ip)
|
||||
self.stack.assert_vlan_is_reachable(ip_version=ip_version)
|
||||
|
||||
def get_vlan_fixed_ip(self, ip_version: int):
|
||||
try:
|
||||
return self.stack.find_vlan_fixed_ip(ip_version=ip_version)
|
||||
except tobiko.ObjectNotFound:
|
||||
self.skipTest(f"Server {self.stack.server_id} has any "
|
||||
f"IPv{ip_version} address on VLAN device.")
|
@ -20,7 +20,6 @@ import testtools
|
||||
|
||||
import tobiko
|
||||
from tobiko import config
|
||||
from tobiko.openstack import nova
|
||||
from tobiko.openstack import stacks
|
||||
|
||||
|
||||
@ -28,31 +27,33 @@ CONF = config.CONF
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class CentosRebootTrunkServerStackFixture(
|
||||
stacks.CentosTrunkServerStackFixture):
|
||||
class RebootTrunkServerStackFixture(stacks.UbuntuServerStackFixture):
|
||||
pass
|
||||
|
||||
|
||||
class CentosTrunkTest(testtools.TestCase):
|
||||
class TrunkTest(testtools.TestCase):
|
||||
"""Tests trunk functionality"""
|
||||
|
||||
stack = tobiko.required_fixture(CentosRebootTrunkServerStackFixture)
|
||||
stack = tobiko.required_fixture(RebootTrunkServerStackFixture)
|
||||
|
||||
vlan_proxy_stack = tobiko.required_fixture(
|
||||
stacks.VlanProxyServerStackFixture)
|
||||
|
||||
@property
|
||||
def vlan_proxy_ssh_client(self):
|
||||
return self.vlan_proxy_stack.ssh_client
|
||||
|
||||
def test_activate_server(self):
|
||||
self.stack.ensure_server_status('ACTIVE')
|
||||
self.stack.assert_is_reachable()
|
||||
self.stack.assert_vlan_is_reachable(ip_version=4)
|
||||
|
||||
def test_shutoff_server(self):
|
||||
self.stack.ensure_server_status('SHUTOFF')
|
||||
self.stack.assert_is_unreachable()
|
||||
self.stack.assert_vlan_is_unreachable(ip_version=4)
|
||||
|
||||
@pytest.mark.ovn_migration
|
||||
def test_after_server_reboot(self):
|
||||
self.shutoff_server()
|
||||
self.activate_server()
|
||||
|
||||
def test_after_server_shutoff(self):
|
||||
self.activate_server()
|
||||
self.shutoff_server()
|
||||
|
||||
def activate_server(self) -> nova.NovaServer:
|
||||
server = self.stack.ensure_server_status('ACTIVE')
|
||||
self.stack.assert_is_reachable()
|
||||
return server
|
||||
|
||||
def shutoff_server(self) -> nova.NovaServer:
|
||||
server = self.stack.ensure_server_status('SHUTOFF')
|
||||
self.stack.assert_is_unreachable()
|
||||
return server
|
||||
def test_shutoff_then_activate_server(self):
|
||||
self.test_shutoff_server()
|
||||
self.test_activate_server()
|
||||
|
Loading…
Reference in New Issue
Block a user