示例#1
0
def setup_connection(endpoint, auth_data, resolved_node_definition):
    """
    Setup the connection to the Nova endpoint.
    """
    project_id = resolved_node_definition['resource'].get('project_id', None)
    user_domain_name = resolved_node_definition['resource'].get(
        'user_domain_name', 'Default')
    region_name = resolved_node_definition['resource'].get('region_name', None)
    auth_type = auth_data.get('type', None)
    if auth_type is None:
        user = auth_data['username']
        password = auth_data['password']
        auth = v3.Password(auth_url=endpoint,
                           username=user,
                           password=password,
                           project_id=project_id,
                           user_domain_name=user_domain_name)
        sess = session.Session(auth=auth)
    elif auth_type == 'application_credential':
        cred_id = auth_data['id']
        cred_secret = auth_data['secret']
        auth = v3.ApplicationCredential(
            auth_url=endpoint,
            application_credential_secret=cred_secret,
            application_credential_id=cred_id)
        sess = session.Session(auth=auth)
    else:
        raise NodeCreationError(
            None, 'Unknown authentication type provided: "%s"' % auth_type)
    os = connection.Connection(session=sess, region_name=region_name)
    return os
示例#2
0
    def _get_auth(self):
        if self.cloud_auth["domain_name"]:
            if self.cloud_auth["auth_type"] == 'password':
                kwargs = {
                    'auth_url': self.cloud_auth["auth_url"],
                    'username': self.cloud_auth["username"],
                    'password': self.cloud_auth["password"],
                    'user_domain_name': self.cloud_auth["domain_name"]
                }
                if self.unscoped:
                    kwargs['unscoped'] = self.unscoped
                else:
                    kwargs['project_id'] = self.cloud_auth["project_id"]

                return v3.Password(**kwargs)
            else:
                access_key = \
                    self.cloud_auth.application_credential_secret
                access_key_id = \
                    self.cloud_auth.application_credential_id
                kwargs = {
                    'auth_url': self.cloud_auth.auth_url,
                    'application_credential_secret': access_key,
                    'application_credential_id': access_key_id
                }
                return v3.ApplicationCredential(**kwargs)
        else:
            kwargs = {
                'auth_url': self.cloud_auth.auth_url,
                'username': self.cloud_auth.username,
                'password': self.cloud_auth.password,
                'tenant_id': self.cloud_auth.project_id
            }
            return v2.Password(**kwargs)
示例#3
0
 def _get_new_session(self):
     try:
         auth = keystoneidentity.ApplicationCredential(
             auth_url=self.auth_url,
             application_credential_secret=self.app_secret,
             application_credential_id=self.app_id,
         )
     except KeyError as err:
         logging.error(
             "Error reading application credentials: {}".format(err))
         return None
     return keystonesession.Session(auth=auth, timeout=self.DEFAULT_TIMEOUT)
示例#4
0
 def test_application_credential_method(self):
     self.stub_auth(json=self.TEST_APP_CRED_TOKEN_RESPONSE)
     ac = v3.ApplicationCredential(
         self.TEST_URL, application_credential_id=self.TEST_APP_CRED_ID,
         application_credential_secret=self.TEST_APP_CRED_SECRET)
     req = {'auth': {'identity':
            {'methods': ['application_credential'],
             'application_credential': {
                 'id': self.TEST_APP_CRED_ID,
                 'secret': self.TEST_APP_CRED_SECRET}}}}
     s = session.Session(auth=ac)
     self.assertEqual({'X-Auth-Token': self.TEST_TOKEN},
                      s.get_auth_headers())
     self.assertRequestBodyIs(json=req)
     self.assertEqual(s.auth.auth_ref.auth_token, self.TEST_TOKEN)
示例#5
0
    def get_connection(self, auth_url, region_name, project_id,
                       user_domain_name):
        """Create OpenStack connection.

        Args:
            auth_url (string): Authentication URL for the NOVA
                resource.
            region_name (string, optional): Name of the region resource.
                Defaults to None.
            project_id (string, optional): ID of the project resource.
                Defaults to None.
            user_domain_name (string, optional): Define the user_domain_name.
                Defaults to 'Default'

        Raises:
            Exception: Project ID missing

        Returns:
            tuple: OpenStackSDK connection, and nova_client Connection
        """
        auth_data = self.get_credentials()
        if auth_data[2]:
            app_cred_id = auth_data[0]
            app_cred_secret = auth_data[1]
            auth = v3.ApplicationCredential(
                auth_url,
                application_credential_id=app_cred_id,
                application_credential_secret=app_cred_secret)
        else:
            if project_id is None:
                raise Exception('Project ID is missing!')
            user = auth_data[0]
            password = auth_data[1]
            auth = v3.Password(auth_url=auth_url,
                               username=user,
                               password=password,
                               user_domain_name=user_domain_name,
                               project_id=project_id)
        sess = session.Session(auth=auth)
        return connection.Connection(
            region_name=region_name,
            session=sess,
            compute_api_version='2',
            identity_interface='public'), nova_client.Client(
                2, session=sess, region_name=region_name)
