Exemplo n.º 1
0
 def authenticate_2_0(self):
     reqbody = json.dumps({
         'auth': {
             'passwordCredentials': {
                 'username': self.user_id,
                 'password': self.key
             }
         }
     })
     resp = self.request('tokens/',
                         data=reqbody,
                         headers={'Content-Type': 'application/json'},
                         method='POST')
     if resp.status == httplib.UNAUTHORIZED:
         raise InvalidCredsError()
     elif resp.status not in [
             httplib.OK, httplib.NON_AUTHORITATIVE_INFORMATION
     ]:
         raise MalformedResponseError('Malformed response',
                                      body='code: %s body: %s' %
                                      (resp.status, resp.body),
                                      driver=self.driver)
     else:
         try:
             body = json.loads(resp.body)
         except Exception, e:
             raise MalformedResponseError('Failed to parse JSON', e)
         try:
             self.auth_token = body['access']['token']['id']
             self.urls = body['access']['serviceCatalog']
         except KeyError, e:
             raise MalformedResponseError(
                 'Auth JSON response is missing required elements', e)
Exemplo n.º 2
0
    def parse_body(self):
        if self.status == httplib.NO_CONTENT or not self.body:
            return None

        if self.has_content_type('application/xml'):
            try:
                try:
                    return ET.XML(self.body)
                except ValueError:
                    # lxml wants a bytes and tests are basically hard-coded to str
                    return ET.XML(self.body.encode('utf-8'))
            except:
                raise MalformedResponseError('Failed to parse XML',
                                             body=self.body,
                                             driver=self.node_driver)

        elif self.has_content_type('application/json'):
            try:
                return json.loads(self.body)
            except:
                raise MalformedResponseError('Failed to parse JSON',
                                             body=self.body,
                                             driver=self.node_driver)
        else:
            return self.body
Exemplo n.º 3
0
    def _authenticate_2_0_with_body(self, reqbody):
        resp = self.request('/v2.0/tokens',
                            data=reqbody,
                            headers={'Content-Type': 'application/json'},
                            method='POST')

        if resp.status == httplib.UNAUTHORIZED:
            raise InvalidCredsError()
        elif resp.status not in [
                httplib.OK, httplib.NON_AUTHORITATIVE_INFORMATION
        ]:
            body = 'code: %s body: %s' % (resp.status, resp.body)
            raise MalformedResponseError('Malformed response',
                                         body=body,
                                         driver=self.driver)
        else:
            body = resp.object

            try:
                access = body['access']
                expires = access['token']['expires']

                self.auth_token = access['token']['id']
                self.auth_token_expires = parse_date(expires)
                self.urls = access['serviceCatalog']
                self.auth_user_info = access.get('user', {})
            except KeyError:
                e = sys.exc_info()[1]
                raise MalformedResponseError(
                    'Auth JSON response is \
                                             missing required elements', e)

        return self
Exemplo n.º 4
0
    def authenticate_1_1(self):
        reqbody = json.dumps(
            {'credentials': {
                'username': self.user_id,
                'key': self.key
            }})
        resp = self.request("/auth", data=reqbody, headers={}, method='POST')

        if resp.status == httplib.UNAUTHORIZED:
            # HTTP UNAUTHORIZED (401): auth failed
            raise InvalidCredsError()
        elif resp.status != httplib.OK:
            raise MalformedResponseError('Malformed response',
                                         body='code: %s body:%s' %
                                         (resp.status, resp.body),
                                         driver=self.driver)
        else:
            try:
                body = json.loads(resp.body)
            except Exception, e:
                raise MalformedResponseError('Failed to parse JSON', e)
            try:
                self.auth_token = body['auth']['token']['id']
                self.urls = body['auth']['serviceCatalog']
            except KeyError, e:
                raise MalformedResponseError(
                    'Auth JSON response is missing required elements', e)
Exemplo n.º 5
0
    def authenticate_1_0(self):
        headers = {
            'X-Auth-User': self.user_id,
            'X-Auth-Key': self.key,
        }

        resp = self.request('/v1.0', headers=headers, method='GET')

        if resp.status == httplib.UNAUTHORIZED:
            # HTTP UNAUTHORIZED (401): auth failed
            raise InvalidCredsError()
        elif resp.status not in [httplib.NO_CONTENT, httplib.OK]:
            body = 'code: %s body:%s headers:%s' % (resp.status, resp.body,
                                                    resp.headers)
            raise MalformedResponseError('Malformed response',
                                         body=body,
                                         driver=self.driver)
        else:
            headers = resp.headers
            # emulate the auth 1.1 URL list
            self.urls = {}
            self.urls['cloudServers'] = \
                [{'publicURL': headers.get('x-server-management-url', None)}]
            self.urls['cloudFilesCDN'] = \
                [{'publicURL': headers.get('x-cdn-management-url', None)}]
            self.urls['cloudFiles'] = \
                [{'publicURL': headers.get('x-storage-url', None)}]
            self.auth_token = headers.get('x-auth-token', None)
            self.auth_user_info = None

            if not self.auth_token:
                raise MalformedResponseError('Missing X-Auth-Token in \
                                              response headers')

        return self
