Add image metadef resource type association commands

'create', 'list', 'delete'

Change-Id: I2c860427b0b2693076cfe57841f0e512ad1f6388
This commit is contained in:
Antonia Gaete 2023-06-06 16:46:56 +00:00 committed by Stephen Finucane
parent b740f2f6bd
commit 276dbb6f56
6 changed files with 385 additions and 4 deletions

View File

@ -28,7 +28,7 @@ md-namespace-import,,Import a metadata definitions namespace from file or standa
md-namespace-list,image metadef namespace list,List metadata definitions namespaces. md-namespace-list,image metadef namespace list,List metadata definitions namespaces.
md-namespace-objects-delete,,Delete all metadata definitions objects inside a specific namespace. md-namespace-objects-delete,,Delete all metadata definitions objects inside a specific namespace.
md-namespace-properties-delete,,Delete all metadata definitions property inside a specific namespace. md-namespace-properties-delete,,Delete all metadata definitions property inside a specific namespace.
md-namespace-resource-type-list,image metadef resource type list,List resource types associated to specific namespace. md-namespace-resource-type-list,image metadef resource type association list,List resource types associated to specific namespace.
md-namespace-show,image metadef namespace show,Describe a specific metadata definitions namespace. md-namespace-show,image metadef namespace show,Describe a specific metadata definitions namespace.
md-namespace-tags-delete,,Delete all metadata definitions tags inside a specific namespace. md-namespace-tags-delete,,Delete all metadata definitions tags inside a specific namespace.
md-namespace-update,,Update an existing metadata definitions namespace. md-namespace-update,,Update an existing metadata definitions namespace.
@ -43,9 +43,9 @@ md-property-delete,image metadef property delete,Delete a specific metadata defi
md-property-list,image metadef property list,List metadata definitions properties inside a specific 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-show,image metadef property show,Describe a specific metadata definitions property inside a namespace.
md-property-update,image metadef property set,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-associate,image metadef resource type association create,Associate resource type with a metadata definitions namespace.
md-resource-type-deassociate,,Deassociate resource type with a metadata definitions namespace. md-resource-type-deassociate,image metadef resource type association delete,Deassociate resource type with a metadata definitions namespace.
md-resource-type-list,,List available resource type names. md-resource-type-list,image metadef resource type list,List available resource type names.
md-tag-create,,Add a new metadata definitions tag inside a namespace. md-tag-create,,Add a new metadata definitions tag inside a namespace.
md-tag-create-multiple,,Create new metadata definitions tags inside a namespace. md-tag-create-multiple,,Create new metadata definitions tags inside a namespace.
md-tag-delete,,Delete a specific metadata definitions tag inside a namespace. md-tag-delete,,Delete a specific metadata definitions tag inside a namespace.

1 cache-clear cached image list Clear all images from cache, queue or both.
28 md-namespace-list image metadef namespace list List metadata definitions namespaces.
29 md-namespace-objects-delete Delete all metadata definitions objects inside a specific namespace.
30 md-namespace-properties-delete Delete all metadata definitions property inside a specific namespace.
31 md-namespace-resource-type-list image metadef resource type list image metadef resource type association list List resource types associated to specific namespace.
32 md-namespace-show image metadef namespace show Describe a specific metadata definitions namespace.
33 md-namespace-tags-delete Delete all metadata definitions tags inside a specific namespace.
34 md-namespace-update Update an existing metadata definitions namespace.
43 md-property-list image metadef property list List metadata definitions properties inside a specific namespace.
44 md-property-show image metadef property show Describe a specific metadata definitions property inside a namespace.
45 md-property-update image metadef property set Update metadata definitions property inside a namespace.
46 md-resource-type-associate image metadef resource type association create Associate resource type with a metadata definitions namespace.
47 md-resource-type-deassociate image metadef resource type association delete Deassociate resource type with a metadata definitions namespace.
48 md-resource-type-list image metadef resource type list List available resource type names.
49 md-tag-create Add a new metadata definitions tag inside a namespace.
50 md-tag-create-multiple Create new metadata definitions tags inside a namespace.
51 md-tag-delete Delete a specific metadata definitions tag inside a namespace.

View File

