Remove and add BGP speaker from dragent

Workaround for LP: #1784083
This commit is contained in:
Frode Nordahl
2018-08-03 16:18:37 +02:00
parent 252a008d23
commit 820ed8083d
4 changed files with 151 additions and 0 deletions

View File

@@ -48,6 +48,19 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
self.networks = {
"networks": [self.network["network"]]}
self.agents = {
"agents": [
{
'id': '7f3afd5b-ff6d-4df3-be0e-3d9651e71873',
'binary': 'neutron-bgp-dragent',
}]}
self.bgp_speakers = {
"bgp_speakers": [
{
'id': '07a0798d-c29c-4a92-8fcb-c1ec56934729',
}]}
self.neutronclient = mock.MagicMock()
self.neutronclient.list_ports.return_value = self.ports
self.neutronclient.create_port.return_value = self.port
@@ -63,6 +76,10 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
self.neutronclient.list_networks.return_value = self.networks
self.neutronclient.create_network.return_value = self.network
self.neutronclient.list_agents.return_value = self.agents
self.neutronclient.list_bgp_speaker_on_dragent.return_value = \
self.bgp_speakers
def test_create_port(self):
self.patch_object(openstack_utils, "get_net_uuid")
self.get_net_uuid.return_value = self.net_uuid
@@ -595,3 +612,36 @@ class TestOpenStackUtils(ut_utils.BaseTestCase):
password='',
pkey='akey',
username='bob')
def test_neutron_agent_appears(self):
self.assertEqual(
openstack_utils.neutron_agent_appears(self.neutronclient,
'neutron-bgp-dragent'),
self.agents)
def test_neutron_agent_appears_not(self):
_neutronclient = copy.deepcopy(self.neutronclient)
_neutronclient.list_agents.return_value = {'agents': []}
openstack_utils.neutron_agent_appears.retry.stop = \
tenacity.stop_after_attempt(1)
with self.assertRaises(exceptions.NeutronAgentMissing):
openstack_utils.neutron_agent_appears(_neutronclient,
'non-existent')
def test_neutron_bgp_speaker_appears_on_agent(self):
openstack_utils.neutron_bgp_speaker_appears_on_agent.retry.stop = \
tenacity.stop_after_attempt(1)
self.assertEqual(
openstack_utils.neutron_bgp_speaker_appears_on_agent(
self.neutronclient, 'FAKE_AGENT_ID'),
self.bgp_speakers)
def test_neutron_bgp_speaker_appears_not_on_agent(self):
_neutronclient = copy.deepcopy(self.neutronclient)
_neutronclient.list_bgp_speaker_on_dragent.return_value = {
'bgp_speakers': []}
openstack_utils.neutron_bgp_speaker_appears_on_agent.retry.stop = \
tenacity.stop_after_attempt(1)
with self.assertRaises(exceptions.NeutronBGPSpeakerMissing):
openstack_utils.neutron_bgp_speaker_appears_on_agent(
_neutronclient, 'FAKE_AGENT_ID')

View File

@@ -4,6 +4,7 @@
import argparse
import logging
import sys
import neutronclient
from zaza.utilities import (
cli as cli_utils,
openstack as openstack_utils,
@@ -83,6 +84,40 @@ def setup_bgp_speaker(peer_application_name, keystone_session=None):
"Advertised floating IP: {}".format(
floating_ip["floating_ip_address"]))
# NOTE(fnordahl): As a workaround for LP: #1784083 remove BGP speaker from
# dragent and add it back.
logging.info(
"Waiting for Neutron agent 'neutron-bgp-dragent' to appear...")
keystone_session = openstack_utils.get_overcloud_keystone_session()
neutron_client = openstack_utils.get_neutron_session_client(
keystone_session)
agents = openstack_utils.neutron_agent_appears(neutron_client,
'neutron-bgp-dragent')
agent_id = None
for agent in agents.get('agents', []):
agent_id = agent.get('id', None)
if agent_id is not None:
break
logging.info(
'Waiting for BGP speaker to appear on agent "{}"...'.format(agent_id))
bgp_speakers = openstack_utils.neutron_bgp_speaker_appears_on_agent(
neutron_client, agent_id)
logging.info(
"Removing and adding back bgp-speakers to agent (LP: #1784083)...")
while True:
try:
for bgp_speaker in bgp_speakers.get('bgp_speakers', []):
bgp_speaker_id = bgp_speaker.get('id', None)
logging.info('removing "{}" from "{}"'
''.format(bgp_speaker_id, agent_id))
neutron_client.remove_bgp_speaker_from_dragent(
agent_id, bgp_speaker_id)
except neutronclient.common.exceptions.NotFound as e:
logging.info('Exception: "{}"'.format(e))
break
neutron_client.add_bgp_speaker_to_dragent(
agent_id, {'bgp_speaker_id': bgp_speaker_id})
def run_from_cli():
"""Run BGP Speaker setup from CLI.

View File

@@ -17,3 +17,15 @@ class SSHFailed(Exception):
"""SSH failed."""
pass
class NeutronAgentMissing(Exception):
"""Agent binary does not appear in the Neutron agent list."""
pass
class NeutronBGPSpeakerMissing(Exception):
"""No BGP speaker appeared on agent."""
pass

View File

@@ -1658,3 +1658,57 @@ def ssh_test(username, ip, vm_name, password=None, privkey=None):
return_string,
vm_name))
raise exceptions.SSHFailed()
@tenacity.retry(wait=tenacity.wait_exponential(multiplier=0.01),
reraise=True, stop=tenacity.stop_after_delay(60) |
tenacity.stop_after_attempt(100))
def neutron_agent_appears(neutron_client, binary):
"""Wait for Neutron agent to appear and return agent_id.
:param neutron_client: Neutron client
:type neutron_client: Pointer to Neutron client object
:param binary: Name of agent we want to appear
:type binary: str
:returns: result set from Neutron list_agents call
:rtype: dict
:raises: exceptions.NeutronAgentMissing
"""
result = neutron_client.list_agents(binary=binary)
for agent in result.get('agents', []):
agent_id = agent.get('id', None)
if agent_id:
break
else:
raise exceptions.NeutronAgentMissing(
'no agents for binary "{}"'.format(binary))
return result
@tenacity.retry(wait=tenacity.wait_exponential(multiplier=0.01),
reraise=True,
stop=tenacity.stop_after_delay(60) |
tenacity.stop_after_attempt(100))
def neutron_bgp_speaker_appears_on_agent(neutron_client, agent_id):
"""Wait for Neutron BGP speaker to appear on agent.
:param neutron_client: Neutron client
:type neutron_client: Pointer to Neutron client object
:param agent_id: Neutron agent UUID
:type agent_id: str
:param speaker_id: Neutron BGP speaker UUID
:type speaker_id: str
:returns: result set from Neutron list_bgp_speaker_on_dragent call
:rtype: dict
:raises: exceptions.NeutronBGPSpeakerMissing
"""
result = neutron_client.list_bgp_speaker_on_dragent(agent_id)
for bgp_speaker in result.get('bgp_speakers', []):
bgp_speaker_id = bgp_speaker.get('id', None)
if bgp_speaker_id:
break
else:
raise exceptions.NeutronBGPSpeakerMissing(
'No BGP Speaker appeared on agent "{}"'
''.format(agent_id))
return result