python-swiftclient client.py源码分析

彭雨华
2023-12-01

python-swiftclient client.py源码分析

Attention:有些解释在代码注释里面,看注释!!!先来看个实例:

import client
authurl = 'http://192.168.0.61:5000/v2.0'
user = 'admin'
key = 'admin'
#实例化类Connection,其实这里还没有建立连接
conn = client.Connection(authurl, user, key, tenant_name='admin', auth_version='2')
#获取认证信息,endpoint swift的url和token
conn.get_auth()
(u'http://192.168.0.63:8080/v1/AUTH_63aa76aa231f49f9a2ebb7ced54149a8', u'3b5d0da722d248cd9d96aa13c701aa06')

类Connection的__init__方法

class Connection(object):
    """Convenience class to make requests that will also retry the request"""
 
    def __init__(self, authurl, user, key, retries=5, preauthurl=None,
                 preauthtoken=None, snet=False, starting_backoff=1,
                 tenant_name=None, os_options={}, auth_version="1"):
        """
        :param authurl: authentication URL
        :param user: user name to authenticate as
        :param key: key/password to authenticate with
        :param retries: Number of times to retry the request before failing
        :param preauthurl: storage URL (if you have already authenticated)
        :param preauthtoken: authentication token (if you have already
                             authenticated)
        :param snet: use SERVICENET internal network default is False
        :param auth_version: OpenStack auth version, default is 1.0
        :param tenant_name: The tenant/account name, required when connecting
                            to a auth 2.0 system.
        :param os_options: The OpenStack options which can have tenant_id,
                           auth_token, service_type, tenant_name,
                           object_storage_url
        """
        self.authurl = authurl
        self.user = user
        self.key = key
        self.retries = retries
        self.http_conn = None
        self.url = preauthurl
        self.token = preauthtoken
        self.attempts = 0
        self.snet = snet
        self.starting_backoff = starting_backoff
        self.auth_version = auth_version
        if tenant_name:
            os_options['tenant_name'] = tenant_name
        self.os_options = os_options

实例化Connection后

self.authurl = 'http://192.168.0.61:5000/v2.0'
self.user = 'admin'
self.key = 'admin'
self.auth_version = 2
self.os_options = {'tenant_name':'admin'}
tenant_name = 'admin'

类Connection的get_auth方法

    def get_auth(self):
        return get_auth(self.authurl,    
                        self.user,
                        self.key,
                        snet=self.snet,
                        auth_version=self.auth_version,
                        os_options=self.os_options)

get_auth()函数

def get_auth(auth_url, user, key, **kwargs):
    """
    Get authentication/authorization credentials.
 
    The snet parameter is used for Rackspace's ServiceNet internal network
    implementation. In this function, it simply adds *snet-* to the beginning
    of the host name for the returned storage URL. With Rackspace Cloud Files,
    use of this network path causes no bandwidth charges but requires the
    client to be running on Rackspace's ServiceNet network.
    """
    #kwargs = {'auth_version':2, 'os_optinons':{'tenant_name':'admin'}},所以auth_version = 2
    auth_version = kwargs.get('auth_version', '1')
 
    if auth_version in ['1.0', '1', 1]:
        return get_auth_1_0(auth_url,
                            user,
                            key,
                            kwargs.get('snet'))
 
    if auth_version in ['2.0', '2', 2]:
 
        # We are allowing to specify a token/storage-url to re-use
        # without having to re-authenticate.
        #不执行
        if (kwargs['os_options'].get('object_storage_url') and
                kwargs['os_options'].get('auth_token')):
            return(kwargs['os_options'].get('object_storage_url'),
                   kwargs['os_options'].get('auth_token'))
 
        # We are handling a special use case here when we were
        # allowing specifying the account/tenant_name with the -U
        # argument
        #不执行
        if not kwargs.get('tenant_name') and ':' in user:
            (kwargs['os_options']['tenant_name'],
             user) = user.split(':')
 
        # We are allowing to have an tenant_name argument in get_auth
        # directly without having os_options
        #不执行
        if kwargs.get('tenant_name'):
            kwargs['os_options']['tenant_name'] = kwargs['tenant_name']
 
        if (not 'tenant_name' in kwargs['os_options']):
            raise ClientException('No tenant specified')
 
        #kwargs['os_options'] = {'tenant_name':'admin'},下面要看get_keystoneclient_2_0()函数了
        (auth_url, token) = get_keystoneclient_2_0(auth_url, user,
                                                   key, kwargs['os_options'])
        return (auth_url, token)
 
    raise ClientException('Unknown auth_version %s specified.'
                          % auth_version)

get_keystoneclient_2_0()函数

def get_keystoneclient_2_0(auth_url, user, key, os_options):
    """
    Authenticate against a auth 2.0 server.
 
    We are using the keystoneclient library for our 2.0 authentication.
    """
    from keystoneclient.v2_0 import client as ksclient
    #tenant_name = 'admin'
    #tenant_id = None
    _ksclient = ksclient.Client(username=user,
                                password=key,
                                tenant_name=os_options.get('tenant_name'),
                                tenant_id=os_options.get('tenant_id'),
                                auth_url=auth_url)
    #service_type = 'object-store'
    service_type = os_options.get('service_type') or 'object-store'
    endpoint = _ksclient.service_catalog.url_for(
        service_type=service_type,
        endpoint_type='publicURL')
    #返回endpoint的url和相应的token
    return (endpoint, _ksclient.auth_token)

从开始到这里是围绕类Connection的get_auth方法分析,为什么要先分析get_auth方法呢,因为她是整合client.py的基础,之后很多方法都需要先使用get_auth获得认证信息。


 类似资料: