Merge "Add "image metadef property create" command"
This commit is contained in:
commit
43cec266d9
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user