From 5a4ce4567b81081b37179e79edfa374b0862c6d5 Mon Sep 17 00:00:00 2001 From: Monty Taylor Date: Sat, 2 Feb 2019 13:48:12 +0000 Subject: [PATCH] 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 --- openstack/compute/v2/server.py | 8 -------- openstack/network/v2/firewall_policy.py | 1 + openstack/resource.py | 27 ++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/openstack/compute/v2/server.py b/openstack/compute/v2/server.py index e7f6b5401..32eeec53f 100644 --- a/openstack/compute/v2/server.py +++ b/openstack/compute/v2/server.py @@ -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, diff --git a/openstack/network/v2/firewall_policy.py b/openstack/network/v2/firewall_policy.py index aa4df63dd..bc4afe484 100644 --- a/openstack/network/v2/firewall_policy.py +++ b/openstack/network/v2/firewall_policy.py @@ -92,4 +92,5 @@ class FirewallPolicy(resource.Resource): raise HttpException(message=message, response=resp) self._body.attributes.update(data) + self._update_location() return self diff --git a/openstack/resource.py b/openstack/resource.py index 98d204144..5cc5eb4e7 100644 --- a/openstack/resource.py +++ b/openstack/resource.py @@ -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):