openstack_ice之wsgi詳解(paste從ini配置文件->routesr具體發佈流程)

感謝朋友支持本博客,歡迎共同探討交流,因爲能力和時間有限,錯誤之處在所不免,歡迎指正! html

若有轉載,請保留源做者博客信息。
python

Better Me的博客blog.csdn.net/tantexian

如需交流,歡迎你們博客留言。 vim

對Restful API有了一個基礎的瞭解,那麼咱們來看經過URL是怎樣映射到具體的應用程序操做函數上了。在OpenStack中的API Daemon都會有一個Router類,來構建資源與URL直接的映射關係,完成從接收到URL請求而後映射到具體的函數上執行的整個過程。

這就要了解Python 中的Routes模塊。 api

Routes 是一個python從新實現的Rails routes system,用來將urls映射到應用具體的action上,相反的,還生成url。因爲Routes是Rails routes system的python實現,而且網上關於Routes的文檔不多,故從rails的routes system入手,就能很好的理解Routes庫了。 瀏覽器

首先看一個簡單的例子,就明白routes的做用, ruby

例如瀏覽器接收到下面的HTTP請求, GET /instances/1 Rails的路由請求則負責將此請求解析後dispatch來代碼中的具體某個函數,完成調用,例如返回虛擬機的信息。 服務器


第一部分:講解wsgi的調用入口(paste) app


python中的WSGI(Web Server Gateway Interface)是Python應用程序或框架與Web服務器之間的一種接口,定義了一套藉口來實現服務器與應用端的通訊規範。按照一套規範,應用端 想要通訊,很簡單,只須要實現一個接受兩個參數的,含有__call__方法並返回一個可遍歷的含有零個或者多個string結果的python對象。 框架

服務端,對於每一個http請求,調用一次應用端「註冊」的那個協議規定應用必須實現的對象,而後返回相應的響應消息。 WSGI Server惟一的任務就是接收來自client的請求,而後將請求傳給application,最後將application的response傳遞給client。中間存在的一些東西,就須要中間件來處理。 curl


Paste Deployment是用於發現和配置WSGI appliaction和server的系統。對於WSGI application,用戶提供一個單獨的函數(loadapp),用於從配置文件或者python egg中加載WSGI application。由於WSGI application提供了惟一的單獨的簡單的訪問入口,因此application不須要暴露application的內部的實現細節。

Paste.Deploy主要是用來載入WSGI中的Web App使用,其核心函數是loadapp()。

如下將以openstack的nova爲例講解paste如何載入啓動nova服務(即發佈routes API給上層提供調用)

一、nova --debug list開始:

命令的主要目的就是發送了兩個url請求:(第一個發送給keystone受權,受權經過發送給nova獲取虛擬機列表)

url中包括了token以及參數值



下圖說明請求url成功,返回200.


二、接下來詳解,發送如下url,如何映射到後臺的v2版本的nova API以及又是如何進行權限認證配置。

http://192.168.1.120 :8774/v2/c865d5a3760348a4b8a92cf657a9176d/servers/detail

三、每個url映射都是有paste模塊進行解析,paste模塊具體解析模塊入口就是*.ini配置文件。
如下展現了整個openstack中全部的url映射控制的paste入口配置文件。
find /etc/ | xargs grep paste --color=auto 查找到全部的paste的ini配置文件。



四、以nova的api-paste.ini配置文件講解。

首先介紹paste配置文件中的幾個概念:

一個配置文件後綴爲ini,內容被分爲不少段(section),paste.depoly只關心帶有前綴的段,好比[app:main]或者[filter:errors],總的來講,一個section的標識就是[type:name],不是這種類型的section將會被忽略。

一個section的內容是以鍵=值來標示的。#是一個註釋。在段的定義中,有如下幾類:

[app:main]:定義WSGI應用,main表示只有一個應用,有多個應用的話main改成應用名字

[server:main]:定義WSGI的一個server。

[composite:xxx]:表示須要將一個請求調度定向(dispatched)到多個,或者多種應用上。如下是一個簡單的例子,例子中,使用了composite,經過urlmap來實現載入多應用。

[fliter:]:定義「過濾器」,將應用進行進一步的封裝。

[DEFAULT]:定義一些默認變量的值。

vim /etc/nova/api-paste.ini 

