Skip to content

Commit 9846092

Browse files
Zuulopenstack-gerrit
authored andcommitted
Merge "Neutron port hints"
2 parents 7ea78b6 + 22d1a26 commit 9846092

4 files changed

Lines changed: 366 additions & 2 deletions

File tree

openstackclient/network/v2/port.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,22 @@ def _add_updatable_args(parser):
322322
action='store_true',
323323
help=_("NUMA affinity policy using legacy mode to schedule this port"),
324324
)
325+
parser.add_argument(
326+
'--hint',
327+
metavar='<alias=value>',
328+
action=JSONKeyValueAction,
329+
default={},
330+
help=_(
331+
'Port hints as ALIAS=VALUE or as JSON. '
332+
'Valid hint aliases/values: '
333+
'ovs-tx-steering=thread, ovs-tx-steering=hash. '
334+
'Valid JSON values are as specified by the Neutron API. '
335+
'(requires port-hints extension) '
336+
'(requires port-hint-ovs-tx-steering extension for alias: '
337+
'ovs-tx-steering) '
338+
'(repeat option to set multiple hints)'
339+
),
340+
)
325341

326342

327343
# TODO(abhiraut): Use the SDK resource mapped attribute names once the
@@ -350,6 +366,34 @@ def _convert_extra_dhcp_options(parsed_args):
350366
return dhcp_options
351367

352368

369+
# When we have multiple hints, we'll need to refactor this to allow
370+
# arbitrary combinations. But until then let's have it as simple as possible.
371+
def _validate_port_hints(hints):
372+
if hints not in (
373+
{},
374+
# by hint alias
375+
{'ovs-tx-steering': 'thread'},
376+
{'ovs-tx-steering': 'hash'},
377+
# by fully specified value of the port's hints field
378+
{'openvswitch': {'other_config': {'tx-steering': 'thread'}}},
379+
{'openvswitch': {'other_config': {'tx-steering': 'hash'}}},
380+
):
381+
msg = _("Invalid value to --hints, see --help for valid values.")
382+
raise argparse.ArgumentTypeError(msg)
383+
384+
385+
# When we have multiple hints, we'll need to refactor this to expand aliases
386+
# without losing other hints. But until then let's have it as simple as
387+
# possible.
388+
def _expand_port_hint_aliases(hints):
389+
if hints == {'ovs-tx-steering': 'thread'}:
390+
return {'openvswitch': {'other_config': {'tx-steering': 'thread'}}}
391+
elif hints == {'ovs-tx-steering': 'hash'}:
392+
return {'openvswitch': {'other_config': {'tx-steering': 'hash'}}}
393+
else:
394+
return hints
395+
396+
353397
class CreatePort(command.ShowOne, common.NeutronCommandWithExtraArgs):
354398
_description = _("Create a new port")
355399

@@ -527,6 +571,29 @@ def take_action(self, parsed_args):
527571
parsed_args.qos_policy, ignore_missing=False
528572
).id
529573

574+
if parsed_args.hint:
575+
_validate_port_hints(parsed_args.hint)
576+
expanded_hints = _expand_port_hint_aliases(parsed_args.hint)
577+
try:
578+
client.find_extension('port-hints', ignore_missing=False)
579+
except Exception as e:
580+
msg = _('Not supported by Network API: %(e)s') % {'e': e}
581+
raise exceptions.CommandError(msg)
582+
if (
583+
'openvswitch' in expanded_hints
584+
and 'other_config' in expanded_hints['openvswitch']
585+
and 'tx-steering'
586+
in expanded_hints['openvswitch']['other_config']
587+
):
588+
try:
589+
client.find_extension(
590+
'port-hint-ovs-tx-steering', ignore_missing=False
591+
)
592+
except Exception as e:
593+
msg = _('Not supported by Network API: %(e)s') % {'e': e}
594+
raise exceptions.CommandError(msg)
595+
attrs['hints'] = expanded_hints
596+
530597
set_tags_in_post = bool(
531598
client.find_extension('tag-ports-during-bulk-creation')
532599
)
@@ -972,6 +1039,29 @@ def take_action(self, parsed_args):
9721039
if parsed_args.data_plane_status:
9731040
attrs['data_plane_status'] = parsed_args.data_plane_status
9741041

1042+
if parsed_args.hint:
1043+
_validate_port_hints(parsed_args.hint)
1044+
expanded_hints = _expand_port_hint_aliases(parsed_args.hint)
1045+
try:
1046+
client.find_extension('port-hints', ignore_missing=False)
1047+
except Exception as e:
1048+
msg = _('Not supported by Network API: %(e)s') % {'e': e}
1049+
raise exceptions.CommandError(msg)
1050+
if (
1051+
'openvswitch' in expanded_hints
1052+
and 'other_config' in expanded_hints['openvswitch']
1053+
and 'tx-steering'
1054+
in expanded_hints['openvswitch']['other_config']
1055+
):
1056+
try:
1057+
client.find_extension(
1058+
'port-hint-ovs-tx-steering', ignore_missing=False
1059+
)
1060+
except Exception as e:
1061+
msg = _('Not supported by Network API: %(e)s') % {'e': e}
1062+
raise exceptions.CommandError(msg)
1063+
attrs['hints'] = expanded_hints
1064+
9751065
attrs.update(
9761066
self._parse_extra_properties(parsed_args.extra_properties)
9771067
)
@@ -1083,6 +1173,12 @@ def get_parser(self, prog_name):
10831173
default=False,
10841174
help=_("Clear host binding for the port."),
10851175
)
1176+
parser.add_argument(
1177+
'--hints',
1178+
action='store_true',
1179+
default=False,
1180+
help=_("Clear hints for the port."),
1181+
)
10861182

10871183
_tag.add_tag_option_to_parser_for_unset(parser, _('port'))
10881184

@@ -1143,6 +1239,8 @@ def take_action(self, parsed_args):
11431239
attrs['numa_affinity_policy'] = None
11441240
if parsed_args.host:
11451241
attrs['binding:host_id'] = None
1242+
if parsed_args.hints:
1243+
attrs['hints'] = None
11461244

11471245
attrs.update(
11481246
self._parse_extra_properties(parsed_args.extra_properties)

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,6 +1778,7 @@ def create_one_port(attrs=None):
17781778
'subnet_id': 'subnet-id-' + uuid.uuid4().hex,
17791779
}
17801780
],
1781+
'hints': {},
17811782
'id': 'port-id-' + uuid.uuid4().hex,
17821783
'mac_address': 'fa:16:3e:a9:4e:72',
17831784
'name': 'port-name-' + uuid.uuid4().hex,

0 commit comments

Comments
 (0)