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

来源:互联网 发布:淘宝该版本不支持授权 编辑:程序博客网 时间:2024/06/06 02:43

使用过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 195DEBUG (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 FoundThe 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 883DEBUG (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
原创粉丝点击