ironicclient是一个cli工具,用来和用户交互的。

首先写一个简单的例子,获取ironic所有的node节点:

from ironicclient import client

if __name__ == '__main__':
kwargs = {'os_username': 'ironic',
'os_password': 'IRONIC_PASSWORD',
'os_auth_url': 'http://192.168.1.72:5000/',
'os_tenant_name': 'services'}
ironic = client.get_client(1, **kwargs)
print ironic.node.list()

这里我们创建了一个client对象,这个对象是通过client类的get_client方法返回的,

这是一个工厂模式,下面看下get_client方法:

def get_client(api_version, os_auth_token=None, ironic_url=None,
os_username=None, os_password=None, os_auth_url=None,
os_project_id=None, os_project_name=None, os_tenant_id=None,
os_tenant_name=None, os_region_name=None,
os_user_domain_id=None, os_user_domain_name=None,
os_project_domain_id=None, os_project_domain_name=None,
os_service_type=None, os_endpoint_type=None,
insecure=None, timeout=None, os_cacert=None, ca_file=None,
os_cert=None, cert_file=None, os_key=None, key_file=None,
os_ironic_api_version=None, max_retries=None,
retry_interval=None, session=None, **ignored_kwargs):
os_service_type = os_service_type or 'baremetal'
os_endpoint_type = os_endpoint_type or 'publicURL'
project_id = (os_project_id or os_tenant_id)
project_name = (os_project_name or os_tenant_name)
kwargs = {
'os_ironic_api_version': os_ironic_api_version,
'max_retries': max_retries,
'retry_interval': retry_interval,
}
endpoint = ironic_url
cacert = os_cacert or ca_file
cert = os_cert or cert_file
key = os_key or key_file
if os_auth_token and endpoint:
kwargs.update({
'token': os_auth_token,
'insecure': insecure,
'ca_file': cacert,
'cert_file': cert,
'key_file': key,
'timeout': timeout,
})
elif os_auth_url:
auth_type = 'password'
auth_kwargs = {
'auth_url': os_auth_url,
'project_id': project_id,
'project_name': project_name,
'user_domain_id': os_user_domain_id,
'user_domain_name': os_user_domain_name,
'project_domain_id': os_project_domain_id,
'project_domain_name': os_project_domain_name,
}
if os_username and os_password:
auth_kwargs.update({
'username': os_username,
'password': os_password,
})
elif os_auth_token:
auth_type = 'token'
auth_kwargs.update({
'token': os_auth_token,
})
# Create new session only if it was not passed in
if not session:
loader = kaloading.get_plugin_loader(auth_type)
auth_plugin = loader.load_from_options(**auth_kwargs)
# Let keystoneauth do the necessary parameter conversions
session = kaloading.session.Session().load_from_options(
auth=auth_plugin, insecure=insecure, cacert=cacert,
cert=cert, key=key, timeout=timeout,
) exception_msg = _('Must provide Keystone credentials or user-defined '
'endpoint and token')
if not endpoint:
if session:
try:
# Pass the endpoint, it will be used to get hostname
# and port that will be used for API version caching. It will
# be also set as endpoint_override.
endpoint = session.get_endpoint(
service_type=os_service_type,
interface=os_endpoint_type,
region_name=os_region_name
)
except Exception as e:
raise exc.AmbiguousAuthSystem(
exception_msg + _(', error was: %s') % e)
else:
# Neither session, nor valid auth parameters provided
raise exc.AmbiguousAuthSystem(exception_msg) # Always pass the session
kwargs['session'] = session return Client(api_version, endpoint, **kwargs)

中间这一大串可以先不看,主要是认证的一些信息。在get_cleint函数结尾,调用了

Client() 方法作为返回值。这里传入了三个参数:

  • api_version
  • endpoint
  • **kwargs

其中api_version是1,endpoint是http://192.168.1.72:6385,kwargs保存了session的

信息:

{'os_ironic_api_version': None, 'session': <keystoneauth1.session.Session object at 0x2441690>, 'retry_interval': None, 'max_retries': None}

