def _prepare_request(self, requires_id=True, prepend_key=False): """Prepare a request to be sent to the server Create operations don't require an ID, but all others do, so only try to append an ID when it's needed with requires_id. Create and update operations sometimes require their bodies to be contained within an dict -- if the instance contains a resource_key and prepend_key=True, the body will be wrapped in a dict with that key. Return a _Request object that contains the constructed URI as well a body and headers that are ready to send. Only dirty body and header contents will be returned. """ body = self._body.dirty if prepend_key and self.resource_key is not None: body = {self.resource_key: body} headers = self._header.dirty uri = self.base_path % self._uri.attributes if requires_id: id = self._get_id(self) if id is None: raise exceptions.InvalidRequest( "Request requires an ID but none was found") uri = utils.urljoin(uri, id) return _Request(uri, body, headers)
def update(self, session, load_balancer_id, **attrs): """Update a load balancer.""" uri = utils.urljoin(self.base_path, load_balancer_id) resp = session.put(uri, endpoint_filter=self.service, json=attrs) self._translate_response(resp, has_body=True) return self
def stack_prepare_request(self, session, requires_id=True, prepend_key=False): """Prepare a request with auth header""" body = self._body.dirty if prepend_key and self.resource_key is not None: body = {self.resource_key: body} headers = self._header.dirty headers["X-Auth-User"] = session.auth._username headers["X-Auth-Key"] = session.auth._password uri = self.base_path % self._uri.attributes if requires_id: id = self._get_id(self) if id is None: raise exceptions.InvalidRequest( "Request requires an ID but none was found") uri = utils.urljoin(uri, id) return resource._Request(uri, body, headers)
def update(self, session, mcic_id, cic_id, has_body=True, **attrs): uri = self.base_path % ({'mcic_id': mcic_id}) uri = utils.urljoin(uri, cic_id) args = {'json': attrs} resp = session.put(uri, endpoint_filter=self.service, **args) self._translate_response(resp, has_body=False) return self
def download(self, session, image_id): """Download the data contained in an image""" # TODO(briancurtin): This method should probably offload the get # operation into another thread or something of that nature. url = utils.urljoin(self.base_path, image_id, 'file') resp = session.get(url, endpoint_filter=self.service) return resp.content
def update(self, session, volume_id, has_body=True, **attrs): uri = utils.urljoin(self.base_path, volume_id) body = {"volume": attrs} args = {'json': body} resp = session.put(uri, endpoint_filter=self.service, **args) self._translate_response(resp, has_body) return self
def _get_url(cls, path_args=None, resource_id=None): if path_args: url = cls.base_path % path_args else: url = cls.base_path if resource_id is not None: url = utils.urljoin(url, resource_id) return url
def change_state(self, session, next_state): """Set the state of an alarm. The next_state may be one of: 'ok' 'insufficient data' 'alarm' """ url = utils.urljoin(self.base_path, self.id, 'state') resp = session.put(url, endpoint_filter=self.service, json=next_state) return resp.json()
def update(self, session, firewall_id, firewall_interface_id, **attrs): """Update a firewall interface.""" update_path = '/' + self.service.version uri = utils.urljoin(update_path, 'firewalls', firewall_id, 'firewall_interfaces', firewall_interface_id) resp = session.put(uri, endpoint_filter=self.service, json=attrs) self._translate_response(resp, has_body=True) return self
def _action(self, session, body, postfix='action'): """Preform virtual network appliance actions given the message body""" url = utils.urljoin(VirtualNetworkAppliance.base_path, self.id, postfix) headers = {'Accept': ''} return session.post(url, endpoint_filter=self.service, json=body, headers=headers)
def check_state(self, session): """Retrieve the current state of an alarm from the service. The properties of the alarm are not modified. """ url = utils.urljoin(self.base_path, self.id, 'state') resp = session.get(url, endpoint_filter=self.service) resp = resp.json() current_state = resp.replace('\"', '') return current_state
def get(self, session, image_id): """Get a single image's detailed information.""" url = utils.urljoin(self.base_path, image_id) resp = session.get(url, headers={"Accept": "application/json"}, endpoint_filter=self.service) #For extra key/value use. self.response = resp.json() self._translate_response(resp, has_body=True) return self
def _action(self, session, body): """Preform server actions given the message body.""" # NOTE: This is using Server.base_path instead of self.base_path # as both Server and ServerDetail instances can be acted on, but # the URL used is sans any additional /detail/ part. url = utils.urljoin(Snapshot.base_path, self.id, 'action') headers = {'Accept': ''} return session.post(url, endpoint_filter=self.service, json=body, headers=headers)
def upload(self, session, image_id, image_data): """Upload data into an existing image""" url = utils.urljoin(self.base_path, image_id, 'file') resp = session.put(url, endpoint_filter=self.service, data=image_data, headers={ "Content-Type": "application/octet-stream", "Accept": "application/json" }) self._translate_response(resp, has_body=False) return self
def _metadata(self, method, key=None, clear=False, delete=False, **metadata): for k, v in metadata.items(): if not isinstance(v, six.string_types): raise ValueError("The value for %s (%s) must be " "a text string" % (k, v)) # If we're in a ServerDetail, we need to pop the "detail" portion # of the URL off and then everything else will work the same. pos = self.base_path.find("detail") if pos != -1: base = self.base_path[:pos] else: base = self.base_path if key is not None: url = utils.urljoin(base, self.id, "metadata", key) else: url = utils.urljoin(base, self.id, "metadata") kwargs = {"endpoint_filter": self.service} if metadata or clear: # 'meta' is the key for singular modifications. # 'metadata' is the key for mass modifications. key = "meta" if key is not None else "metadata" kwargs["json"] = {key: metadata} headers = {"Accept": ""} if delete else {} response = method(url, headers=headers, **kwargs) # DELETE doesn't return a JSON body while everything else does. return response.json() if not delete else None
def update(self, session, image_id, attrs_list): """Updates a specified image.""" url = utils.urljoin(self.base_path, image_id) attrs_list = json.dumps(attrs_list) resp = session.patch( url, endpoint_filter=self.service, data=attrs_list, headers={ "Content-Type": "application/openstack-images-v2.1-json-patch", "Accept": "" }) self._translate_response(resp, has_body=True) return self
def _get_version_match(self, versions, profile_version, service_type, root_endpoint, requires_project_id): """Return the best matching version Look through each version trying to find the best match for the version specified in this profile. * The best match will only ever be found within the same major version, meaning a v2 profile will never match if only v3 is available on the server. * The search for the best match is fuzzy if needed. * If the profile specifies v2 and the server has v2.0, v2.1, and v2.2, the match will be v2.2. * When an exact major/minor is specified, e.g., v2.0, it will only match v2.0. """ match = None for version in versions: api_version = self._parse_version(version["id"]) if profile_version.major != api_version.major: continue if profile_version.minor <= api_version.minor: for link in version["links"]: if link["rel"] == "self": match = link["href"] # Only break out of the loop on an exact match, # otherwise keep trying. if profile_version.minor == api_version.minor: break if match is None: raise exceptions.EndpointNotFound( "Unable to determine endpoint for %s" % service_type) # Some services return only the path fragment of a URI. # If we split and see that we're not given the scheme and netloc, # construct the match with the root from the service catalog. match_split = parse.urlsplit(match) if not all([match_split.scheme, match_split.netloc]): match = root_endpoint + match # For services that require the project id in the request URI, # add them in here. if requires_project_id: match = utils.urljoin(match, self.get_project_id()) return match
def test_strings(self): root = "http://www.example.com" leaves = "foo", "bar" result = utils.urljoin(root, *leaves) self.assertEqual(result, "http://www.example.com/foo/bar")
def _action(self, session, body): """Perform stack actions""" url = utils.urljoin(self.base_path, self._get_id(self), 'actions') resp = session.post(url, endpoint_filter=self.service, json=body) return resp.json()
def execute(self, session): """Preform tenant connection execute.""" url = utils.urljoin(TenantConnection.base_path, self.id, 'execute') headers = {'Accept': ''} return session.post( url, endpoint_filter=self.service, headers=headers)
def test_with_none(self): root = "http://www.example.com" leaves = "foo", None result = utils.urljoin(root, *leaves) self.assertEqual(result, "http://www.example.com/foo/")