diff options
| author | Zuul <zuul@review.opendev.org> | 2019-11-05 00:41:31 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2019-11-05 00:41:31 +0000 |
| commit | d17a1c8039807cdac29e77eb5f0724d181bdd831 (patch) | |
| tree | 99035b35ff29205fedb4115a2778e1b2152aad77 /openstackclient | |
| parent | d2f44e645e4f0396991695a5fa90064702dd64fb (diff) | |
| parent | cd6c285cc6c2274e6b42cc452ba4a61a3487ca23 (diff) | |
| download | python-openstackclient-d17a1c8039807cdac29e77eb5f0724d181bdd831.tar.gz | |
Merge "neutron: autogenerate docs"
Diffstat (limited to 'openstackclient')
| -rw-r--r-- | openstackclient/identity/common.py | 8 | ||||
| -rw-r--r-- | openstackclient/network/common.py | 199 | ||||
| -rw-r--r-- | openstackclient/network/v2/_tag.py | 46 | ||||
| -rw-r--r-- | openstackclient/network/v2/floating_ip.py | 74 | ||||
| -rw-r--r-- | openstackclient/network/v2/network.py | 109 | ||||
| -rw-r--r-- | openstackclient/network/v2/security_group.py | 46 | ||||
| -rw-r--r-- | openstackclient/network/v2/security_group_rule.py | 205 |
7 files changed, 385 insertions, 302 deletions
diff --git a/openstackclient/identity/common.py b/openstackclient/identity/common.py index d125d285..7be2a17b 100644 --- a/openstackclient/identity/common.py +++ b/openstackclient/identity/common.py @@ -233,13 +233,13 @@ def add_group_domain_option_to_parser(parser): ) -def add_project_domain_option_to_parser(parser): +def add_project_domain_option_to_parser(parser, enhance_help=lambda _h: _h): parser.add_argument( '--project-domain', metavar='<project-domain>', - help=_('Domain the project belongs to (name or ID). ' - 'This can be used in case collisions between project names ' - 'exist.'), + help=enhance_help(_('Domain the project belongs to (name or ID). This ' + 'can be used in case collisions between project ' + 'names exist.')), ) diff --git a/openstackclient/network/common.py b/openstackclient/network/common.py index d22b2caa..e68628b3 100644 --- a/openstackclient/network/common.py +++ b/openstackclient/network/common.py @@ -34,6 +34,10 @@ _required_opt_extensions_map = { 'security_groups': 'security-groups', } +_NET_TYPE_NEUTRON = 'neutron' +_NET_TYPE_COMPUTE = 'nova-network' +_QUALIFIER_FMT = "%s\n\n*%s*" + @contextlib.contextmanager def check_missing_extension_if_error(client_manager, attrs): @@ -51,35 +55,87 @@ def check_missing_extension_if_error(client_manager, attrs): @six.add_metaclass(abc.ABCMeta) -class NetworkAndComputeCommand(command.Command): - """Network and Compute Command +class NetDetectionMixin(object): + """Convenience methods for nova-network vs. neutron decisions. - Command class for commands that support implementation via - the network or compute endpoint. Such commands have different - implementations for take_action() and may even have different - arguments. - """ + A live environment detects which network type it is running and creates its + parser with only the options relevant to that network type. - def take_action(self, parsed_args): - if self.app.client_manager.is_network_endpoint_enabled(): - return self.take_action_network(self.app.client_manager.network, - parsed_args) - else: - return self.take_action_compute(self.app.client_manager.compute, - parsed_args) + But the command classes are used for docs builds as well, and docs must + present the options for both network types, often qualified accordingly. + """ + @property + def _network_type(self): + """Discover whether the running cloud is using neutron or nova-network. + + :return: + * ``NET_TYPE_NEUTRON`` if neutron is detected + * ``NET_TYPE_COMPUTE`` if running in a cloud but neutron is not + detected. + * ``None`` if not running in a cloud, which hopefully means we're + building docs. + """ + # Have we set it up yet for this command? + if not hasattr(self, '_net_type'): + # import pdb; pdb.set_trace() + try: + if self.app.client_manager.is_network_endpoint_enabled(): + net_type = _NET_TYPE_NEUTRON + else: + net_type = _NET_TYPE_COMPUTE + except AttributeError: + LOG.warning( + "%s: Could not detect a network type. Assuming we are " + "building docs.", self.__class__.__name__) + net_type = None + self._net_type = net_type + return self._net_type + + @property + def is_neutron(self): + return self._network_type is _NET_TYPE_NEUTRON + + @property + def is_nova_network(self): + return self._network_type is _NET_TYPE_COMPUTE + + @property + def is_docs_build(self): + return self._network_type is None + + def enhance_help_neutron(self, _help): + if self.is_docs_build: + # Why can't we say 'neutron'? + return _QUALIFIER_FMT % (_help, _("Network version 2 only")) + return _help + + def enhance_help_nova_network(self, _help): + if self.is_docs_build: + # Why can't we say 'nova-network'? + return _QUALIFIER_FMT % (_help, _("Compute version 2 only")) + return _help + + @staticmethod + def split_help(network_help, compute_help): + return ( + "*%(network_qualifier)s:*\n %(network_help)s\n\n" + "*%(compute_qualifier)s:*\n %(compute_help)s" % dict( + network_qualifier=_("Network version 2"), + network_help=network_help, + compute_qualifier=_("Compute version 2"), + compute_help=compute_help)) def get_parser(self, prog_name): LOG.debug('get_parser(%s)', prog_name) - parser = super(NetworkAndComputeCommand, self).get_parser(prog_name) + parser = super(NetDetectionMixin, self).get_parser(prog_name) parser = self.update_parser_common(parser) LOG.debug('common parser: %s', parser) - if ( - self.app is None or - self.app.client_manager.is_network_endpoint_enabled() - ): - return self.update_parser_network(parser) - else: - return self.update_parser_compute(parser) + if self.is_neutron or self.is_docs_build: + parser = self.update_parser_network(parser) + if self.is_nova_network or self.is_docs_build: + # Add nova-net options if running nova-network or building docs + parser = self.update_parser_compute(parser) + return parser def update_parser_common(self, parser): """Default is no updates to parser.""" @@ -93,18 +149,36 @@ class NetworkAndComputeCommand(command.Command): """Default is no updates to parser.""" return parser - @abc.abstractmethod + def take_action(self, parsed_args): + if self.is_neutron: + return self.take_action_network(self.app.client_manager.network, + parsed_args) + elif self.is_nova_network: + return self.take_action_compute(self.app.client_manager.compute, + parsed_args) + def take_action_network(self, client, parsed_args): """Override to do something useful.""" pass - @abc.abstractmethod def take_action_compute(self, client, parsed_args): """Override to do something useful.""" pass @six.add_metaclass(abc.ABCMeta) +class NetworkAndComputeCommand(NetDetectionMixin, command.Command): + """Network and Compute Command + + Command class for commands that support implementation via + the network or compute endpoint. Such commands have different + implementations for take_action() and may even have different + arguments. + """ + pass + + +@six.add_metaclass(abc.ABCMeta) class NetworkAndComputeDelete(NetworkAndComputeCommand): """Network and Compute Delete @@ -149,7 +223,7 @@ class NetworkAndComputeDelete(NetworkAndComputeCommand): @six.add_metaclass(abc.ABCMeta) -class NetworkAndComputeLister(command.Lister): +class NetworkAndComputeLister(NetDetectionMixin, command.Lister): """Network and Compute Lister Lister class for commands that support implementation via @@ -157,50 +231,11 @@ class NetworkAndComputeLister(command.Lister): implementations for take_action() and may even have different arguments. """ - - def take_action(self, parsed_args): - if self.app.client_manager.is_network_endpoint_enabled(): - return self.take_action_network(self.app.client_manager.network, - parsed_args) - else: - return self.take_action_compute(self.app.client_manager.compute, - parsed_args) - - def get_parser(self, prog_name): - LOG.debug('get_parser(%s)', prog_name) - parser = super(NetworkAndComputeLister, self).get_parser(prog_name) - parser = self.update_parser_common(parser) - LOG.debug('common parser: %s', parser) - if self.app.client_manager.is_network_endpoint_enabled(): - return self.update_parser_network(parser) - else: - return self.update_parser_compute(parser) - - def update_parser_common(self, parser): - """Default is no updates to parser.""" - return parser - - def update_parser_network(self, parser): - """Default is no updates to parser.""" - return parser - - def update_parser_compute(self, parser): - """Default is no updates to parser.""" - return parser - - @abc.abstractmethod - def take_action_network(self, client, parsed_args): - """Override to do something useful.""" - pass - - @abc.abstractmethod - def take_action_compute(self, client, parsed_args): - """Override to do something useful.""" - pass + pass @six.add_metaclass(abc.ABCMeta) -class NetworkAndComputeShowOne(command.ShowOne): +class NetworkAndComputeShowOne(NetDetectionMixin, command.ShowOne): """Network and Compute ShowOne ShowOne class for commands that support implementation via @@ -222,35 +257,3 @@ class NetworkAndComputeShowOne(command.ShowOne): if exc.details: msg += ", " + six.text_type(exc.details) raise exceptions.CommandError(msg) - - def get_parser(self, prog_name): - LOG.debug('get_parser(%s)', prog_name) - parser = super(NetworkAndComputeShowOne, self).get_parser(prog_name) - parser = self.update_parser_common(parser) - LOG.debug('common parser: %s', parser) - if self.app.client_manager.is_network_endpoint_enabled(): - return self.update_parser_network(parser) - else: - return self.update_parser_compute(parser) - - def update_parser_common(self, parser): - """Default is no updates to parser.""" - return parser - - def update_parser_network(self, parser): - """Default is no updates to parser.""" - return parser - - def update_parser_compute(self, parser): - """Default is no updates to parser.""" - return parser - - @abc.abstractmethod - def take_action_network(self, client, parsed_args): - """Override to do something useful.""" - pass - - @abc.abstractmethod - def take_action_compute(self, client, parsed_args): - """Override to do something useful.""" - pass diff --git a/openstackclient/network/v2/_tag.py b/openstackclient/network/v2/_tag.py index ce39f35e..e1cba22e 100644 --- a/openstackclient/network/v2/_tag.py +++ b/openstackclient/network/v2/_tag.py @@ -22,34 +22,39 @@ class _CommaListAction(argparse.Action): setattr(namespace, self.dest, values.split(',')) -def add_tag_filtering_option_to_parser(parser, collection_name): +def add_tag_filtering_option_to_parser(parser, collection_name, + enhance_help=lambda _h: _h): parser.add_argument( '--tags', metavar='<tag>[,<tag>,...]', action=_CommaListAction, - help=_('List %s which have all given tag(s) ' - '(Comma-separated list of tags)') % collection_name + help=enhance_help( + _('List %s which have all given tag(s) (Comma-separated list of ' + 'tags)') % collection_name) ) parser.add_argument( '--any-tags', metavar='<tag>[,<tag>,...]', action=_CommaListAction, - help=_('List %s which have any given tag(s) ' - '(Comma-separated list of tags)') % collection_name + help=enhance_help( + _('List %s which have any given tag(s) (Comma-separated list of ' + 'tags)') % collection_name) ) parser.add_argument( '--not-tags', metavar='<tag>[,<tag>,...]', action=_CommaListAction, - help=_('Exclude %s which have all given tag(s) ' - '(Comma-separated list of tags)') % collection_name + help=enhance_help( + _('Exclude %s which have all given tag(s) (Comma-separated list ' + 'of tags)') % collection_name) ) parser.add_argument( '--not-any-tags', metavar='<tag>[,<tag>,...]', action=_CommaListAction, - help=_('Exclude %s which have any given tag(s) ' - '(Comma-separated list of tags)') % collection_name + help=enhance_help( + _('Exclude %s which have any given tag(s) (Comma-separated list ' + 'of tags)') % collection_name) ) @@ -64,37 +69,42 @@ def get_tag_filtering_args(parsed_args, args): args['not_any_tags'] = ','.join(parsed_args.not_any_tags) -def add_tag_option_to_parser_for_create(parser, resource_name): +def add_tag_option_to_parser_for_create(parser, resource_name, + enhance_help=lambda _h: _h): tag_group = parser.add_mutually_exclusive_group() tag_group.add_argument( '--tag', action='append', dest='tags', metavar='<tag>', - help=_("Tag to be added to the %s " - "(repeat option to set multiple tags)") % resource_name + help=enhance_help( + _("Tag to be added to the %s " + "(repeat option to set multiple tags)") % resource_name) ) tag_group.add_argument( '--no-tag', action='store_true', - help=_("No tags associated with the %s") % resource_name + help=enhance_help(_("No tags associated with the %s") % resource_name) ) -def add_tag_option_to_parser_for_set(parser, resource_name): +def add_tag_option_to_parser_for_set(parser, resource_name, + enhance_help=lambda _h: _h): parser.add_argument( '--tag', action='append', dest='tags', metavar='<tag>', - help=_("Tag to be added to the %s " - "(repeat option to set multiple tags)") % resource_name + help=enhance_help( + _("Tag to be added to the %s (repeat option to set multiple " + "tags)") % resource_name) ) parser.add_argument( '--no-tag', action='store_true', - help=_("Clear tags associated with the %s. Specify both " - "--tag and --no-tag to overwrite current tags") % resource_name + help=enhance_help( + _("Clear tags associated with the %s. Specify both --tag and " + "--no-tag to overwrite current tags") % resource_name) ) diff --git a/openstackclient/network/v2/floating_ip.py b/openstackclient/network/v2/floating_ip.py index e0aa0435..bd43379a 100644 --- a/openstackclient/network/v2/floating_ip.py +++ b/openstackclient/network/v2/floating_ip.py @@ -114,57 +114,65 @@ class CreateFloatingIP(common.NetworkAndComputeShowOne): parser.add_argument( '--subnet', metavar='<subnet>', - help=_("Subnet on which you want to create the floating IP " - "(name or ID)") + help=self.enhance_help_neutron( + _("Subnet on which you want to create the floating IP " + "(name or ID)")) ) parser.add_argument( '--port', metavar='<port>', - help=_("Port to be associated with the floating IP " - "(name or ID)") + help=self.enhance_help_neutron( + _("Port to be associated with the floating IP " + "(name or ID)")) ) parser.add_argument( '--floating-ip-address', metavar='<ip-address>', dest='floating_ip_address', - help=_("Floating IP address") + help=self.enhance_help_neutron(_("Floating IP address")) ) parser.add_argument( '--fixed-ip-address', metavar='<ip-address>', dest='fixed_ip_address', - help=_("Fixed IP address mapped to the floating IP") + help=self.enhance_help_neutron( + _("Fixed IP address mapped to the floating IP")) ) parser.add_argument( '--qos-policy', metavar='<qos-policy>', - help=_("Attach QoS policy to the floating IP (name or ID)") + help=self.enhance_help_neutron( + _("Attach QoS policy to the floating IP (name or ID)")) ) parser.add_argument( '--description', metavar='<description>', - help=_('Set floating IP description') + help=self.enhance_help_neutron(_('Set floating IP description')) ) parser.add_argument( '--project', metavar='<project>', - help=_("Owner's project (name or ID)") + help=self.enhance_help_neutron(_("Owner's project (name or ID)")) ) parser.add_argument( '--dns-domain', metavar='<dns-domain>', dest='dns_domain', - help=_("Set DNS domain for this floating IP") + help=self.enhance_help_neutron( + _("Set DNS domain for this floating IP")) ) parser.add_argument( '--dns-name', metavar='<dns-name>', dest='dns_name', - help=_("Set DNS name for this floating IP") + help=self.enhance_help_neutron( + _("Set DNS name for this floating IP")) ) - identity_common.add_project_domain_option_to_parser(parser) - _tag.add_tag_option_to_parser_for_create(parser, _('floating IP')) + identity_common.add_project_domain_option_to_parser( + parser, enhance_help=self.enhance_help_neutron) + _tag.add_tag_option_to_parser_for_create( + parser, _('floating IP'), enhance_help=self.enhance_help_neutron) return parser def take_action_network(self, client, parsed_args): @@ -217,60 +225,68 @@ class DeleteFloatingIP(common.NetworkAndComputeDelete): class ListFloatingIP(common.NetworkAndComputeLister): # TODO(songminglong): Use SDK resource mapped attribute names once # the OSC minimum requirements include SDK 1.0 + _description = _("List floating IP(s)") def update_parser_network(self, parser): parser.add_argument( '--network', metavar='<network>', - help=_("List floating IP(s) according to " - "given network (name or ID)") + help=self.enhance_help_neutron( + _("List floating IP(s) according to " + "given network (name or ID)")) ) parser.add_argument( '--port', metavar='<port>', - help=_("List floating IP(s) according to " - "given port (name or ID)") + help=self.enhance_help_neutron( + _("List floating IP(s) according to given port (name or ID)")) ) parser.add_argument( '--fixed-ip-address', metavar='<ip-address>', - help=_("List floating IP(s) according to " - "given fixed IP address") + help=self.enhance_help_neutron( + _("List floating IP(s) according to given fixed IP address")) ) parser.add_argument( '--floating-ip-address', metavar='<ip-address>', - help=_("List floating IP(s) according to " - "given floating IP address") + help=self.enhance_help_neutron( + _("List floating IP(s) according to given floating IP " + "address")) ) parser.add_argument( '--long', action='store_true', default=False, - help=_("List additional fields in output") + help=self.enhance_help_neutron( + _("List additional fields in output")) ) parser.add_argument( '--status', metavar='<status>', choices=['ACTIVE', 'DOWN'], - help=_("List floating IP(s) according to " - "given status ('ACTIVE', 'DOWN')") + help=self.enhance_help_neutron( + _("List floating IP(s) according to given status ('ACTIVE', " + "'DOWN')")) ) parser.add_argument( '--project', metavar='<project>', - help=_("List floating IP(s) according to " - "given project (name or ID)") + help=self.enhance_help_neutron( + _("List floating IP(s) according to given project (name or " + "ID)")) ) identity_common.add_project_domain_option_to_parser(parser) parser.add_argument( '--router', metavar='<router>', - help=_("List floating IP(s) according to " - "given router (name or ID)") + help=self.enhance_help_neutron( + _("List floating IP(s) according to given router (name or " + "ID)")) ) - _tag.add_tag_filtering_option_to_parser(parser, _('floating IP')) + _tag.add_tag_filtering_option_to_parser( + parser, _('floating IP'), enhance_help=self.enhance_help_neutron) return parser diff --git a/openstackclient/network/v2/network.py b/openstackclient/network/v2/network.py index 09f3556c..e7031266 100644 --- a/openstackclient/network/v2/network.py +++ b/openstackclient/network/v2/network.py @@ -219,27 +219,27 @@ class CreateNetwork(common.NetworkAndComputeShowOne): '--enable', action='store_true', default=True, - help=_("Enable network (default)") + help=self.enhance_help_neutron(_("Enable network (default)")) ) admin_group.add_argument( '--disable', action='store_true', - help=_("Disable network") + help=self.enhance_help_neutron(_("Disable network")) ) parser.add_argument( '--project', metavar='<project>', - help=_("Owner's project (name or ID)") + help=self.enhance_help_neutron(_("Owner's project (name or ID)")) ) parser.add_argument( '--description', metavar='<description>', - help=_("Set network description") + help=self.enhance_help_neutron(_("Set network description")) ) parser.add_argument( '--mtu', metavar='<mtu>', - help=_("Set network mtu") + help=self.enhance_help_neutron(_("Set network mtu")) ) identity_common.add_project_domain_option_to_parser(parser) parser.add_argument( @@ -247,65 +247,76 @@ class CreateNetwork(common.NetworkAndComputeShowOne): action='append', dest='availability_zone_hints', metavar='<availability-zone>', - help=_("Availability Zone in which to create this network " - "(Network Availability Zone extension required, " - "repeat option to set multiple availability zones)") + help=self.enhance_help_neutron( + _("Availability Zone in which to create this network " + "(Network Availability Zone extension required, " + "repeat option to set multiple availability zones)")) ) port_security_group = parser.add_mutually_exclusive_group() port_security_group.add_argument( '--enable-port-security', action='store_true', - help=_("Enable port security by default for ports created on " - "this network (default)") + help=self.enhance_help_neutron( + _("Enable port security by default for ports created on " + "this network (default)")) ) port_security_group.add_argument( '--disable-port-security', action='store_true', - help=_("Disable port security by default for ports created on " - "this network") + help=self.enhance_help_neutron( + _("Disable port security by default for ports created on " + "this network")) ) external_router_grp = parser.add_mutually_exclusive_group() external_router_grp.add_argument( '--external', action='store_true', - help=_("Set this network as an external network " - "(external-net extension required)") + help=self.enhance_help_neutron( + _("Set this network as an external network " + "(external-net extension required)")) ) external_router_grp.add_argument( '--internal', action='store_true', - help=_("Set this network as an internal network (default)") + help=self.enhance_help_neutron( + _("Set this network as an internal network (default)")) ) default_router_grp = parser.add_mutually_exclusive_group() default_router_grp.add_argument( '--default', action='store_true', - help=_("Specify if this network should be used as " - "the default external network") + help=self.enhance_help_neutron( + _("Specify if this network should be used as the default " + "external network")) ) default_router_grp.add_argument( '--no-default', action='store_true', - help=_("Do not use the network as the default external network " - "(default)") + help=self.enhance_help_neutron( + _("Do not use the network as the default external network " + "(default)")) ) parser.add_argument( '--qos-policy', metavar='<qos-policy>', - help=_("QoS policy to attach to this network (name or ID)") + help=self.enhance_help_neutron( + _("QoS policy to attach to this network (name or ID)")) ) vlan_transparent_grp = parser.add_mutually_exclusive_group() vlan_transparent_grp.add_argument( '--transparent-vlan', action='store_true', - help=_("Make the network VLAN transparent")) + help=self.enhance_help_neutron( + _("Make the network VLAN transparent"))) vlan_transparent_grp.add_argument( '--no-transparent-vlan', action='store_true', - help=_("Do not make the network VLAN transparent")) + help=self.enhance_help_neutron( + _("Do not make the network VLAN transparent"))) _add_additional_network_options(parser) - _tag.add_tag_option_to_parser_for_create(parser, _('network')) + _tag.add_tag_option_to_parser_for_create( + parser, _('network'), enhance_help=self.enhance_help_neutron) return parser def update_parser_compute(self, parser): @@ -313,7 +324,8 @@ class CreateNetwork(common.NetworkAndComputeShowOne): '--subnet', metavar='<subnet>', required=True, - help=_("IPv4 subnet for fixed IPs (in CIDR notation)") + help=self.enhance_help_nova_network( + _("IPv4 subnet for fixed IPs (in CIDR notation)")) ) return parser @@ -376,87 +388,98 @@ class ListNetwork(common.NetworkAndComputeLister): router_ext_group.add_argument( '--external', action='store_true', - help=_("List external networks") + help=self.enhance_help_neutron(_("List external networks")) ) router_ext_group.add_argument( '--internal', action='store_true', - help=_("List internal networks") + help=self.enhance_help_neutron(_("List internal networks")) ) parser.add_argument( '--long', action='store_true', - help=_("List additional fields in output") + help=self.enhance_help_neutron( + _("List additional fields in output")) ) parser.add_argument( '--name', metavar='<name>', - help=_("List networks according to their name") + help=self.enhance_help_neutron( + _("List networks according to their name")) ) admin_state_group = parser.add_mutually_exclusive_group() admin_state_group.add_argument( '--enable', action='store_true', - help=_("List enabled networks") + help=self.enhance_help_neutron(_("List enabled networks")) ) admin_state_group.add_argument( '--disable', action='store_true', - help=_("List disabled networks") + help=self.enhance_help_neutron(_("List disabled networks")) ) parser.add_argument( '--project', metavar='<project>', help=_("List networks according to their project (name or ID)") ) - identity_common.add_project_domain_option_to_parser(parser) + identity_common.add_project_domain_option_to_parser( + parser, enhance_help=self.enhance_help_neutron) shared_group = parser.add_mutually_exclusive_group() shared_group.add_argument( '--share', action='store_true', - help=_("List networks shared between projects") + help=self.enhance_help_neutron( + _("List networks shared between projects")) ) shared_group.add_argument( '--no-share', action='store_true', - help=_("List networks not shared between projects") + help=self.enhance_help_neutron( + _("List networks not shared between projects")) ) parser.add_argument( '--status', metavar='<status>', choices=['ACTIVE', 'BUILD', 'DOWN', 'ERROR'], - help=_("List networks according to their status " - "('ACTIVE', 'BUILD', 'DOWN', 'ERROR')") + help=self.enhance_help_neutron( + _("List networks according to their status " + "('ACTIVE', 'BUILD', 'DOWN', 'ERROR')")) ) parser.add_argument( '--provider-network-type', metavar='<provider-network-type>', choices=['flat', 'geneve', 'gre', 'local', 'vlan', 'vxlan'], - help=_("List networks according to their physical mechanisms. " - "The supported options are: flat, geneve, gre, local, " - "vlan, vxlan.") + help=self.enhance_help_neutron( + _("List networks according to their physical mechanisms. The " + "supported options are: flat, geneve, gre, local, vlan, " + "vxlan.")) ) parser.add_argument( '--provider-physical-network', metavar='<provider-physical-network>', dest='physical_network', - help=_("List networks according to name of the physical network") + help=self.enhance_help_neutron( + _("List networks according to name of the physical network")) ) parser.add_argument( '--provider-segment', metavar='<provider-segment>', dest='segmentation_id', - help=_("List networks according to VLAN ID for VLAN networks " - "or Tunnel ID for GENEVE/GRE/VXLAN networks") + help=self.enhance_help_neutron( + _("List networks according to VLAN ID for VLAN networks or " + "Tunnel ID for GENEVE/GRE/VXLAN networks")) ) parser.add_argument( '--agent', metavar='<agent-id>', dest='agent_id', - help=_('List networks hosted by agent (ID only)') + help=self.enhance_help_neutron( + _('List networks hosted by agent (ID only)')) ) - _tag.add_tag_filtering_option_to_parser(parser, _('networks')) + _tag.add_tag_filtering_option_to_parser( + parser, _('networks'), enhance_help=self.enhance_help_neutron) return parser def take_action_network(self, client, parsed_args): diff --git a/openstackclient/network/v2/security_group.py b/openstackclient/network/v2/security_group.py index 38b4e97a..9f0ca0a1 100644 --- a/openstackclient/network/v2/security_group.py +++ b/openstackclient/network/v2/security_group.py @@ -119,10 +119,13 @@ class CreateSecurityGroup(common.NetworkAndComputeShowOne): parser.add_argument( '--project', metavar='<project>', - help=_("Owner's project (name or ID)") + help=self.enhance_help_neutron(_("Owner's project (name or ID)")) ) - identity_common.add_project_domain_option_to_parser(parser) - _tag.add_tag_option_to_parser_for_create(parser, _('security group')) + identity_common.add_project_domain_option_to_parser( + parser, enhance_help=self.enhance_help_neutron) + _tag.add_tag_option_to_parser_for_create( + parser, _('security group'), + enhance_help=self.enhance_help_neutron) return parser def _get_description(self, parsed_args): @@ -202,22 +205,28 @@ class ListSecurityGroup(common.NetworkAndComputeLister): _description = _("List security groups") def update_parser_network(self, parser): - # Maintain and hide the argument for backwards compatibility. - # Network will always return all projects for an admin. - parser.add_argument( - '--all-projects', - action='store_true', - default=False, - help=argparse.SUPPRESS, - ) + if not self.is_docs_build: + # Maintain and hide the argument for backwards compatibility. + # Network will always return all projects for an admin. + parser.add_argument( + '--all-projects', + action='store_true', + default=False, + help=argparse.SUPPRESS, + ) + parser.add_argument( '--project', metavar='<project>', - help=_("List security groups according to the project " - "(name or ID)") + help=self.enhance_help_neutron( + _("List security groups according to the project (name or " + "ID)")) ) - identity_common.add_project_domain_option_to_parser(parser) - _tag.add_tag_filtering_option_to_parser(parser, _('security group')) + identity_common.add_project_domain_option_to_parser( + parser, enhance_help=self.enhance_help_neutron) + _tag.add_tag_filtering_option_to_parser( + parser, _('security group'), + enhance_help=self.enhance_help_neutron) return parser def update_parser_compute(self, parser): @@ -225,7 +234,8 @@ class ListSecurityGroup(common.NetworkAndComputeLister): '--all-projects', action='store_true', default=False, - help=_("Display information from all projects (admin only)") + help=self.enhance_help_nova_network( + _("Display information from all projects (admin only)")) ) return parser @@ -307,7 +317,9 @@ class SetSecurityGroup(common.NetworkAndComputeCommand): return parser def update_parser_network(self, parser): - _tag.add_tag_option_to_parser_for_set(parser, _('security group')) + _tag.add_tag_option_to_parser_for_set( + parser, _('security group'), + enhance_help=self.enhance_help_neutron) return parser def take_action_network(self, client, parsed_args): diff --git a/openstackclient/network/v2/security_group_rule.py b/openstackclient/network/v2/security_group_rule.py index 15f099b1..a38587fa 100644 --- a/openstackclient/network/v2/security_group_rule.py +++ b/openstackclient/network/v2/security_group_rule.py @@ -133,109 +133,120 @@ class CreateSecurityGroupRule(common.NetworkAndComputeShowOne): metavar="<group>", help=_("Remote security group (name or ID)"), ) - return parser - def update_parser_network(self, parser): - parser.add_argument( - '--description', - metavar='<description>', - help=_("Set security group rule description") - ) + # NOTE(efried): The --dst-port, --protocol, and --proto options exist + # for both nova-network and neutron, but differ slightly. For the sake + # of the docs build, which has to account for both variants, but only + # add each to the parser once, they are handled here rather than in the + # _network- or _compute-specific methods below. + + # --dst-port has a default for nova-net only + if self.is_nova_network: + dst_port_default = dict(default=(0, 0)) + else: + dst_port_default = {} parser.add_argument( '--dst-port', metavar='<port-range>', action=parseractions.RangeAction, help=_("Destination port, may be a single port or a starting and " "ending port range: 137:139. Required for IP protocols TCP " - "and UDP. Ignored for ICMP IP protocols.") - ) - parser.add_argument( - '--icmp-type', - metavar='<icmp-type>', - type=int, - help=_("ICMP type for ICMP IP protocols") - ) - parser.add_argument( - '--icmp-code', - metavar='<icmp-code>', - type=int, - help=_("ICMP code for ICMP IP protocols") + "and UDP. Ignored for ICMP IP protocols."), + **dst_port_default ) + # NOTE(rtheis): Support either protocol option name for now. # However, consider deprecating and then removing --proto in # a future release. protocol_group = parser.add_mutually_exclusive_group() + # --proto[col] has choices for nova-network only + if self.is_nova_network: + proto_choices = dict(choices=['icmp', 'tcp', 'udp']) + else: + proto_choices = {} + protocol_help_compute = _("IP protocol (icmp, tcp, udp; default: tcp)") + protocol_help_network = _( + "IP protocol (ah, dccp, egp, esp, gre, icmp, igmp, ipv6-encap, " + "ipv6-frag, ipv6-icmp, ipv6-nonxt, ipv6-opts, ipv6-route, ospf, " + "pgm, rsvp, sctp, tcp, udp, udplite, vrrp and integer " + "representations [0-255] or any; default: any (all protocols))") + if self.is_nova_network: + protocol_help = protocol_help_compute + elif self.is_neutron: + protocol_help = protocol_help_network + else: + # Docs build: compose help for both nova-network and neutron + protocol_help = self.split_help( + protocol_help_network, protocol_help_compute) + protocol_group.add_argument( '--protocol', metavar='<protocol>', type=_convert_to_lowercase, - help=_("IP protocol (ah, dccp, egp, esp, gre, icmp, igmp, " - "ipv6-encap, ipv6-frag, ipv6-icmp, ipv6-nonxt, " - "ipv6-opts, ipv6-route, ospf, pgm, rsvp, sctp, tcp, " - "udp, udplite, vrrp and integer representations [0-255] " - "or any; default: any (all protocols))") + help=protocol_help, + **proto_choices ) - protocol_group.add_argument( - '--proto', - metavar='<proto>', - type=_convert_to_lowercase, - help=argparse.SUPPRESS + if not self.is_docs_build: + protocol_group.add_argument( + '--proto', + metavar='<proto>', + type=_convert_to_lowercase, + help=argparse.SUPPRESS, + **proto_choices + ) + + return parser + + def update_parser_network(self, parser): + parser.add_argument( + '--description', + metavar='<description>', + help=self.enhance_help_neutron( + _("Set security group rule description")) + ) + parser.add_argument( + '--icmp-type', + metavar='<icmp-type>', + type=int, + help=self.enhance_help_neutron( + _("ICMP type for ICMP IP protocols")) + ) + parser.add_argument( + '--icmp-code', + metavar='<icmp-code>', + type=int, + help=self.enhance_help_neutron( + _("ICMP code for ICMP IP protocols")) ) direction_group = parser.add_mutually_exclusive_group() direction_group.add_argument( '--ingress', action='store_true', - help=_("Rule applies to incoming network traffic (default)") + help=self.enhance_help_neutron( + _("Rule applies to incoming network traffic (default)")) ) direction_group.add_argument( '--egress', action='store_true', - help=_("Rule applies to outgoing network traffic") + help=self.enhance_help_neutron( + _("Rule applies to outgoing network traffic")) ) parser.add_argument( '--ethertype', metavar='<ethertype>', choices=['IPv4', 'IPv6'], type=_convert_ipvx_case, - help=_("Ethertype of network traffic " - "(IPv4, IPv6; default: based on IP protocol)") + help=self.enhance_help_neutron( + _("Ethertype of network traffic " + "(IPv4, IPv6; default: based on IP protocol)")) ) parser.add_argument( '--project', metavar='<project>', - help=_("Owner's project (name or ID)") - ) - identity_common.add_project_domain_option_to_parser(parser) - return parser - - def update_parser_compute(self, parser): - parser.add_argument( - '--dst-port', - metavar='<port-range>', - default=(0, 0), - action=parseractions.RangeAction, - help=_("Destination port, may be a single port or a starting and " - "ending port range: 137:139. Required for IP protocols TCP " - "and UDP. Ignored for ICMP IP protocols.") - ) - # NOTE(rtheis): Support either protocol option name for now. - # However, consider deprecating and then removing --proto in - # a future release. - protocol_group = parser.add_mutually_exclusive_group() - protocol_group.add_argument( - '--protocol', - metavar='<protocol>', - choices=['icmp', 'tcp', 'udp'], - type=_convert_to_lowercase, - help=_("IP protocol (icmp, tcp, udp; default: tcp)") - ) - protocol_group.add_argument( - '--proto', - metavar='<proto>', - choices=['icmp', 'tcp', 'udp'], - type=_convert_to_lowercase, - help=argparse.SUPPRESS + help=self.enhance_help_neutron(_("Owner's project (name or ID)")) ) + identity_common.add_project_domain_option_to_parser( + parser, enhance_help=self.enhance_help_neutron) return parser def _get_protocol(self, parsed_args, default_protocol='any'): @@ -424,47 +435,53 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister): return parser def update_parser_network(self, parser): - # Accept but hide the argument for consistency with compute. - # Network will always return all projects for an admin. - parser.add_argument( - '--all-projects', - action='store_true', - default=False, - help=argparse.SUPPRESS - ) + if not self.is_docs_build: + # Accept but hide the argument for consistency with compute. + # Network will always return all projects for an admin. + parser.add_argument( + '--all-projects', + action='store_true', + default=False, + help=argparse.SUPPRESS + ) + parser.add_argument( '--protocol', metavar='<protocol>', type=_convert_to_lowercase, - help=_("List rules by the IP protocol (" - "ah, dhcp, egp, esp, gre, icmp, igmp, " - "ipv6-encap, ipv6-frag, ipv6-icmp, ipv6-nonxt, " - "ipv6-opts, ipv6-route, ospf, pgm, rsvp, sctp, tcp, " - "udp, udplite, vrrp and integer representations [0-255] " - "or any; default: any (all protocols))") + help=self.enhance_help_neutron( + _("List rules by the IP protocol (ah, dhcp, egp, esp, gre, " + "icmp, igmp, ipv6-encap, ipv6-frag, ipv6-icmp, ipv6-nonxt, " + "ipv6-opts, ipv6-route, ospf, pgm, rsvp, sctp, tcp, udp, " + "udplite, vrrp and integer representations [0-255] or any; " + "default: any (all protocols))")) ) parser.add_argument( '--ethertype', metavar='<ethertype>', type=_convert_to_lowercase, - help=_("List rules by the Ethertype (IPv4 or IPv6)") + help=self.enhance_help_neutron( + _("List rules by the Ethertype (IPv4 or IPv6)")) ) direction_group = parser.add_mutually_exclusive_group() direction_group.add_argument( '--ingress', action='store_true', - help=_("List rules applied to incoming network traffic") + help=self.enhance_help_neutron( + _("List rules applied to incoming network traffic")) ) direction_group.add_argument( '--egress', action='store_true', - help=_("List rules applied to outgoing network traffic") + help=self.enhance_help_neutron( + _("List rules applied to outgoing network traffic")) ) parser.add_argument( '--long', action='store_true', default=False, - help=_("List additional fields in output") + help=self.enhance_help_neutron( + _("List additional fields in output")) ) return parser @@ -473,16 +490,18 @@ class ListSecurityGroupRule(common.NetworkAndComputeLister): '--all-projects', action='store_true', default=False, - help=_("Display information from all projects (admin only)") - ) - # Accept but hide the argument for consistency with network. - # There are no additional fields to display at this time. - parser.add_argument( - '--long', - action='store_false', - default=False, - help=argparse.SUPPRESS + help=self.enhance_help_nova_network( + _("Display information from all projects (admin only)")) ) + if not self.is_docs_build: + # Accept but hide the argument for consistency with network. + # There are no additional fields to display at this time. + parser.add_argument( + '--long', + action='store_false', + default=False, + help=argparse.SUPPRESS + ) return parser def _get_column_headers(self, parsed_args): |