Exemplo n.º 6
0
    def authenticate_2_0_with_body(self, reqbody):
        resp = self.request('/v2.0/tokens/',
                    data=reqbody,
                    headers={'Content-Type':'application/json'},
                    method='POST')
        if resp.status == httplib.UNAUTHORIZED:
            raise InvalidCredsError()
        elif resp.status not in [httplib.OK, httplib.NON_AUTHORITATIVE_INFORMATION]:
            raise MalformedResponseError('Malformed response',
                    body='code: %s body: %s' % (resp.status, resp.body),
                    driver=self.driver)
        else:
            try:
                body = json.loads(resp.body)
            except Exception:
                e = sys.exc_info()[1]
                raise MalformedResponseError('Failed to parse JSON', e)

            try:
                access = body['access']
                token = access['token']
                self.auth_token = token['id']
                self.urls = access['serviceCatalog']
            except KeyError:
                e = sys.exc_info()[1]
                raise MalformedResponseError('Auth JSON response is missing required elements', e)
Exemplo n.º 7
0
    def _populate_hosts_and_request_paths(self):
        """
        Rackspace uses a separate host for API calls which is only provided
        after an initial authentication request. If we haven't made that
        request yet, do it here. Otherwise, just return the management host.
        """
        if not self.auth_token:
            # Initial connection used for authentication
            conn = self.conn_classes[self.secure](self.auth_host,
                                                  self.port[self.secure])
            conn.request(method='GET',
                         url='/%s' % (AUTH_API_VERSION),
                         headers={
                             'X-Auth-User': self.user_id,
                             'X-Auth-Key': self.key
                         })

            resp = conn.getresponse()

            if resp.status == httplib.NO_CONTENT:
                # HTTP NO CONTENT (204): auth successful
                headers = dict(resp.getheaders())

                try:
                    self.server_url = headers['x-server-management-url']
                    self.storage_url = headers['x-storage-url']
                    self.cdn_management_url = headers['x-cdn-management-url']
                    self.lb_url = self.server_url.replace(
                        "servers", "ord.loadbalancers")
                    self.auth_token = headers['x-auth-token']
                except KeyError, e:
                    # Returned 204 but has missing information in the header, something is wrong
                    raise MalformedResponseError('Malformed response',
                                                 body='Missing header: %s' %
                                                 (str(e)),
                                                 driver=self.driver)
            elif resp.status == httplib.UNAUTHORIZED:
                # HTTP UNAUTHORIZED (401): auth failed
                raise InvalidCredsError()
            else:
                # Any response code != 401 or 204, something is wrong
                raise MalformedResponseError(
                    'Malformed response',
                    body='code: %s body:%s' %
                    (resp.status, ''.join(resp.body.readlines())),
                    driver=self.driver)

            for key in [
                    'server_url', 'storage_url', 'cdn_management_url', 'lb_url'
            ]:
                scheme, server, request_path, param, query, fragment = (
                    urlparse.urlparse(getattr(self, key)))
                # Set host to where we want to make further requests to
                setattr(self, '__%s' % (key), server)
                setattr(self, '__request_path_%s' % (key), request_path)

            conn.close()
Exemplo n.º 8
0
    def parse_body(self):
        if not self.body:
            return None

        if 'content-type' in self.headers:
            key = 'content-type'
        elif 'Content-Type' in self.headers:
            key = 'Content-Type'
        else:
            raise LibcloudError('Missing content-type header',
                                driver=OpenStackAuthConnection)

        content_type = self.headers[key]
        if content_type.find(';') != -1:
            content_type = content_type.split(';')[0]

        if content_type == 'application/json':
            try:
                data = json.loads(self.body)
            except:
                raise MalformedResponseError('Failed to parse JSON',
                                             body=self.body,
                                             driver=OpenStackAuthConnection)
        elif content_type == 'text/plain':
            data = self.body
        else:
            data = self.body

        return data
