diff --git a/openstackclient/image/v2/metadef_namespaces.py b/openstackclient/image/v2/metadef_namespaces.py
index 158fd94e3b..f09f200249 100644
--- a/openstackclient/image/v2/metadef_namespaces.py
+++ b/openstackclient/image/v2/metadef_namespaces.py
@@ -15,8 +15,11 @@
 
 """Image V2 Action Implementations"""
 
+import logging
+
 from osc_lib.cli import format_columns
 from osc_lib.command import command
+from osc_lib import exceptions
 from osc_lib import utils
 
 from openstackclient.i18n import _
@@ -25,6 +28,149 @@ _formatters = {
     'tags': format_columns.ListColumn,
 }
 
+LOG = logging.getLogger(__name__)
+
+
+def _format_namespace(namespace):
+    info = {}
+
+    fields_to_show = [
+        'created_at',
+        'description',
+        'display_name',
+        'namespace',
+        'owner',
+        'protected',
+        'schema',
+        'visibility',
+    ]
+
+    namespace = namespace.to_dict(ignore_none=True, original_names=True)
+
+    # split out the usual key and the properties which are top-level
+    for key in namespace:
+        if key in fields_to_show:
+            info[key] = namespace.get(key)
+        elif key == "resource_type_associations":
+            info[key] = [resource_type['name']
+                         for resource_type in namespace.get(key)]
+        elif key == 'properties':
+            info['properties'] = list(namespace.get(key).keys())
+
+    return info
+
+
+class CreateMetadefNameSpace(command.ShowOne):
+    _description = _("Create a metadef namespace")
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            "namespace",
+            metavar="<namespace>",
+            help=_("New metadef namespace name"),
+        )
+        parser.add_argument(
+            "--display-name",
+            metavar="<display_name>",
+            help=_("A user-friendly name for the namespace."),
+        )
+        parser.add_argument(
+            "--description",
+            metavar="<description>",
+            help=_("A description of the namespace"),
+        )
+        visibility_group = parser.add_mutually_exclusive_group()
+        visibility_group.add_argument(
+            "--public",
+            action="store_const",
+            const="public",
+            dest="visibility",
+            help=_("Set namespace visibility 'public'"),
+        )
+        visibility_group.add_argument(
+            "--private",
+            action="store_const",
+            const="private",
+            dest="visibility",
+            help=_("Set namespace visibility 'private'"),
+        )
+        protected_group = parser.add_mutually_exclusive_group()
+        protected_group.add_argument(
+            "--protected",
+            action="store_const",
+            const=True,
+            dest="is_protected",
+            help=_("Prevent metadef namespace from being deleted"),
+        )
+        protected_group.add_argument(
+            "--unprotected",
+            action="store_const",
+            const=False,
+            dest="is_protected",
+            help=_("Allow metadef namespace to be deleted (default)"),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        image_client = self.app.client_manager.image
+        filter_keys = [
+            'namespace',
+            'display_name',
+            'description'
+        ]
+        kwargs = {}
+
+        for key in filter_keys:
+            argument = getattr(parsed_args, key, None)
+            if argument is not None:
+                kwargs[key] = argument
+
+        if parsed_args.is_protected is not None:
+            kwargs['protected'] = parsed_args.is_protected
+
+        if parsed_args.visibility is not None:
+            kwargs['visibility'] = parsed_args.visibility
+
+        data = image_client.create_metadef_namespace(**kwargs)
+
+        return zip(*sorted(data.items()))
+
+
+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_name>",
+            nargs="+",
+            help=_("An identifier (a name) for the namespace"),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        image_client = self.app.client_manager.image
+
+        result = 0
+        for i in parsed_args.namespace_name:
+            try:
+                namespace = image_client.get_metadef_namespace(i)
+                image_client.delete_metadef_namespace(namespace.id)
+            except Exception as e:
+                result += 1
+                LOG.error(_("Failed to delete namespace with name or "
+                            "ID '%(namespace)s': %(e)s"),
+                          {'namespace': i, 'e': e}
+                          )
+
+        if result > 0:
+            total = len(parsed_args.namespace_name)
+            msg = (_("%(result)s of %(total)s namespace failed "
+                     "to delete.") % {'result': result, 'total': total})
+            raise exceptions.CommandError(msg)
+
 
 class ListMetadefNameSpaces(command.Lister):
     _description = _("List metadef namespaces")
@@ -63,3 +209,104 @@ class ListMetadefNameSpaces(command.Lister):
                 formatters=_formatters,
             ) for s in data)
         )
