openstacksdk/openstack/common/metadata.py

131 lines
4.9 KiB
Python

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from openstack import exceptions
from openstack import resource
from openstack import utils
class MetadataMixin:
#: *Type: list of tag strings*
metadata = resource.Body('metadata', type=dict)
def fetch_metadata(self, session):
"""Lists metadata set on the entity.
:param session: The session to use for making this request.
:return: The dictionary with metadata attached to the entity
"""
url = utils.urljoin(self.base_path, self.id, 'metadata')
response = session.get(url)
exceptions.raise_from_response(response)
json = response.json()
if 'metadata' in json:
self._body.attributes.update({'metadata': json['metadata']})
return self
def set_metadata(self, session, metadata=None, replace=False):
"""Sets/Replaces metadata key value pairs on the resource.
:param session: The session to use for making this request.
:param dict metadata: Dictionary with key-value pairs
:param bool replace: Replace all resource metadata with the new object
or merge new and existing.
"""
url = utils.urljoin(self.base_path, self.id, 'metadata')
if not metadata:
metadata = {}
if not replace:
response = session.post(url, json={'metadata': metadata})
else:
response = session.put(url, json={'metadata': metadata})
exceptions.raise_from_response(response)
self._body.attributes.update({'metadata': metadata})
return self
def replace_metadata(self, session, metadata=None):
"""Replaces all metadata key value pairs on the resource.
:param session: The session to use for making this request.
:param dict metadata: Dictionary with key-value pairs
:param bool replace: Replace all resource metadata with the new object
or merge new and existing.
"""
return self.set_metadata(session, metadata, replace=True)
def delete_metadata(self, session):
"""Removes all metadata on the entity.
:param session: The session to use for making this request.
"""
self.set_metadata(session, None, replace=True)
return self
def get_metadata_item(self, session, key):
"""Get the single metadata item on the entity.
If the metadata key does not exist a 404 will be returned
:param session: The session to use for making this request.
:param str key: The key of a metadata item.
"""
url = utils.urljoin(self.base_path, self.id, 'metadata', key)
response = session.get(url)
exceptions.raise_from_response(
response, error_message='Metadata item does not exist'
)
meta = response.json().get('meta', {})
# Here we need to potentially init metadata
metadata = self.metadata or {}
metadata[key] = meta.get(key)
self._body.attributes.update({'metadata': metadata})
return self
def set_metadata_item(self, session, key, value):
"""Create or replace single metadata item to the resource.
:param session: The session to use for making this request.
:param str key: The key for the metadata item.
:param str value: The value.
"""
url = utils.urljoin(self.base_path, self.id, 'metadata', key)
response = session.put(url, json={'meta': {key: value}})
exceptions.raise_from_response(response)
# we do not want to update tags directly
metadata = self.metadata
metadata[key] = value
self._body.attributes.update({'metadata': metadata})
return self
def delete_metadata_item(self, session, key):
"""Removes a single metadata item from the specified resource.
:param session: The session to use for making this request.
:param str key: The key as a string.
"""
url = utils.urljoin(self.base_path, self.id, 'metadata', key)
response = session.delete(url)
exceptions.raise_from_response(response)
# we do not want to update tags directly
metadata = self.metadata
try:
if metadata:
metadata.pop(key)
else:
metadata = {}
except ValueError:
pass # do nothing!
self._body.attributes.update({'metadata': metadata})
return self