我们再来看看Client()方法的具体实现:

def Client(version, *args, **kwargs):
module = utils.import_versioned_module(version, 'client')
client_class = getattr(module, 'Client')
return client_class(*args, **kwargs)

这里module内容如下:

<module 'ironicclient.v1.client' from '/usr/lib/python2.7/site-packages/ironicclient/v1/client.pyc'>

后面的client_class使用反射的机制来获取Client类。简单的说就是调用文件

/usr/lib/python2.7/site-packages/ironicclient/v1/client.py中的

Client类,并返回其对象。

再来看下Client类的具体实现:

class Client(object):
def __init__(self, *args, **kwargs):
"""Initialize a new client for the Ironic v1 API."""
if kwargs.get('os_ironic_api_version'):
kwargs['api_version_select_state'] = "user"
else:
# If the user didn't specify a version, use a cached version if
# one has been stored
host, netport = http.get_server(args[0])
saved_version = filecache.retrieve_data(host=host, port=netport)
if saved_version:
kwargs['api_version_select_state'] = "cached"
kwargs['os_ironic_api_version'] = saved_version
else:
kwargs['api_version_select_state'] = "default"
kwargs['os_ironic_api_version'] = DEFAULT_VER self.http_client = http._construct_http_client(*args, **kwargs) self.chassis = chassis.ChassisManager(self.http_client)
self.node = node.NodeManager(self.http_client)
self.port = port.PortManager(self.http_client)
self.driver = driver.DriverManager(self.http_client)

可以看出Client类的chassis,node,port,driver属性都是对应类的manager。

先看看NodeManager的实现:

class NodeManager(base.CreateManager):
resource_class = Node
_creation_attributes = ['chassis_uuid', 'driver', 'driver_info',
'extra', 'uuid', 'properties', 'name']
_resource_name = 'nodes' def list(self, associated=None, maintenance=None, marker=None, limit=None,
detail=False, sort_key=None, sort_dir=None, fields=None,
provision_state=None, driver=None):
if limit is not None:
limit = int(limit) if detail and fields:
raise exc.InvalidAttribute(_("Can't fetch a subset of fields "
"with 'detail' set")) filters = utils.common_filters(marker, limit, sort_key, sort_dir,
fields)
if associated is not None:
filters.append('associated=%s' % associated)
if maintenance is not None:
filters.append('maintenance=%s' % maintenance)
if provision_state is not None:
filters.append('provision_state=%s' % provision_state)
if driver is not None:
filters.append('driver=%s' % driver) path = ''
if detail:
path += 'detail'
if filters:
path += '?' + '&'.join(filters) if limit is None:
return self._list(self._path(path), "nodes")
else:
return self._list_pagination(self._path(path), "nodes",
limit=limit)
...

我们看list方法,前面是一些过滤条件,因为我们没有穿limit参数,所有limit是None,

然后调用了_list()方法。这个是在父类里定义的。实现代码在:

/usr/lib/python2.7/site-packages/ironicclient/common/base.py

    def _list(self, url, response_key=None, obj_class=None, body=None):
resp, body = self.api.json_request('GET', url) if obj_class is None:
obj_class = self.resource_class data = self._format_body_data(body, response_key)
return [obj_class(self, res, loaded=True) for res in data if res]

我们可以看到,这里是发送了HTTP GET请求,然就将收到的数据格式化并返回。

这里的api是我们在前面传入的,使用http创建的一个client对象。

self.http_client = http._construct_http_client(*args, **kwargs)
... self.node = node.NodeManager(self.http_client)

