def _get_isolated_creds(cls): """ Creates a new set of user/tenant/password credentials for a **regular** user of the Compute API so that a test case can operate in an isolated tenant container. """ admin_client = cls._get_identity_admin_client() rand_name_root = cls.__name__ if cls.isolated_creds: # Main user already created. Create the alt one... rand_name_root += '-alt' username = rand_name_root + "-user" email = rand_name_root + "@example.com" tenant_name = rand_name_root + "-tenant" tenant_desc = tenant_name + "-desc" password = "******" try: resp, tenant = admin_client.create_tenant(name=tenant_name, description=tenant_desc) except exceptions.Duplicate: if cls.config.compute.allow_tenant_reuse: tenant = admin_client.get_tenant_by_name(tenant_name) LOG.info('Re-using existing tenant %s' % tenant) else: msg = ('Unable to create isolated tenant %s because ' + 'it already exists. If this is related to a ' + 'previous test failure, try using ' + 'allow_tenant_reuse in tempest.conf') % tenant_name raise exceptions.Duplicate(msg) try: resp, user = admin_client.create_user(username, password, tenant['id'], email) except exceptions.Duplicate: if cls.config.compute.allow_tenant_reuse: user = admin_client.get_user_by_username( tenant['id'], username) LOG.info('Re-using existing user %s' % user) else: msg = ('Unable to create isolated user %s because ' + 'it already exists. If this is related to a ' + 'previous test failure, try using ' + 'allow_tenant_reuse in tempest.conf') % tenant_name raise exceptions.Duplicate(msg) # Store the complete creds (including UUID ids...) for later # but return just the username, tenant_name, password tuple # that the various clients will use. cls.isolated_creds.append((user, tenant)) return username, tenant_name, password
def request(self, method, url, headers=None, body=None, depth=0): """A simple HTTP request interface.""" self.http_obj = httplib2.Http() if headers == None: headers = {} if (self.token == None): return None, None headers['X-Auth-Token'] = self.token req_url = url resp, resp_body = self.http_obj.request(req_url, method, headers=headers, body=body) if resp.status == 401: raise exceptions.Unauthorized() if resp.status == 404: raise exceptions.NotFound(resp_body) if resp.status == 400: resp_body = json.loads(resp_body) raise exceptions.BadRequest(resp_body['badRequest']['message']) if resp.status == 409: resp_body = json.loads(resp_body) raise exceptions.Duplicate(resp_body) if resp.status == 413: resp_body = json.loads(resp_body) if 'overLimit' in resp_body: raise exceptions.OverLimit(resp_body['overLimit']['message']) elif depth < MAX_RECURSION_DEPTH: delay = resp['Retry-After'] if 'Retry-After' in resp else 60 time.sleep(int(delay)) return self.request(method, url, headers, body, depth + 1) else: raise exceptions.RateLimitExceeded( message=resp_body['overLimitFault']['message'], details=resp_body['overLimitFault']['details']) if resp.status in (500, 501): resp_body = json.loads(resp_body) #I'm seeing both computeFault and cloudServersFault come back. #Will file a bug to fix, but leave as is for now. if 'cloudServersFault' in resp_body: message = resp_body['cloudServersFault']['message'] else: message = resp_body['computeFault']['message'] raise exceptions.ComputeFault(message) if resp.status >= 400: resp_body = json.loads(resp_body) raise exceptions.TempestException(str(resp.status)) return resp, resp_body
def _error_checker(self, method, url, headers, body, resp, resp_body): # NOTE(mtreinish): Check for httplib response from glance_http. The # object can't be used here because importing httplib breaks httplib2. # If another object from a class not imported were passed here as # resp this could possibly fail if str(type(resp)) == "<type 'instance'>": ctype = resp.getheader('content-type') else: try: ctype = resp['content-type'] # NOTE(mtreinish): Keystone delete user responses doesn't have a # content-type header. (They don't have a body) So just pretend it # is set. except KeyError: ctype = 'application/json' # It is not an error response if resp.status < 400: return JSON_ENC = [ 'application/json; charset=UTF-8', 'application/json', 'application/json; charset=utf-8' ] # NOTE(mtreinish): This is for compatibility with Glance and swift # APIs. These are the return content types that Glance api v1 # (and occasionally swift) are using. TXT_ENC = [ 'text/plain; charset=UTF-8', 'text/html; charset=UTF-8', 'text/plain; charset=utf-8' ] XML_ENC = ['application/xml', 'application/xml; charset=UTF-8'] if ctype in JSON_ENC or ctype in XML_ENC: parse_resp = True elif ctype in TXT_ENC: parse_resp = False else: raise exceptions.RestClientException(str(resp.status)) if resp.status == 401 or resp.status == 403: raise exceptions.Unauthorized() if resp.status == 404: raise exceptions.NotFound(resp_body) if resp.status == 400: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.BadRequest(resp_body) if resp.status == 409: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.Duplicate(resp_body) if resp.status == 413: if parse_resp: resp_body = self._parse_resp(resp_body) if self.is_absolute_limit(resp, resp_body): raise exceptions.OverLimit(resp_body) else: raise exceptions.RateLimitExceeded(resp_body) if resp.status == 422: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.UnprocessableEntity(resp_body) if resp.status in (500, 501): message = resp_body if parse_resp: resp_body = self._parse_resp(resp_body) #I'm seeing both computeFault and cloudServersFault come back. #Will file a bug to fix, but leave as is for now. if 'cloudServersFault' in resp_body: message = resp_body['cloudServersFault']['message'] elif 'computeFault' in resp_body: message = resp_body['computeFault']['message'] elif 'error' in resp_body: # Keystone errors message = resp_body['error']['message'] raise exceptions.IdentityError(message) elif 'message' in resp_body: message = resp_body['message'] raise exceptions.ComputeFault(message) if resp.status >= 400: if parse_resp: resp_body = self._parse_resp(resp_body) raise exceptions.RestClientException(str(resp.status))
def request(self, method, url, headers=None, body=None, depth=0): """A simple HTTP request interface.""" if (self.token is None) or (self.base_url is None): self._set_auth() self.http_obj = httplib2.Http() if headers == None: headers = {} headers['X-Auth-Token'] = self.token req_url = "%s/%s" % (self.base_url, url) resp, resp_body = self.http_obj.request(req_url, method, headers=headers, body=body) if resp.status == 401 or resp.status == 403: self._log(req_url, body, resp, resp_body) raise exceptions.Unauthorized() if resp.status == 404: self._log(req_url, body, resp, resp_body) raise exceptions.NotFound(resp_body) if resp.status == 400: resp_body = self._parse_resp(resp_body) self._log(req_url, body, resp, resp_body) raise exceptions.BadRequest(resp_body) if resp.status == 409: resp_body = self._parse_resp(resp_body) self._log(req_url, body, resp, resp_body) raise exceptions.Duplicate(resp_body) if resp.status == 413: resp_body = self._parse_resp(resp_body) self._log(req_url, body, resp, resp_body) if 'overLimit' in resp_body: raise exceptions.OverLimit(resp_body['overLimit']['message']) elif 'limit' in resp_body['message']: raise exceptions.OverLimit(resp_body['message']) elif depth < MAX_RECURSION_DEPTH: delay = resp['Retry-After'] if 'Retry-After' in resp else 60 time.sleep(int(delay)) return self.request(method, url, headers, body, depth + 1) else: raise exceptions.RateLimitExceeded( message=resp_body['overLimitFault']['message'], details=resp_body['overLimitFault']['details']) if resp.status in (500, 501): resp_body = self._parse_resp(resp_body) self._log(req_url, body, resp, resp_body) #I'm seeing both computeFault and cloudServersFault come back. #Will file a bug to fix, but leave as is for now. if 'cloudServersFault' in resp_body: message = resp_body['cloudServersFault']['message'] elif 'computeFault' in resp_body: message = resp_body['computeFault']['message'] elif 'error' in resp_body: # Keystone errors message = resp_body['error']['message'] raise exceptions.IdentityError(message) raise exceptions.ComputeFault(message) if resp.status >= 400: resp_body = self._parse_resp(resp_body) self._log(req_url, body, resp, resp_body) raise exceptions.TempestException(str(resp.status)) return resp, resp_body