diff --git a/openstack/network/v2/agent.py b/openstack/network/v2/agent.py index ff5f664da..181d10dcf 100644 --- a/openstack/network/v2/agent.py +++ b/openstack/network/v2/agent.py @@ -11,6 +11,7 @@ # under the License. from openstack import exceptions +from openstack.network.v2 import bgp_speaker as _speaker from openstack import resource from openstack import utils @@ -112,12 +113,17 @@ class Agent(resource.Resource): :param session: The session to communicate through. :type session: :class:`~keystoneauth1.adapter.Adapter` + + :returns: A list of BgpSpeakers + :rtype: :class:`~openstack.network.v2.bgp_speaker.BgpSpeaker` """ url = utils.urljoin(self.base_path, self.id, 'bgp-drinstances') resp = session.get(url) exceptions.raise_from_response(resp) self._body.attributes.update(resp.json()) - return resp.json() + speaker_ids = [sp['id'] for sp in resp.json()['bgp_speakers']] + speakers = _speaker.BgpSpeaker.list(session=session) + return [sp for sp in speakers if sp.id in speaker_ids] class NetworkHostingDHCPAgent(Agent): diff --git a/openstack/network/v2/bgp_speaker.py b/openstack/network/v2/bgp_speaker.py index 8c96764a1..1be9f0080 100644 --- a/openstack/network/v2/bgp_speaker.py +++ b/openstack/network/v2/bgp_speaker.py @@ -11,6 +11,7 @@ # under the License. from openstack import exceptions +from openstack.network.v2 import agent as _agent from openstack import resource from openstack import utils @@ -136,14 +137,16 @@ class BgpSpeaker(resource.Resource): :type session: :class:`~keystoneauth1.adapter.Adapter` :returns: The response as a list of dragents hosting a specific BGP Speaker. - + :rtype: :class:`~openstack.network.v2.agent.Agent` :raises: :class:`~openstack.exceptions.SDKException` on error. """ url = utils.urljoin(self.base_path, self.id, 'bgp-dragents') resp = session.get(url) exceptions.raise_from_response(resp) self._body.attributes.update(resp.json()) - return resp.json() + agent_ids = [ag['id'] for ag in resp.json()['agents']] + agents = _agent.Agent.list(session=session) + return [ag for ag in agents if ag.id in agent_ids] def add_bgp_speaker_to_dragent(self, session, bgp_agent_id): """Add BGP Speaker to a Dynamic Routing Agent diff --git a/openstack/tests/unit/network/v2/test_agent.py b/openstack/tests/unit/network/v2/test_agent.py index 80d4b8abe..16ad82bbd 100644 --- a/openstack/tests/unit/network/v2/test_agent.py +++ b/openstack/tests/unit/network/v2/test_agent.py @@ -13,6 +13,7 @@ from unittest import mock from openstack.network.v2 import agent +from openstack.network.v2 import bgp_speaker from openstack.tests.unit import base IDENTIFIER = 'IDENTIFIER' @@ -119,19 +120,28 @@ class TestAgent(base.TestCase): 'agents/IDENTIFIER/l3-routers/', json=body ) - def test_get_bgp_speakers_hosted_by_dragent(self): + @mock.patch.object(bgp_speaker.BgpSpeaker, 'list') + def test_get_bgp_speakers_hosted_by_dragent(self, mock_list): sot = agent.Agent(**EXAMPLE) sess = mock.Mock() response = mock.Mock() - response.body = { - 'bgp_speakers': [{'name': 'bgp_speaker_1', 'ip_version': 4}] + speaker_body = { + 'bgp_speakers': [ + {'name': 'bgp_speaker_1', 'ip_version': 4, 'id': IDENTIFIER} + ] } + response.body = speaker_body + mock_list.return_value = [ + bgp_speaker.BgpSpeaker(**speaker_body['bgp_speakers'][0]) + ] response.json = mock.Mock(return_value=response.body) response.status_code = 200 sess.get = mock.Mock(return_value=response) resp = sot.get_bgp_speakers_hosted_by_dragent(sess) - self.assertEqual(resp, response.body) + self.assertEqual( + resp, [bgp_speaker.BgpSpeaker(**response.body['bgp_speakers'][0])] + ) sess.get.assert_called_with('agents/IDENTIFIER/bgp-drinstances') diff --git a/openstack/tests/unit/network/v2/test_bgp_speaker.py b/openstack/tests/unit/network/v2/test_bgp_speaker.py index 848aa590d..56c4532d2 100644 --- a/openstack/tests/unit/network/v2/test_bgp_speaker.py +++ b/openstack/tests/unit/network/v2/test_bgp_speaker.py @@ -12,6 +12,7 @@ from unittest import mock +from openstack.network.v2 import agent from openstack.network.v2 import bgp_speaker from openstack.tests.unit import base @@ -143,12 +144,21 @@ class TestBgpSpeaker(base.TestCase): sess.get.assert_called_with(url) self.assertEqual(ret, response.body) - def test_get_bgp_dragents(self): + @mock.patch.object(agent.Agent, 'list') + def test_get_bgp_dragents(self, mock_list): sot = bgp_speaker.BgpSpeaker(**EXAMPLE) response = mock.Mock() - response.body = { - 'agents': [{'binary': 'neutron-bgp-dragent', 'alive': True}] + agent_body = { + 'agents': [ + { + 'binary': 'neutron-bgp-dragent', + 'alive': True, + 'id': IDENTIFIER, + } + ] } + response.body = agent_body + mock_list.return_value = [agent.Agent(**agent_body['agents'][0])] response.json = mock.Mock(return_value=response.body) response.status_code = 200 sess = mock.Mock() @@ -157,7 +167,8 @@ class TestBgpSpeaker(base.TestCase): url = 'bgp-speakers/IDENTIFIER/bgp-dragents' sess.get.assert_called_with(url) - self.assertEqual(ret, response.body) + print('BBBBB0 ', ret) + self.assertEqual(ret, [agent.Agent(**response.body['agents'][0])]) def test_add_bgp_speaker_to_dragent(self): sot = bgp_speaker.BgpSpeaker(**EXAMPLE) diff --git a/releasenotes/notes/return-list-of-agent-for-BGP-dragents-3608d8119012b11c.yaml b/releasenotes/notes/return-list-of-agent-for-BGP-dragents-3608d8119012b11c.yaml new file mode 100644 index 000000000..8c9b509db --- /dev/null +++ b/releasenotes/notes/return-list-of-agent-for-BGP-dragents-3608d8119012b11c.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + ``get_dragents`` and ``get_bgp_speakers_hosted_by_dragent`` return list + of Agents and BgpSpeakers, see https://launchpad.net/bugs/2067039