summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2020-04-06 15:31:17 +0000
committerGerrit Code Review <review@openstack.org>2020-04-06 15:31:17 +0000
commit565a256f4e8bfc37e1203e22437cfdcfb73436b0 (patch)
treea3617abdf5814999f6b4298d268900c0068e01e1
parent54bd3682268955d92ddfff4b57c9f15f980dfe9b (diff)
parentf7662b01c2ff319a7a1d6c712c516f004cd7ce0b (diff)
downloadpython-ironicclient-565a256f4e8bfc37e1203e22437cfdcfb73436b0.tar.gz
Merge "A standalone CLI for ironic"
-rw-r--r--doc/source/cli/index.rst1
-rw-r--r--doc/source/cli/osc_plugin_cli.rst16
-rw-r--r--doc/source/cli/standalone.rst69
-rw-r--r--ironicclient/shell.py134
-rw-r--r--lower-constraints.txt2
-rw-r--r--releasenotes/notes/standalone-cli-f07834585909334a.yaml11
-rw-r--r--requirements.txt3
-rw-r--r--setup.cfg3
-rw-r--r--test-requirements.txt2
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
diff --git a/setup.cfg b/setup.cfg
index cc24257..23d68a8 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -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