Add "image metadef property create" command
Change-Id: Icb4fab0aef13b28212771da3a3b7c4a0775bb38e
This commit is contained in:
		@@ -38,7 +38,7 @@ md-object-list,,List metadata definitions objects inside a specific namespace.
 | 
			
		||||
md-object-property-show,,Describe a specific metadata definitions property inside an object.
 | 
			
		||||
md-object-show,,Describe a specific metadata definitions object inside a namespace.
 | 
			
		||||
md-object-update,,Update metadata definitions object inside a namespace.
 | 
			
		||||
md-property-create,,Create a new metadata definitions property inside a namespace.
 | 
			
		||||
md-property-create,image metadef property create,Create a new metadata definitions property inside a namespace.
 | 
			
		||||
md-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.
 | 
			
		||||
 
 | 
			
		||||
		
		
			
  | 
@@ -12,12 +12,101 @@
 | 
			
		||||
# License for the specific language governing permissions and limitations
 | 
			
		||||
# under the License.
 | 
			
		||||
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
from osc_lib.command import command
 | 
			
		||||
from osc_lib import exceptions
 | 
			
		||||
from osc_lib import utils
 | 
			
		||||
 | 
			
		||||
from openstackclient.i18n import _
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _format_property(prop):
 | 
			
		||||
    prop = prop.to_dict(ignore_none=True, original_names=True)
 | 
			
		||||
    return {
 | 
			
		||||
        key: prop[key]
 | 
			
		||||
        for key in [
 | 
			
		||||
            'namespace_name',
 | 
			
		||||
            'name',
 | 
			
		||||
            'type',
 | 
			
		||||
            'title',
 | 
			
		||||
            'description',
 | 
			
		||||
            'operators',
 | 
			
		||||
            'default',
 | 
			
		||||
            'is_readonly',
 | 
			
		||||
            'minimum',
 | 
			
		||||
            'maximum',
 | 
			
		||||
            'enum',
 | 
			
		||||
            'pattern',
 | 
			
		||||
            'min_length',
 | 
			
		||||
            'max_length',
 | 
			
		||||
            'items',
 | 
			
		||||
            'require_unique_items',
 | 
			
		||||
            'min_items',
 | 
			
		||||
            'max_items',
 | 
			
		||||
            'allow_additional_items',
 | 
			
		||||
        ]
 | 
			
		||||
        if key in prop
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CreateMetadefProperty(command.ShowOne):
 | 
			
		||||
    _description = _("Create a metadef property")
 | 
			
		||||
 | 
			
		||||
    def get_parser(self, prog_name):
 | 
			
		||||
        parser = super().get_parser(prog_name)
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--name",
 | 
			
		||||
            required=True,
 | 
			
		||||
            help=_("Internal name of the property"),
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--title",
 | 
			
		||||
            required=True,
 | 
			
		||||
            help=_("Property name displayed to the user"),
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--type",
 | 
			
		||||
            required=True,
 | 
			
		||||
            help=_("Property type"),
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "--schema",
 | 
			
		||||
            required=True,
 | 
			
		||||
            help=_("Valid JSON schema of the property"),
 | 
			
		||||
        )
 | 
			
		||||
        parser.add_argument(
 | 
			
		||||
            "namespace_name",
 | 
			
		||||
            help=_("Name of namespace the property will belong."),
 | 
			
		||||
        )
 | 
			
		||||
        return parser
 | 
			
		||||
 | 
			
		||||
    def take_action(self, parsed_args):
 | 
			
		||||
        image_client = self.app.client_manager.image
 | 
			
		||||
 | 
			
		||||
        kwargs = {
 | 
			
		||||
            'name': parsed_args.name,
 | 
			
		||||
            'title': parsed_args.title,
 | 
			
		||||
            'type': parsed_args.type,
 | 
			
		||||
        }
 | 
			
		||||
        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,
 | 
			
		||||
                }
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        data = image_client.create_metadef_property(
 | 
			
		||||
            parsed_args.namespace_name, **kwargs
 | 
			
		||||
        )
 | 
			
		||||
        info = _format_property(data)
 | 
			
		||||
 | 
			
		||||
        return zip(*sorted(info.items()))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class ListMetadefProperties(command.Lister):
 | 
			
		||||
    _description = _("List metadef properties")
 | 
			
		||||
 | 
			
		||||
