@@ -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')
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user