感謝朋友支持本博客,歡迎共同探討交流,因爲能力和時間有限,錯誤之處在所不免,歡迎指正! html
若有轉載,請保留源做者博客信息。
python
如需交流,歡迎你們博客留言。 vim
這就要了解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_v2,osapi_compute_app_v2和osapi_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,接下來匹配:
faultwrap sizelimit過濾器不作進一步詳解,有興趣者請自行跟進代碼查看。
keystone_nolimit = faultwrap sizelimit authtoken keystonecontext osapi_compute_app_v2
五、分析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應用,而後發佈路由規則處。
找到父類 nova.api.openstack.APIRouter:
class 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 restarttailf /var/log/nova/api.log
根據上述的routes信息,能夠知道openstack nova模塊發佈出了哪些api開發給上層調用。(其餘keystone、glance等模塊發佈流程相似,請自行研究。)
關於routes更多信息,請參考文章WSGI熟悉之Rails 入門(ruby-rails環境配置及簡單使用)
關於如何在如何後臺模塊router中增長自定義api,及在前臺dashboard中調用該自定義api,請參考後續文章--openstack_ice之routes自定義及調用詳解。