Skip to content

Commit 7719128

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "network: Add --evpn-vni to a Neutron router create command"
2 parents f4c28ef + 6126609 commit 7719128

2 files changed

Lines changed: 180 additions & 1 deletion

File tree

openstackclient/network/v2/router.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,31 @@ def _get_attrs(
262262
flavor = n_client.find_flavor(parsed_args.flavor, ignore_missing=False)
263263
attrs['flavor_id'] = flavor.id
264264

265-
for attr in ('enable_default_route_bfd', 'enable_default_route_ecmp'):
265+
for attr in (
266+
'enable_default_route_bfd',
267+
'enable_default_route_ecmp',
268+
'evpn_vni',
269+
):
266270
value = getattr(parsed_args, attr, None)
267271
if value is not None:
268272
attrs[attr] = value
269273

270274
return attrs
271275

272276

277+
def _parse_evpn_vni(value: str) -> int:
278+
try:
279+
vni = int(value)
280+
except ValueError:
281+
raise argparse.ArgumentTypeError(
282+
_("'%(value)s' is not a valid VNI (use a positive integer)")
283+
% {'value': value}
284+
)
285+
if vni <= 0:
286+
raise argparse.ArgumentTypeError(_("VNI must be a positive integer"))
287+
return vni
288+
289+
273290
def _parser_add_bfd_ecmp_arguments(parser: argparse.ArgumentParser) -> None:
274291
"""Helper to add BFD and ECMP args for CreateRouter and SetRouter."""
275292
parser.add_argument(
@@ -611,6 +628,24 @@ def get_parser(self, prog_name: str) -> argparse.ArgumentParser:
611628
metavar='<qos-policy>',
612629
help=_('Attach QoS policy to router gateway IPs'),
613630
)
631+
evpn_group = parser.add_mutually_exclusive_group()
632+
evpn_group.add_argument(
633+
'--evpn-vni',
634+
metavar='<vni>',
635+
default=None,
636+
type=_parse_evpn_vni,
637+
dest='evpn_vni',
638+
help=_("Associate the router with an EVPN identified by a VNI."),
639+
)
640+
evpn_group.add_argument(
641+
'--auto-evpn-vni',
642+
action='store_const',
643+
dest='evpn_vni',
644+
const=0,
645+
help=_(
646+
"Associate the router with an EVPN using an auto-assigned VNI."
647+
),
648+
)
614649

615650
return parser
616651

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

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,150 @@ def test_create_with_qos_policy_no_external_gateway(self):
613613
parsed_args,
614614
)
615615

616+
def test_create_with_evpn_vni_auto(self):
617+
arglist = [
618+
'--auto-evpn-vni',
619+
self.new_router.name,
620+
]
621+
verifylist = [
622+
('name', self.new_router.name),
623+
('enable', True),
624+
('distributed', False),
625+
('ha', False),
626+
('evpn_vni', 0),
627+
]
628+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
629+
630+
columns, data = self.cmd.take_action(parsed_args)
631+
632+
self.network_client.create_router.assert_called_once_with(
633+
**{
634+
'admin_state_up': True,
635+
'name': self.new_router.name,
636+
'evpn_vni': 0,
637+
}
638+
)
639+
self.assertEqual(self.columns, columns)
640+
self.assertCountEqual(self.data, data)
641+
642+
def test_create_with_evpn_vni_explicit(self):
643+
arglist = [
644+
'--evpn-vni',
645+
'10000',
646+
self.new_router.name,
647+
]
648+
verifylist = [
649+
('name', self.new_router.name),
650+
('enable', True),
651+
('distributed', False),
652+
('ha', False),
653+
('evpn_vni', 10000),
654+
]
655+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
656+
657+
columns, data = self.cmd.take_action(parsed_args)
658+
659+
self.network_client.create_router.assert_called_once_with(
660+
**{
661+
'admin_state_up': True,
662+
'name': self.new_router.name,
663+
'evpn_vni': 10000,
664+
}
665+
)
666+
self.assertEqual(self.columns, columns)
667+
self.assertCountEqual(self.data, data)
668+
669+
def test_create_without_evpn_vni(self):
670+
arglist = [
671+
self.new_router.name,
672+
]
673+
verifylist = [
674+
('name', self.new_router.name),
675+
('enable', True),
676+
('distributed', False),
677+
('ha', False),
678+
('evpn_vni', None),
679+
]
680+
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
681+
682+
_columns, _data = self.cmd.take_action(parsed_args)
683+
684+
self.network_client.create_router.assert_called_once_with(
685+
**{
686+
'admin_state_up': True,
687+
'name': self.new_router.name,
688+
}
689+
)
690+
self.assertNotIn(
691+
'evpn_vni',
692+
self.network_client.create_router.call_args[1],
693+
)
694+
695+
def test_create_with_evpn_vni_invalid_string(self):
696+
arglist = [
697+
'--evpn-vni',
698+
'foo',
699+
self.new_router.name,
700+
]
701+
verifylist = []
702+
703+
self.assertRaises(
704+
tests_utils.ParserException,
705+
self.check_parser,
706+
self.cmd,
707+
arglist,
708+
verifylist,
709+
)
710+
711+
def test_create_with_evpn_vni_zero(self):
712+
arglist = [
713+
'--evpn-vni',
714+
'0',
715+
self.new_router.name,
716+
]
717+
verifylist = []
718+
719+
self.assertRaises(
720+
tests_utils.ParserException,
721+
self.check_parser,
722+
self.cmd,
723+
arglist,
724+
verifylist,
725+
)
726+
727+
def test_create_with_evpn_vni_negative(self):
728+
arglist = [
729+
'--evpn-vni',
730+
'-1',
731+
self.new_router.name,
732+
]
733+
verifylist = []
734+
735+
self.assertRaises(
736+
tests_utils.ParserException,
737+
self.check_parser,
738+
self.cmd,
739+
arglist,
740+
verifylist,
741+
)
742+
743+
def test_create_with_evpn_vni_mutually_exclusive_args(self):
744+
arglist = [
745+
'--evpn-vni',
746+
'10000',
747+
'--auto-evpn-vni',
748+
self.new_router.name,
749+
]
750+
verifylist = []
751+
752+
self.assertRaises(
753+
tests_utils.ParserException,
754+
self.check_parser,
755+
self.cmd,
756+
arglist,
757+
verifylist,
758+
)
759+
616760

617761
class TestDeleteRouter(TestRouter):
618762
# The routers to delete.

0 commit comments

Comments
 (0)