101 lines
3.3 KiB
Python
101 lines
3.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright 2014 Mirantis, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import json
|
|
import logging
|
|
import socket
|
|
|
|
import requests
|
|
|
|
from fuel_upgrade import errors
|
|
from fuel_upgrade import utils
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class KeystoneClient(object):
|
|
"""Simple keystone authentification client
|
|
|
|
:param str username: is user name
|
|
:param str password: is user password
|
|
:param str auth_url: authentification url
|
|
:param str tenant_name: tenant name
|
|
"""
|
|
|
|
def __init__(self, username=None, password=None,
|
|
auth_url=None, tenant_name=None):
|
|
self.auth_url = auth_url
|
|
self.tenant_name = tenant_name
|
|
self.username = username
|
|
self.password = password
|
|
|
|
@property
|
|
def request(self):
|
|
"""Creates authentification session if required
|
|
|
|
:returns: :class:`requests.Session` object
|
|
"""
|
|
session = requests.Session()
|
|
|
|
# NOTE(ikalnitsky):
|
|
# After starting a new Keystone container, the first attempt to
|
|
# get a token fails. Unfortunately, the logs keep silent and say
|
|
# nothing. As a workaround, we can just increase retries number.
|
|
#
|
|
# See https://bugs.launchpad.net/fuel/+bug/1399144 for details.
|
|
try:
|
|
token = utils.wait_for_true(self.get_token, timeout=10)
|
|
session.headers.update({'X-Auth-Token': token})
|
|
except errors.TimeoutError:
|
|
logger.exception(
|
|
'Cannot retrieve an auth token - an unauthenticated '
|
|
'request will be performed.')
|
|
|
|
return session
|
|
|
|
def get_token(self):
|
|
"""Retrieves auth token from keystone
|
|
|
|
:returns: authentification token or None in case of error
|
|
|
|
NOTE(eli): for 5.0.x versions of fuel we don't
|
|
have keystone and fuel access control feature,
|
|
as result this client should work with and without
|
|
authentication, in order to do this, we are
|
|
trying to create Keystone client and in case if
|
|
it fails we don't use authentication
|
|
"""
|
|
try:
|
|
resp = requests.post(
|
|
self.auth_url,
|
|
headers={'content-type': 'application/json'},
|
|
data=json.dumps({
|
|
'auth': {
|
|
'tenantName': self.tenant_name,
|
|
'passwordCredentials': {
|
|
'username': self.username,
|
|
'password': self.password}}})).json()
|
|
|
|
return (isinstance(resp, dict) and
|
|
resp.get('access', {}).get('token', {}).get('id'))
|
|
except (ValueError,
|
|
socket.timeout,
|
|
requests.exceptions.RequestException) as exc:
|
|
logger.debug('Cannot authenticate in keystone: %s', exc)
|
|
|
|
return None
|