Exemplo n.º 9
0
    def authenticate(self, force=False):
        if not self._is_authentication_needed(force=force):
            return self

        reqbody = json.dumps(
            {'credentials': {
                'username': self.user_id,
                'key': self.key
            }})
        resp = self.request('/v1.1/auth',
                            data=reqbody,
                            headers={},
                            method='POST')

        if resp.status == httplib.UNAUTHORIZED:
            # HTTP UNAUTHORIZED (401): auth failed
            raise InvalidCredsError()
        elif resp.status != httplib.OK:
            body = 'code: %s body:%s' % (resp.status, resp.body)
            raise MalformedResponseError('Malformed response',
                                         body=body,
                                         driver=self.driver)
        else:
            try:
                body = json.loads(resp.body)
            except Exception:
                e = sys.exc_info()[1]
                raise MalformedResponseError('Failed to parse JSON', e)

            try:
                expires = body['auth']['token']['expires']

                self.auth_token = body['auth']['token']['id']
                self.auth_token_expires = parse_date(expires)
                self.urls = body['auth']['serviceCatalog']
                self.auth_user_info = None
            except KeyError:
                e = sys.exc_info()[1]
                raise MalformedResponseError(
                    'Auth JSON response is \
                                             missing required elements', e)

        return self
    def parse_body(self):
        if len(self.body) == 0 and not self.parse_zero_length_body:
            return self.body

        try:
            body = lxml_ET.XML(self.body)
        except Exception as e:
            raise MalformedResponseError('Failed to parse XML %s' % e,
                                         body=self.body,
                                         driver=self.connection.driver)
        return body
Exemplo n.º 11
0
 def _parse_url_headers(self, headers):
     try:
         self.server_url = headers['x-server-management-url']
         self.storage_url = headers['x-storage-url']
         self.cdn_management_url = headers['x-cdn-management-url']
         self.lb_url = self.server_url.replace("servers", "ord.loadbalancers")
         self.auth_token = headers['x-auth-token']
     except KeyError, e:
         # Returned 204 but has missing information in the header, something is wrong
         raise MalformedResponseError('Malformed response',
                                      body='Missing header: %s' % (str(e)),
                                      driver=self.driver)
Exemplo n.º 12
0
    def parse_body(self):
        if self.status == httplib.NO_CONTENT or not self.body:
            return None

        if self.has_content_type('application/xml'):
            try:
                return ET.XML(self.body)
            except:
                raise MalformedResponseError('Failed to parse XML',
                                             body=self.body,
                                             driver=self.node_driver)

        elif self.has_content_type('application/json'):
            try:
                return json.loads(self.body)
            except:
                raise MalformedResponseError('Failed to parse JSON',
                                             body=self.body,
                                             driver=self.node_driver)
        else:
            return self.body
Exemplo n.º 13
0
 def parse_body(self):
     # length of 1 can't be valid XML, but on destroy node,
     # slicehost returns a 1 byte response with a "Content-Type:
     # application/xml" header. booya.
     if not self.body or len(self.body) <= 1:
         return None
     try:
         body = ET.XML(self.body)
     except:
         raise MalformedResponseError(
             "Failed to parse XML",
             body=self.body,
             driver=SlicehostNodeDriver)
     return body
Exemplo n.º 14
0
    def parse_error(self):
        if self.status == 401:
            raise InvalidCredsError(self.body)

        try:
            body = ET.XML(self.body)
        except:
            raise MalformedResponseError(
                "Failed to parse XML",
                body=self.body,
                driver=SlicehostNodeDriver)
        try:
            return "; ".join([ err.text
                               for err in
                               body.findall('error') ])
        except ExpatError:
            return self.body
Exemplo n.º 15
0
    def _auth(self):
        conn = None
        try:
            conn = self.conn_classes[self.secure](
                self.auth_host, self.auth_port)

            conn.request(
                method='GET',
                url=self.auth_path,
                headers={
                    'X-Auth-User': self.user_id,
                    'X-Auth-Key': self.key
                }
            )

            resp = conn.getresponse()

            if resp.status == httplib.NO_CONTENT:
                # HTTP NO CONTENT (204): auth successful
                self._parse_url_headers(dict(resp.getheaders()))

            elif resp.status == httplib.UNAUTHORIZED:
                # HTTP UNAUTHORIZED (401): auth failed
                raise InvalidCredsError()
            else:
                # Any response code != 401 or 204, something is wrong
                raise MalformedResponseError('Malformed response',
                        body='code: %s body:%s' % (resp.status, ''.join(resp.body.readlines())),
                        driver=self.driver)

            for key in ['server_url', 'storage_url', 'cdn_management_url',
                        'lb_url']:
                url = getattr(self, key, None)
                if url:
                    scheme, server, request_path, param, query, fragment = (
                        urlparse.urlparse(getattr(self, key)))
                    # Set host to where we want to make further requests to
                    setattr(self, '__%s' % (key), server)
                    setattr(self, '__request_path_%s' % (key), request_path)
        finally:
            if conn:
                conn.close()
