diff --git a/doc/source/cli/data/glance.csv b/doc/source/cli/data/glance.csv index 706a894ba..5b1bef0b2 100644 --- a/doc/source/cli/data/glance.csv +++ b/doc/source/cli/data/glance.csv @@ -42,7 +42,7 @@ md-property-create,image metadef property create,Create a new metadata definitio md-property-delete,image metadef property delete,Delete a specific metadata definitions property inside a namespace. md-property-list,image metadef property list,List metadata definitions properties inside a specific namespace. md-property-show,image metadef property show,Describe a specific metadata definitions property inside a namespace. -md-property-update,,Update metadata definitions property inside a namespace. +md-property-update,image metadef property set,Update metadata definitions property inside a namespace. md-resource-type-associate,,Associate resource type with a metadata definitions namespace. md-resource-type-deassociate,,Deassociate resource type with a metadata definitions namespace. md-resource-type-list,,List available resource type names. diff --git a/openstackclient/image/v2/metadef_properties.py b/openstackclient/image/v2/metadef_properties.py index 007e018ae..d2fa4abd4 100644 --- a/openstackclient/image/v2/metadef_properties.py +++ b/openstackclient/image/v2/metadef_properties.py @@ -173,6 +173,68 @@ class ListMetadefProperties(command.Lister): ) +class SetMetadefProperty(command.Command): + _description = _("Update metadef namespace property") + + def get_parser(self, prog_name): + parser = super().get_parser(prog_name) + parser.add_argument( + "--name", + help=_("Internal name of the property"), + ) + parser.add_argument( + "--title", + help=_("Property name displayed to the user"), + ) + parser.add_argument( + "--type", + help=_("Property type"), + ) + parser.add_argument( + "--schema", + help=_("Valid JSON schema of the property"), + ) + parser.add_argument( + "namespace_name", + help=_("Namespace of the namespace to which the property belongs"), + ) + parser.add_argument( + "property_name", + help=_("Property to update"), + ) + return parser + + def take_action(self, parsed_args): + image_client = self.app.client_manager.image + + # We need to pass the values for *all* attributes as kwargs to + # 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 + ) + kwargs = _format_property(data) + for key in ['name', 'title', 'type']: + argument = getattr(parsed_args, key, None) + if argument is not None: + kwargs[key] = argument + + if parsed_args.schema: + try: + kwargs.update(json.loads(parsed_args.schema)) + except json.JSONDecodeError as e: + raise exceptions.CommandError( + _("Failed to load JSON schema: %(e)s") + % { + 'e': e, + } + ) + + image_client.update_metadef_property( + parsed_args.property_name, parsed_args.namespace_name, **kwargs + ) + + class ShowMetadefProperty(command.ShowOne): _description = _("Describe a specific property from a namespace") diff --git a/openstackclient/tests/unit/image/v2/test_metadef_properties.py b/openstackclient/tests/unit/image/v2/test_metadef_properties.py index fa59c29cd..274ed6635 100644 --- a/openstackclient/tests/unit/image/v2/test_metadef_properties.py +++ b/openstackclient/tests/unit/image/v2/test_metadef_properties.py @@ -160,6 +160,40 @@ class TestMetadefPropertyList(image_fakes.TestImagev2): self.assertEqual(getattr(self.datalist[0], 'name'), next(data)[0]) +class TestMetadefPropertySet(image_fakes.TestImagev2): + _metadef_property = image_fakes.create_one_metadef_property() + + def setUp(self): + super().setUp() + + self.cmd = metadef_properties.SetMetadefProperty(self.app, None) + self.image_client.get_metadef_property.return_value = ( + self._metadef_property + ) + + def test_metadef_property_set(self): + arglist = ['--title', 'new title', 'namespace', 'property'] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + self.assertIsNone(result) + + def test_metadef_property_set_invalid_schema(self): + arglist = [ + '--title', + 'new title', + '--schema', + '{invalid}', + 'namespace', + 'property', + ] + verifylist = [] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises( + exceptions.CommandError, self.cmd.take_action, parsed_args + ) + + class TestMetadefPropertyShow(image_fakes.TestImagev2): _metadef_property = image_fakes.create_one_metadef_property() diff --git a/releasenotes/notes/add-metadef-property-set-ab9cdcb73adf6397.yaml b/releasenotes/notes/add-metadef-property-set-ab9cdcb73adf6397.yaml new file mode 100644 index 000000000..cf07d527d --- /dev/null +++ b/releasenotes/notes/add-metadef-property-set-ab9cdcb73adf6397.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Add ``image metadef property set`` command to update a + metadef property inside a specific namespace. diff --git a/setup.cfg b/setup.cfg index 9f1f254e6..1212ad9fe 100644 --- a/setup.cfg +++ b/setup.cfg @@ -400,6 +400,7 @@ openstack.image.v2 = 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 + image_metadef_property_set = openstackclient.image.v2.metadef_properties:SetMetadefProperty image_metadef_property_show = openstackclient.image.v2.metadef_properties:ShowMetadefProperty image_metadef_resource_type_list = openstackclient.image.v2.metadef_resource_types:ListMetadefResourceTypes