python ironicclient源码分析的更多相关文章

  1. eos源码分析和应用(一)调试环境搭建

    转载自 http://www.limerence2017.com/2018/09/02/eos1/#more eos基于区块链技术实现的开源引擎,开发人员可以基于该引擎开发DAPP(分布式应用).下面 ...

  2. python multiprocessing 源码分析

    1. 文档是最先需要了解的,读完文档可能会有很多的意外的收获同时也会留下疑惑,对于一般的使用我觉得读完文档就差不多了,除非一些很有疑惑的地方你可能需要再深入的了解一下.我读文档的目的第一个就是为了找出 ...

  3. python slots源码分析

    上次总结Python3的字典实现后的某一天,突然开窍Python的__slots__的实现应该也是类似,于是翻了翻CPython的源码,果然如此! 关于在自定义类里面添加__slots__的效果,网上 ...

  4. Python SocketServer源码分析

    1      XXXServer 1.1      BaseSever 提供基础的循环等待请求的处理框架.使用serve_forever启动服务,使用shutdown停止.同时提供了一些可自行扩展的方 ...

  5. python SocketServer 源码分析

    附上原文链接: http://beginman.cn/python/2015/04/06/python-SocketServer/

  6. selenium3 + python - action_chains源码分析

    ActionChains简介 actionchains是selenium里面专门处理鼠标相关的操作如:鼠标移动,鼠标按钮操作,按键和上下文菜单(鼠标右键)交互.这对于做更复杂的动作非常有用,比如悬停和 ...

  7. Python之美[从菜鸟到高手]--urlparse源码分析

    urlparse是用来解析url格式的,url格式如下:protocol :// hostname[:port] / path / [;parameters][?query]#fragment,其中; ...

  8. [python] 基于词云的关键词提取:wordcloud的使用、源码分析、中文词云生成和代码重写

    1. 词云简介 词云,又称文字云.标签云,是对文本数据中出现频率较高的“关键词”在视觉上的突出呈现,形成关键词的渲染形成类似云一样的彩色图片,从而一眼就可以领略文本数据的主要表达意思.常见于博客.微博 ...

  9. Python源码分析(二) - List对象

    python中的高级特性之一就是内置了list,dict等.今天就先围绕列表(List)进行源码分析. Python中的List对象(PyListObject) Python中的的PyListObje ...

随机推荐

  1. Unity 阴影的制作方式

    Unity阴影制作的三种方式. 方式一:Light中Shadow Type的类型 包括Hard Shadows.Soft Shadows.No Shadows:  Mesh Renderer中的属性 ...

  2. js的几大重点

    闭包,:作用域(函数创建),上下文环境(函数执行,会销毁) 匿名函数,:没有函数名的函数,function(){} 自执行函数,:立即调用的匿名函数,(function(){})() 原型链,:继承的 ...

  3. 查找命令which、whereis、locate

      1.find 最常用和最强大的查找命令.它能做到实时查找,精确查找,但速度慢. find的使用格式如下: $ find [指定目录] [指定条件] [指定动作] 指定目录:是指所要搜索的目录和其子 ...

  4. javaScript drag对象进行拖拽使用详解

    目录 drag简介 兼容性 drag事件 拖拽流程 DataTransfer对象 drag拖放桌面文件 drag实例 小结 drag简介 HMTL5提供的支持原生拖拽的实现 兼容性如何? 桌面端的支持 ...

  5. [高中作文赏析]妈妈, 我心中的"灯"

  6. [物理学与PDEs]第1章习题13 静磁场的矢势在媒质交界面上的条件

    试讨论对静磁场的矢势, 如何决定其在媒质交界面上的条件. 解答: 由 $\rot{\bf A}={\bf B}$ 知 $$\bex \oint_l {\bf A}\cdot\rd {\bf l} =\ ...

  7. Collections.unmodifiableMap(Map map)

    public static <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m)返回指定映射 ...

  8. Codeforces 1100F(线性基+贪心)

    题目链接 题意 给定序列,$q(1\leq q \leq 100000) $次询问,每次查询给定区间内的最大异或子集. 思路 涉及到最大异或子集肯定从线性基角度入手.将询问按右端点排序后离线处理询问, ...

  9. hadoop集群完全分布式搭建

    Hadoop环境搭建:完全分布式 集群规划: ip                 hostname 192.168.204.154     master      namenode   resour ...

  10. bat执行python脚本,执行多条命令

    1.新建一个txt文档,输入以下命令 @echo offcmd /k python F:\Pycharm_Projection\Test\test2.py 2.将txt文档保存为.bat格式,然后双击 ...