Replace 'bgp speaker show dragents' with 'bgp dragent list'

In order to follow other agent related commands in OSC, it is more
appropriate and friendly to replace 'bgp speaker show dragents' with
'bgp dragent list'. this patch uses 'openstack bgp dragent list' to
show the list of dragents, and the optional parameter 'bgp-speaker'
shows the list of dragents hosting a specific bgp speaker.

Change-Id: I9e0703fccf535b1e1a2055ed917336055b7395f5
Closes-Bug: #1858377
This commit is contained in:
zhanghao 2020-01-06 05:33:53 -05:00
parent b3fa5e530b
commit bb5b9cac6e
5 changed files with 215 additions and 4 deletions

View File

@ -70,18 +70,25 @@ class RemoveBgpSpeakerFromDRAgent(command.Command):
class ListDRAgentsHostingBgpSpeaker(command.Lister):
"""List dynamic routing agents hosting a BGP speaker"""
"""(Deprecated) List dynamic routing agents hosting a BGP speaker
(Use "bgp dragent list" instead)
"""
resource = 'agent'
list_columns = ['id', 'host', 'admin_state_up', 'alive']
unknown_parts_flag = False
def get_parser(self, prog_name):
self.log.warning("The 'openstack bgp speaker show dragents' CLI is "
"deprecated and will be removed in the future. Use "
"'openstack bgp dragent list' CLI instead.")
parser = super(ListDRAgentsHostingBgpSpeaker,
self).get_parser(prog_name)
parser.add_argument('bgp_speaker',
metavar='<bgp-speaker>',
help=_("ID or name of the BGP speaker"))
help=_("List dynamic routing agents hosting a "
"BGP speaker (name or ID)"))
return parser
def take_action(self, parsed_args):
@ -97,3 +104,39 @@ class ListDRAgentsHostingBgpSpeaker(command.Lister):
(utils.get_dict_properties(
s, columns, formatters=_formatters,
) for s in data['agents']))
class ListDRAgent(command.Lister):
"""List dynamic routing agents"""
resource = 'agent'
list_columns = ['id', 'host', 'admin_state_up', 'alive']
unknown_parts_flag = False
def get_parser(self, prog_name):
parser = super(ListDRAgent,
self).get_parser(prog_name)
parser.add_argument('--bgp-speaker',
metavar='<bgp-speaker>',
help=_("List dynamic routing agents hosting a "
"BGP speaker (name or ID)"))
return parser
def take_action(self, parsed_args):
search_opts = {}
client = self.app.client_manager.neutronclient
if parsed_args.bgp_speaker is not None:
search_opts = {}
speaker_id = client.find_resource(constants.BGP_SPEAKER,
parsed_args.bgp_speaker)['id']
search_opts['bgp_speaker'] = speaker_id
data = client.list_dragents_hosting_bgp_speaker(**search_opts)
else:
attrs = {'agent_type': 'BGP dynamic routing agent'}
data = client.list_agents(**attrs)
headers = ('ID', 'Host', 'State', 'Alive')
columns = ('id', 'host', 'admin_state_up', 'alive')
return (headers,
(utils.get_dict_properties(
s, columns, formatters=_formatters,
) for s in data['agents']))

View File