示例#6
0
def join():
    """Authorize a client node and return relevant config."""

    # Retrieve an API version from the request - it is a mandatory
    # header for this API.
    request_version = request.headers.get('API-Version')
    if request_version is None:
        logger.debug('The client has not specified the API-version header.')
        raise APIVersionMissing()
    else:
        try:
            api_version = semantic_version.Version(request_version)
        except ValueError:
            logger.debug('The client has specified an invalid API version.'
                         f': {request_version}')
            raise APIVersionInvalid()

    # Compare the API version used by the clustering service with the
    # one specified in the request and return an appropriate response.
    if api_version.major > API_VERSION.major:
        logger.debug('The client requested a version that is not'
                     f' supported yet: {api_version}.')
        raise APIVersionNotImplemented()
    elif api_version.major < API_VERSION.major:
        logger.debug('The client request version is no longer supported'
                     f': {api_version}.')
        raise APIVersionDropped()
    else:
        # Flask raises a BadRequest if the JSON content is invalid and
        # returns None if the Content-Type header is missing or not set
        # to application/json.
        try:
            req_json = request.json
        except BadRequest:
            logger.debug('The client has POSTed an invalid JSON'
                         ' in the request.')
            raise InvalidJSONInRequest()
        if req_json is None:
            logger.debug('The client has not specified the application/json'
                         ' content type in the request.')
            raise IncorrectContentType()

        # So far we don't have any minor versions with backwards-compatible
        # changes so just assume that all data will be present or error out.
        credential_id = req_json.get('credential-id')
        credential_secret = req_json.get('credential-secret')
        if not credential_id or not credential_secret:
            logger.debug('The client has not specified the required'
                         ' authentication data in the request.')
            return MissingAuthDataInRequest()

        # TODO: handle https here when TLS termination support is added.
        keystone_base_url = 'http://localhost:5000/v3'

        # In an unlikely event of failing to construct an auth object
        # treat it as if invalid data got passed in terms of responding
        # to the client.
        try:
            auth = v3.ApplicationCredential(
                auth_url=keystone_base_url,
                application_credential_id=credential_id,
                application_credential_secret=credential_secret)
        except Exception:
            logger.exception('An exception has occurred while trying to build'
                             ' an auth object for an application credential'
                             ' passed from the clustering client.')
            raise InvalidAuthDataInRequest()

        try:
            # Use the auth object with the app credential to create a session
            # which the Keystone client will use.
            sess = session.Session(auth=auth)
        except Exception:
            logger.exception('An exception has occurred while trying to build'
                             ' a Session object with auth data'
                             ' passed from the clustering client.')
            raise UnexpectedError()

        try:
            keystone_client = v3client.Client(session=sess)
        except Exception:
            logger.exception('An exception has occurred while trying to build'
                             ' a Keystone Client object with auth data'
                             ' passed from the clustering client.')
            raise UnexpectedError()

        try:
            # The add-compute command creates application credentials that
            # allow access to /v3/auth/catalog with an expiration time.
            # Authorization failures occur after an app credential expires
            # in which case an error is returned to the client.
            keystone_client.get(f'{keystone_base_url}/auth/catalog')
        except (kc_exceptions.AuthorizationFailure,
                kc_exceptions.Unauthorized):
            logger.exception('Failed to get a Keystone token'
                             ' with the application credentials'
                             ' passed from the clustering client.')
            raise AuthorizationFailed()
        except ValueError:
            logger.exception('Insufficient amount of parameters were'
                             ' used in the request to Keystone.')
            raise UnexpectedError()
        except kc_exceptions.ConnectionError:
            logger.exception('Failed to connect to Keystone')
            raise UnexpectedError()
        except kc_exceptions.SSLError:
            logger.exception('A TLS-related error has occurred while'
                             ' connecting to Keystone')
            raise UnexpectedError()

        # We were able to authenticate against Keystone using the
        # application credential and verify that it has not expired
        # so the information for a compute node to join the cluster can
        # now be returned.
        return json.dumps(join_info())