From c1914078fc2d75ca18e875cdc55a3ee49a9bcd9c Mon Sep 17 00:00:00 2001 From: Jens Harbott Date: Mon, 19 Feb 2018 10:53:04 +0100 Subject: [PATCH] Fix failure when adding a speaker to an agent When get_bgp_speaker_with_advertised_routes() collects the data for BGP peers, it needs to include the auth_type field, otherwise adding the speaker to an agent will fail. (cherry picked from commit fd497a491afec89d4a15cf061b5d5610fb7ad6d2) Change-Id: I668397be4a531ba5c0628eb23df9a84d0de8c28c Closes-Bug: 1750121 --- neutron_dynamic_routing/db/bgp_db.py | 2 +- .../services/bgp/agent/bgp_dragent.py | 6 ++-- .../tests/tempest/bgp_client.py | 13 ++++++++ .../tempest/scenario/basic/test_basic.py | 32 +++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/neutron_dynamic_routing/db/bgp_db.py b/neutron_dynamic_routing/db/bgp_db.py index 899d0ddb..11d201af 100644 --- a/neutron_dynamic_routing/db/bgp_db.py +++ b/neutron_dynamic_routing/db/bgp_db.py @@ -148,7 +148,7 @@ class BgpDbMixin(common_db.CommonDbMixin): def get_bgp_speaker_with_advertised_routes(self, context, bgp_speaker_id): bgp_speaker_attrs = ['id', 'local_as', 'tenant_id'] - bgp_peer_attrs = ['peer_ip', 'remote_as', 'password'] + bgp_peer_attrs = ['peer_ip', 'remote_as', 'auth_type', 'password'] with db_api.context_manager.reader.using(context): bgp_speaker = self.get_bgp_speaker(context, bgp_speaker_id, fields=bgp_speaker_attrs) diff --git a/neutron_dynamic_routing/services/bgp/agent/bgp_dragent.py b/neutron_dynamic_routing/services/bgp/agent/bgp_dragent.py index 838fda06..5d524479 100644 --- a/neutron_dynamic_routing/services/bgp/agent/bgp_dragent.py +++ b/neutron_dynamic_routing/services/bgp/agent/bgp_dragent.py @@ -400,10 +400,12 @@ class BgpDrAgent(manager.Manager): LOG.debug('Calling driver interface for adding BGP peer %(peer_ip)s ' 'remote_as=%(remote_as)s to BGP Speaker running for ' - 'local_as=%(local_as)d', + 'local_as=%(local_as)d ' + 'auth_type=%(auth_type)s', {'peer_ip': bgp_peer['peer_ip'], 'remote_as': bgp_peer['remote_as'], - 'local_as': bgp_speaker_as}) + 'local_as': bgp_speaker_as, + 'auth_type': bgp_peer['auth_type']}) try: self.dr_driver_cls.add_bgp_peer(bgp_speaker_as, bgp_peer['peer_ip'], diff --git a/neutron_dynamic_routing/tests/tempest/bgp_client.py b/neutron_dynamic_routing/tests/tempest/bgp_client.py index 99a00a5e..64ba8048 100644 --- a/neutron_dynamic_routing/tests/tempest/bgp_client.py +++ b/neutron_dynamic_routing/tests/tempest/bgp_client.py @@ -118,6 +118,13 @@ class BgpSpeakerClientJSON(rest_client.RestClient): self.expected_success(200, resp.status) return rest_client.ResponseBody(resp, body) + def list_dragents_for_bgp_speaker(self, bgp_speaker_id): + uri = 'v2.0/bgp-speakers/%s/bgp-dragents' % bgp_speaker_id + resp, body = self.get(uri) + self.expected_success(200, resp.status) + body = jsonutils.loads(body) + return rest_client.ResponseBody(resp, body) + def add_bgp_speaker_to_dragent(self, agent_id, bgp_speaker_id): uri = 'v2.0/agents/%s/bgp-drinstances' % agent_id update_body = {"bgp_speaker_id": bgp_speaker_id} @@ -126,3 +133,9 @@ class BgpSpeakerClientJSON(rest_client.RestClient): self.expected_success(201, resp.status) body = jsonutils.loads(body) return rest_client.ResponseBody(resp, body) + + def remove_bgp_speaker_from_dragent(self, agent_id, bgp_speaker_id): + uri = 'v2.0/agents/%s/bgp-drinstances/%s' % (agent_id, bgp_speaker_id) + resp, body = self.delete(uri) + self.expected_success(204, resp.status) + return rest_client.ResponseBody(resp, body) diff --git a/neutron_dynamic_routing/tests/tempest/scenario/basic/test_basic.py b/neutron_dynamic_routing/tests/tempest/scenario/basic/test_basic.py index 92f1705c..9fbc838e 100644 --- a/neutron_dynamic_routing/tests/tempest/scenario/basic/test_basic.py +++ b/neutron_dynamic_routing/tests/tempest/scenario/basic/test_basic.py @@ -74,3 +74,35 @@ class BgpSpeakerBasicTest(base.BgpSpeakerBasicTestJSONBase): self.check_remote_as_state(self.dr, self.r_ass[0], ctn_base.BGP_FSM_ACTIVE, init_state=ctn_base.BGP_FSM_ESTABLISHED) + + @decorators.idempotent_id('aa6c565c-ded3-413b-8dc9-3928b3b0e38f') + def test_remove_add_speaker_agent(self): + self.bgp_peer_args[0]['peer_ip'] = self.r_as_ip[0].split('/')[0] + num, subnet = self.tnet_gen.next() + mask = '/' + str(self.TPool.prefixlen) + TNet = s_base.Net(name='', net=subnet, mask=self.TPool.prefixlen, + cidr=subnet + mask, router=None) + TSubNet = s_base.SubNet(name='', cidr=TNet.cidr, mask=TNet.mask) + MyRouter = s_base.Router(name='my-router' + str(num), gw='', + dist=False) + ext_net_id = self.create_bgp_network( + 4, self.MyScope, + self.PNet, self.PPool, self.PSubNet, + self.TPool, [[TNet, TSubNet, MyRouter]]) + speaker_id, peers_ids = self.create_and_add_peers_to_speaker( + ext_net_id, + self.bgp_speaker_args, + [self.bgp_peer_args[0]]) + self.check_remote_as_state(self.dr, self.r_ass[0], + ctn_base.BGP_FSM_ESTABLISHED) + agent_list = self.bgp_client.list_dragents_for_bgp_speaker( + speaker_id)['agents'] + self.assertEqual(1, len(agent_list)) + agent_id = agent_list[0]['id'] + self.bgp_client.remove_bgp_speaker_from_dragent(agent_id, speaker_id) + self.check_remote_as_state(self.dr, self.r_ass[0], + ctn_base.BGP_FSM_ACTIVE, + init_state=ctn_base.BGP_FSM_ESTABLISHED) + self.bgp_client.add_bgp_speaker_to_dragent(agent_id, speaker_id) + self.check_remote_as_state(self.dr, self.r_ass[0], + ctn_base.BGP_FSM_ESTABLISHED)