diff options
author | Zuul <zuul@review.opendev.org> | 2020-04-06 15:31:17 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2020-04-06 15:31:17 +0000 |
commit | 565a256f4e8bfc37e1203e22437cfdcfb73436b0 (patch) | |
tree | a3617abdf5814999f6b4298d268900c0068e01e1 | |
parent | 54bd3682268955d92ddfff4b57c9f15f980dfe9b (diff) | |
parent | f7662b01c2ff319a7a1d6c712c516f004cd7ce0b (diff) | |
download | python-ironicclient-565a256f4e8bfc37e1203e22437cfdcfb73436b0.tar.gz |
Merge "A standalone CLI for ironic"
-rw-r--r-- | doc/source/cli/index.rst | 1 | ||||
-rw-r--r-- | doc/source/cli/osc_plugin_cli.rst | 16 | ||||
-rw-r--r-- | doc/source/cli/standalone.rst | 69 | ||||
-rw-r--r-- | ironicclient/shell.py | 134 | ||||
-rw-r--r-- | lower-constraints.txt | 2 | ||||
-rw-r--r-- | releasenotes/notes/standalone-cli-f07834585909334a.yaml | 11 | ||||
-rw-r--r-- | requirements.txt | 3 | ||||
-rw-r--r-- | setup.cfg | 3 | ||||
-rw-r--r-- | test-requirements.txt | 2 |
9 files changed, 235 insertions, 6 deletions
diff --git a/doc/source/cli/index.rst b/doc/source/cli/index.rst index ac8ad07..51704ce 100644 --- a/doc/source/cli/index.rst +++ b/doc/source/cli/index.rst @@ -4,4 +4,5 @@ python-ironicclient User Documentation .. toctree:: + standalone osc_plugin_cli diff --git a/doc/source/cli/osc_plugin_cli.rst b/doc/source/cli/osc_plugin_cli.rst index e3e9805..76815fd 100644 --- a/doc/source/cli/osc_plugin_cli.rst +++ b/doc/source/cli/osc_plugin_cli.rst @@ -30,6 +30,16 @@ package must be installed. There are two ways to do this: $ pip install python-openstackclient +This CLI is provided by python-openstackclient and osc-lib projects: + +* https://opendev.org/openstack/python-openstackclient +* https://opendev.org/openstack/osc-lib + +.. _osc-auth: + +Authentication +-------------- + To use the CLI, you must provide your OpenStack username, password, project, and auth endpoint. You can use configuration options ``--os-username``, ``--os-password``, ``--os-project-id`` @@ -44,11 +54,6 @@ or set the corresponding environment variables:: $ export OS_IDENTITY_API_VERSION=3 $ export OS_AUTH_URL=http://auth.example.com:5000/identity -This CLI is provided by python-openstackclient and osc-lib projects: - -* https://opendev.org/openstack/python-openstackclient -* https://opendev.org/openstack/osc-lib - Getting help ============ @@ -91,6 +96,7 @@ The baremetal API version can be specified via: $ openstack baremetal port group list --os-baremetal-api-version 1.25 + Command Reference ================= .. toctree:: diff --git a/doc/source/cli/standalone.rst b/doc/source/cli/standalone.rst new file mode 100644 index 0000000..ff694a9 --- /dev/null +++ b/doc/source/cli/standalone.rst @@ -0,0 +1,69 @@ +===================================================== +``baremetal`` Standalone Command-Line Interface (CLI) +===================================================== + +.. program:: baremetal +.. highlight:: bash + +Synopsis +======== + +:program:`baremetal [options]` <command> [command-options] + +:program:`baremetal help` <command> + + +Description +=========== + +The standalone ``baremetal`` tool allows interacting with the Bare Metal +service without installing the OpenStack Client tool as in +:doc:`osc_plugin_cli`. + +The standalone tool is mostly identical to its OSC counterpart, with two +exceptions: + +#. No need to prefix commands with ``openstack``. +#. No authentication is assumed by default. + +Check the :doc:`OSC CLI reference </cli/osc/v1/index>` for a list of available +commands. + +Standalone usage +---------------- + +To use the CLI with a standalone bare metal service, you need to provide an +endpoint to connect to. It can be done in three ways: + +#. Provide an explicit ``--os-endpoint`` argument, e.g.: + + .. code-block:: bash + + $ baremetal --os-endpoint https://ironic.host:6385 node list + +#. Set the corresponding environment variable, e.g.: + + .. code-block:: bash + + $ export OS_ENDPOINT=https://ironic.host:6385 + $ baremetal node list + +#. Populate a clouds.yaml_ file, setting ``baremetal_endpoint_override``, e.g.: + + .. code-block:: bash + + $ cat ~/.config/openstack/clouds.yaml + clouds: + ironic: + auth_type: none + baremetal_endpoint_override: http://127.0.0.1:6385 + $ export OS_CLOUD=ironic + $ baremetal node list + +.. _clouds.yaml: https://docs.openstack.org/openstacksdk/latest/user/guides/connect_from_config.html + +Usage with OpenStack +-------------------- + +The standalone CLI can also be used with the Bare Metal service installed as +part of OpenStack. See :ref:`osc-auth` for information on the required input. diff --git a/ironicclient/shell.py b/ironicclient/shell.py new file mode 100644 index 0000000..67e1d24 --- /dev/null +++ b/ironicclient/shell.py @@ -0,0 +1,134 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import collections +import logging +import sys + +from cliff import app +from cliff import commandmanager +from openstack import config as os_config +from osc_lib import utils +import pbr.version + +from ironicclient.common import http +from ironicclient.common.i18n import _ +from ironicclient import exc +from ironicclient.v1 import client + + +_DEFAULTS = { + 'auth_type': 'none', +} +_TYPE = 'baremetal' +_DESCRIPTION = 'Bare Metal service (ironic) client' +_NAMESPACE = 'openstack.baremetal.v1' + +LOG = logging.getLogger(__name__) + +ClientManager = collections.namedtuple('ClientManager', ['baremetal']) + + +class CommandManager(commandmanager.CommandManager): + + def load_commands(self, namespace): + super(CommandManager, self).load_commands(namespace) + # Stip the 'baremetal' prefix used in OSC + prefix = 'baremetal ' + prefix_len = len(prefix) + self.commands = dict( + (cmd[prefix_len:] if cmd.startswith(prefix) else cmd, ep) + for (cmd, ep) in self.commands.items() + ) + + +class App(app.App): + + def __init__(self): + version_info = pbr.version.VersionInfo('python-ironicclient') + mgr = CommandManager(_NAMESPACE) + self.config = os_config.OpenStackConfig(override_defaults=_DEFAULTS) + super(App, self).__init__(description=_DESCRIPTION, + version=str(version_info), + command_manager=mgr) + + def build_option_parser(self, description, version, argparse_kwargs=None): + parser = super(App, self).build_option_parser( + description, version, argparse_kwargs=argparse_kwargs) + self.config.register_argparse_arguments(parser, sys.argv[1:]) + + parser.add_argument( + '--os-baremetal-api-version', + metavar='<baremetal-api-version>', + default=utils.env('OS_BAREMETAL_API_VERSION'), + help='Bare metal API version, default="latest" (the maximum ' + 'version supported by both the client and the server). ' + '(Env: OS_BAREMETAL_API_VERSION)', + ) + parser.add_argument( + '--max-retries', + metavar='<max-retries-number>', + default=http.DEFAULT_MAX_RETRIES, + type=int, + help='Maximum number of retries on connection problems and ' + 'resource state conflicts' + ) + parser.add_argument( + '--retry-interval', + metavar='<retry-interval-seconds>', + default=http.DEFAULT_RETRY_INTERVAL, + type=int, + help='Interval in seconds between two retries' + ) + return parser + + def initialize_app(self, argv): + super(App, self).initialize_app(argv) + self.cloud_region = self.config.get_one(argparse=self.options) + + api_version = self.options.os_baremetal_api_version + allow_api_version_downgrade = False + if not api_version: + api_version = self.cloud_region.get_default_microversion(_TYPE) + if not api_version: + api_version = http.LATEST_VERSION + allow_api_version_downgrade = True + LOG.debug('Using API version %s, downgrade %s', api_version, + 'allowed' if allow_api_version_downgrade else 'disallowed') + + # NOTE(dtantsur): endpoint_override is required to respect settings in + # clouds.yaml, such as baremetal_endpoint_override. + endpoint_override = self.cloud_region.get_endpoint(_TYPE) + try: + self.client = client.Client( + os_ironic_api_version=api_version, + allow_api_version_downgrade=allow_api_version_downgrade, + session=self.cloud_region.get_session(), + region_name=self.cloud_region.get_region_name(_TYPE), + endpoint_override=endpoint_override, + max_retries=self.options.max_retries, + retry_interval=self.options.retry_interval, + ) + except exc.EndpointNotFound as e: + # Re-raise with a more obvious message. + msg = _("%(err)s.\n* Use --os-endpoint for standalone ironic.\n" + "* Use --os-auth-url and credentials for authentication.\n" + "* Use --os-cloud to load configuration from clouds.yaml\n" + "* See `%(cmd)s --help` for more details") + raise exc.EndpointNotFound(msg % {'err': e, 'cmd': sys.argv[0]}) + + # Compatibility with OSC + self.client_manager = ClientManager(self.client) + + +def main(argv=sys.argv[1:]): + return App().run(argv) diff --git a/lower-constraints.txt b/lower-constraints.txt index bc2dbc6..918571e 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -42,7 +42,7 @@ munch==2.1.0 netaddr==0.7.18 netifaces==0.10.4 openstackdocstheme==1.20.0 -openstacksdk==0.11.2 +openstacksdk==0.18.0 os-client-config==1.28.0 os-service-types==1.2.0 os-testr==1.0.0 diff --git a/releasenotes/notes/standalone-cli-f07834585909334a.yaml b/releasenotes/notes/standalone-cli-f07834585909334a.yaml new file mode 100644 index 0000000..228f80c --- /dev/null +++ b/releasenotes/notes/standalone-cli-f07834585909334a.yaml @@ -0,0 +1,11 @@ +--- +prelude: | + This release includes a new standalone CLI tool ``baremetal`` that is + mostly identical to the existing OSC plugin, but + + * Does not require commands to be prefixed with ``openstack``. + * Does not require ``python-openstackclient`` to be installed. + * Defaults to no authentication. +features: + - | + Adds a new ``baremetal`` CLI tool, mostly targeted at standalone users. diff --git a/requirements.txt b/requirements.txt index b53d8cd..6cc1836 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,12 +3,15 @@ # process, which may cause wedges in the gate later. pbr!=2.1.0,>=2.0.0 # Apache-2.0 appdirs>=1.3.0 # MIT License +cliff!=2.9.0,>=2.8.0 # Apache-2.0 dogpile.cache>=0.6.2 # BSD jsonschema>=2.6.0 # MIT keystoneauth1>=3.4.0 # Apache-2.0 +openstacksdk>=0.18.0 # Apache-2.0 osc-lib>=1.10.0 # Apache-2.0 oslo.config>=5.2.0 # Apache-2.0 oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0 oslo.utils>=3.33.0 # Apache-2.0 PyYAML>=3.12 # MIT requests>=2.14.2 # Apache-2.0 +stevedore>=1.20.0 # Apache-2.0 @@ -23,6 +23,9 @@ classifier = packages = ironicclient [entry_points] +console_scripts = + baremetal = ironicclient.shell:main + openstack.cli.extension = baremetal = ironicclient.osc.plugin diff --git a/test-requirements.txt b/test-requirements.txt index b1a8602..de50d72 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -14,3 +14,5 @@ tempest>=17.1.0 # Apache-2.0 stestr>=1.0.0 # Apache-2.0 ddt>=1.0.1 # MIT python-openstackclient>=3.12.0 # Apache-2.0 +# Required for syntax highlighting check +Pygments>=2.2.0 # BSD |