heat客户端的stack查询命令的stack_name/stack_id转换流程

使用过heat的朋友都应该利用过heatclient查询stack信息。

例如stack-show命令,该命令的参数如下:

heat stack-show <NAME or ID>

也就是既可以用stack名,也可以用stack ID,来指定要查询的stack。


期初以为是heat engine在处理show_stack请求时进行了区分。

但是通过查看相关代码,发现并不是这样。

传递到EngineService.show_stack的参数stack_identity已经包含了stack_name和stack_id。

这说明heatclient在调用查询请求前,将单独的stack_name或stack_id进行了转换。


打开调试命令执行stack-show命令,相关流程如下:

DEBUG (connectionpool) "GET /v1/c4df22dc73ef478190e1cc80f01219ce/stacks/stack111 HTTP/1.1" 302 195
DEBUG (session) RESP: [302] Content-Length: 195 Connection: keep-alive Location: http://192.168.98.248:8004/v1/c4df22dc73ef478190e1cc80f01219ce/stacks/stack111/eb9e2e45-a2b4-4d43-aaaa-06da51e63bdb Date: Thu, 29 Oct 2015 08:42:34 GMT Content-Type: text/plain; charset=UTF-8 X-Openstack-Request-Id: req-31862d02-54ef-4209-9f7c-5a5c218de881 
RESP BODY: 302 Found

The resource was found at http://192.168.98.248:8004/v1/c4df22dc73ef478190e1cc80f01219ce/stacks/stack111/eb9e2e45-a2b4-4d43-aaaa-06da51e63bdb; you should be redirected automatically.  

DEBUG (connectionpool) "GET /v1/c4df22dc73ef478190e1cc80f01219ce/stacks/stack111/eb9e2e45-a2b4-4d43-aaaa-06da51e63bdb HTTP/1.1" 200 883
DEBUG (session) RESP: [200] Date: Thu, 29 Oct 2015 08:42:34 GMT Connection: keep-alive Content-Type: application/json; charset=UTF-8 Content-Length: 883 X-Openstack-Request-Id: req-64cd9d04-d4ad-4fbe-84db-fdbcbeefd24b

从请求响应流程上可以看出,client向service发起了两次请求:

第一次发送的“GET /v1/c4df22dc73ef478190e1cc80f01219ce/stacks/stack111”

第二次发送的“GET /v1/c4df22dc73ef478190e1cc80f01219ce/stacks/stack111/eb9e2e45-a2b4-4d43-aaaa-06da51e63bdb”


查看heat API的路由定义,发现/{tenant_id}/stacks/{stack_name}这种格式的url调用的函数是StackController.lookup。

此函数返回HTTPFound结果,里面包含了完整的stack url,即前面打印信息中的Location字段。

而第二次请求的url格式/{tenant_id}/stacks/{stack_name}/{stack_id},在路由定义中才是真正调用的StackController.show。

说明client是利用返回的完整url再次发送了GET请求。


那么client是在哪里第二次发送的GET请求呢?就在client处理HTTP请求的逻辑中。

查看HTTPClient._http_request函数,在判断请求结果时,有一段逻辑:

        elif resp.status_code in (301, 302, 305):
            # Redirected. Reissue the request to the new location,
            # unless caller specified redirect=False
            if redirect:
                location = resp.headers.get('location')
                path = self.strip_endpoint(location)
                resp = self._http_request(path, method, **kwargs)
这里就是判断是否需要重发请求,如果是,就利用返回的location重发。

前面的stack-show命令例子中,第一次请求的返回错误码就是302,所以又以完整url发送了第二次请求,获取了最终的结果。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值