@ -0,0 +1,189 @@
# 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 logging
from osc_lib.command import command
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.i18n import _
LOG = logging.getLogger(__name__)
def _get_columns(item):
column_map = {}
hidden_columns = ['location']
return utils.get_osc_show_columns_for_sdk_resource(
item, column_map, hidden_columns
)
class CreateMetadefResourceTypeAssociation(command.ShowOne):
_description = _("Create metadef resource type association")
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
parser.add_argument(
"namespace",
metavar="<namespace>",
help=_(
"The name of the namespace you want to create the "
"resource type association in"
),
)
parser.add_argument(
"name",
metavar="<name>",
help=_("A name of the new resource type"),
)
parser.add_argument(
"--properties-target",
metavar="<properties_target>",
help=_(
"Some resource types allow more than one "
"key/value pair per instance."
),
)
return parser
def take_action(self, parsed_args):
image_client = self.app.client_manager.image
kwargs = {}
kwargs['namespace'] = parsed_args.namespace
kwargs['name'] = parsed_args.name
if parsed_args.properties_target:
kwargs['properties_target'] = parsed_args.properties_target
obj = image_client.create_metadef_resource_type_association(
parsed_args.namespace, **kwargs
)
display_columns, columns = _get_columns(obj)
data = utils.get_item_properties(obj, columns, formatters={})
return (display_columns, data)
class DeleteMetadefResourceTypeAssociation(command.Command):
_description = _("Delete metadef resource type association")
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
parser.add_argument(
"metadef_namespace",
metavar="<metadef_namespace>",
help=_("The name of the namespace whose details you want to see"),
)
parser.add_argument(
"name",
metavar="<name>",
nargs="+",
help=_(
"The name of the resource type(s) (repeat option to delete"
"multiple metadef resource type associations)"
),
)
parser.add_argument(
"--force",
dest='force',
action='store_true',
default=False,
help=_(
"Force delete the resource type association if the"
"namespace is protected"
),
)
return parser
def take_action(self, parsed_args):
image_client = self.app.client_manager.image
result = 0
for resource_type in parsed_args.name:
try:
metadef_namespace = image_client.get_metadef_namespace(
parsed_args.metadef_namespace
)
kwargs = {}
is_initially_protected = (
True if metadef_namespace.is_protected else False
)
if is_initially_protected and parsed_args.force:
kwargs['is_protected'] = False
image_client.update_metadef_namespace(
metadef_namespace.namespace, **kwargs
)
try:
image_client.delete_metadef_resource_type_association(
resource_type, metadef_namespace, ignore_missing=False
)
finally:
if is_initially_protected:
kwargs['is_protected'] = True
image_client.update_metadef_namespace(
metadef_namespace.namespace, **kwargs
)
except Exception as e:
result += 1
LOG.error(
_(
"Failed to delete resource type with name or "
"ID '%(resource_type)s': %(e)s"
),
{'resource_type': resource_type, 'e': e},
)
if result > 0:
total = len(parsed_args.metadef_namespace)
msg = _(
"%(result)s of %(total)s resource type failed to delete."
) % {'result': result, 'total': total}
raise exceptions.CommandError(msg)
class ListMetadefResourceTypeAssociations(command.Lister):
_description = _("List metadef resource type associations")
def get_parser(self, prog_name):
parser = super().get_parser(prog_name)
parser.add_argument(
"metadef_namespace",
metavar="<metadef_namespace>",
help=_("The name of the namespace whose details you want to see"),
)
return parser
def take_action(self, parsed_args):
image_client = self.app.client_manager.image
data = image_client.metadef_resource_type_associations(
parsed_args.metadef_namespace,
)
columns = ['Name']
column_headers = columns
return (
column_headers,
(
utils.get_item_properties(
s,
columns,
)
for s in data
),
)

View File

@ -381,3 +381,44 @@ def create_one_metadef_object(attrs=None):
# Overwrite default attributes if there are some attributes set # Overwrite default attributes if there are some attributes set
metadef_objects_list.update(attrs) metadef_objects_list.update(attrs)
return metadef_object.MetadefObject(**metadef_objects_list) return metadef_object.MetadefObject(**metadef_objects_list)
def create_one_resource_type_association(attrs=None):
"""Create a fake MetadefResourceTypeAssociation.
:param attrs: A dictionary with all attributes of
metadef_resource_type_association member
:type attrs: dict
:return: A fake MetadefResourceTypeAssociation object
:rtype: A `metadef_resource_type_association.
MetadefResourceTypeAssociation`
"""
attrs = attrs or {}
metadef_resource_type_association_info = {
'namespace_name': 'OS::Compute::Quota',
'name': 'OS::Nova::Flavor',
}
metadef_resource_type_association_info.update(attrs)
return metadef_resource_type.MetadefResourceTypeAssociation(
**metadef_resource_type_association_info
)
def create_resource_type_associations(attrs=None, count=2):
"""Create mutiple fake resource type associations/
:param attrs: A dictionary with all attributes of
metadef_resource_type_association member
:type attrs: dict
:return: A list of fake MetadefResourceTypeAssociation objects
:rtype: list
"""
resource_type_associations = []
for n in range(0, count):
resource_type_associations.append(
create_one_resource_type_association(attrs)
)
return resource_type_associations

