Merge "Prepare for osc-lib changes"

This commit is contained in:
Zuul 2025-04-01 17:57:57 +00:00 committed by Gerrit Code Review
commit ade7da8797
6 changed files with 85 additions and 63 deletions

@ -0,0 +1,57 @@
# 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 os
from openstackclient.i18n import _
def bool_from_str(value, strict=False):
true_strings = ('1', 't', 'true', 'on', 'y', 'yes')
false_strings = ('0', 'f', 'false', 'off', 'n', 'no')
if isinstance(value, bool):
return value
lowered = value.strip().lower()
if lowered in true_strings:
return True
elif lowered in false_strings or not strict:
return False
msg = _(
"Unrecognized value '%(value)s'; acceptable values are: %(valid)s"
) % {
'value': value,
'valid': ', '.join(
f"'{s}'" for s in sorted(true_strings + false_strings)
),
}
raise ValueError(msg)
def boolenv(*vars, default=False):
"""Search for the first defined of possibly many bool-like env vars.
Returns the first environment variable defined in vars, or returns the
default.
:param vars: Arbitrary strings to search for. Case sensitive.
:param default: The default to return if no value found.
:returns: A boolean corresponding to the value found, else the default if
no value found.
"""
for v in vars:
value = os.environ.get(v, None)
if value:
return bool_from_str(value)
return default

