@@ -246,6 +246,17 @@ def _add_updatable_args(parser):
246246
247247# TODO(abhiraut): Use the SDK resource mapped attribute names once the
248248# OSC minimum requirements include SDK 1.0.
249+ def _convert_address_pairs (parsed_args ):
250+ ops = []
251+ for opt in parsed_args .allowed_address_pairs :
252+ addr = {}
253+ addr ['ip_address' ] = opt ['ip-address' ]
254+ if 'mac-address' in opt :
255+ addr ['mac_address' ] = opt ['mac-address' ]
256+ ops .append (addr )
257+ return ops
258+
259+
249260class CreatePort (command .ShowOne ):
250261 _description = _ ("Create a new port" )
251262
@@ -305,7 +316,7 @@ def get_parser(self, prog_name):
305316 help = _ ("Name of this port" )
306317 )
307318 # TODO(singhj): Add support for extended options:
308- # qos,dhcp, address pairs
319+ # qos,dhcp
309320 secgroups = parser .add_mutually_exclusive_group ()
310321 secgroups .add_argument (
311322 '--security-group' ,
@@ -332,7 +343,17 @@ def get_parser(self, prog_name):
332343 action = 'store_true' ,
333344 help = _ ("Disable port security for this port" )
334345 )
335-
346+ parser .add_argument (
347+ '--allowed-address' ,
348+ metavar = 'ip-address=<ip-address>[,mac-address=<mac-address>]' ,
349+ action = parseractions .MultiKeyValueAction ,
350+ dest = 'allowed_address_pairs' ,
351+ required_keys = ['ip-address' ],
352+ optional_keys = ['mac-address' ],
353+ help = _ ("Add allowed-address pair associated with this port: "
354+ "ip-address=<ip-address>[,mac-address=<mac-address>] "
355+ "(repeat option to set multiple allowed-address pairs)" )
356+ )
336357 return parser
337358
338359 def take_action (self , parsed_args ):
@@ -349,6 +370,9 @@ def take_action(self, parsed_args):
349370 for sg in parsed_args .security_groups ]
350371 if parsed_args .no_security_group :
351372 attrs ['security_groups' ] = []
373+ if parsed_args .allowed_address_pairs :
374+ attrs ['allowed_address_pairs' ] = (
375+ _convert_address_pairs (parsed_args ))
352376
353377 obj = client .create_port (** attrs )
354378 display_columns , columns = _get_columns (obj )
@@ -569,7 +593,26 @@ def get_parser(self, prog_name):
569593 action = 'store_true' ,
570594 help = _ ("Disable port security for this port" )
571595 )
572-
596+ parser .add_argument (
597+ '--allowed-address' ,
598+ metavar = 'ip-address=<ip-address>[,mac-address=<mac-address>]' ,
599+ action = parseractions .MultiKeyValueAction ,
600+ dest = 'allowed_address_pairs' ,
601+ required_keys = ['ip-address' ],
602+ optional_keys = ['mac-address' ],
603+ help = _ ("Add allowed-address pair associated with this port: "
604+ "ip-address=<ip-address>[,mac-address=<mac-address>] "
605+ "(repeat option to set multiple allowed-address pairs)" )
606+ )
607+ parser .add_argument (
608+ '--no-allowed-address' ,
609+ dest = 'no_allowed_address_pair' ,
610+ action = 'store_true' ,
611+ help = _ ("Clear existing allowed-address pairs associated"
612+ "with this port."
613+ "(Specify both --allowed-address and --no-allowed-address"
614+ "to overwrite the current allowed-address pairs)" )
615+ )
573616 return parser
574617
575618 def take_action (self , parsed_args ):
@@ -609,6 +652,19 @@ def take_action(self, parsed_args):
609652 elif parsed_args .no_security_group :
610653 attrs ['security_groups' ] = []
611654
655+ if (parsed_args .allowed_address_pairs and
656+ parsed_args .no_allowed_address_pair ):
657+ attrs ['allowed_address_pairs' ] = (
658+ _convert_address_pairs (parsed_args ))
659+
660+ elif parsed_args .allowed_address_pairs :
661+ attrs ['allowed_address_pairs' ] = (
662+ [addr for addr in obj .allowed_address_pairs if addr ] +
663+ _convert_address_pairs (parsed_args ))
664+
665+ elif parsed_args .no_allowed_address_pair :
666+ attrs ['allowed_address_pairs' ] = []
667+
612668 client .update_port (obj , ** attrs )
613669
614670
@@ -669,6 +725,19 @@ def get_parser(self, prog_name):
669725 metavar = "<port>" ,
670726 help = _ ("Port to modify (name or ID)" )
671727 )
728+ parser .add_argument (
729+ '--allowed-address' ,
730+ metavar = 'ip-address=<ip-address>[,mac-address=<mac-address>]' ,
731+ action = parseractions .MultiKeyValueAction ,
732+ dest = 'allowed_address_pairs' ,
733+ required_keys = ['ip-address' ],
734+ optional_keys = ['mac-address' ],
735+ help = _ ("Desired allowed-address pair which should be removed "
736+ "from this port: ip-address=<ip-address> "
737+ "[,mac-address=<mac-address>] (repeat option to set "
738+ "multiple allowed-address pairs)" )
739+ )
740+
672741 return parser
673742
674743 def take_action (self , parsed_args ):
@@ -680,6 +749,7 @@ def take_action(self, parsed_args):
680749 tmp_fixed_ips = copy .deepcopy (obj .fixed_ips )
681750 tmp_binding_profile = copy .deepcopy (obj .binding_profile )
682751 tmp_secgroups = copy .deepcopy (obj .security_groups )
752+ tmp_addr_pairs = copy .deepcopy (obj .allowed_address_pairs )
683753 _prepare_fixed_ips (self .app .client_manager , parsed_args )
684754 attrs = {}
685755 if parsed_args .fixed_ip :
@@ -708,6 +778,14 @@ def take_action(self, parsed_args):
708778 msg = _ ("Port does not contain security group %s" ) % sg
709779 raise exceptions .CommandError (msg )
710780 attrs ['security_groups' ] = tmp_secgroups
781+ if parsed_args .allowed_address_pairs :
782+ try :
783+ for addr in _convert_address_pairs (parsed_args ):
784+ tmp_addr_pairs .remove (addr )
785+ except ValueError :
786+ msg = _ ("Port does not contain allowed-address-pair %s" ) % addr
787+ raise exceptions .CommandError (msg )
788+ attrs ['allowed_address_pairs' ] = tmp_addr_pairs
711789
712790 if attrs :
713791 client .update_port (obj , ** attrs )
0 commit comments