+
+
+class SetMetadefNameSpace(command.Command):
+    _description = _("Set metadef namespace properties")
+
+    def get_parser(self, prog_name):
+        parser = super().get_parser(prog_name)
+        parser.add_argument(
+            "namespace",
+            metavar="<namespace>",
+            help=_("Namespace (name) for the namespace"),
+        )
+        parser.add_argument(
+            "--display-name",
+            metavar="<display_name>",
+            help=_("Set a user-friendly name for the namespace."),
+        )
+        parser.add_argument(
+            "--description",
+            metavar="<description>",
+            help=_("Set the description of the namespace"),
+        )
+        visibility_group = parser.add_mutually_exclusive_group()
+        visibility_group.add_argument(
+            "--public",
+            action="store_const",
+            const="public",
+            dest="visibility",
+            help=_("Set namespace visibility 'public'"),
+        )
+        visibility_group.add_argument(
+            "--private",
+            action="store_const",
+            const="private",
+            dest="visibility",
+            help=_("Set namespace visibility 'private'"),
+        )
+        protected_group = parser.add_mutually_exclusive_group()
+        protected_group.add_argument(
+            "--protected",
+            action="store_const",
+            const=True,
+            dest="is_protected",
+            help=_("Prevent metadef namespace from being deleted"),
+        )
+        protected_group.add_argument(
+            "--unprotected",
+            action="store_const",
+            const=False,
+            dest="is_protected",
+            help=_("Allow metadef namespace to be deleted (default)"),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        image_client = self.app.client_manager.image
+
+        namespace = parsed_args.namespace
+
+        filter_keys = [
+            'namespace',
+            'display_name',
+            'description'
+        ]
+        kwargs = {}
+
+        for key in filter_keys:
+            argument = getattr(parsed_args, key, None)
+            if argument is not None:
+                kwargs[key] = argument
+
+        if parsed_args.is_protected is not None:
+            kwargs['protected'] = parsed_args.is_protected
+
+        if parsed_args.visibility is not None:
+            kwargs['visibility'] = parsed_args.visibility
+
+        image_client.update_metadef_namespace(namespace, **kwargs)
+
+
+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="<namespace_name>",
+            help=_("Namespace (name) for the namespace"),
+        )
+        return parser
+
+    def take_action(self, parsed_args):
+        image_client = self.app.client_manager.image
+
+        namespace_name = parsed_args.namespace_name
+
+        data = image_client.get_metadef_namespace(namespace_name)
+        info = _format_namespace(data)
+
+        return zip(*sorted(info.items()))
diff --git a/openstackclient/tests/unit/image/v2/fakes.py b/openstackclient/tests/unit/image/v2/fakes.py
index ded9ff313a..8ddd9a0992 100644
--- a/openstackclient/tests/unit/image/v2/fakes.py
+++ b/openstackclient/tests/unit/image/v2/fakes.py
@@ -239,7 +239,11 @@ def create_tasks(attrs=None, count=2):
 class FakeMetadefNamespaceClient:
 
     def __init__(self, **kwargs):
+        self.create_metadef_namespace = mock.Mock()
+        self.delete_metadef_namespace = mock.Mock()
         self.metadef_namespaces = mock.Mock()
+        self.get_metadef_namespace = mock.Mock()
+        self.update_metadef_namespace = mock.Mock()
 
         self.auth_token = kwargs['token']
         self.management_url = kwargs['endpoint']
@@ -277,10 +281,11 @@ def create_one_metadef_namespace(attrs=None):
         'display_name': 'Flavor Quota',
         'namespace': 'OS::Compute::Quota',
         'owner': 'admin',
-        'resource_type_associations': ['OS::Nova::Flavor'],
+        # 'resource_type_associations': ['OS::Nova::Flavor'],
+        # The part that receives the list type factor is not implemented.
         'visibility': 'public',
     }
 
     # Overwrite default attributes if there are some attributes set
     metadef_namespace_list.update(attrs)
-    return metadef_namespace.MetadefNamespace(metadef_namespace_list)
+    return metadef_namespace.MetadefNamespace(**metadef_namespace_list)
diff --git a/openstackclient/tests/unit/image/v2/test_metadef_namespaces.py b/openstackclient/tests/unit/image/v2/test_metadef_namespaces.py
index 5eae289cdc..7ed1183866 100644
--- a/openstackclient/tests/unit/image/v2/test_metadef_namespaces.py
+++ b/openstackclient/tests/unit/image/v2/test_metadef_namespaces.py
@@ -30,8 +30,89 @@ class TestMetadefNamespaces(md_namespace_fakes.TestMetadefNamespaces):
         self.domain_mock.reset_mock()
 
 
-class TestMetadefNamespaceList(TestMetadefNamespaces):
+class TestMetadefNamespaceCreate(TestMetadefNamespaces):
+    _metadef_namespace = md_namespace_fakes.create_one_metadef_namespace()
 