@ -34,6 +34,7 @@ from osc_lib import exceptions
from osc_lib import utils
from openstackclient.api import compute_v2
from openstackclient.common import envvars
from openstackclient.common import pagination
from openstackclient.i18n import _
from openstackclient.identity import common as identity_common
@ -324,48 +325,6 @@ def _prep_server_detail(compute_client, image_client, server, *, refresh=True):
return info
def bool_from_str(value, strict=False):
true_strings = ('1', 't', 'true', 'on', 'y', 'yes')
false_strings = ('0', 'f', 'false', 'off', 'n', 'no')
if isinstance(value, bool):
return value
lowered = value.strip().lower()
if lowered in true_strings:
return True
elif lowered in false_strings or not strict:
return False
msg = _(
"Unrecognized value '%(value)s'; acceptable values are: %(valid)s"
) % {
'value': value,
'valid': ', '.join(
f"'{s}'" for s in sorted(true_strings + false_strings)
),
}
raise ValueError(msg)
def boolenv(*vars, default=False):
"""Search for the first defined of possibly many bool-like env vars.
Returns the first environment variable defined in vars, or returns the
default.
:param vars: Arbitrary strings to search for. Case sensitive.
:param default: The default to return if no value found.
:returns: A boolean corresponding to the value found, else the default if
no value found.
"""
for v in vars:
value = os.environ.get(v, None)
if value:
return bool_from_str(value)
return default
class AddFixedIP(command.ShowOne):
_description = _("Add fixed IP address to server")
@ -1876,7 +1835,7 @@ class CreateServer(command.ShowOne):
if 'delete_on_termination' in mapping:
try:
value = bool_from_str(
value = envvars.bool_from_str(
mapping['delete_on_termination'],
strict=True,
)
@ -2223,7 +2182,7 @@ class DeleteServer(command.Command):
parser.add_argument(
'--all-projects',
action='store_true',
default=boolenv('ALL_PROJECTS'),
default=envvars.boolenv('ALL_PROJECTS'),
help=_(
'Delete server(s) in another project by name (admin only)'
'(can be specified using the ALL_PROJECTS envvar)'
@ -2389,7 +2348,7 @@ class ListServer(command.Lister):
parser.add_argument(
'--all-projects',
action='store_true',
default=boolenv('ALL_PROJECTS'),
default=envvars.boolenv('ALL_PROJECTS'),
help=_(
'Include all projects (admin only) '
'(can be specified using the ALL_PROJECTS envvar)'
@ -4967,7 +4926,7 @@ class StartServer(command.Command):
parser.add_argument(
'--all-projects',
action='store_true',
default=boolenv('ALL_PROJECTS'),
default=envvars.boolenv('ALL_PROJECTS'),
help=_(
'Start server(s) in another project by name (admin only) '
'(can be specified using the ALL_PROJECTS envvar)'
@ -5002,7 +4961,7 @@ class StopServer(command.Command):
parser.add_argument(
'--all-projects',
action='store_true',
default=boolenv('ALL_PROJECTS'),
default=envvars.boolenv('ALL_PROJECTS'),
help=_(
'Stop server(s) in another project by name (admin only) '
'(can be specified using the ALL_PROJECTS envvar)'

@ -183,14 +183,14 @@ class TestShell(osc_lib_test_utils.TestShell):
osc_lib_test_utils.fake_execute(_shell, _cmd)
self.app.assert_called_with(["list", "role"])
self.assertEqual(
default_args.get("token", ''), _shell.options.token, "token"
)
self.assertEqual(
default_args.get("auth_url", ''),
_shell.options.auth_url,
"auth_url",
)
if default_args.get('token'):
self.assertEqual(default_args['token'], _shell.options.token)
if default_args.get('auth_url'):
self.assertEqual(
default_args['auth_url'], _shell.options.auth_url
)
def _assert_cli(self, cmd_options, default_args):
with mock.patch(
@ -204,25 +204,28 @@ class TestShell(osc_lib_test_utils.TestShell):
osc_lib_test_utils.fake_execute(_shell, _cmd)
self.app.assert_called_with(["list", "server"])
# TODO(stephenfin): Remove "or ''" when we bump osc-lib minimum to
# a version that includes I1d26133c9d9ed299d1035f207059aa8fe463a001
self.assertEqual(
default_args["compute_api_version"],
_shell.options.os_compute_api_version,
_shell.options.os_compute_api_version or '',
)
self.assertEqual(
default_args["identity_api_version"],
_shell.options.os_identity_api_version,
_shell.options.os_identity_api_version or '',
)
self.assertEqual(
default_args["image_api_version"],
_shell.options.os_image_api_version,
_shell.options.os_image_api_version or '',
)
self.assertEqual(
default_args["volume_api_version"],
_shell.options.os_volume_api_version,
_shell.options.os_volume_api_version or '',
)
self.assertEqual(
default_args["network_api_version"],
_shell.options.os_network_api_version,
_shell.options.os_network_api_version or '',
)

@ -18,6 +18,7 @@ from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.common import envvars
from openstackclient.common import pagination
from openstackclient.i18n import _
from openstackclient.identity import common as identity_common
@ -399,7 +400,7 @@ class ListVolumeAttachment(command.Lister):
'--all-projects',
dest='all_projects',
action='store_true',
default=utils.env('ALL_PROJECTS', default=False),
default=envvars.boolenv('ALL_PROJECTS'),
help=_('Shows details for all projects (admin only).'),
)
parser.add_argument(

@ -17,6 +17,7 @@ from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.common import envvars
from openstackclient.i18n import _
@ -410,7 +411,7 @@ class ListVolumeGroup(command.Lister):
'--all-projects',
dest='all_projects',
action='store_true',
default=utils.env('ALL_PROJECTS', default=False),
default=envvars.boolenv('ALL_PROJECTS'),
help=_('Shows details for all projects (admin only).'),
)
# TODO(stephenfin): Add once we have an equivalent command for

@ -17,6 +17,7 @@ from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.common import envvars
from openstackclient.i18n import _
LOG = logging.getLogger(__name__)
@ -145,7 +146,7 @@ class ListVolumeGroupSnapshot(command.Lister):
'--all-projects',
dest='all_projects',
action='store_true',
default=utils.env('ALL_PROJECTS', default=False),
default=envvars.boolenv('ALL_PROJECTS'),
help=_('Shows details for all projects (admin only).'),
)
# TODO(stephenfin): Add once we have an equivalent command for