Merge "Add Active standby support"

This commit is contained in:
Zuul 2021-10-30 19:33:24 +00:00 committed by Gerrit Code Review
commit a13d6d7140
3 changed files with 54 additions and 28 deletions

View File

@ -29,8 +29,8 @@ get_member = _client.get_member
list_members = _client.list_members
list_amphorae = _client.list_amphorae
get_amphora_vm = _client.get_amphora_vm
list_amphoras_compute_nodes = _client.list_amphoras_compute_nodes
get_amphoras_compute_nodes = _client.get_amphoras_compute_nodes
get_amphora_compute_node = _client.get_amphora_compute_node
get_master_amphora = _client.get_master_amphora
# Waiters
wait_for_status = _waiters.wait_for_status

View File

@ -21,6 +21,7 @@ import tobiko
from tobiko.openstack import _client
from tobiko.openstack import keystone
from tobiko.openstack import nova
from tobiko.openstack.octavia import _validators
from tobiko.openstack import topology
@ -91,31 +92,59 @@ def list_amphorae(loadbalancer_id: str, client=None):
loadbalancer_id=loadbalancer_id)['amphorae']
def list_amphoras_compute_nodes(load_balancer_id: str, client=None):
"""List the compute nodes which host the LB amphoras
def get_amphora_compute_node(loadbalancer_id: str,
lb_port: str,
lb_protocol: str,
ip_address: str) -> (
topology.OpenStackTopologyNode):
"""Gets the compute node which hosts the LB amphora
This function finds the Overcloud compute nodes which
host the amphoras and returns a list of their instances.
This function finds the Overcloud compute node which
hosts the amphora. In case there are more than 1 amphora
(e.g. if the LB's topology is Active/standby), so the compute node which
hosts the master amphora will be returned.
:param loadbalancer_id (str): The loadbalancer ID.
:return (TripleoTopologyNode): The compute node which hosts the Amphora
"""
hostnames = set()
for amphora in list_amphorae(loadbalancer_id=load_balancer_id,
client=client):
server = nova.get_server(amphora['compute_id'])
hostnames.add(getattr(server, 'OS-EXT-SRV-ATTR:hypervisor_hostname'))
return list(hostnames)
amphorae = list_amphorae(loadbalancer_id)
if len(amphorae) > 1: # For a high available LB
amphora = get_master_amphora(amphorae, ip_address, lb_port,
lb_protocol)
else:
amphora = amphorae[0]
server = nova.get_server(amphora['compute_id'])
hostname = getattr(server, 'OS-EXT-SRV-ATTR:hypervisor_hostname')
return topology.get_openstack_node(hostname=hostname)
def get_amphoras_compute_nodes(load_balancer_id: str, client=None):
"""Gets the hostnames/compute nodes which host the LB amphoras
def get_master_amphora(amphorae, ip_address, lb_port, lb_protocol,
client=None):
"""Gets the master Amphora in a High Available LB
(a loadbalancer which uses the Active/standby topology)
This function finds the Overcloud compute nodes which
host the amphoras and returns a list of their instances.
:param loadbalancer_id (str): The loadbalancer ID.
:return amphora (str): JSON of the Master Amphora.
"""
hostnames = list_amphoras_compute_nodes(load_balancer_id=load_balancer_id,
client=client)
return topology.list_openstack_nodes(hostnames=hostnames)
# Generate traffic on the LB so we can identify the current Master
_validators.check_members_balanced(
ip_address=ip_address,
protocol=lb_protocol,
port=lb_port,
members_count=1)
# The amphora which has total_connections > 0 is the master.
for amphora in amphorae:
amphora_stats = octavia_client(client).amphora_stats_show(
amphora['id'])
for listener in list(amphora_stats.values())[0]:
if listener['total_connections'] > 0:
return amphora
raise ValueError("Amphora wasn't found! Invalid parameters were sent!")
def get_amphora_vm(

View File

@ -58,12 +58,6 @@ class OctaviaBasicFaultTest(testtools.TestCase):
# pylint: disable=no-member
super(OctaviaBasicFaultTest, self).setUp()
# Skipping the test in case the topology is Active/Standby
if len(octavia.list_amphorae(
self.loadbalancer_stack.loadbalancer_id)) > 1:
tobiko.skip_test('Fault tests to Active/Standby topology were not'
' implemented yet')
# Wait for Octavia objects to be active
LOG.info(f'Waiting for {self.member1_stack.stack_name} and '
f'{self.member2_stack.stack_name} to be created...')
@ -81,13 +75,16 @@ class OctaviaBasicFaultTest(testtools.TestCase):
port=self.listener_stack.lb_port)
def test_reboot_amphora_compute_node(self):
amphora_compute_hosts = octavia.get_amphoras_compute_nodes(
self.loadbalancer_stack.loadbalancer_id)
amphora_compute_host = octavia.get_amphora_compute_node(
loadbalancer_id=self.loadbalancer_stack.loadbalancer_id,
lb_port=self.listener_stack.lb_port,
lb_protocol=self.listener_stack.lb_protocol,
ip_address=self.loadbalancer_stack.floating_ip_address)
LOG.debug('Rebooting compute node...')
# Reboot Amphora's compute node will initiate a failover
amphora_compute_hosts[0].reboot_overcloud_node()
amphora_compute_host.reboot_overcloud_node()
LOG.debug('Compute node has been rebooted')