Skip to content

Commit 9242790

Browse files
committed
network: Add --advertise-host argument to "add subnet"
The parameter sets a boolean for the "openstack router add subnet" command. If "--advertise-host" is passed then the REST request contains "advertise_host": "true" in the body according the spec [1]. There is a conditional handling of that parameter because of the openstacksdk dependency. Once openstacksdk gets implemented the parameter and is released, we should remove the condition and pass the parameter directly to the add_interface_to_router method Related-Bug: #2144617 Assisted-By: Claude Opus 4.6 [1] https://opendev.org/openstack/neutron-specs/src/branch/master/specs/2026.2/bgp_evpn_type_5_route_support.rst#changes-to-cli-and-rest-api Change-Id: I7b760ad963901eb149e3149057aed17e654af0aa Signed-off-by: Jakub Libosvar <libosvar@redhat.com>
1 parent 4d650ca commit 9242790

2 files changed

Lines changed: 69 additions & 4 deletions

File tree

openstackclient/network/v2/router.py

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,15 +367,36 @@ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
367367
metavar='<subnet>',
368368
help=_("Subnet to be added (name or ID)"),
369369
)
370+
parser.add_argument(
371+
'--advertise-host',
372+
action='store_true',
373+
default=False,
374+
dest='advertise_host',
375+
help=_(
376+
"Mark the subnet's prefixes to be advertised as host "
377+
"routes within the router's EVPN VNI. "
378+
"Only valid for EVPN routers."
379+
),
380+
)
370381
return parser
371382

372383
def take_action(self, parsed_args: argparse.Namespace) -> None:
373384
client = self.app.client_manager.network
374385
subnet = client.find_subnet(parsed_args.subnet, ignore_missing=False)
375-
client.add_interface_to_router(
376-
client.find_router(parsed_args.router, ignore_missing=False),
377-
subnet=subnet.id,
378-
)
386+
if parsed_args.advertise_host:
387+
# TODO(evpn): switch to client.add_interface_to_router() once
388+
# openstacksdk supports the advertise_host parameter.
389+
router = client.find_router(
390+
parsed_args.router, ignore_missing=False
391+
)
392+
router.add_interface(
393+
client, subnet_id=subnet.id, advertise_host=True
394+
)
395+
else:
396+
client.add_interface_to_router(
397+
client.find_router(parsed_args.router, ignore_missing=False),
398+
subnet=subnet.id,
399+
)
379400

380401

381402
class AddExtraRoutesToRouter(command.ShowOne):

openstackclient/tests/unit/network/v2/test_router.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ def setUp(self):
8686

8787
self.network_client.find_router.return_value = self._router
8888
self.network_client.find_subnet.return_value = self._subnet
89+
self._router.add_interface = mock.Mock()
8990

9091
self.cmd = router.AddSubnetToRouter(self.app, None)
9192

@@ -119,6 +120,49 @@ def test_add_subnet_required_options(self):
119120

120121
self.assertIsNone(result)
121122

123+
def test_add_subnet_with_advertise_host(self):
124+
arglist = [
125+
self._router.id,
126+
self._router.subnet,
127+
'--advertise-host',
128+
]
129+
verifylist = [
130+
('router', self._router.id),
131+
('subnet', self._router.subnet),
132+
('advertise_host', True),
133+
]
134+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
135+
136+
result = self.cmd.take_action(parsed_args)
137+
self._router.add_interface.assert_called_once_with(
138+
self.network_client,
139+
subnet_id=self._subnet.id,
140+
advertise_host=True,
141+
)
142+
self.network_client.add_interface_to_router.assert_not_called()
143+
144+
self.assertIsNone(result)
145+
146+
def test_add_subnet_without_advertise_host(self):
147+
arglist = [
148+
self._router.id,
149+
self._router.subnet,
150+
]
151+
verifylist = [
152+
('router', self._router.id),
153+
('subnet', self._router.subnet),
154+
('advertise_host', False),
155+
]
156+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
157+
158+
result = self.cmd.take_action(parsed_args)
159+
self.network_client.add_interface_to_router.assert_called_once_with(
160+
self._router, subnet=self._subnet.id
161+
)
162+
self._router.add_interface.assert_not_called()
163+
164+
self.assertIsNone(result)
165+
122166

123167
class TestCreateRouter(TestRouter):
124168
# The new router created.

0 commit comments

Comments
 (0)