)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"3542c023f7db77f66288e8632b25c3408339ddf7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"277f86e0_aafea97a","updated":"2023-10-06 11:10:19.000000000","message":"I don\u0027t think you want to do this. We don\u0027t usually consider tags to be resources in and of themselves. Instead, we consider them attributes of existing resources using the `TagMixin` from `openstack.common.tag`. There should be plenty of examples of this in use around the code base. Is there any reason *not* to use that mixin here? fwiw, from the CLI perspective I suspect if implemented it would be as simple as:\n\n```\nnamespace \u003d image_client.get_namespace(args.namespace)\nnamespace.fetch_tags(image_client)\n# do whatever with namespace.tags\n```","commit_id":"7409732e5d460a1e329a7687fdd85a3e8ea43b7b"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"7eb1331afd19279b510f363924170b06f3fcb154","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"0d8c3a7c_0c61e0be","updated":"2023-09-27 06:29:02.000000000","message":"Looks good to me!","commit_id":"7409732e5d460a1e329a7687fdd85a3e8ea43b7b"},{"author":{"_account_id":33765,"name":"Mridula Joshi","email":"mrjoshi@redhat.com","username":"mrjoshi"},"change_message_id":"71d2f93e559e8892857b017dc3c48a139eed4df5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"8f679774_9b1bfb74","updated":"2023-09-29 09:10:27.000000000","message":"recheck","commit_id":"7409732e5d460a1e329a7687fdd85a3e8ea43b7b"},{"author":{"_account_id":33765,"name":"Mridula Joshi","email":"mrjoshi@redhat.com","username":"mrjoshi"},"change_message_id":"59dabdb9b42aac7dba42c12efc7d5d21fb930779","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"0892fec0_d3ef6283","updated":"2024-01-17 04:33:01.000000000","message":"recheck","commit_id":"c675e0bb0d1717527d81832d1445c53699d3fe42"},{"author":{"_account_id":33765,"name":"Mridula Joshi","email":"mrjoshi@redhat.com","username":"mrjoshi"},"change_message_id":"ed9630aed3529e63da748119945911136e6b1aca","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"f7b23c6b_66887c68","updated":"2024-01-17 05:57:53.000000000","message":"recheck","commit_id":"c675e0bb0d1717527d81832d1445c53699d3fe42"},{"author":{"_account_id":33765,"name":"Mridula Joshi","email":"mrjoshi@redhat.com","username":"mrjoshi"},"change_message_id":"32cf976f80b17430c6358485aa34c56494b5c9b9","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"e2981be9_360ff274","updated":"2024-01-31 07:28:47.000000000","message":"Abandoning this patch as we have already added support in https://review.opendev.org/c/openstack/openstacksdk/+/897276","commit_id":"9b473934e2509d3cf2a75fe0ec4739a109115706"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"77e82894caa59541d5065bcece5a2b6b908c903a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"f1067c32_911b13c9","updated":"2024-01-30 14:54:50.000000000","message":"This is working mostly okay. However, as you\u0027ve noted in other patches, you need to override `add_tag` and `set_tags` since Glance works differently to other services. My notes from testing are below.\n\nCreate namespace and add tag via glanceclient:\n\n```\n$ glance md-namespace-create --description \u0027A test namespace\u0027 --display-name \u0027Foo\u0027 foo\n$ glance md-tag-create --name my-tag foo\n```\n\nSwitching to SDK, first get namespace and ensure tags show up:\n\n```\n\u003e\u003e\u003e from openstack import connection\n\u003e\u003e\u003e conn \u003d connection.Connection(\u0027devstack-admin\u0027)\n\u003e\u003e\u003e ns \u003d conn.image.get_metadef_namespace(\u0027foo\u0027)\n\u003e\u003e\u003e ns\nopenstack.image.v2.metadef_namespace.MetadefNamespace(id\u003dfoo, namespace\u003dfoo, display_name\u003dFoo, description\u003dA test namespace, visibility\u003dprivate, protected\u003dFalse, owner\u003d1fd93a4455c74d2ea94b929fc5f0e488, created_at\u003d2024-01-30T14:30:58Z, updated_at\u003d2024-01-30T14:30:58Z, tags\u003d[{\u0027name\u0027: \u0027my-tag\u0027}], location\u003dMunch({\u0027cloud\u0027: \u0027devstack-admin\u0027, \u0027region_name\u0027: \u0027RegionOne\u0027, \u0027zone\u0027: None, \u0027project\u0027: Munch({\u0027id\u0027: \u00271fd93a4455c74d2ea94b929\nfc5f0e488\u0027, \u0027name\u0027: \u0027admin\u0027, \u0027domain_id\u0027: \u0027default\u0027, \u0027domain_name\u0027: None})}))\n\u003e\u003e\u003e ns.tags\n[{\u0027name\u0027: \u0027my-tag\u0027}]\n```\n\nTesting `fetch_tags` (working):\n\n```\n\u003e\u003e\u003e ns.tags \u003d None\n\u003e\u003e\u003e ns.tags\n[None]\n\u003e\u003e\u003e ns.fetch_tags(conn.image)\nopenstack.image.v2.metadef_namespace.MetadefNamespace(id\u003dfoo, namespace\u003dfoo, display_name\u003dFoo, description\u003dA test namespace, visibility\u003dprivate, protected\u003dFalse, owner\u003d1fd93a4455c74d2ea94b929fc5f0e488, created_at\u003d2024-01-30T14:30:58Z, updated_at\u003d2024-01-30T14:30:58Z, tags\u003d[{\u0027name\u0027: \u0027my-tag\u0027}], location\u003dMunch({\u0027cloud\u0027: \u0027devstack-admin\u0027, \u0027region_name\u0027: \u0027RegionOne\u0027, \u0027zone\u0027: None, \u0027project\u0027: Munch({\u0027id\u0027: \u00271fd93a4455c74d2ea94b929fc5f0e488\u0027, \u0027name\u0027: \u0027admin\u0027, \u0027domain_id\u0027: \u0027default\u0027, \u0027domain_name\u0027: None})}))\n\u003e\u003e\u003e ns.tags\n[{\u0027name\u0027: \u0027my-tag\u0027}]\n```\n\nTesting `check_tag` and `remove_all_tags` (working):\n\n```\n\u003e\u003e\u003e ns.check_tag(conn.image, \u0027my-tag\u0027)\nopenstack.image.v2.metadef_namespace.MetadefNamespace(id\u003dfoo, namespace\u003dfoo, display_name\u003dFoo, description\u003dA test namespace, visibility\u003dprivate, protected\u003dFalse, owner\u003d1fd93a4455c74d2ea94b929fc5f0e488, created_at\u003d2024-01-30T14:30:58Z, updated_at\u003d2024-01-30T14:30:58Z, tags\u003d[{\u0027name\u0027: \u0027my-tag\u0027}], location\u003dMunch({\u0027cloud\u0027: \u0027devstack-admin\u0027, \u0027region_name\u0027: \u0027RegionOne\u0027, \u0027zone\u0027: None, \u0027project\u0027: Munch({\u0027id\u0027: \u00271fd93a4455c74d2ea94b929fc5f0e488\u0027, \u0027name\u0027: \u0027admin\u0027, \u0027domain_id\u0027: \u0027default\u0027, \u0027domain_name\u0027: None})}))\n\n\u003e\u003e\u003e ns.remove_all_tags(conn.image)\nopenstack.image.v2.metadef_namespace.MetadefNamespace(id\u003dfoo, namespace\u003dfoo, display_name\u003dFoo, description\u003dA test namespace, visibility\u003dprivate, protected\u003dFalse, owner\u003d1fd93a4455c74d2ea94b929fc5f0e488, created_at\u003d2024-01-30T14:30:58Z, updated_at\u003d2024-01-30T14:30:58Z, tags\u003d[], location\u003dMunch({\u0027cloud\u0027: \u0027devstack-admin\u0027, \u0027region_name\u0027: \u0027RegionOne\u0027, \u0027zone\u0027: None, \u0027project\u0027: Munch({\u0027id\u0027: \u00271fd93a4455c74d2ea94b929fc5f0e488\u0027, \u0027name\u0027: \u0027admin\u0027, \u0027domain_id\u0027: \u0027default\u0027, \u0027domain_name\u0027: None})}))\n\n\u003e\u003e\u003e ns.check_tag(conn.image, \u0027my-tag\u0027)\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/home/stephenfin/Development/openstack/openstacksdk/openstack/common/tag.py\", line 92, in check_tag\n    exceptions.raise_from_response(\n  File \"/home/stephenfin/Development/openstack/openstacksdk/openstack/exceptions.py\", line 250, in raise_from_response\n    raise cls(\nopenstack.exceptions.ResourceNotFound: Tag does not exist: Client Error for url: http://10.0.109.150/image/v2/metadefs/namespaces/foo/tags/my-tag, : 404 Not Found: Could not find metadata tag my-tag\n```\n\n(here I re-added the tag using glanceclient...)\n\nTesting `check_tag` and `remove_tag` (working):\n\n```\n\u003e\u003e\u003e ns.remove_tag(conn.image, \u0027my-tag\u0027)\nopenstack.image.v2.metadef_namespace.MetadefNamespace(id\u003dfoo, namespace\u003dfoo, display_name\u003dFoo, description\u003dA test namespace, visibility\u003dprivate, protected\u003dFalse, owner\u003d1fd93a4455c74d2ea94b929fc5f0e488, created_at\u003d2024-01-30T14:30:58Z, updated_at\u003d2024-01-30T14:30:58Z, tags\u003d[], location\u003dMunch({\u0027cloud\u0027: \u0027devstack-admin\u0027, \u0027region_name\u0027: \u0027RegionOne\u0027, \u0027zone\u0027: None, \u0027project\u0027: Munch({\u0027id\u0027: \u00271fd93a4455c74d2ea94b929fc5f0e488\u0027, \u0027name\u0027: \u0027admin\u0027, \u0027domain_id\u0027: \u0027default\u0027, \u0027domain_name\u0027: None})}))\n\n\u003e\u003e\u003e ns.check_tag(conn.image, \u0027my-tag\u0027)\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/home/stephenfin/Development/openstack/openstacksdk/openstack/common/tag.py\", line 92, in check_tag\n    exceptions.raise_from_response(\n  File \"/home/stephenfin/Development/openstack/openstacksdk/openstack/exceptions.py\", line 250, in raise_from_response\n    raise cls(\nopenstack.exceptions.ResourceNotFound: Tag does not exist: Client Error for url: http://10.0.109.150/image/v2/metadefs/namespaces/foo/tags/my-tag, : 404 Not Found: Could not find metadata tag my-tag\n```\n\nTesting `add_tag` (**broken**):\n\n```\n\u003e\u003e\u003e ns.add_tag(conn.image, \u0027my-tag\u0027)\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/home/stephenfin/Development/openstack/openstacksdk/openstack/common/tag.py\", line 106, in add_tag\n    exceptions.raise_from_response(response)\n  File \"/home/stephenfin/Development/openstack/openstacksdk/openstack/exceptions.py\", line 250, in raise_from_response\n    raise cls(\nopenstack.exceptions.BadRequestException: BadRequestException: 400: Client Error for url: http://10.0.109.150/image/v2/metadefs/namespaces/foo/tags/my-tag, : 400 Bad Request: Body expected in request.\n```\n\nTesting `set_tags` (**broken**):\n\n```\n\u003e\u003e\u003e ns.set_tags(conn.image, [\u0027my-new-tag-a\u0027, \u0027my-new-tag-b\u0027])\nTraceback (most recent call last):\n  File \"\u003cstdin\u003e\", line 1, in \u003cmodule\u003e\n  File \"/home/stephenfin/Development/openstack/openstacksdk/openstack/common/tag.py\", line 65, in set_tags\n    exceptions.raise_from_response(response)\n  File \"/home/stephenfin/Development/openstack/openstacksdk/openstack/exceptions.py\", line 250, in raise_from_response\n    raise cls(\nopenstack.exceptions.HttpException: HttpException: 405: Client Error for url: http://10.0.109.150/image/v2/metadefs/namespaces/foo/tags, : 405 Method Not Allowed: The method PUT is not allowed for this resource.\n```\n\nDelete namespace:\n\n```\n\u003e\u003e\u003e conn.image.delete_metadef_namespace(ns)\n```","commit_id":"9b473934e2509d3cf2a75fe0ec4739a109115706"}],"openstack/image/v2/_proxy.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"f0064c0207820442ccd4f25310f1de35af0019eb","unresolved":true,"context_lines":[{"line_number":1313,"context_line":"        )"},{"line_number":1314,"context_line":""},{"line_number":1315,"context_line":"    # \u003d\u003d\u003d\u003d\u003d\u003d METADEF TAGS \u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":1316,"context_line":"    def fetch_metadef_tags(self, namespace):"},{"line_number":1317,"context_line":"        \"\"\"Get metadef tags list of the namespace"},{"line_number":1318,"context_line":""},{"line_number":1319,"context_line":"        :param namespace: The value can be either the name of a metadef"}],"source_content_type":"text/x-python","patch_set":5,"id":"09a9525e_a3771044","line":1316,"updated":"2024-01-26 15:32:43.000000000","message":"As with other patches in this series, I don\u0027t think if this is necessary when the user can show tags via `get_metadef_namespace`.","commit_id":"c675e0bb0d1717527d81832d1445c53699d3fe42"},{"author":{"_account_id":33765,"name":"Mridula Joshi","email":"mrjoshi@redhat.com","username":"mrjoshi"},"change_message_id":"b27a6dc087bdb157962e9f24fcaf38b28880a8e2","unresolved":false,"context_lines":[{"line_number":1313,"context_line":"        )"},{"line_number":1314,"context_line":""},{"line_number":1315,"context_line":"    # \u003d\u003d\u003d\u003d\u003d\u003d METADEF TAGS \u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":1316,"context_line":"    def fetch_metadef_tags(self, namespace):"},{"line_number":1317,"context_line":"        \"\"\"Get metadef tags list of the namespace"},{"line_number":1318,"context_line":""},{"line_number":1319,"context_line":"        :param namespace: The value can be either the name of a metadef"}],"source_content_type":"text/x-python","patch_set":5,"id":"f43b2a5e_b5ca1806","line":1316,"in_reply_to":"09a9525e_a3771044","updated":"2024-01-30 07:40:32.000000000","message":"Acknowledged","commit_id":"c675e0bb0d1717527d81832d1445c53699d3fe42"}]}