View File

@ -0,0 +1,131 @@
# 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.
from openstackclient.image.v2 import metadef_resource_type_association
from openstackclient.tests.unit.image.v2 import fakes as resource_type_fakes
class TestMetadefResourceTypeAssociationCreate(
resource_type_fakes.TestImagev2
):
resource_type_association = (
resource_type_fakes.create_one_resource_type_association()
)
columns = (
'created_at',
'id',
'name',
'prefix',
'properties_target',
'updated_at',
)
data = (
resource_type_association.created_at,
resource_type_association.id,
resource_type_association.name,
resource_type_association.prefix,
resource_type_association.properties_target,
resource_type_association.updated_at,
)
def setUp(self):
super().setUp()
self.image_client.create_metadef_resource_type_association.return_value = (
self.resource_type_association
)
self.cmd = metadef_resource_type_association.CreateMetadefResourceTypeAssociation(
self.app, None
)
def test_resource_type_association_create(self):
arglist = [
self.resource_type_association.namespace_name,
self.resource_type_association.name,
]
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
class TestMetadefResourceTypeAssociationDelete(
resource_type_fakes.TestImagev2
):
resource_type_association = (
resource_type_fakes.create_one_resource_type_association()
)
def setUp(self):
super().setUp()
self.image_client.delete_metadef_resource_type_association.return_value = (
self.resource_type_association
)
self.cmd = metadef_resource_type_association.DeleteMetadefResourceTypeAssociation(
self.app, None
)
def test_resource_type_association_delete(self):
arglist = [
self.resource_type_association.namespace_name,
self.resource_type_association.name,
]
verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.assertIsNone(result)
class TestMetadefResourceTypeAssociationList(resource_type_fakes.TestImagev2):
resource_type_associations = (
resource_type_fakes.create_resource_type_associations()
)
columns = ['Name']
datalist = [
(resource_type_association.name,)
for resource_type_association in resource_type_associations
]
def setUp(self):
super().setUp()
self.image_client.metadef_resource_type_associations.side_effect = [
self.resource_type_associations,
[],
]
self.cmd = metadef_resource_type_association.ListMetadefResourceTypeAssociations(
self.app, None
)
def test_resource_type_association_list(self):
arglist = [
self.resource_type_associations[0].namespace_name,
]
parsed_args = self.check_parser(self.cmd, arglist, [])
columns, data = self.cmd.take_action(parsed_args)
self.assertEqual(self.columns, columns)
self.assertCountEqual(self.datalist, data)

View File

@ -0,0 +1,17 @@
---
features:
- |
Added ``image metadef resource type association list``
to list resource type associations for the image service.
This is equivalent to the
``md-namespace-resource-type-list`` command in glance.
- |
Added ``image metadef resource type association create``
to create a resource type association for the image service.
This is equivalent to the
``md-resource-type-associate`` command in glance.
- |
Added ``image metadef resource type association delete``
to delete a resource type association for the image service.
This is equivalent to the
``md-resource-type-deassociate`` command in glance.

View File

@ -411,6 +411,9 @@ openstack.image.v2 =
image_metadef_property_show = openstackclient.image.v2.metadef_properties:ShowMetadefProperty image_metadef_property_show = openstackclient.image.v2.metadef_properties:ShowMetadefProperty
image_metadef_resource_type_list = openstackclient.image.v2.metadef_resource_types:ListMetadefResourceTypes image_metadef_resource_type_list = openstackclient.image.v2.metadef_resource_types:ListMetadefResourceTypes
image_metadef_resource_type_association_create = openstackclient.image.v2.metadef_resource_type_association:CreateMetadefResourceTypeAssociation
image_metadef_resource_type_association_delete = openstackclient.image.v2.metadef_resource_type_association:DeleteMetadefResourceTypeAssociation
image_metadef_resource_type_association_list = openstackclient.image.v2.metadef_resource_type_association:ListMetadefResourceTypeAssociations
cached_image_list = openstackclient.image.v2.cache:ListCachedImage cached_image_list = openstackclient.image.v2.cache:ListCachedImage
cached_image_queue = openstackclient.image.v2.cache:QueueCachedImage cached_image_queue = openstackclient.image.v2.cache:QueueCachedImage