Fix up object-store show commands
1) Change metadata to appear under a common 'properties' key, and use the utility to format them, this applied to object, account and container. 2) Clean up container and object output, which were setting the x-container-meta-owner property, but this is metadata only for the container, so it's pointless to have, removed it. 3) Container show was showing read/write ACLs and sync stuff, but these are not being returned by my swift by default, so I moved these to be checks, so we don't clutter the output. Change-Id: Ife7521fe9c2724035b06963c118bd6016ba2f5b5
This commit is contained in:
		| @@ -15,6 +15,7 @@ | ||||
|  | ||||
| import io | ||||
| import os | ||||
|  | ||||
| import six | ||||
| from six.moves import urllib | ||||
|  | ||||
| @@ -176,13 +177,24 @@ class APIv1(api.BaseAPI): | ||||
|                 'x-container-object-count', | ||||
|                 None, | ||||
|             ), | ||||
|             'meta-owner': response.headers.get('x-container-meta-owner', None), | ||||
|             'bytes_used': response.headers.get('x-container-bytes-used', None), | ||||
|             'read_acl': response.headers.get('x-container-read', None), | ||||
|             'write_acl': response.headers.get('x-container-write', None), | ||||
|             'sync_to': response.headers.get('x-container-sync-to', None), | ||||
|             'sync_key': response.headers.get('x-container-sync-key', None), | ||||
|             'bytes_used': response.headers.get('x-container-bytes-used', None) | ||||
|         } | ||||
|  | ||||
|         if 'x-container-read' in response.headers: | ||||
|             data['read_acl'] = response.headers.get('x-container-read', None) | ||||
|         if 'x-container-write' in response.headers: | ||||
|             data['write_acl'] = response.headers.get('x-container-write', None) | ||||
|         if 'x-container-sync-to' in response.headers: | ||||
|             data['sync_to'] = response.headers.get('x-container-sync-to', None) | ||||
|         if 'x-container-sync-key' in response.headers: | ||||
|             data['sync_key'] = response.headers.get('x-container-sync-key', | ||||
|                                                     None) | ||||
|  | ||||
|         properties = self._get_properties(response.headers, | ||||
|                                           'x-container-meta-') | ||||
|         if properties: | ||||
|             data['properties'] = properties | ||||
|  | ||||
|         return data | ||||
|  | ||||
|     def container_unset( | ||||
| @@ -434,12 +446,12 @@ class APIv1(api.BaseAPI): | ||||
|         response = self._request('HEAD', "%s/%s" % | ||||
|                                  (urllib.parse.quote(container), | ||||
|                                   urllib.parse.quote(object))) | ||||
|  | ||||
|         data = { | ||||
|             'account': self._find_account_id(), | ||||
|             'container': container, | ||||
|             'object': object, | ||||
|             'content-type': response.headers.get('content-type', None), | ||||
|             'meta-owner': response.headers.get('x-container-meta-owner', None), | ||||
|         } | ||||
|         if 'content-length' in response.headers: | ||||
|             data['content-length'] = response.headers.get( | ||||
| @@ -455,19 +467,10 @@ class APIv1(api.BaseAPI): | ||||
|                 'x-object-manifest', | ||||
|                 None, | ||||
|             ) | ||||
|         for key, value in six.iteritems(response.headers): | ||||
|             if key.startswith('x-object-meta-'): | ||||
|                 data[key[len('x-object-meta-'):].lower()] = value | ||||
|             elif key not in ( | ||||
|                     'content-type', | ||||
|                     'content-length', | ||||
|                     'last-modified', | ||||
|                     'etag', | ||||
|                     'date', | ||||
|                     'x-object-manifest', | ||||
|                     'x-container-meta-owner', | ||||
|             ): | ||||
|                 data[key.lower()] = value | ||||
|  | ||||
|         properties = self._get_properties(response.headers, 'x-object-meta-') | ||||
|         if properties: | ||||
|             data['properties'] = properties | ||||
|  | ||||
|         return data | ||||
|  | ||||
| @@ -495,12 +498,16 @@ class APIv1(api.BaseAPI): | ||||
|         # catalog should be enough. | ||||
|         response = self._request("HEAD", "") | ||||
|         data = {} | ||||
|         for k, v in response.headers.iteritems(): | ||||
|             data[k] = v | ||||
|  | ||||
|         properties = self._get_properties(response.headers, 'x-account-meta-') | ||||
|         if properties: | ||||
|             data['properties'] = properties | ||||
|  | ||||
|         # Map containers, bytes and objects a bit nicer | ||||
|         data['Containers'] = data.pop('x-account-container-count', None) | ||||
|         data['Objects'] = data.pop('x-account-object-count', None) | ||||
|         data['Bytes'] = data.pop('x-account-bytes-used', None) | ||||
|         data['Containers'] = response.headers.get('x-account-container-count', | ||||
|                                                   None) | ||||
|         data['Objects'] = response.headers.get('x-account-object-count', None) | ||||
|         data['Bytes'] = response.headers.get('x-account-bytes-used', None) | ||||
|         # Add in Account info too | ||||
|         data['Account'] = self._find_account_id() | ||||
|         return data | ||||
| @@ -549,3 +556,12 @@ class APIv1(api.BaseAPI): | ||||
|             header_name = header_tag % k | ||||
|             headers[header_name] = v | ||||
|         return headers | ||||
|  | ||||
|     def _get_properties(self, headers, header_tag): | ||||
|         # Add in properties as a top level key, this is consistent with other | ||||
|         # OSC commands | ||||
|         properties = {} | ||||
|         for k, v in six.iteritems(headers): | ||||
|             if k.startswith(header_tag): | ||||
|                 properties[k[len(header_tag):]] = v | ||||
|         return properties | ||||
|   | ||||
| @@ -55,6 +55,8 @@ class ShowAccount(show.ShowOne): | ||||
|     @utils.log_method(log) | ||||
|     def take_action(self, parsed_args): | ||||
|         data = self.app.client_manager.object_store.account_show() | ||||
|         if 'properties' in data: | ||||
|             data['properties'] = utils.format_dict(data.pop('properties')) | ||||
|         return zip(*sorted(six.iteritems(data))) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -229,6 +229,8 @@ class ShowContainer(show.ShowOne): | ||||
|         data = self.app.client_manager.object_store.container_show( | ||||
|             container=parsed_args.container, | ||||
|         ) | ||||
|         if 'properties' in data: | ||||
|             data['properties'] = utils.format_dict(data.pop('properties')) | ||||
|  | ||||
|         return zip(*sorted(six.iteritems(data))) | ||||
|  | ||||
|   | ||||
| @@ -284,6 +284,8 @@ class ShowObject(show.ShowOne): | ||||
|             container=parsed_args.container, | ||||
|             object=parsed_args.object, | ||||
|         ) | ||||
|         if 'properties' in data: | ||||
|             data['properties'] = utils.format_dict(data.pop('properties')) | ||||
|  | ||||
|         return zip(*sorted(six.iteritems(data))) | ||||
|  | ||||
|   | ||||
| @@ -157,11 +157,6 @@ class TestContainer(TestObjectAPIv1): | ||||
|             'container': 'qaz', | ||||
|             'object_count': '1', | ||||
|             'bytes_used': '577', | ||||
|             'meta-owner': FAKE_ACCOUNT, | ||||
|             'read_acl': None, | ||||
|             'write_acl': None, | ||||
|             'sync_to': None, | ||||
|             'sync_key': None, | ||||
|         } | ||||
|         self.requests_mock.register_uri( | ||||
|             'HEAD', | ||||
| @@ -323,10 +318,8 @@ class TestObject(TestObjectAPIv1): | ||||
|             'content-type': 'text/alpha', | ||||
|             'content-length': '577', | ||||
|             'last-modified': '20130101', | ||||
|             'meta-owner': FAKE_ACCOUNT, | ||||
|             'etag': 'qaz', | ||||
|             'wife': 'Wilma', | ||||
|             'x-tra-header': 'yabba-dabba-do', | ||||
|             'properties': {'wife': 'Wilma'}, | ||||
|         } | ||||
|         self.requests_mock.register_uri( | ||||
|             'HEAD', | ||||
|   | ||||
| @@ -286,7 +286,6 @@ class TestContainerShow(TestContainerAll): | ||||
|  | ||||
|     def test_object_show_container(self): | ||||
|         headers = { | ||||
|             'x-container-meta-owner': object_fakes.ACCOUNT_ID, | ||||
|             'x-container-object-count': '42', | ||||
|             'x-container-bytes-used': '123', | ||||
|             'x-container-read': 'qaz', | ||||
| @@ -316,7 +315,6 @@ class TestContainerShow(TestContainerAll): | ||||
|             'account', | ||||
|             'bytes_used', | ||||
|             'container', | ||||
|             'meta-owner', | ||||
|             'object_count', | ||||
|             'read_acl', | ||||
|             'sync_key', | ||||
| @@ -328,7 +326,6 @@ class TestContainerShow(TestContainerAll): | ||||
|             object_fakes.ACCOUNT_ID, | ||||
|             '123', | ||||
|             'ernie', | ||||
|             object_fakes.ACCOUNT_ID, | ||||
|             '42', | ||||
|             'qaz', | ||||
|             'rfv', | ||||
|   | ||||
| @@ -160,7 +160,6 @@ class TestObjectShow(TestObjectAll): | ||||
|             'content-type', | ||||
|             'etag', | ||||
|             'last-modified', | ||||
|             'meta-owner', | ||||
|             'object', | ||||
|             'x-object-manifest', | ||||
|         ) | ||||
| @@ -172,7 +171,6 @@ class TestObjectShow(TestObjectAll): | ||||
|             'text/plain', | ||||
|             '4c4e39a763d58392724bccf76a58783a', | ||||
|             'yesterday', | ||||
|             object_fakes.ACCOUNT_ID, | ||||
|             object_fakes.object_name_1, | ||||
|             'manifest', | ||||
|         ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Steve Martinelli
					Steve Martinelli