+    expected_columns = (
+        'created_at',
+        'description',
+        'display_name',
+        'id',
+        'is_protected',
+        'location',
+        'name',
+        'namespace',
+        'owner',
+        'resource_type_associations',
+        'updated_at',
+        'visibility'
+    )
+    expected_data = (
+        _metadef_namespace.created_at,
+        _metadef_namespace.description,
+        _metadef_namespace.display_name,
+        _metadef_namespace.id,
+        _metadef_namespace.is_protected,
+        _metadef_namespace.location,
+        _metadef_namespace.name,
+        _metadef_namespace.namespace,
+        _metadef_namespace.owner,
+        _metadef_namespace.resource_type_associations,
+        _metadef_namespace.updated_at,
+        _metadef_namespace.visibility
+    )
+
+    def setUp(self):
+        super().setUp()
+
+        self.client.create_metadef_namespace.return_value \
+            = self._metadef_namespace
+        self.cmd = metadef_namespaces.CreateMetadefNameSpace(self.app, None)
+        self.datalist = self._metadef_namespace
+
+    def test_namespace_create(self):
+        arglist = [
+            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)
+
+
+class TestMetadefNamespaceDelete(TestMetadefNamespaces):
+    _metadef_namespace = md_namespace_fakes.create_one_metadef_namespace()
+
+    def setUp(self):
+        super().setUp()
+
+        self.client.delete_metadef_namespace.return_value \
+            = self._metadef_namespace
+        self.cmd = metadef_namespaces.DeleteMetadefNameSpace(self.app, None)
+        self.datalist = self._metadef_namespace
+
+    def test_namespace_create(self):
+        arglist = [
+            self._metadef_namespace.namespace
+        ]
+
+        verifylist = [
+
+        ]
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.assertIsNone(result)
+
+
+class TestMetadefNamespaceList(TestMetadefNamespaces):
     _metadef_namespace = [md_namespace_fakes.create_one_metadef_namespace()]
 
     columns = [
@@ -65,3 +146,70 @@ class TestMetadefNamespaceList(TestMetadefNamespaces):
         self.assertEqual(self.columns, columns)
         self.assertEqual(getattr(self.datalist[0], 'namespace'),
                          next(data)[0])
+
+
+class TestMetadefNamespaceSet(TestMetadefNamespaces):
+    _metadef_namespace = md_namespace_fakes.create_one_metadef_namespace()
+
+    def setUp(self):
+        super().setUp()
+
+        self.client.update_metadef_namespace.return_value \
+            = self._metadef_namespace
+        self.cmd = metadef_namespaces.SetMetadefNameSpace(self.app, None)
+        self.datalist = self._metadef_namespace
+
+    def test_namespace_set_no_options(self):
+        arglist = [
+            self._metadef_namespace.namespace
+        ]
+        verifylist = [
+            ('namespace', self._metadef_namespace.namespace),
+        ]
+
+        parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+        result = self.cmd.take_action(parsed_args)
+
+        self.assertIsNone(result)
+
+
+class TestMetadefNamespaceShow(TestMetadefNamespaces):
+    _metadef_namespace = md_namespace_fakes.create_one_metadef_namespace()
+
+    expected_columns = (
+        'created_at',
+        'display_name',
+        'namespace',
+        'owner',
+        'visibility'
+    )
+    expected_data = (
+        _metadef_namespace.created_at,
+        _metadef_namespace.display_name,
+        _metadef_namespace.namespace,
+        _metadef_namespace.owner,
+        _metadef_namespace.visibility
+    )
+
+    def setUp(self):
+        super().setUp()
+
+        self.client.get_metadef_namespace.return_value \
+            = self._metadef_namespace
+        self.cmd = metadef_namespaces.ShowMetadefNameSpace(self.app, None)
+
+    def test_namespace_show_no_options(self):
+        arglist = [
+            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)
diff --git a/releasenotes/notes/image-metadef-namespace-b940206bece64f97.yaml b/releasenotes/notes/image-metadef-namespace-b940206bece64f97.yaml
new file mode 100644
index 0000000000..361e57fe72
--- /dev/null
+++ b/releasenotes/notes/image-metadef-namespace-b940206bece64f97.yaml
@@ -0,0 +1,10 @@
+---
+features:
+  - Add ``openstack image metadef namespace create`` command
+    to create metadef namespace for the image service.
+  - Add ``openstack image metadef namespace delete`` command
+    to delete image metadef namespace.
+  - Add ``openstack image metadef namespace set`` command
+    to update metadef namespace for the image service.
+  - Add ``openstack image metadef namespace show`` command
+    to show metadef namespace for the image service.
diff --git a/setup.cfg b/setup.cfg
index fa3d30fe35..42ce970b32 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -386,7 +386,12 @@ openstack.image.v2 =
     image_stage = openstackclient.image.v2.image:StageImage
     image_task_show = openstackclient.image.v2.task:ShowTask
     image_task_list = openstackclient.image.v2.task:ListTask
+
+    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
 
 openstack.network.v2 =
     address_group_create = openstackclient.network.v2.address_group:CreateAddressGroup