其中openstack_compute_api_v2的use = call:nova.api.auth:pipeline_factory表示經過訪問的url,來選擇具體使用哪一個應用。

根據http://192.168.1.120:8774/v2/c865d5a3760348a4b8a92cf657a9176d/servers/detail,由匹配規則,接下來調用

/v2: openstack_compute_api_v2應用。


這個Application對應了三個參數:noauth,keystone和keystone_nolimit。咱們能夠看到這裏Application具體實現的方法是pipeline_factory。咱們能夠看到在參數noauth,keystone和keystone_nolimit中,分別集成了多個應用,實際上每一個參數最終實現的Application分別是最後一個,即osapi_compute_app_v2osapi_compute_app_v2osapi_compute_app_v2,其前面的Application都扮演這最後一個Application的過濾器。咱們以參數keystone爲例,實現參數keystone的Application爲osapi_compute_app_v2,它前面的faultwrap sizelimit authtoken keystonecontext等應用都是它的過濾器,其實現過程也就是faultwrap(sizelimit(authtoken(keystonecontext(osapi_compute_app_v2)))),具體的調用過程就是osapi_compute_app_v2->keystonecontext->authtoken->sizelimit->faultwrap,前面方法的執行結果做爲後面方法的輸入參數,最後獲得的運行結果做爲參數keystone的值。能夠說明,三個參數noauth,keystone和keystone_nolimit的值都是這樣獲得的。


詳解:

後面三句分別對應配置文件中不一樣配置執行不通的過濾流程,最終三個都將返回osapi_compute_app_v2應用。

use = call:nova.api.auth:pipeline_factory代碼:

pipeline_factory函數的目的就是讀取解析配置文件(/etc/nova/nova.conf)中定義的認證策略:noauth、keystone、keystone_nolimit。

倘若在配置文件nova.conf中,配置的是auth_strategy=keystone,接下來匹配:

keystone_nolimit = faultwrap sizelimit authtoken keystonecontext osapi_compute_app_v2
faultwrap sizelimit過濾器不作進一步詳解,有興趣者請自行跟進代碼查看。
五、分析authtoken 過濾器:

找到對應的代碼:
由上述代碼可知,受權對應過濾器authtoken,具體操做在AuthProtocol類的__call__函數。受權的具體細節請自行分析以上函數,再次不作過多講解。
注:有paste的知識可知,每個factory,都會有一個__call__函數。調用該factory就會調用此函數。


六、接下來分析keystonecontext 過濾器:

對應代碼:

上述代碼功能:在上一步受權走過濾器authtoken時候,從keystone中獲取了一些必要的信息。例如X_USER_ID、X_TENANT_NAME、X_ROLES、token值等等,而後組裝成一個http的request,請求對應的url信息。


從命令執行結果也能夠看出authtoken、和keystonecontext兩個過濾器各自功能及交互過程。

authtoken過濾器執行過程:(curl -i是發送一個url請求,INFO後面則是從keystone模塊請求回來的參數,這些參數傳遞給keystonecontext過濾器,

keystonecontext過濾器根據這些參數,再組裝出對應的http request,請求相應的url)

keystonecontext過濾器執行過程:


七、到此過濾器執行完了,接下來重點分析osapi_compute_app_v2應用:

keystone_nolimit = faultwrap sizelimit authtoken keystonecontext osapi_compute_app_v2

找到對應入口代碼:

上述APIRouter類就是paste加載osapi_compute_app_v2應用,而後發佈路由規則處。

class APIRouter(nova.api.openstack.APIRouter):
找到父類 nova.api.openstack.APIRouter:




八、打印router信息:

 vim /usr/lib/python2.6/site-packages/nova/api/openstack/__init__.py



重啓openstack-nova-api服務

service  openstack-nova-api restart
tailf /var/log/nova/api.log


根據上述的routes信息,能夠知道openstack nova模塊發佈出了哪些api開發給上層調用。(其餘keystone、glance等模塊發佈流程相似,請自行研究。)

關於routes更多信息,請參考文章WSGI熟悉之Rails 入門(ruby-rails環境配置及簡單使用)


關於如何在如何後臺模塊router中增長自定義api,及在前臺dashboard中調用該自定義api,請參考後續文章--openstack_ice之routes自定義及調用詳解。

相關文章
相關標籤/搜索