資訊人筆記

Work hard, Have fun, Make history!

使用者工具

網站工具


ccis_lab:openstack:neutron:ch2-api_layer

Neutron WSGI/HTTP API layer

0x00 前言

這章節會涵蓋 Neutron 內部的 HTTP API 和用來建立 Extensions 給 Neutron API 的一些 classes

以及透過 Python Web Server Gateway Interface (WSGI) 運作在網頁伺服器上的 python 應用程式介面


0x01 Startup

<html>
<style>
pre {

  box-shadow: none;

}

table, td {

  border: none;

}
</style>

<body>
<script type='text/javascript' src='gistfy-app.herokuapp.com/github/nike1000/neutron/neutron/cmd/eventlet/server/init.py?branch=master&slice=13:33&lang=python'></script>
</body>
</html>

</WRAP>

<html><br/><br/><br/><br/><br/><br/><br/><br/></html>

在上一章節我們看到 setup.cgf 顯示了 neutron-server 的 entry point 為 neutron-server = neutron.cmd.eventlet.server:main

檔案為 neutron/neutron/cmd/eventlet/server/__init__.py

而在 main 中呼叫了 boot_server,將 _main_neutron_server 函式做為參數傳入


</WRAP>

<html>
<style>
pre {

  box-shadow: none;

}

table, td {

  border: none;

}
</style>

<body>
<script type='text/javascript' src='gistfy-app.herokuapp.com/github/nike1000/neutron/neutron/server/init.py?branch=master&slice=19:41&lang=python'></script>
</body>
</html>

</WRAP>

<html><br/><br/><br/><br/><br/><br/><br/><br/></html>

/neutron/server/__init__.py

boot_server 函式會取讀取 neutron/common/config.py 裡的設定值,並將設定保存在 cfg.CONF 這個全域的資料結構中

在配置好初始化設定後會嘗試執行 server_func(),而這個 server_func() 就是上面檔案的 _main_neutron_server 函式

_main_neutron_server 函式會執行 eventlet_wsgi_server 去啟動 WSGI server


</WRAP>

<html>
<style>
pre {

  box-shadow: none;

}

table, td {

  border: none;

}
</style>

<body>
<script type='text/javascript' src='gistfy-app.herokuapp.com/github/nike1000/neutron/neutron/conf/common.py?branch=master&slice=134:138&lang=python'></script>
</body>
</html>

</WRAP>

<html><br/><br/></html>

web_framework 預設值為 legacy,在我系統中這可以在 neutron/common/config.py 中看到


</WRAP>

不過 github 上的版本比較新,獨立出了 neutron/conf 資料夾,neutron/common/config.py 中部分東西放到 neutron/conf/common.py

然後 neutron/common/config.py 中改用 from neutron.conf import common as common_config 匯入

<html>
<style>
pre {

  box-shadow: none;

}

table, td {

  border: none;

}
</style>

<body>

<script type='text/javascript' src='gistfy-app.herokuapp.com/github/nike1000/neutron/neutron/server/wsgi_eventlet.py?branch=master&slice=14:47&lang=python'></script>
</body>
</html>

</WRAP>

<html><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/></html>

eventlet_wsgi_server 函式中第一行會嘗試取得一個 NeutronApiService 實例 (instance)

接著會產生 Eventlet GreenPool,執行 WSGI application 然後回應來自 client 的請求


</WRAP>

<html>
<style>
pre {

  box-shadow: none;

}

table, td {

  border: none;

}
</style>

<body>

<script type='text/javascript' src='gistfy-app.herokuapp.com/github/nike1000/neutron/neutron/service.py?branch=master&slice=69:94&lang=python'></script>
</body>
</html>
</WRAP>

<html><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/></html>

serve_wsgi 取得的參數 cls 其實就是上面丟進來的 NeutronApiService 類別

這邊會建立並啟動這個實例


</WRAP>


—-

=====0x02 WSGI Application=====

上面在建立 NeutronApiService instance 時,會執行 _run_wsgi 函式去建立 WSGI application

_run_wsgi 的觸發點是在上面 NeutronApiService 類別,這個類別繼承了 WsgiService 類別

<html>
<style>
pre {

  box-shadow: none;

}

table, td {

  border: none;

}
</style>

<body>

<script type='text/javascript' src='gistfy-app.herokuapp.com/github/nike1000/neutron/neutron/service.py?branch=master&slice=49:66&lang=python'></script>
<script type='text/javascript' src='
gistfy-app.herokuapp.com/github/nike1000/neutron/neutron/service.py?branch=master&slice=288:302&lang=python'></script>
</body>
</html>

<html><br/><br/><br/><br/><br/><br/><br/><br/></html>

上面 NeutronApiService 類別因為繼承了 WsgiService 類別,在 87 行執行 service.start() 時觸發了 _run_wsgi

<html><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/></html>

這邊則會執行 neutron/common/config.py 中的 load_paste_app

<html>
<style>
pre {

  box-shadow: none;

}

table, td {

  border: none;

}
</style>

<body>

<script type='text/javascript' src='gistfy-app.herokuapp.com/github/nike1000/neutron/
neutron/common/config.py?branch=master&slice=119:126&lang=python'></script>
</body>
</html>

</WRAP>

<html><br/><br/><br/><br/></html>

load_paste_app 會 parses /etc/neutron/api-paste.ini 這個檔案來載入一個 WSGI app

這邊看到的 wsgi 是 python 自己的 library,不是 neutron 特有的


</WRAP>


api-paste.ini 檔案定義了 WSGI applications 和 routes 路徑,使用的是 Python Paste INI file format

/etc/neutron/api-paste.ini
[composite:neutron]                                                                 
use = egg:Paste#urlmap
/: neutronversions
/v2.0: neutronapi_v2_0
 
[composite:neutronapi_v2_0]
use = call:neutron.auth:pipeline_factory
noauth = cors request_id catch_errors extensions neutronapiapp_v2_0
keystone = cors request_id catch_errors authtoken keystonecontext extensions neutronapiapp_v2_0
 
[filter:request_id]
paste.filter_factory = oslo_middleware:RequestId.factory
 
[filter:catch_errors]
paste.filter_factory = oslo_middleware:CatchErrors.factory
 
[filter:cors]
paste.filter_factory = oslo_middleware.cors:filter_factory
oslo_config_project = neutron
 
[filter:keystonecontext]
paste.filter_factory = neutron.auth:NeutronKeystoneContext.factory
 
[filter:authtoken]
paste.filter_factory = keystonemiddleware.auth_token:filter_factory
 
[filter:extensions]
paste.filter_factory = neutron.api.extensions:plugin_aware_extension_middleware_factory
 
[app:neutronversions]
paste.app_factory = neutron.api.versions:Versions.factory
 
[app:neutronapiapp_v2_0]
paste.app_factory = neutron.api.v2.router:APIRouter.factory

<html><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/></html>
最後面可以看到 neutronapiapp_v2_0

APIRouter 類別可以將 Neutron resource (Ports, Networks, Subnets…) 對應到 URLs,並控制操作這些 resource

路徑為 neutron/api/v2/router.py



—-

=====0x03 參考資料=====

* OpenStack developer documentation:Neutron WSGI/HTTP API layer

ccis_lab/openstack/neutron/ch2-api_layer.txt · 上一次變更: 127.0.0.1