@ -57,7 +57,7 @@ class FakeBgpSpeaker(object):
"""
bgp_speakers = []
for i in range(0, count):
for i in range(count):
bgp_speaker = FakeBgpSpeaker.create_one_bgp_speaker(attrs)
bgp_speakers.append(bgp_speaker)
@ -89,8 +89,42 @@ class FakeBgpPeer(object):
def create_bgp_peers(attrs=None, count=1):
"""Create one or multiple fake bgp peers."""
bgp_peers = []
for i in range(0, count):
for i in range(count):
bgp_peer = FakeBgpPeer.create_one_bgp_peer(attrs)
bgp_peers.append(bgp_peer)
return {'bgp_peers': bgp_peers}
class FakeDRAgent(object):
"""Fake one or more dynamic routing agents."""
@staticmethod
def create_one_dragent(attrs=None):
attrs = attrs or {}
# Set default attributes.
dragent_attrs = {
'binary': 'neutron-bgp-dragent',
'admin_state_up': True,
'alive': True,
'topic': 'bgp_dragent',
'host': 'network-' + uuid.uuid4().hex,
'name': 'bgp-dragent-' + uuid.uuid4().hex,
'agent_type': 'BGP dynamic routing agent',
'id': uuid.uuid4().hex,
}
# Overwrite default attributes.
dragent_attrs.update(attrs)
return copy.deepcopy(dragent_attrs)
@staticmethod
def create_dragents(attrs=None, count=1):
"""Create one or multiple fake dynamic routing agents."""
agents = []
for i in range(count):
agent = FakeDRAgent.create_one_dragent(attrs)
agents.append(agent)
return {'agents': agents}

View File

@ -0,0 +1,123 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
import mock
from neutronclient.osc.v2.dynamic_routing import bgp_dragent
from neutronclient.tests.unit.osc.v2.dynamic_routing import fakes
class TestAddBgpSpeakerToDRAgent(fakes.TestNeutronDynamicRoutingOSCV2):
_bgp_speaker = fakes.FakeBgpSpeaker.create_one_bgp_speaker()
_bgp_dragent = fakes.FakeDRAgent.create_one_dragent()
_bgp_speaker_id = _bgp_speaker['id']
_bgp_dragent_id = _bgp_dragent['id']
def setUp(self):
super(TestAddBgpSpeakerToDRAgent, self).setUp()
# Get the command object to test
self.cmd = bgp_dragent.AddBgpSpeakerToDRAgent(self.app, self.namespace)
def test_add_bgp_speaker_to_dragent(self):
arglist = [
self._bgp_dragent_id,
self._bgp_speaker_id,
]
verifylist = [
('dragent_id', self._bgp_dragent_id),
('bgp_speaker', self._bgp_speaker_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(self.neutronclient,
"add_bgp_speaker_to_dragent",
return_value=None):
result = self.cmd.take_action(parsed_args)
self.neutronclient.add_bgp_speaker_to_dragent.\
assert_called_once_with(
self._bgp_dragent_id,
{'bgp_speaker_id': self._bgp_speaker_id})
self.assertIsNone(result)
class TestRemoveBgpSpeakerFromDRAgent(fakes.TestNeutronDynamicRoutingOSCV2):
_bgp_speaker = fakes.FakeBgpSpeaker.create_one_bgp_speaker()
_bgp_dragent = fakes.FakeDRAgent.create_one_dragent()
_bgp_speaker_id = _bgp_speaker['id']
_bgp_dragent_id = _bgp_dragent['id']
def setUp(self):
super(TestRemoveBgpSpeakerFromDRAgent, self).setUp()
# Get the command object to test
self.cmd = bgp_dragent.RemoveBgpSpeakerFromDRAgent(
self.app, self.namespace)
def test_remove_bgp_speaker_from_dragent(self):
arglist = [
self._bgp_dragent_id,
self._bgp_speaker_id,
]
verifylist = [
('dragent_id', self._bgp_dragent_id),
('bgp_speaker', self._bgp_speaker_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(self.neutronclient,
"remove_bgp_speaker_from_dragent",
return_value=None):
result = self.cmd.take_action(parsed_args)
self.neutronclient.remove_bgp_speaker_from_dragent.\
assert_called_once_with(self._bgp_dragent_id,
self._bgp_speaker_id)
self.assertIsNone(result)
class TestListDRAgentsHostingBgpSpeaker(fakes.TestNeutronDynamicRoutingOSCV2):
_bgp_speaker = fakes.FakeBgpSpeaker.create_one_bgp_speaker()
_bgp_speaker_id = _bgp_speaker['id']
attrs = {'bgp_speaker_id': _bgp_speaker_id}
_bgp_dragents = fakes.FakeDRAgent.create_dragents(attrs)
columns = ('ID', 'Host', 'State', 'Alive')
data = [(_bgp_dragent['id'],
_bgp_dragent['host'],
_bgp_dragent['admin_state_up'],
':-)' if _bgp_dragent['alive'] else 'XXX')
for _bgp_dragent in _bgp_dragents['agents']]
def setUp(self):
super(TestListDRAgentsHostingBgpSpeaker, self).setUp()
# Get the command object to test
self.cmd = bgp_dragent.ListDRAgent(self.app, self.namespace)
def test_list_dragents_hosting_bgp_speaker(self):
arglist = [
'--bgp-speaker', self._bgp_speaker_id,
]
verifylist = [
('bgp_speaker', self._bgp_speaker_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
with mock.patch.object(self.neutronclient,
"list_dragents_hosting_bgp_speaker",
return_value=self._bgp_dragents):
columns, data = self.cmd.take_action(parsed_args)
attrs = {'bgp_speaker': self._bgp_speaker_id}
self.neutronclient.list_dragents_hosting_bgp_speaker.\
assert_called_once_with(**attrs)
self.assertEqual(self.columns, columns)
self.assertListEqual(self.data, list(data))

View File

@ -0,0 +1,10 @@
---
deprecations:
- |
The ``openstack bgp speaker show dragents`` CLI is deprecated and
will be removed in the future. Use ``openstack bgp dragent list
--bgp-speaker <bgp-speaker>`` CLI instead.
features:
- |
The ``openstack bgp dragent list`` CLI is added to support showing
the list of dynamic routing agents.

View File

@ -70,6 +70,7 @@ openstack.neutronclient.v2 =
sfc_service_graph_show = neutronclient.osc.v2.sfc.sfc_service_graph:ShowSfcServiceGraph
bgp_dragent_add_speaker = neutronclient.osc.v2.dynamic_routing.bgp_dragent:AddBgpSpeakerToDRAgent
bgp_dragent_list = neutronclient.osc.v2.dynamic_routing.bgp_dragent:ListDRAgent
bgp_dragent_remove_speaker = neutronclient.osc.v2.dynamic_routing.bgp_dragent:RemoveBgpSpeakerFromDRAgent
bgp_peer_create = neutronclient.osc.v2.dynamic_routing.bgp_peer:CreateBgpPeer
bgp_peer_delete = neutronclient.osc.v2.dynamic_routing.bgp_peer:DeleteBgpPeer