Exemplo n.º 16
0
    def authenticate_3_x_with_password(self):
        # TODO: Support for custom domain
        # TODO: Refactor and add a class per API version
        domain = 'Default'

        data = {
            'auth': {
                'identity': {
                    'methods': ['password'],
                    'password': {
                        'user': {
                            'domain': {
                                'name': domain
                            },
                            'name': self.user_id,
                            'password': self.key
                        }
                    }
                },
                'scope': {
                    'project': {
                        'domain': {
                            'name': domain
                        },
                        'name': self.tenant_name
                    }
                }
            }
        }

        if self.tenant_name:
            data['auth']['scope'] = {
                'project': {
                    'domain': {
                        'name': domain
                    },
                    'name': self.tenant_name
                }
            }

        data = json.dumps(data)
        response = self.request('/v3/auth/tokens',
                                data=data,
                                headers={'Content-Type': 'application/json'},
                                method='POST')

        if response.status == httplib.UNAUTHORIZED:
            # Invalid credentials
            raise InvalidCredsError()
        elif response.status in [httplib.OK, httplib.CREATED]:
            headers = response.headers

            try:
                body = json.loads(response.body)
            except Exception:
                e = sys.exc_info()[1]
                raise MalformedResponseError('Failed to parse JSON', e)

            try:
                expires = body['token']['expires_at']

                self.auth_token = headers['x-subject-token']
                self.auth_token_expires = parse_date(expires)
                self.urls = body['token']['catalog']
                self.auth_user_info = None
            except KeyError:
                e = sys.exc_info()[1]
                raise MalformedResponseError(
                    'Auth JSON response is \
                                             missing required elements', e)
            body = 'code: %s body:%s' % (response.status, response.body)
        else:
            raise MalformedResponseError('Malformed response',
                                         body=body,
                                         driver=self.driver)

        return self
Exemplo n.º 17
0
    def authenticate(self, force=False):
        """
        Perform authentication.
        """
        if not self._is_authentication_needed(force=force):
            return self

        data = {
            'auth': {
                'identity': {
                    'methods': ['password'],
                    'password': {
                        'user': {
                            'domain': {
                                'name': self.domain_name
                            },
                            'name': self.user_id,
                            'password': self.key
                        }
                    }
                }
            }
        }

        if self.token_scope == OpenStackIdentityTokenScope.PROJECT:
            # Scope token to project (tenant)
            data['auth']['scope'] = {
                'project': {
                    'domain': {
                        'name': self.domain_name
                    },
                    'name': self.tenant_name
                }
            }
        elif self.token_scope == OpenStackIdentityTokenScope.DOMAIN:
            # Scope token to domain
            data['auth']['scope'] = {'domain': {'name': self.domain_name}}
        elif self.token_scope == OpenStackIdentityTokenScope.UNSCOPED:
            pass
        else:
            raise ValueError('Token needs to be scoped either to project or '
                             'a domain')

        data = json.dumps(data)
        response = self.request('/v3/auth/tokens',
                                data=data,
                                headers={'Content-Type': 'application/json'},
                                method='POST')

        if response.status == httplib.UNAUTHORIZED:
            # Invalid credentials
            raise InvalidCredsError()
        elif response.status in [httplib.OK, httplib.CREATED]:
            headers = response.headers

            try:
                body = json.loads(response.body)
            except Exception:
                e = sys.exc_info()[1]
                raise MalformedResponseError('Failed to parse JSON', e)

            try:
                roles = self._to_roles(body['token']['roles'])
            except Exception:
                e = sys.exc_info()[1]
                roles = []

            try:
                expires = body['token']['expires_at']

                self.auth_token = headers['x-subject-token']
                self.auth_token_expires = parse_date(expires)
                # Note: catalog is not returned for unscoped tokens
                self.urls = body['token'].get('catalog', None)
                self.auth_user_info = None
                self.auth_user_roles = roles
            except KeyError:
                e = sys.exc_info()[1]
                raise MalformedResponseError(
                    'Auth JSON response is \
                                             missing required elements', e)
            body = 'code: %s body:%s' % (response.status, response.body)
        else:
            raise MalformedResponseError('Malformed response',
                                         body=body,
                                         driver=self.driver)

        return self