Make all resource locations process project_id

All resources have a location property now that describes the
location of the object in the cloud, but the majority of that
information is taken directly from the connection that is in
use. Some resources contain server-side project_id or availability
zone information. When those exist, they should override the
project_id implied by the connection.

Change-Id: I48c116bf62d726be8d906c3d232e1ee203347b0a
This commit is contained in:
Monty Taylor 2019-02-02 13:48:12 +00:00
parent 85e1408e36
commit 5a4ce4567b
3 changed files with 27 additions and 9 deletions

View File

@ -138,14 +138,6 @@ class Server(resource.Resource, metadata.MetadataMixin, resource.TagMixin):
#: only.
instance_name = resource.Body('OS-EXT-SRV-ATTR:instance_name')
def __init__(self, *args, **kwargs):
super(Server, self).__init__(*args, **kwargs)
if self._connection:
self.location = self._connection._get_current_location(
project_id=self.project_id,
zone=self.availability_zone)
def _prepare_request(self, requires_id=True, prepend_key=True,
base_path=None):
request = super(Server, self)._prepare_request(requires_id=requires_id,

View File

@ -92,4 +92,5 @@ class FirewallPolicy(resource.Resource):
raise HttpException(message=message, response=resp)
self._body.attributes.update(data)
self._update_location()
return self

View File

@ -464,6 +464,8 @@ class Resource(dict):
else:
self._original_body = {}
self._update_location()
# TODO(mordred) This is terrible, but is a hack at the moment to ensure
# json.dumps works. The json library does basically if not obj: and
# obj.items() ... but I think the if not obj: is short-circuiting down
@ -571,6 +573,7 @@ class Resource(dict):
self._header.update(header)
self._uri.update(uri)
self._computed.update(computed)
self._update_location()
# TODO(mordred) This is terrible, but is a hack at the moment to ensure
# json.dumps works. The json library does basically if not obj: and
@ -601,10 +604,31 @@ class Resource(dict):
# TODO(mordred) We should make a Location Resource and add it here
# instead of just the dict.
if self._connection:
computed['location'] = self._connection.current_location
computed.setdefault('location', self._connection.current_location)
return body, header, uri, computed
def _update_location(self):
"""Update location to include resource project/zone information.
Location should describe the location of the resource. For some
resources, where the resource doesn't have any such baked-in notion
we assume the resource exists in the same project as the logged-in
user's token.
However, if a resource contains a project_id, then that project is
where the resource lives, and the location should reflect that.
"""
if not self._connection:
return
kwargs = {}
if hasattr(self, 'project_id'):
kwargs['project_id'] = self.project_id
if hasattr(self, 'availability_zone'):
kwargs['zone'] = self.availability_zone
if kwargs:
self.location = self._connection._get_current_location(**kwargs)
def _compute_attributes(self, body, header, uri):
"""Compute additional attributes from the remote resource."""
return {}
@ -948,6 +972,7 @@ class Resource(dict):
headers = self._consume_header_attrs(response.headers)
self._header.attributes.update(headers)
self._header.clean()
self._update_location()
@classmethod
def _get_session(cls, session):