Memo García b3161b0f39 Add default namespace to apiclient
When a client is created from other method rather than command line arguments,
it skips the commandline arguments and by doing this a Namespace is not created,
this commit fix that by creating a default Namespace when the value of self.opts is None

Resolves bug: 1532205

Change-Id: I7a01715c675756e0ce66111939b71a2761b0657a
2016-01-08 15:16:24 +00:00

262 lines
9.7 KiB
Python

"""
Copyright 2015 Hewlett-Packard
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.
client interface to the Freezer API
"""
import argparse
import os
import socket
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
from jobs import JobManager
from actions import ActionManager
from sessions import SessionManager
from oslo_config import cfg
from freezer.utils import Namespace
CONF = cfg.CONF
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):
def __init__(self, func):
self.__doc__ = getattr(func, '__doc__')
self.func = func
def __get__(self, obj, cls):
if obj is None:
return self
value = obj.__dict__[self.func.__name__] = self.func(obj)
return value
def build_os_options():
osclient_opts = [
cfg.StrOpt('os-username',
default=env('OS_USERNAME'),
help='Name used for authentication with the OpenStack '
'Identity service. Defaults to env[OS_USERNAME].',
dest='os_username'),
cfg.StrOpt('os-password',
default=env('OS_PASSWORD'),
help='Password used for authentication with the OpenStack '
'Identity service. Defaults to env[OS_PASSWORD].',
dest='os_password'),
cfg.StrOpt('os-project-name',
default=env('OS_PROJECT_NAME'),
help='Project name to scope to. Defaults to '
'env[OS_PROJECT_NAME].',
dest='os_project_name'),
cfg.StrOpt('os-project-domain-name',
default=env('OS_PROJECT_DOMAIN_NAME'),
help='Domain name containing project. Defaults to '
'env[OS_PROJECT_DOMAIN_NAME].',
dest='os_project_domain_name'),
cfg.StrOpt('os-user-domain-name',
default=env('OS_USER_DOMAIN_NAME'),
help='User\'s domain name. Defaults to '
'env[OS_USER_DOMAIN_NAME].',
dest='os_user_domain_name'),
cfg.StrOpt('os-tenant-name',
default=env('OS_TENANT_NAME'),
help='Tenant to request authorization on. Defaults to '
'env[OS_TENANT_NAME].',
dest='os_tenant_name'),
cfg.StrOpt('os-tenant-id',
default=env('OS_TENANT_ID'),
help='Tenant to request authorization on. Defaults to '
'env[OS_TENANT_ID].',
dest='os_tenant_id'),
cfg.StrOpt('os-auth-url',
default=env('OS_AUTH_URL'),
help='Specify the Identity endpoint to use for '
'authentication. Defaults to env[OS_AUTH_URL].',
dest='os_auth_url'),
cfg.StrOpt('os-backup-url',
default=env('OS_BACKUP_URL'),
help='Specify the Freezer backup service endpoint to use. '
'Defaults to env[OS_BACKUP_URL].',
dest='os_backup_url'),
cfg.StrOpt('os-region-name',
default=env('OS_REGION_NAME'),
help='Specify the region to use. Defaults to '
'env[OS_REGION_NAME].',
dest='os_region_name'),
cfg.StrOpt('os-token',
default=env('OS_TOKEN'),
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'),
cfg.StrOpt('os-identity-api-version',
default=env('OS_IDENTITY_API_VERSION'),
help='Identity API version: 2.0 or 3. '
'Defaults to env[OS_IDENTITY_API_VERSION]',
dest='os_identity_api_version'),
cfg.StrOpt('os-endpoint-type',
choices=['public', 'publicURL', 'internal', 'internalURL',
'admin', 'adminURL'],
default=env('OS_ENDPOINT_TYPE') or 'public',
help='Endpoint type to select. Valid endpoint types: '
'"public" or "publicURL", "internal" or "internalURL",'
' "admin" or "adminURL". Defaults to '
'env[OS_ENDPOINT_TYPE] or "public"',
dest='os_endpoint_type'),
]
return osclient_opts
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'
raise Exception('Please provide valid keystone auth url with valid'
' keystone api version to use')
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, please provide'
' either username or token')
class Client(object):
def __init__(self,
version='1',
token=None,
username=None,
password=None,
tenant_name=None,
auth_url=None,
session=None,
endpoint=None,
opts=None,
project_name=None,
user_domain_name=None,
project_domain_name=None,
verify=True):
self.opts = opts
# this creates a namespace for self.opts when the client is
# created from other method rather than command line arguments.
if self.opts is None:
self.opts = Namespace({})
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
if project_name:
self.opts.os_project_name = project_name
if user_domain_name:
self.opts.user_domain_name = user_domain_name
if project_domain_name:
self.opts.project_domain_name = project_domain_name
# flag to initialize freezer-scheduler with insecure mode
self.verify = verify
self._session = session
self.version = version
self.backups = BackupsManager(self, verify=verify)
self.registration = RegistrationManager(self, verify=verify)
self.jobs = JobManager(self, verify=verify)
self.actions = ActionManager(self, verify=verify)
self.sessions = SessionManager(self, verify=verify)
@cached_property
def session(self):
if self._session:
return self._session
auth_plugin = get_auth_plugin(self.opts)
return ksc_session.Session(auth=auth_plugin, verify=self.verify)
@cached_property
def endpoint(self):
if self.opts.os_backup_url:
return self.opts.os_backup_url
else:
auth_ref = self.session.auth.get_auth_ref(self.session)
endpoint = auth_ref.service_catalog.url_for(
service_type=FREEZER_SERVICE_TYPE,
endpoint_type=self.opts.os_endpoint_type,
)
return endpoint
@property
def auth_token(self):
return self.session.get_token()
@cached_property
def client_id(self):
return '{0}_{1}'.format(self.session.get_project_id(),
socket.gethostname())