everything start from keystone(2)

本文详细解析了使用keystoneclient调用OpenStack服务的过程,特别是通过/usr/bin/keystone脚本执行main函数实现命令行操作。以keystoneclient为例,展示其与rest API的不同之处,以及在不同服务调用方法中的应用,如通过shell.py的main函数处理命令和参数。同时,阐述了client初始化和调用方法的具体实现,如在do_tenant_list方法中如何执行真正的API调用,以及通过client对象进行实际请求的过程。

和调用openstack的其他服务一样,keystone服务在被其他模块调用时也是用keystone client,来看一看keystone client调用时的方式,以及和rest的不同。

前面仔细分析过ironic的client启动过过程,argparser等虽然没有细说,是因为我暂时不用修改client,虽然不难:),我更多是将client作为研究openstack的入口,

就像看一个大型项目,从测试开始浏览全貌一样,从client入手是对server端实现方式最合适的探测点。


一样的,通过/usr/bin/keystone脚本,在keystoneclient.shell.py中执行main:

OpenStackIdentityShell().main(sys.argv[1:])

client这不是服务,是函数的执行,来一个command line的命令配上参数,shell执行一下,对不同的调用方法, 和ironic类似,严格来说,ironic遵循了这一风格,

在shell.py的main中:

subcommand_parser = self.get_subcommand_parser(api_version)

subparsers = parser.add_subparsers(metavar='<subcommand>')

self._find_actions(subparsers, actions_module) #不错关键在这一部分,我们输入keystone tenant-list对应的是什么方法呢?

在_find_action方法中:

for attr in (a for a in dir(actions_module) if a.startswith('do_')):
            # I prefer to be hyphen-separated instead of underscores.
            command = attr[3:].replace('_', '-')
            callback = getattr(actions_module, attr)

           。。。。

是不是和ironic一样:),对命令指明callback的方法,(这里对使用keystone v2.0 api来说在keystoneclient/v2.0目录下的client.py中指定了命令的list),


OK,那现在有一个命令 “keystone tenant-list”:

self.cs = self.get_api_class #由shell_v2_0.CLIENT_CLASS,得到v2.0下的client

args.func(self.cs, args) #这里的func就是刚才所说的callback,第一个参数cs为v2.0下的client

来看do_tenant_list::

def do_tenant_list(kc, args):
    """List all tenants."""
    tenants = kc.tenants.list() #真正的执行
    utils.print_list(tenants, ['id', 'name', 'enabled'], order_by='name')


而在client中:

 def __init__(self, **kwargs):
        """Initialize a new client for the Keystone v2.0 API."""
        super(Client, self).__init__(**kwargs)
        self.endpoints = endpoints.EndpointManager(self)
        self.extensions = extensions.ExtensionManager(self)
        self.roles = roles.RoleManager(self)
        self.services = services.ServiceManager(self)
        self.tokens = tokens.TokenManager(self)

       self.tenants = tenants.TenantManager(self, self.roles, self.users)

       。。。。

所以在do_tenant_list中kc.tenants.list()执行的是self.tenants.list() 也就是TenantManager,在TenantManager中:

tenant_list = self._list('/tenants%s' % query, 'tenants')

trace一下发现调用的_list实际上是发送client的get或者post方法(client继承自HttpClient,进行了封装

在_lsit中:

        if body:
            resp, body = self.client.post(url, body=body, **kwargs)
        else:
            resp, body = self.client.get(url, **kwargs)


trace一下keystoneclient/httpclient.py中的HttpClient

get/post/delete/put -> _cs_request -->request

当然了所有的call都会受到前面说的“token_auth admin_token_auth”等filter的check,因为这里所有的调用也都变成了rest call

知道了client调用时候的流程,那么怎么样传递参数得到client的对象,再用client 去call方法呢,如何使用client才能让鉴权通过呢,本来想和

在一起做一节,累了,下一节再说。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值