现在其实很流行使用rest,尤其是分布式计算和云计算的框架和平台中,rest以其轻量级,易于扩展伸缩的特点被大量使用,
不只是ironic,在openstack的很多模块中,打入自己的driver是最直接的贡献开源的一种方式,很多公司会选择将openstack
trunk出来搞一个自己的分支,除了改写部分openstack的core代码之外,和现有系统集成也很流行,尤其是平台级的现有产品,
由于本身对外暴漏有接口,文档完善,使得集成变得简单。
此时,进行http cal的调用时第一步,要在ironic里面完成这一功能,并和ironic源生的代码显得统一,一般的,模仿各种client,
ironicclient,cinder client,glance client等,会实现一个httpclient,包装python “httplib.HTTP”类,使得调用与keystone结合起来
进行验证,比如在ironic client中:
def get_connection_params(endpoint, **kwargs):
parts = urlparse.urlparse(endpoint)
path = _trim_endpoint_api_version(parts.path)
_args = (parts.hostname, parts.port, path)
_kwargs = {'timeout': (float(kwargs.get('timeout'))
if kwargs.get('timeout') else 600)}
if parts.scheme == 'https':
_class = VerifiedHTTPSConnection
_kwargs['ca_file'] = kwargs.get('ca_file', None)
_kwargs['cert_file'] = kwargs.get('cert_file', None)
_kwargs['key_file'] = kwargs.get('key_file', None)
_kwargs['insecure'] = kwargs.get('insecure', False)
elif parts.scheme == 'http':
_class = six.moves.http_client.HTTPConnection
else:
msg = 'Unsupported scheme: %s' % parts.scheme
raise exc.EndpointException(msg)
return (_class, _args, _kwargs)
实际调用时,需要在heaser中传入token
def _http_request(self, url, method, **kwargs):
"""Send an http request with the specified characteristics.
Wrapper around httplib.HTTP(S)Connection.request to handle tasks such
as setting headers and error handling.
"""
# Copy the kwargs so we can reuse the original in case of redirects
kwargs['headers'] = copy.deepcopy(kwargs.get('headers', {}))
kwargs['headers'].setdefault('User-Agent', USER_AGENT)
if self.auth_token:
kwargs['headers'].setdefault('X-Auth-Token', self.auth_token)
在client中这么做很合理,封装http client使得在程序中调用rest call更加方便,但是显得用点儿“重”,说
这种方式重,因为仅仅进行rest call的话linux的工具cURL就显得非常简单,那么想在ironic或者其他模块中
使用cURL行不行呢?
首先的确定在现有的模块中有使用cURL,因为如果我们想将自己的东西贡献到社区去,除非不可避免,我觉得
我们应该尽可能让依赖的类库被现有的框架包含,即使不被包含,我们希望使用yum或者apt-get 等命令可以在
源中下到,不会给安装的用户带来不便。
我们前一篇讲ironic pxe时提到,在80-deploy-ironic脚本中有cURL的call,同时在ironic client中有:
def log_curl_request(self, method, url, kwargs):curl = ['curl -i -X %s' % method]
for (key, value) in kwargs['headers'].items():
header = '-H \'%s: %s\'' % (key, value)
curl.append(header)
所以使用cURL是可以,基本上cURL都是linux自带的核心工具,因此对于较小的模块,使用cURL我认为是更好的选择,
而功能较为繁复的模块,封装http client更合适。
续:
搜索了openstack的源码之后,发现curl还是很少使用的,虽然在ironic client中发现了对它的使用,但是requests库以其轻量级,
易于使用在多个部分被使用,特别是测试code中,因此在验证或者调试阶段可以使用curl,实际发布时使用requests看起来更好
来一个requests的小例子:
>>>import requests
>>>from requests.auth import HTTPBasicAuth
>>> r=requests.get('https://xxx', params={'param1':'value1','param2':'value2'}, auth=HTTPBasicAuth('user','password'), verify=False)
关于verify的设置参见:
http://stackoverflow.com/questions/10667960/python-requests-throwing-up-sslerror