Merge "apiclient support for keystone v2.0 and v3"
This commit is contained in:
commit
f9b3146a13
217
client.py
217
client.py
@ -17,11 +17,17 @@ This product includes cryptographic software written by Eric Young
|
||||
(eay@cryptsoft.com). This product includes software written by Tim
|
||||
Hudson (tjh@cryptsoft.com).
|
||||
========================================================================
|
||||
|
||||
client interface to the Freezer API
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import socket
|
||||
|
||||
from openstackclient.identity import client as os_client
|
||||
from keystoneclient.auth.identity import v2
|
||||
from keystoneclient.auth.identity import v3
|
||||
from keystoneclient import session as ksc_session
|
||||
|
||||
from backups import BackupsManager
|
||||
from registration import RegistrationManager
|
||||
@ -29,7 +35,16 @@ from jobs import JobManager
|
||||
from actions import ActionManager
|
||||
from sessions import SessionManager
|
||||
|
||||
import exceptions
|
||||
|
||||
FREEZER_SERVICE_TYPE = 'backup'
|
||||
|
||||
|
||||
def env(*vars, **kwargs):
|
||||
for v in vars:
|
||||
value = os.environ.get(v, None)
|
||||
if value:
|
||||
return value
|
||||
return kwargs.get('default', '')
|
||||
|
||||
|
||||
class cached_property(object):
|
||||
@ -45,24 +60,145 @@ class cached_property(object):
|
||||
return value
|
||||
|
||||
|
||||
class Client(object):
|
||||
def build_os_option_parser(parser):
|
||||
parser.add_argument(
|
||||
'--os-username', action='store',
|
||||
help=('Name used for authentication with the OpenStack '
|
||||
'Identity service. Defaults to env[OS_USERNAME].'),
|
||||
dest='os_username', default=env('OS_USERNAME'))
|
||||
parser.add_argument(
|
||||
'--os-password', action='store',
|
||||
help=('Password used for authentication with the OpenStack '
|
||||
'Identity service. Defaults to env[OS_PASSWORD].'),
|
||||
dest='os_password', default=env('OS_PASSWORD'))
|
||||
parser.add_argument(
|
||||
'--os-project-name', action='store',
|
||||
help=('Project name to scope to. Defaults to '
|
||||
'env[OS_PROJECT_NAME].'),
|
||||
dest='os_project_name',
|
||||
default=env('OS_PROJECT_NAME', default='default'))
|
||||
parser.add_argument(
|
||||
'--os-project-domain-name', action='store',
|
||||
help=('Domain name containing project. Defaults to '
|
||||
'env[OS_PROJECT_DOMAIN_NAME].'),
|
||||
dest='os_project_domain_name', default=env('OS_PROJECT_DOMAIN_NAME',
|
||||
default='default'))
|
||||
parser.add_argument(
|
||||
'--os-user-domain-name', action='store',
|
||||
help=('User\'s domain name. Defaults to '
|
||||
'env[OS_USER_DOMAIN_NAME].'),
|
||||
dest='os_user_domain_name', default=env('OS_USER_DOMAIN_NAME',
|
||||
default='default'))
|
||||
parser.add_argument(
|
||||
'--os-tenant-name', action='store',
|
||||
help=('Tenant to request authorization on. Defaults to '
|
||||
'env[OS_TENANT_NAME].'),
|
||||
dest='os_tenant_name', default=env('OS_TENANT_NAME'))
|
||||
parser.add_argument(
|
||||
'--os-tenant-id', action='store',
|
||||
help=('Tenant to request authorization on. Defaults to '
|
||||
'env[OS_TENANT_ID].'),
|
||||
dest='os_tenant_id', default=env('OS_TENANT_ID'))
|
||||
parser.add_argument(
|
||||
'--os-auth-url', action='store',
|
||||
help=('Specify the Identity endpoint to use for '
|
||||
'authentication. Defaults to env[OS_AUTH_URL].'),
|
||||
dest='os_auth_url', default=env('OS_AUTH_URL'))
|
||||
parser.add_argument(
|
||||
'--os-backup-url', action='store',
|
||||
help=('Specify the Freezer backup service endpoint to use. '
|
||||
'Defaults to env[OS_BACKUP_URL].'),
|
||||
dest='os_backup_url', default=env('OS_BACKUP_URL'))
|
||||
parser.add_argument(
|
||||
'--os-region-name', action='store',
|
||||
help=('Specify the region to use. Defaults to '
|
||||
'env[OS_REGION_NAME].'),
|
||||
dest='os_region_name', default=env('OS_REGION_NAME'))
|
||||
parser.add_argument(
|
||||
'--os-token', action='store',
|
||||
help=('Specify an existing token to use instead of retrieving'
|
||||
' one via authentication (e.g. with username & password). '
|
||||
'Defaults to env[OS_TOKEN].'),
|
||||
dest='os_token', default=env('OS_TOKEN'))
|
||||
parser.add_argument(
|
||||
'--os-identity-api-version', action='store',
|
||||
help=('Identity API version: 2.0 or 3. '
|
||||
'Defaults to env[OS_IDENTITY_API_VERSION]'),
|
||||
dest='os_identity_api_version',
|
||||
default=env('OS_IDENTITY_API_VERSION'))
|
||||
return parser
|
||||
|
||||
def __init__(self, version='1',
|
||||
|
||||
def guess_auth_version(opts):
|
||||
if opts.os_identity_api_version == '3':
|
||||
return '3'
|
||||
elif opts.os_identity_api_version == '2.0':
|
||||
return '2.0'
|
||||
elif opts.os_auth_url.endswith('v3'):
|
||||
return '3'
|
||||
elif opts.os_auth_url.endswith('v2.0'):
|
||||
return '2.0'
|
||||
return None
|
||||
|
||||
|
||||
def get_auth_plugin(opts):
|
||||
auth_version = guess_auth_version(opts)
|
||||
if opts.os_username:
|
||||
if auth_version == '3':
|
||||
return v3.Password(auth_url=opts.os_auth_url,
|
||||
username=opts.os_username,
|
||||
password=opts.os_password,
|
||||
project_name=opts.os_project_name,
|
||||
user_domain_name=opts.os_user_domain_name,
|
||||
project_domain_name=opts.os_project_domain_name)
|
||||
elif auth_version == '2.0':
|
||||
return v2.Password(auth_url=opts.os_auth_url,
|
||||
username=opts.os_username,
|
||||
password=opts.os_password,
|
||||
tenant_name=opts.os_tenant_name)
|
||||
elif opts.os_token:
|
||||
if auth_version == '3':
|
||||
return v3.Token(auth_url=opts.os_auth_url,
|
||||
token=opts.os_token,
|
||||
project_name=opts.os_project_name,
|
||||
project_domain_name=opts.os_project_domain_name)
|
||||
elif auth_version == '2.0':
|
||||
return v2.Token(auth_url=opts.os_auth_url,
|
||||
token=opts.os_token,
|
||||
tenant_name=opts.os_tenant_name)
|
||||
raise Exception('Unable to determine correct auth method')
|
||||
|
||||
|
||||
class Client(object):
|
||||
def __init__(self,
|
||||
version='1',
|
||||
token=None,
|
||||
username=None,
|
||||
password=None,
|
||||
tenant_name=None,
|
||||
auth_url=None,
|
||||
session=None,
|
||||
endpoint=None):
|
||||
endpoint=None,
|
||||
opts=None):
|
||||
|
||||
self.opts = opts or build_os_option_parser(
|
||||
argparse.ArgumentParser(description='Freezer Client')
|
||||
).parse_args()
|
||||
if token:
|
||||
self.opts.os_token = token
|
||||
if username:
|
||||
self.opts.os_username = username
|
||||
if password:
|
||||
self.opts.os_password = password
|
||||
if tenant_name:
|
||||
self.opts.os_tenant_name = tenant_name
|
||||
if auth_url:
|
||||
self.opts.os_auth_url = auth_url
|
||||
if endpoint:
|
||||
self.opts.os_backup_url = endpoint
|
||||
self._session = session
|
||||
self.version = version
|
||||
self.token = token
|
||||
self.username = username
|
||||
self.tenant_name = tenant_name
|
||||
self.password = password
|
||||
self.auth_url = auth_url
|
||||
self._endpoint = endpoint
|
||||
self.session = session
|
||||
|
||||
self.backups = BackupsManager(self)
|
||||
self.registration = RegistrationManager(self)
|
||||
self.jobs = JobManager(self)
|
||||
@ -70,52 +206,29 @@ class Client(object):
|
||||
self.sessions = SessionManager(self)
|
||||
|
||||
@cached_property
|
||||
def endpoint(self):
|
||||
if self._endpoint:
|
||||
return self._endpoint
|
||||
services = self.auth.services.list()
|
||||
try:
|
||||
freezer_service = next(x for x in services if x.name == 'freezer')
|
||||
except:
|
||||
raise exceptions.ApiClientException(
|
||||
'freezer service not found in services list')
|
||||
endpoints = self.auth.endpoints.list()
|
||||
try:
|
||||
freezer_endpoint =\
|
||||
next(x for x in endpoints
|
||||
if x.service_id == freezer_service.id)
|
||||
except:
|
||||
raise exceptions.ApiClientException(
|
||||
'freezer endpoint not found in endpoint list')
|
||||
return freezer_endpoint.publicurl
|
||||
def session(self):
|
||||
if self._session:
|
||||
return self._session
|
||||
auth_plugin = get_auth_plugin(self.opts)
|
||||
return ksc_session.Session(auth=auth_plugin)
|
||||
|
||||
@cached_property
|
||||
def auth(self):
|
||||
if self.username and self.password:
|
||||
_auth = os_client.IdentityClientv2(
|
||||
auth_url=self.auth_url,
|
||||
username=self.username,
|
||||
password=self.password,
|
||||
tenant_name=self.tenant_name)
|
||||
elif self.token:
|
||||
_auth = os_client.IdentityClientv2(
|
||||
endpoint=self.auth_url,
|
||||
token=self.token)
|
||||
def endpoint(self):
|
||||
if self.opts.os_backup_url:
|
||||
return self.opts.os_backup_url
|
||||
else:
|
||||
raise exceptions.ApiClientException("Missing auth credentials")
|
||||
return _auth
|
||||
auth_ref = self.session.auth.get_auth_ref(self.session)
|
||||
endpoint = auth_ref.service_catalog.url_for(
|
||||
service_type=FREEZER_SERVICE_TYPE,
|
||||
endpoint_type='public',
|
||||
)
|
||||
return endpoint
|
||||
|
||||
@property
|
||||
def auth_token(self):
|
||||
return self.auth.auth_token
|
||||
|
||||
def api_exists(self):
|
||||
try:
|
||||
if self.endpoint is not None:
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
return self.session.get_token()
|
||||
|
||||
@cached_property
|
||||
def client_id(self):
|
||||
return '{0}_{1}'.format(self.auth.project_id, socket.gethostname())
|
||||
return '{0}_{1}'.format(self.session.get_project_id(),
|
||||
socket.gethostname())
|
||||
|
Loading…
x
Reference in New Issue
Block a user