def do_http(self, method, path, body, custom_headers=None, login=False): """Makes http calls. Args: method: HTTP methods (GET, POST, PUT, DELETE). path: URL body: Request body. custom_headers: Custom headers to update/append default headers. login: True if the call is for login and get the token. Returns: tuple: Tuple with two members (HTTP response object and the response body in json). """ http_headers = self._headers.copy() full_path = "{}{}".format(self._base_url, path) if login: user_pass = b64encode(b"simplivity:").decode("ascii") http_headers.update({ 'Content-type': 'application/x-www-form-urlencoded', 'Authorization': 'Basic %s' % user_pass }) else: if not self._access_token: raise exceptions.HPESimpliVityException( "There is no active session, please login") http_headers[ 'Content-type'] = 'application/vnd.simplivity.v1.8+json' http_headers['Authorization'] = "Bearer " + self._access_token # Updates default headers with the custom headers if custom_headers: http_headers.update(custom_headers) json_body = None try: connection = self.get_connection() connection.request(method, full_path, body, http_headers) resp = connection.getresponse() resp_body = resp.read() connection.close() if resp_body: json_body = json.loads(resp_body.decode('utf-8')) except http.client.HTTPException: raise exceptions.HPESimpliVityException(traceback.format_exc()) # Obtain a new token, if the Simplivity Product returns an invalid token error. if json_body and 'error' in json_body and json_body[ 'error'] == 'invalid_token': self.login(self._username, self._password) resp, json_body = self.do_http(method, path, body, custom_headers) return resp, json_body
def test_exception_constructor_with_unicode(self): exception = exceptions.HPESimpliVityException(u"A message string") self.assertEqual(exception.msg, "A message string") self.assertEqual(exception.response, None) self.assertEqual(exception.args[0], "A message string") self.assertEqual(len(exception.args), 1)
def __do_rest_call(self, http_method, url, body, custom_headers): """Calls do_http method and handles the http status code. Args: http_method: HTTP method (GET, POST, PUT and DELETE) url: Resource URL body: Request body custom_headers: Headers to appened/update default headers Returns: tuple: A tuple of two elements (task and response body) Raises: HPESimpliVityException: if the response status code is 401/403/404 """ resp, body = self.do_http(method=http_method, path=url, body=json.dumps(body), custom_headers=custom_headers) if resp.status in [400, 401, 403, 404]: raise exceptions.HPESimpliVityException(body) if self.__body_content_is_task(body): return body, body return None, body
def from_environment_variables(cls): """ Construct OVC Client using environment variables. Returns: OVC object """ ip = os.environ.get('SIMPLIVITYSDK_OVC_IP', '') username = os.environ.get('SIMPLIVITYSDK_USERNAME', '') password = os.environ.get('SIMPLIVITYSDK_PASSWORD', '') ssl_certificate = os.environ.get('SIMPLIVITYSDK_SSL_CERTIFICATE', '') timeout = os.environ.get('SIMPLIVITYSDK_CONNECTION_TIMEOUT') if not ip or not username or not password: raise exceptions.HPESimpliVityException( "Make sure you have set mandatory env variables \ (SIMPLIVITYSDK_OVC_IP, SIMPLIVITYSDK_USERNAME, SIMPLIVITYSDK_PASSWORD)" ) config = dict(ip=ip, ssl_certificate=ssl_certificate, credentials=dict(username=username, password=password), timeout=timeout) return cls(config)
def test_exception_constructor_with_invalid_dict(self): exception = exceptions.HPESimpliVityException( {'msg': "A message string"}) self.assertEqual(exception.msg, None) self.assertEqual(exception.response, {'msg': "A message string"}) self.assertEqual(exception.args[0], None) self.assertEqual(exception.args[1], {'msg': "A message string"})
def test_exception_constructor_with_invalid_type(self): exception = exceptions.HPESimpliVityException( ['List, item 1', "List, item 2: A message string"]) self.assertEqual(exception.msg, None) self.assertEqual(exception.response, ['List, item 1', "List, item 2: A message string"]) self.assertEqual(exception.args[0], None) self.assertEqual(exception.args[1], ['List, item 1', "List, item 2: A message string"])
def get_all(self, resource_url, members_field=None, pagination=False, page_size=0, limit=500, offset=0, sort=None, order='descending', filters=None, fields=None, case_sensitive=True, show_optional_fields=False): """Gets all resources. Args: resource_url: URL of the resource members_field: Name of the resource field(to fetch the resources from get call response) pagination: Default value is False, set to True if pagination is required page_size: Number of resources per page - mandatory field if pagination is on limit: A positive integer that represents the maximum number of results to return sort: The name of the field where the sort occurs order: The sort order preference, valid values: ascending or descending filters: Dictionary of filers, example: {'name': 'name'} fields: A comma-separated list of fields to include in the returned objects. Default: all case_sensitive: An indicator that specifies if the filter and sort results use a case-sensitive or insensitive manner. Default: True show_optional_fields: An indicator to show or not show the ha_status, ha_resynchronization_progress, hypervisor_virtual_machine_power_state, and hypervisor_is_template Returns: list/pagination object: Pagination object if pagination is on or list of resources """ query_params = {"limit": limit, "offset": offset, "order": order} if filters and isinstance(filters, dict): query_params.update(filters) if fields: query_params["fields"] = quote(fields) if show_optional_fields: query_params["show_optional_fields"] = quote(show_optional_fields) query_params["sort"] = sort if sort else 'name' query_params["case"] = "sensitive" if case_sensitive else "insensitive" if pagination: if not page_size: raise exceptions.HPESimpliVityException(PAGE_SIZE_NOT_SET) out = Pagination(self._connection, resource_url, self._resource_obj, query_params, members_field, page_size) else: url = build_uri_with_query_string(resource_url, query_params) response = self._connection.get(url) data_list = response.get(members_field, []) out = [] for data in data_list: out.append(self._resource_obj.get_by_data(data)) return out
def test_pickle_HPESimpliVityException_dict(self): message = {"msg": "test message"} exception = exceptions.HPESimpliVityException(message) tempf = tempfile.NamedTemporaryFile(delete=False) with tempf as f: pickle.dump(exception, f) with open(tempf.name, 'rb') as f: exception = pickle.load(f) os.remove(tempf.name) self.assertEqual('HPESimpliVityException', exception.__class__.__name__)
def get_affected_resources(self): """ Retrieve a resource associated with a task. Args: task: task dict Returns: list: list of resource ids """ if self.state not in TASK_COMPLETED_STATES: raise exceptions.HPESimpliVityException(self.data["message"]) affected_resources = self.data['affected_objects'] return affected_resources
def _set_data(self): """ Sets data(page size and the resources) of the current page. """ url = build_uri_with_query_string(self._url, self._params) response = self._connection.get(url) resources = response.get(self._members_field, []) if not len(resources): raise exceptions.HPESimpliVityException(PAGINATION_NO_MORE_PAGES) for index, resource in enumerate(resources): resources[index] = self._resource_obj.get_by_data(resource) self.data["resources"] = resources self.data["size"] = len(resources)
def get(self, url): """Calls get http method. Args: url: Resource URL Returns: tuple: Tuple with two members (HTTP response object and the response body in json). Raises: HPESimpliVityException: if the response status is 400 and above """ resp, body = self.do_http('GET', url, '') if resp.status >= 400: raise exceptions.HPESimpliVityException(body) return body
def previous_page(self): """Gets previous page. Returns list of resources from previous page. Raises: HPESimpliVityException: if no more pages to return. """ if self.data["page"] - 1 < self._first_page: raise exceptions.HPESimpliVityException(PAGINATION_NO_MORE_PAGES) self.data["page"] -= 1 self._params["limit"] = self._page_size self._params["offset"] -= self._page_size self._set_data() return self.data
def __init__(self, config): """Initialize OVC class.""" self.__connection = Connection(config["ip"], config.get('ssl_certificate', False), config.get('timeout')) if config.get("credentials"): username = config["credentials"].get("username") password = config["credentials"].get("password") self.__connection.login(username, password) else: exceptions.HPESimpliVityException("Credentials not provided") self.__virtual_machines = None self.__policies = None self.__datastores = None self.__omnistack_clusters = None self.__backups = None self.__hosts = None
def next_page(self): """Gets next page. Returns list of resources from next page. Raises: HPESimpliVityException: if no more pages to return. """ if self.data["page"] + 1 > self._last_page: raise exceptions.HPESimpliVityException(PAGINATION_NO_MORE_PAGES) self.data["page"] += 1 if self.data["page"] == self._last_page: self._params["limit"] = self._last_page_size self._params["offset"] += self._page_size self._set_data() return self.data