From 8a63b51039ababa3327900a3b46f2392351e14a6 Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Mon, 29 Jan 2024 13:34:54 +0000 Subject: [PATCH] image: Trivial fixes Mostly stylistic, with the exception that we now allow deleting multiple metadef properties in a given namespace. Change-Id: Ib0c243f0d647ce74c0165ee666beed6eb5d5c5a7 Signed-off-by: Stephen Finucane --- .../image/v2/metadef_namespaces.py | 42 ++++---- openstackclient/image/v2/metadef_objects.py | 56 +++++------ .../image/v2/metadef_properties.py | 98 ++++++++++++------- .../unit/image/v2/test_metadef_namespaces.py | 10 +- setup.cfg | 14 +-- 5 files changed, 118 insertions(+), 102 deletions(-) diff --git a/openstackclient/image/v2/metadef_namespaces.py b/openstackclient/image/v2/metadef_namespaces.py index cc0277c54..8294daa02 100644 --- a/openstackclient/image/v2/metadef_namespaces.py +++ b/openstackclient/image/v2/metadef_namespaces.py @@ -62,7 +62,7 @@ def _format_namespace(namespace): return info -class CreateMetadefNameSpace(command.ShowOne): +class CreateMetadefNamespace(command.ShowOne): _description = _("Create a metadef namespace") def get_parser(self, prog_name): @@ -136,16 +136,16 @@ class CreateMetadefNameSpace(command.ShowOne): return zip(*sorted(info.items())) -class DeleteMetadefNameSpace(command.Command): +class DeleteMetadefNamespace(command.Command): _description = _("Delete metadef namespace") def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument( - "namespace_name", - metavar="", + "namespace", + metavar="", nargs="+", - help=_("An identifier (a name) for the namespace"), + help=_("Metadef namespace(s) to delete (name)"), ) return parser @@ -153,9 +153,9 @@ class DeleteMetadefNameSpace(command.Command): image_client = self.app.client_manager.image result = 0 - for i in parsed_args.namespace_name: + for ns in parsed_args.namespace: try: - namespace = image_client.get_metadef_namespace(i) + namespace = image_client.get_metadef_namespace(ns) image_client.delete_metadef_namespace(namespace.id) except Exception as e: result += 1 @@ -164,18 +164,18 @@ class DeleteMetadefNameSpace(command.Command): "Failed to delete namespace with name or " "ID '%(namespace)s': %(e)s" ), - {'namespace': i, 'e': e}, + {'namespace': ns, 'e': e}, ) if result > 0: - total = len(parsed_args.namespace_name) + total = len(parsed_args.namespace) msg = _( "%(result)s of %(total)s namespace failed " "to delete." ) % {'result': result, 'total': total} raise exceptions.CommandError(msg) -class ListMetadefNameSpaces(command.Lister): +class ListMetadefNamespace(command.Lister): _description = _("List metadef namespaces") def get_parser(self, prog_name): @@ -217,7 +217,7 @@ class ListMetadefNameSpaces(command.Lister): ) -class SetMetadefNameSpace(command.Command): +class SetMetadefNamespace(command.Command): _description = _("Set metadef namespace properties") def get_parser(self, prog_name): @@ -225,7 +225,7 @@ class SetMetadefNameSpace(command.Command): parser.add_argument( "namespace", metavar="", - help=_("Namespace (name) for the namespace"), + help=_("Metadef namespace to modify (name)"), ) parser.add_argument( "--display-name", @@ -243,14 +243,16 @@ class SetMetadefNameSpace(command.Command): action="store_const", const="public", dest="visibility", - help=_("Set namespace visibility 'public'"), + help=_("Metadef namespace is accessible to the public"), ) visibility_group.add_argument( "--private", action="store_const", const="private", dest="visibility", - help=_("Set namespace visibility 'private'"), + help=_( + "Metadef namespace is inaccessible to the public (default)" + ), ) protected_group = parser.add_mutually_exclusive_group() protected_group.add_argument( @@ -291,24 +293,24 @@ class SetMetadefNameSpace(command.Command): image_client.update_metadef_namespace(namespace, **kwargs) -class ShowMetadefNameSpace(command.ShowOne): +class ShowMetadefNamespace(command.ShowOne): _description = _("Show a metadef namespace") def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument( - "namespace_name", - metavar="", - help=_("Namespace (name) for the namespace"), + "namespace", + metavar="", + help=_("Metadef namespace to show (name)"), ) return parser def take_action(self, parsed_args): image_client = self.app.client_manager.image - namespace_name = parsed_args.namespace_name + namespace = parsed_args.namespace - data = image_client.get_metadef_namespace(namespace_name) + data = image_client.get_metadef_namespace(namespace) info = _format_namespace(data) return zip(*sorted(info.items())) diff --git a/openstackclient/image/v2/metadef_objects.py b/openstackclient/image/v2/metadef_objects.py index 014a953d2..88a70f684 100644 --- a/openstackclient/image/v2/metadef_objects.py +++ b/openstackclient/image/v2/metadef_objects.py @@ -55,7 +55,7 @@ class CreateMetadefObjects(command.ShowOne): parser.add_argument( "--namespace", metavar="", - help=_("Metadef namespace to create the metadef object in (name)"), + help=_("Metadef namespace to create the object in (name)"), ) parser.add_argument( "name", @@ -81,31 +81,29 @@ class CreateMetadefObjects(command.ShowOne): class ShowMetadefObjects(command.ShowOne): - _description = _( - "Describe a specific metadata definitions object inside a namespace" - ) + _description = _("Show a particular metadef object") def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument( - "namespace_name", - metavar="", - help=_("Namespace (name) for the namespace"), + "namespace", + metavar="", + help=_("Metadef namespace of the object (name)"), ) parser.add_argument( - "object_name", - metavar="", - help=_("Name of an object."), + "object", + metavar="", + help=_("Metadef object to show"), ) return parser def take_action(self, parsed_args): image_client = self.app.client_manager.image - namespace_name = parsed_args.namespace_name - object_name = parsed_args.object_name + namespace = parsed_args.namespace + object = parsed_args.object - data = image_client.get_metadef_object(object_name, namespace_name) + data = image_client.get_metadef_object(object, namespace) fields, value = _format_object(data) @@ -113,35 +111,33 @@ class ShowMetadefObjects(command.ShowOne): class DeleteMetadefObject(command.Command): - _description = _( - "Delete a specific metadata definitions object inside a namespace" - ) + _description = _("Delete metadata definitions object(s)") def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument( - "namespace_name", - metavar="", - help=_("Namespace (name) for the namespace"), + "namespace", + metavar="", + help=_("Metadef namespace of the object (name)"), ) parser.add_argument( - "object_name", - metavar="", + "objects", + metavar="", nargs="+", - help=_("Name of an object."), + help=_("Metadef object(s) to delete (name)"), ) return parser def take_action(self, parsed_args): image_client = self.app.client_manager.image - namespace_name = parsed_args.namespace_name + namespace = parsed_args.namespace result = 0 - for i in parsed_args.object_name: + for obj in parsed_args.objects: try: - object = image_client.get_metadef_object(i, namespace_name) - image_client.delete_metadef_object(object, namespace_name) + object = image_client.get_metadef_object(obj, namespace) + image_client.delete_metadef_object(object, namespace) except Exception as e: result += 1 LOG.error( @@ -149,11 +145,11 @@ class DeleteMetadefObject(command.Command): "Failed to delete object with name or " "ID '%(object)s': %(e)s" ), - {'object': i, 'e': e}, + {'object': obj, 'e': e}, ) if result > 0: - total = len(parsed_args.namespace_name) + total = len(parsed_args.namespace) msg = _("%(result)s of %(total)s object failed to delete.") % { 'result': result, 'total': total, @@ -176,10 +172,10 @@ class ListMetadefObjects(command.Lister): def take_action(self, parsed_args): image_client = self.app.client_manager.image - namespace_name = parsed_args.namespace + namespace = parsed_args.namespace columns = ['name', 'description'] - md_objects = list(image_client.metadef_objects(namespace_name)) + md_objects = list(image_client.metadef_objects(namespace)) column_headers = columns return ( column_headers, diff --git a/openstackclient/image/v2/metadef_properties.py b/openstackclient/image/v2/metadef_properties.py index d2fa4abd4..40440c029 100644 --- a/openstackclient/image/v2/metadef_properties.py +++ b/openstackclient/image/v2/metadef_properties.py @@ -13,6 +13,7 @@ # under the License. import json +import logging from osc_lib.command import command from osc_lib import exceptions @@ -21,6 +22,9 @@ from osc_lib import utils from openstackclient.i18n import _ +LOG = logging.getLogger(__name__) + + def _format_property(prop): prop = prop.to_dict(ignore_none=True, original_names=True) return { @@ -76,7 +80,7 @@ class CreateMetadefProperty(command.ShowOne): help=_("Valid JSON schema of the property"), ) parser.add_argument( - "namespace_name", + "namespace", help=_("Name of namespace the property will belong."), ) return parser @@ -100,7 +104,7 @@ class CreateMetadefProperty(command.ShowOne): ) data = image_client.create_metadef_property( - parsed_args.namespace_name, **kwargs + parsed_args.namespace, **kwargs ) info = _format_property(data) @@ -108,41 +112,55 @@ class CreateMetadefProperty(command.ShowOne): class DeleteMetadefProperty(command.Command): - _description = _("Delete a metadef property") + _description = _("Delete metadef propert(ies)") def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument( - "namespace_name", - help=_("An identifier (a name) for the namespace"), + "namespace", + metavar="", + help=_("Metadef namespace of the property (name)"), ) parser.add_argument( - "property_name", - help=_("Property to delete"), + "properties", + metavar="", + nargs="+", + help=_("Metadef propert(ies) to delete (name)"), ) return parser def take_action(self, parsed_args): image_client = self.app.client_manager.image - try: - image_client.delete_metadef_property( - parsed_args.property_name, - parsed_args.namespace_name, - ignore_missing=False, - ) - except Exception as e: - raise exceptions.CommandError( - _( - "Failed to delete property with name or " - "ID '%(property)s' from namespace '%(namespace)s': %(e)s" + result = 0 + for prop in parsed_args.properties: + try: + image_client.delete_metadef_property( + prop, + parsed_args.namespace, + ignore_missing=False, ) - % { - 'property': parsed_args.property_name, - 'namespace': parsed_args.namespace_name, - 'e': e, - } - ) + except Exception as e: + result += 1 + LOG.error( + _( + "Failed to delete property with name or ID " + "'%(property)s' from namespace '%(namespace)s': %(e)s" + ), + { + 'property': prop, + 'namespace': parsed_args.namespace, + 'e': e, + }, + ) + + if result > 0: + total = len(parsed_args.namespace) + msg = _("%(result)s of %(total)s properties failed to delete.") % { + 'result': result, + 'total': total, + } + raise exceptions.CommandError(msg) class ListMetadefProperties(command.Lister): @@ -151,15 +169,15 @@ class ListMetadefProperties(command.Lister): def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument( - "namespace_name", - metavar="", + "namespace", + metavar="", help=_("An identifier (a name) for the namespace"), ) return parser def take_action(self, parsed_args): image_client = self.app.client_manager.image - props = image_client.metadef_properties(parsed_args.namespace_name) + props = image_client.metadef_properties(parsed_args.namespace) columns = ['name', 'title', 'type'] return ( columns, @@ -195,11 +213,11 @@ class SetMetadefProperty(command.Command): help=_("Valid JSON schema of the property"), ) parser.add_argument( - "namespace_name", + "namespace", help=_("Namespace of the namespace to which the property belongs"), ) parser.add_argument( - "property_name", + "property", help=_("Property to update"), ) return parser @@ -211,7 +229,8 @@ class SetMetadefProperty(command.Command): # update_metadef_property(), otherwise the attributes that are not # listed will be reset. data = image_client.get_metadef_property( - parsed_args.property_name, parsed_args.namespace_name + parsed_args.property, + parsed_args.namespace, ) kwargs = _format_property(data) for key in ['name', 'title', 'type']: @@ -231,23 +250,25 @@ class SetMetadefProperty(command.Command): ) image_client.update_metadef_property( - parsed_args.property_name, parsed_args.namespace_name, **kwargs + parsed_args.property, + parsed_args.namespace, + **kwargs, ) class ShowMetadefProperty(command.ShowOne): - _description = _("Describe a specific property from a namespace") + _description = _("Show a particular metadef property") def get_parser(self, prog_name): parser = super().get_parser(prog_name) parser.add_argument( - "namespace_name", - metavar="", - help=_("Namespace (name) for the namespace"), + "namespace", + metavar="", + help=_("Metadef namespace of the property (name)"), ) parser.add_argument( - "property_name", - metavar="", + "property", + metavar="", help=_("Property to show"), ) return parser @@ -255,7 +276,8 @@ class ShowMetadefProperty(command.ShowOne): def take_action(self, parsed_args): image_client = self.app.client_manager.image data = image_client.get_metadef_property( - parsed_args.property_name, parsed_args.namespace_name + parsed_args.property, + parsed_args.namespace, ) info = _format_property(data) diff --git a/openstackclient/tests/unit/image/v2/test_metadef_namespaces.py b/openstackclient/tests/unit/image/v2/test_metadef_namespaces.py index 0b0ddbe0b..68b3076d5 100644 --- a/openstackclient/tests/unit/image/v2/test_metadef_namespaces.py +++ b/openstackclient/tests/unit/image/v2/test_metadef_namespaces.py @@ -40,7 +40,7 @@ class TestMetadefNamespaceCreate(image_fakes.TestImagev2): self.image_client.create_metadef_namespace.return_value = ( self._metadef_namespace ) - self.cmd = metadef_namespaces.CreateMetadefNameSpace(self.app, None) + self.cmd = metadef_namespaces.CreateMetadefNamespace(self.app, None) self.datalist = self._metadef_namespace def test_namespace_create(self): @@ -64,7 +64,7 @@ class TestMetadefNamespaceDelete(image_fakes.TestImagev2): self.image_client.delete_metadef_namespace.return_value = ( self._metadef_namespace ) - self.cmd = metadef_namespaces.DeleteMetadefNameSpace(self.app, None) + self.cmd = metadef_namespaces.DeleteMetadefNamespace(self.app, None) self.datalist = self._metadef_namespace def test_namespace_create(self): @@ -97,7 +97,7 @@ class TestMetadefNamespaceList(image_fakes.TestImagev2): self.image_client.metadef_namespaces.return_value = iter( self._metadef_namespace ) - self.cmd = metadef_namespaces.ListMetadefNameSpaces(self.app, None) + self.cmd = metadef_namespaces.ListMetadefNamespace(self.app, None) self.datalist = self._metadef_namespace def test_namespace_list_no_options(self): @@ -122,7 +122,7 @@ class TestMetadefNamespaceSet(image_fakes.TestImagev2): self.image_client.update_metadef_namespace.return_value = ( self._metadef_namespace ) - self.cmd = metadef_namespaces.SetMetadefNameSpace(self.app, None) + self.cmd = metadef_namespaces.SetMetadefNamespace(self.app, None) self.datalist = self._metadef_namespace def test_namespace_set_no_options(self): @@ -162,7 +162,7 @@ class TestMetadefNamespaceShow(image_fakes.TestImagev2): self.image_client.get_metadef_namespace.return_value = ( self._metadef_namespace ) - self.cmd = metadef_namespaces.ShowMetadefNameSpace(self.app, None) + self.cmd = metadef_namespaces.ShowMetadefNamespace(self.app, None) def test_namespace_show_no_options(self): arglist = [self._metadef_namespace.namespace] diff --git a/setup.cfg b/setup.cfg index ac1c7d67e..e19c46488 100644 --- a/setup.cfg +++ b/setup.cfg @@ -393,20 +393,17 @@ openstack.image.v2 = image_import = openstackclient.image.v2.image:ImportImage image_stores_list = openstackclient.image.v2.image:StoresInfo - - image_metadef_namespace_create = openstackclient.image.v2.metadef_namespaces:CreateMetadefNameSpace - image_metadef_namespace_delete = openstackclient.image.v2.metadef_namespaces:DeleteMetadefNameSpace - image_metadef_namespace_list = openstackclient.image.v2.metadef_namespaces:ListMetadefNameSpaces - image_metadef_namespace_set = openstackclient.image.v2.metadef_namespaces:SetMetadefNameSpace - image_metadef_namespace_show = openstackclient.image.v2.metadef_namespaces:ShowMetadefNameSpace - + image_metadef_namespace_create = openstackclient.image.v2.metadef_namespaces:CreateMetadefNamespace + image_metadef_namespace_delete = openstackclient.image.v2.metadef_namespaces:DeleteMetadefNamespace + image_metadef_namespace_list = openstackclient.image.v2.metadef_namespaces:ListMetadefNamespace + image_metadef_namespace_set = openstackclient.image.v2.metadef_namespaces:SetMetadefNamespace + image_metadef_namespace_show = openstackclient.image.v2.metadef_namespaces:ShowMetadefNamespace image_metadef_object_create = openstackclient.image.v2.metadef_objects:CreateMetadefObjects image_metadef_object_show = openstackclient.image.v2.metadef_objects:ShowMetadefObjects image_metadef_object_list = openstackclient.image.v2.metadef_objects:ListMetadefObjects image_metadef_object_delete = openstackclient.image.v2.metadef_objects:DeleteMetadefObject - image_metadef_property_create = openstackclient.image.v2.metadef_properties:CreateMetadefProperty image_metadef_property_delete = openstackclient.image.v2.metadef_properties:DeleteMetadefProperty image_metadef_property_list = openstackclient.image.v2.metadef_properties:ListMetadefProperties @@ -420,7 +417,6 @@ openstack.image.v2 = cached_image_delete = openstackclient.image.v2.cache:DeleteCachedImage cached_image_clear = openstackclient.image.v2.cache:ClearCachedImage - openstack.network.v2 = address_group_create = openstackclient.network.v2.address_group:CreateAddressGroup address_group_delete = openstackclient.network.v2.address_group:DeleteAddressGroup