@@ -68,31 +157,6 @@ class ShowMetadefProperty(command.ShowOne):
 | 
			
		||||
        data = image_client.get_metadef_property(
 | 
			
		||||
            parsed_args.property_name, parsed_args.namespace_name
 | 
			
		||||
        )
 | 
			
		||||
        data = data.to_dict(ignore_none=True, original_names=True)
 | 
			
		||||
        info = {
 | 
			
		||||
            key: data[key]
 | 
			
		||||
            for key in [
 | 
			
		||||
                'namespace_name',
 | 
			
		||||
                'name',
 | 
			
		||||
                'type',
 | 
			
		||||
                'title',
 | 
			
		||||
                'description',
 | 
			
		||||
                'operators',
 | 
			
		||||
                'default',
 | 
			
		||||
                'is_readonly',
 | 
			
		||||
                'minimum',
 | 
			
		||||
                'maximum',
 | 
			
		||||
                'enum',
 | 
			
		||||
                'pattern',
 | 
			
		||||
                'min_length',
 | 
			
		||||
                'max_length',
 | 
			
		||||
                'items',
 | 
			
		||||
                'require_unique_items',
 | 
			
		||||
                'min_items',
 | 
			
		||||
                'max_items',
 | 
			
		||||
                'allow_additional_items',
 | 
			
		||||
            ]
 | 
			
		||||
            if key in data
 | 
			
		||||
        }
 | 
			
		||||
        info = _format_property(data)
 | 
			
		||||
 | 
			
		||||
        return zip(*sorted(info.items()))
 | 
			
		||||
 
 | 
			
		||||
@@ -12,8 +12,77 @@
 | 
			
		||||
# License for the specific language governing permissions and limitations
 | 
			
		||||
# under the License.
 | 
			
		||||
 | 
			
		||||
from osc_lib import exceptions
 | 
			
		||||
 | 
			
		||||
from openstackclient.image.v2 import metadef_properties
 | 
			
		||||
from openstackclient.tests.unit.image.v2 import fakes as image_fakes
 | 
			
		||||
from openstackclient.tests.unit import utils as tests_utils
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestMetadefPropertyCreate(image_fakes.TestImagev2):
 | 
			
		||||
    _metadef_namespace = image_fakes.create_one_metadef_namespace()
 | 
			
		||||
    _metadef_property = image_fakes.create_one_metadef_property()
 | 
			
		||||
    expected_columns = (
 | 
			
		||||
        'name',
 | 
			
		||||
        'title',
 | 
			
		||||
        'type',
 | 
			
		||||
    )
 | 
			
		||||
    expected_data = (
 | 
			
		||||
        _metadef_property.name,
 | 
			
		||||
        _metadef_property.title,
 | 
			
		||||
        _metadef_property.type,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        super().setUp()
 | 
			
		||||
        self.image_client.create_metadef_property.return_value = (
 | 
			
		||||
            self._metadef_property
 | 
			
		||||
        )
 | 
			
		||||
        self.cmd = metadef_properties.CreateMetadefProperty(self.app, None)
 | 
			
		||||
 | 
			
		||||
    def test_metadef_property_create_missing_arguments(self):
 | 
			
		||||
        self.assertRaises(
 | 
			
		||||
            tests_utils.ParserException, self.check_parser, self.cmd, [], []
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def test_metadef_property_create(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--name',
 | 
			
		||||
            'cpu_cores',
 | 
			
		||||
            '--schema',
 | 
			
		||||
            '{}',
 | 
			
		||||
            '--title',
 | 
			
		||||
            'vCPU Cores',
 | 
			
		||||
            '--type',
 | 
			
		||||
            'integer',
 | 
			
		||||
            self._metadef_namespace.namespace,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = []
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        columns, data = self.cmd.take_action(parsed_args)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual(self.expected_columns, columns)
 | 
			
		||||
        self.assertEqual(self.expected_data, data)
 | 
			
		||||
 | 
			
		||||
    def test_metadef_property_create_invalid_schema(self):
 | 
			
		||||
        arglist = [
 | 
			
		||||
            '--name',
 | 
			
		||||
            'cpu_cores',
 | 
			
		||||
            '--schema',
 | 
			
		||||
            '{invalid}',
 | 
			
		||||
            '--title',
 | 
			
		||||
            'vCPU Cores',
 | 
			
		||||
            '--type',
 | 
			
		||||
            'integer',
 | 
			
		||||
            self._metadef_namespace.namespace,
 | 
			
		||||
        ]
 | 
			
		||||
        verifylist = []
 | 
			
		||||
        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
 | 
			
		||||
 | 
			
		||||
        self.assertRaises(
 | 
			
		||||
            exceptions.CommandError, self.cmd.take_action, parsed_args
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestMetadefPropertyList(image_fakes.TestImagev2):
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,5 @@
 | 
			
		||||
---
 | 
			
		||||
features:
 | 
			
		||||
  - |
 | 
			
		||||
    Add ``image metadef property create`` command to create a new
 | 
			
		||||
    metadef property inside a specific namespace.
 | 
			
		||||
@@ -397,6 +397,7 @@ openstack.image.v2 =
 | 
			
		||||
    image_metadef_namespace_set = openstackclient.image.v2.metadef_namespaces:SetMetadefNameSpace
 | 
			
		||||
    image_metadef_namespace_show = openstackclient.image.v2.metadef_namespaces:ShowMetadefNameSpace
 | 
			
		||||
 | 
			
		||||
    image_metadef_property_create = openstackclient.image.v2.metadef_properties:CreateMetadefProperty
 | 
			
		||||
    image_metadef_property_list = openstackclient.image.v2.metadef_properties:ListMetadefProperties
 | 
			
		||||
    image_metadef_property_show = openstackclient.image.v2.metadef_properties:ShowMetadefProperty
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user