做 爲 OpenStack 用戶或管理員,您經常須要編寫腳原本自動化常見任務。除了 REST 和命令行接口以外,OpenStack 還公開了原生的 Python API 綁定。瞭解如何使用這些 Python 綁定簡化編寫 OpenStack 自動化腳本的過程。html
OpenStack 是一個愈來愈流行的、用於部署基礎架構即服務 (IaaS) 雲的開源解決方案。OpenStack 附帶了一個儀表板 Web 應用程序,很是適合執行手動任務,好比啓動單個虛擬機 (VM) 實例,可是,若是但願自動化基於雲的任務,則須要編寫可操做 OpenStack 的腳本。python
許多用戶直接爲 OpenStack 具象狀態傳輸 (REST) 應用編程接口 (API) 編寫自動化腳本,或者編寫調用命令行工具(好比keystone 或 nova)的 shell 腳本。但 Python 中有一種編寫 OpenStack 自動化腳本的更好方法。全部 OpenStack 服務都公開了原生 Python API,以公開與命令行工具相同的特性集。不幸的是,描述如何使用這些 API 的文檔不多。git
若是您是 Python 程序員,那麼 Python API 會比命令行工具或 REST API 容易使用得多。在本文中,我將演示如何使用原生 OpenStack Python API 自動化常見的用戶和管理性任務。程序員
OpenStack 這個詞不是指單個應用程序。它是一個服務集合,這些服務協同工做來實現 IaaS 雲。每一個 OpenStack 服務都有一個正式名稱和一個代號,如表 1 所示,並且每一個 OpenStack 服務公開了本身的 Python API。github
表 1. OpenStack 服務和代號Python 綁定與每一個服務的命令行工具捆綁在一塊兒。事實上,每一個命令行工具使用相應的 Python API 實現。可從 Python Package Index(PyPi — 參見參考資料,獲取相關連接)中使用 pip(一個 Python 包安裝程序)來安裝每一個工具。pip 包名稱包括:shell
python-keystoneclient數據庫
python-glanceclient編程
python-novaclientswift
python-quantumclient後端
python-cinderclient
python-swiftclient
例如,要安裝 keystone 客戶端,可運行如下命令:
$ pip install python-keystoneclient
可將這些包安裝到 Python 虛擬環境或您的系統級 Python 包中,只要您擁有本地機器上的根用戶特權。
全部 OpenStack API 都有一些版本,Python 綁定支持多個 API 版本,以保持向後兼容性。所以能夠安全地下載這些包的最新版本,由於它們將會適合 OpenStack 服務的全部更低版本。
在本文中,我將重點介紹來自如下服務的 Python API 示例:
OpenStack Identity Service (keystone)
OpenStack Image Service (glance)
OpenStack Compute Service (nova)
設置一個測試環境
爲 了最充分地掌握本文的內容,建議您使用管理員特權訪問一個 OpenStack 雲,以便試用這些代碼段。若是目前沒有 OpenStack 雲的管理員訪問權,那麼最簡單的方法就是在一個 VM 中部署 OpenStack。DevStack 項目旨在簡化在單個機器上建立一個面向開發的 OpenStack 部署的過程。配合 VirtualBox 等虛擬化工具,您能夠在筆記本電腦上(甚至在 Mac 或 Windows® 上)實現一個 OpenStack 雲。
您還能夠得到 TryStack 上的一個免費賬戶,TryStack 是由社區維護的 OpenStack 沙盒。請注意,只能獲取 TryStack 上的用戶級特權,不能得到管理級特權,因此您沒法使用 TryStack 測試須要管理特權的腳本。
OpenStack Identity (keystone)
客戶端要對 Identity (keystone) API 發出請求,可實例化適當的 keystone 客戶端 Python 對象並調用它的方法。由於 API 提供了版本控制,因此 Python 客戶端始終與該 API 的一個特定版本有關聯。
清單 1 顯示了使用 keystone 客戶端的 2.0 版將 Image Service 添加到服務目錄的示例。
清單 1. 使用 keystone 建立一個管理員角色
import keystoneclient.v2_0.client as ksclient # Replace the method arguments with the ones from your local config keystone = ksclient.Client(auth_url="http://192.168.27.100:35357/v2.0", username="admin", password="devstack", tenant_name="demo") glance_service = keystone.services.create(name="glance", service_type="image", description="OpenStack Image Service") 複製代碼
憑據
在 實例化 keystoneclient.v2_0.client.Client 對象時必須提供憑據。keystone 端點接受兩種類型的憑據:令牌,或者用戶名和密碼。若是您是管理員,那麼您可使用 admin 令牌,這是一種具備管理員特權且永不過時的特殊令牌。要定義此令牌,可使用運行 keystone 服務的機器上的 /etc/keystone/keystone.conf 文件中的 admin_token 選項(參見清單 2)。
清單 2. 使用身份驗證令牌執行身份驗證
import keystoneclient.v2_0.client as ksclient # Replace the values below with the ones from your local config endpoint = "http://192.168.27.100:35357/v2.0" admin_token = "devstack" keystone = ksclient.Client(endpoint=endpoint, token=admin_token) 複製代碼
出於安全緣由,通常不同意使用 admin 令牌。相反,在建立了具備管理特權的用戶以後,建議 OpenStack Identity 開發人員始終使用用戶名和密碼進行身份驗證(參見清單 3)。
清單 3. 使用用戶名和密碼執行身份驗證
import keystoneclient.v2_0.client as ksclient # Replace the values below the ones from your local config, auth_url = "http://192.168.27.100:35357/v2.0" username = "admin" password = "devstack" tenant_name = "demo" keystone = ksclient.Client(auth_url=auth_url, username=username, password=password, tenant_name=tenant_name) 複製代碼
加載一個 openrc 文件
爲了簡化身份驗證,建議建立一個 openrc 文件,將憑據導出到環境變量中。這樣作能夠避免將登陸信息硬編碼到腳本中。清單 4 顯示了一個 openrc 文件示例。
清單 4. 從環境變量加載憑據
export OS_USERNAME="myname" export OS_PASSWORD="mypassword" export OS_TENANT_NAME="mytenant" export OS_AUTH_URL="http://10.20.0.2:5000/v2.0/" 複製代碼
環 境變量 OS_USERNAME、OS_PASSWORD、OS_TENANT_NAME 和 OS_AUTH_URL 在全部 Python 命令行工具中已標準化。若是設置了這些環境變量,命令行工具(keystone、nova)將會使用它們對其 API 端點進行身份驗證。
使用 Bash source 內置命令將這些環境變量加載到您當前的 shell 中。若是使用 Bash 做爲標準 shell,那麼您可能但願將這行代碼添加到 .profile 中,以便在您每次登陸時自動設置這些環境變量:
$ source openrc 複製代碼
找 到 openrc 文件後,Python 腳本就能夠從環境中檢索憑據。咱們建立了一個名爲 credentials.py 的 Python 文件(如清單 5 所示),以便從環境中提取登陸信息。請注意,keystone 和 nova 在其客戶端初始化器方法中使用了稍微不一樣的變量名,因此我爲每一個工具定義了不一樣的函數。
清單 5. credentials.py
#!/usr/bin/env python import os def get_keystone_creds(): d = {} d['username'] = os.environ['OS_USERNAME'] d['password'] = os.environ['OS_PASSWORD'] d['auth_url'] = os.environ['OS_AUTH_URL'] d['tenant_name'] = os.environ['OS_TENANT_NAME'] return d def get_nova_creds(): d = {} d['username'] = os.environ['OS_USERNAME'] d['api_key'] = os.environ['OS_PASSWORD'] d['auth_url'] = os.environ['OS_AUTH_URL'] d['project_id'] = os.environ['OS_TENANT_NAME'] return d 複製代碼
身份驗證令牌
如 果客戶端初始化器返回時沒有拋出異常,則它已成功向端點驗證。您可訪問剛纔經過返回的對象 auth_token 屬性發出的keystone 令牌,如清單 6 所示。當對 glance API 進行身份驗證時,須要顯式地將一個 keystone 身份驗證令牌做爲參數傳遞給初始化器,咱們稍後會對此進行討論。
清單 6. 在一個交互式 Python 會話中對一個 keystone 端點執行成功的驗證
>>> import keystoneclient.v2_0.client as ksclient >>> from credentials import get_keystone_creds >>> creds = get_keystone_creds() >>> keystone = ksclient.Client(**creds) >>> keystone.auth_token u'MIILkAYJKoZIhvcNAQcCoIILgTCCC30CAQExCTAHBgUrDgMCGjCCCmkGCSqGSIb3DQEHAaCCCloE ggpWeyJhY2Nlc3MiOiB7InRva2VuIjogeyJpc3N1ZWRfYXQiOiAiMjAxMy0wNS0yNlQwMjoxMjo0Mi 42MDAwMjUiLCAiZXhwaXJlcyI6ICIyMDEzLTA1LTI3VDAyOjEyOjQyWiIsICJpZCI6ICJwbGFjZWhv bGRlciIsICJ0ZW5hbnQiOiB7ImRlc2NyaXB0aW9uIjogbnVsbCwgImVuYWJsZWQiOiB0cnVlLCAiaW ... fI9JnOBZJwuoma8je0a1AvLff6AcJ1zFkVZGb' 複製代碼
備註:OpenStack Identity 的 Grizzly 版本默認狀況下使用了公鑰基礎架構令牌,這些令牌比 OpenStack 的之前版本中使用的通用唯一標識符令牌(例如 7d9fde355f09458f8e97986a5a652bfe)要長得多。
CRUD 操做
keystone API 實質上是一個建立、讀取、更新、刪除 (CRUD) 接口:與 keystone API 的大多數交互都會讀取 keystone後端數據庫或修改它。與該 API 的大多數交互都會調用 Manager 對象。一個 Manager 表示一個具備相同類型的對象集合。例如,UserManager 處理 keystone 用戶,TenantManager 處理租戶,RoleManager 處理角色,等等。這些管理器支持多種操做,好比 create(建立一個新對象)、get(按 ID 檢索一個對象)、list(檢索全部對象)和 delete。
建立用戶、租戶和角色
一般,在部署 OpenStack 時,執行的第一個任務是建立一個 keystone 租戶,而後建立一個具備管理特權的 keystone 用戶。清單 7 顯示了一個使用 Python API 自動化此過程的示例。該腳本可執行如下任務:
建立一個用戶角色 (Client.roles.create)。
建立一個管理角色 (Client.roles.create)。
建立一個名爲 acme 的租戶 (Client.tenants.create)。
建立一個名爲 admin 的用戶 (Client.users.create)。
爲 admin 用戶分配 acme 租戶中的管理角色 (Client.roles.add_user_role)。
這是一個適合使用 admin 令牌的場景,由於 Identity Service 不包含任何具備管理特權的用戶。
清單 7. 建立一個用戶、租戶和角色
import keystoneclient.v2_0.client as ksclient endpoint = "http://192.168.27.100:35357/v2.0" admin_token = "devstack" keystone = ksclient.Client(endpoint=endpoint, token=admin_token) user_role = keystone.roles.create("user") admin_role = keystone.roles.create("admin") acme_tenant = keystone.tenants.create(tenant_name="Acme", description="Employees of Acme Corp.", enabled=True) admin_user = keystone.users.create(name="admin", password="a.G'03134!j", email="cloudmaster@example.com", tenant_id=acme_tenant.id) keystone.roles.add_user_role(admin_user, admin_role, acme_tenant) 複製代碼
建立服務和端點
通 常,在 OpenStack 雲中,部署 Identity Service 的下一個任務是在 keystone 中填充雲和端點中的服務。清單 8 顯示了使用 Client.services.create 和 Client.endpoints.create 方法爲 Identity Service 添加一個服務和端點的示例。
清單 8. 建立一個服務和端點
import keystoneclient.v2_0.client as ksclient creds = get_keystone_creds() # See openrc-creds keystone = ksclient.Client(**creds) service = keystone.services.create(name="keystone", service_type="identity", description="OpenStack Identity Service") keystone_publicurl = "http://192.168.27.100:5000/v2.0" keystone_adminurl = "http://192.168.27.100:35357/v2.0" keystone.endpoints.create(service_id=service.id, region="Northeast", publicurl=keystone_publicurl, adminurl=keystone_adminurl, internalurl=keystone_publicurl) 複製代碼
訪問服務目錄
keystone 的主要功能之一就是充當服務目錄。客戶端可以使用 keystone 查找 OpenStack 服務的端點 URL。該 API 經過keystoneclient.v2_0.client.Client.service_catalog.url_for 方法提供此功能。此方法支持按類型(例如 image、volume、compute、network)和端點類型(publicURL、internalURL、adminURL)查找服務端 點。
清單 9 演示瞭如何使用 url_for 方法檢索 OpenStack Image (glance) Service 的端點。
清單 9. 在一個交互式 Python 會話中查詢 glance 端點
>>> import keystoneclient.v2_0.client as ksclient >>> creds = get_keystone_creds() # See <a href="openrc-creds" /> >>> keystone = ksclient.Client(**creds) >>> glance_endpoint = keystone.service_catalog.url_for(service_type='image', endpoint_type='publicURL') >>> glance_endpoint u'http://192.168.27.100:9292' 複製代碼
OpenStack Compute (nova)
nova API 的 1.1 版和第 2 版
nova API 的 1.1 版和第 2 版是相同的。可用 「2」 代替 「1.1」,傳遞它做爲 novaclient.client.Client initializer 的第一個參數,但沒有 novaclient.v2 模塊,只有一個 novaclient.v1_1 模塊。
OpenStack Compute (nova) Python API 的工做原理相似於 OpenStack Identity API。這裏使用了 nova API 的 1.1 版,因此本文中使用的 nova Python 綁定的 1.1 版中的類位於 novaclient.v1_1 Python 命名空間中。
對 nova-api 端點執行身份驗證
要 向 nova-api 端點發出請求,可實例化一個 novaclient.v1_1.client.Client 對象並對它執行調用。可經過兩種方式獲取一個與該 API 的 1.1 版進行通訊的客戶端。清單 10 演示瞭如何經過傳遞版本字符串做爲參數來獲取合適的客戶端。
清單 10. 傳遞版本做爲參數
from novaclient import client as novaclient from credentials import get_nova_creds creds = get_nova_creds() nova = novaclient.Client("1.1", **creds) 複製代碼
清單 11 演示瞭如何經過顯式導入 1.1 版模塊來獲取合適的客戶端。
清單 11. 直接導入版本
import novaclient.v1_1.client as nvclient from credentials import get_nova_creds creds = get_nova_creds() nova = nvclient.Client(**creds) 複製代碼
清單實例
使用 Client.servers.list 方法列出當前的 VM 實例,如清單 12 所示。
清單 12. 在一個交互式 Python 會話中獲取一個 VM 實例列表
>>> import novaclient.v1_1.client as nvclient >>> from credentials import get_nova_creds >>> creds = get_nova_creds() >>> nova = nvclient.Client(**creds) >>> nova.servers.list() [<Server: cirros>] 複製代碼
按名稱獲取一個實例並關閉它
若是不知道實例的 ID,只知道它的名稱,那麼可使用 Server.find 方法。清單 13 顯示瞭如何按名稱找到一個實例,而後使用 Server.delete 方法終止它。
清單 13. 終止 「my-vm」 實例
import novaclient.v1_1.client as nvclient from credentials import get_nova_creds creds = get_nova_creds() nova = nvclient.Client(**creds) server = nova.servers.find(name="my-vm") server.delete() 複製代碼
啓動一個實例並檢查狀態
要 啓動一個新實例,可使用 Client.servers.create 方法,如清單 14 所示。請注意,必須傳遞一個 image 對象和flavor 對象,而不是 image 和 flavor 的名稱。該示例還使用 Client.keypairs.create 方法將 Secure Shell (SSH) 公鑰上傳到 ~/.ssh/id_rsa.pub,並將密鑰對命名爲 mykey(假設該密鑰對還不存在)。最後,它使用 Client.servers.get 方法獲取該實例的當前狀態,使用它來輪詢狀態。
清單 14. 啓動一個新實例
import os import time import novaclient.v1_1.client as nvclient from credentials import get_nova_creds creds = get_nova_creds() nova = nvclient.Client(**creds) if not nova.keypairs.findall(name="mykey"): with open(os.path.expanduser('~/.ssh/id_rsa.pub')) as fpubkey: nova.keypairs.create(name="mykey", public_key=fpubkey.read()) image = nova.images.find(name="cirros") flavor = nova.flavors.find(name="m1.tiny") instance = nova.servers.create(name="test", image=image, flavor=flavor, key_name="mykey") # Poll at 5 second intervals, until the status is no longer 'BUILD' status = instance.status while status == 'BUILD': time.sleep(5) # Retrieve the instance again so the status field updates instance = nova.servers.get(instance.id) status = instance.status print "status: %s" % status 複製代碼
附加一個浮動 IP 地址
要 附加一個浮動 IP 地址,必須首先驗證 OpenStack 是否擁有一個可用的浮動 IP 地址。使用 Client.floating_ips.list 方法獲取可用的浮動 IP 地址列表。若是結果列表是空的,可以使用 Client.floating_ips.create 方法分配一個新的浮動 IP 地址,而後使用 Server.add_floating_ip 方法將它分配給該實例,如清單 15 所示。
清單 15. 建立一個浮動 IP 地址
>>> nova.floating_ips.list() [] >>> floating_ip = nova.floating_ips.create() <FloatingIP fixed_ip=None, id=1, instance_id=None, ip=192.168.27.129, pool=public> >>> instance = nova.servers.find(name="test") >>> instance.add_floating_ip(floating_ip) 複製代碼
更改一個安全組
使 用 Client.security_group_rules.create 方法向一個安全組添加規則。清單 16 中的示例修改了默認的安全組,以便支持 SSH(在端口 22 上運行)以及全部 Internet Control Message Protocol (ICMP) 流量。爲此,我使用Client.security_groups.find 方法獲取了名爲 default 的安全組。
清單 16. 容許使用 default 安全組中的端口 22 和 ICMP
import novaclient.v1_1.client as nvclient from credentials import get_nova_creds creds = get_nova_creds() nova = nvclient.Client(**creds) secgroup = nova.security_groups.find(name="default") nova.security_group_rules.create(secgroup.id, ip_protocol="tcp", from_port=22, to_port=22) nova.security_group_rules.create(secgroup.id, ip_protocol="icmp", from_port=-1, to_port=-1) 複製代碼
獲取控制檯日誌
Server.get_console_output 方法獲取了在啓動 VM 時發送給控制檯的文本。能夠分析控制檯輸出,以解決更改主機密鑰的常見問題。
IaaS 雲(好比 OpenStack)的一個缺陷是,它不能很好地與 SSH 主機密鑰檢查功能進行互操做。若是登陸到(好比 10.40.1.150 上的)某個實例,而該 IP 地址以前被您過去登陸的另外一個實例使用過,那麼您將得到一個相似清單 17 的錯誤。
清單 17. ID 更改後的錯誤
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that a host key has just been changed. The fingerprint for the RSA key sent by the remote host is 6f:2b:59:46:cb:8c:81:48:06:f3:c5:db:40:23:d3:be. Please contact your system administrator. Add correct host key in /home/mylogin/.ssh/known_hosts to get rid of this message. Offending key in /home/mylogin/.ssh/known_hosts:1 RSA host key for 10.40.1.150 has changed and you have requested strict checking. Host key verification failed. 複製代碼
若是您的 VM 映像安裝了 cloud-init 包(參見參考資料),那麼它會將主機密鑰輸出到控制檯,如清單 8 所示。
清單 18. 控制檯中的 SSH 密鑰輸出示例
-----BEGIN SSH HOST KEY KEYS----- ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBDciNMyzj0osyPOM+ 1OyseTWgkzw+M43zp5H2CchG8daRDHel7V3OHETVdI6WofNn SdBJAwIoisRFPxyroNGiVw= root@my-name ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDU854+fNdcKMZTLCUejMOZllQmmphr6V5Aaz1F2+x2jXql5rqKQ d5/h6OdFszcp+gdTeVtfgG++/298qodTemVVrvqwjp4eN87iHvhPxH6GDEevAKlEed2ckdAmgvzI9rcOYgR/46G9x Iea0IdgNjMvN1baj6WPtv+HfcfH/ZV58G306lSJfbz/GVxNTIxW+Wg7ZQCAe6jWgm4oQ+66sco+7Fub24EPue3kO8 jqufqq3mY5+MFlzEHSX5B04ioG5Alw/JuqVx5+7zHt9I2wA3nzsyUdKtCTrw8V4fYEhWDm53WLOpW+8CeYCXuv+yL 7EjwLqhIH/TUuzGQiWmFGvyz root@my-name -----END SSH HOST KEY KEYS----- 複製代碼
清單 19 給出的腳本使用 Server.get_console_output API 方法從控制檯中提取 SSH 主機密鑰,而後更新~/.ssh/known_hosts 文件,因此在首次使用 SSH 訪問浮動 IP 地址時,您不會得到此 SSH 警告。
清單 19. 從控制檯提取 SSH 主機密鑰
import os import subprocess import novaclient.v1_1.client as nvclient from credentials import get_nova_creds def get_server(creds, servername): nova = nvclient.Client(**creds) return nova.servers.find(name=servername) def remove_hostkey(ip): subprocess.call(["ssh-keygen", "-R", ip]) def get_hostkey_from_console(text): lines = text.split('\n') start = '-----BEGIN SSH HOST KEY KEYS-----\r' end = '-----END SSH HOST KEY KEYS-----\r' start_ind = lines.index(start) end_ind = lines.index(end) for i in range(start_ind+1, end_ind): key = lines[i].rstrip() if key.startswith('ssh-rsa'): return key raise KeyError("ssh host key not found") def main(): server = get_server(get_nova_creds(), "my-server") netname = "my-network" (fixed_ip, floating_ip) = server.networks[netname] # Remove existing key, if any remove_hostkey(floating_ip) output = server.get_console_output() key = get_hostkey_from_console(output) with open(os.path.expanduser("~/.ssh/known_hosts"), 'a') as f: f.write("{0} {1}\n".format(floating_ip, key)) if __name__ == '__main__': main() 複製代碼
OpenStack Image (glance)
OpenStack Image Service (glance) 負責管理 Compute Service 所使用的一個 VM 映像目錄。
對 glance 端點執行身份驗證
OpenStack Image (glance) Python API 在執行初始身份驗證時與 Compute API 有一些細微的差異。glance API 依賴於必須從 keystone API 獲取的信息:
glance 端點 URL
一個 keystone 身份驗證令牌
像 nova API 同樣,對於 glance API,您能夠傳遞 API 的版本做爲參數或直接導入該模塊。清單 20 中的示例展現瞭如何使用該 API 的第 2 版,對 glance 端點執行身份驗證。
清單 20. 對 glance API 執行身份驗證
import keystoneclient.v2_0.client as ksclient import glanceclient creds = get_keystone_creds() keystone = ksclient.Client(**creds) glance_endpoint = keystone.service_catalog.url_for(service_type='image', endpoint_type='publicURL') glance = glanceclient.Client('2',glance_endpoint, token=keystone.auth_token) 複製代碼
清單 21 中的示例直接導入了相關的 glance 模塊。
清單 21. 直接導入 glance 模塊
import keystoneclient.v2_0.client as ksclient import glanceclient.v2.client as glclient creds = get_keystone_creds() keystone = ksclient.Client(**creds) glance_endpoint = keystone.service_catalog.url_for(service_type='image', endpoint_type='publicURL') glance = glclient.Client(glance_endpoint, token=keystone.auth_token) 複製代碼
列出可用映像
使用 Client.images.list 方法列出當前的映像,如清單 22 所示。請注意,此方法會返回一個生成器,其中 nova API 中的 list 方法將會返回列表對象。
清單 22. 獲取一個 VM 映像列表
>>> import keystoneclient.v2_0.client as ksclient >>> import glanceclient.v2.client as glclient >>> creds = get_keystone_creds() >>> keystone = ksclient.Client(**creds) >>> glance_endpoint = keystone.service_catalog.url_for(service_type='image', ... endpoint_type='publicURL') >>> glance = glclient.Client(glance_endpoint, token=keystone.auth_token) >>> images = glance.images.list() >>> images <generator object list at 0x10c8efd70> >>> images.next() {u'status': u'active', u'tags': [], u'kernel_id': u'8ab02091-21ea-434c-9b7b-9b4e2ae49591', u'container_format': u'ami', u'min_ram': 0, u'ramdisk_id': u'd36267b5-7cae-4dec-b5bc-6d2de5c89c64', u'updated_at': u'2013-05-28T00:44:21Z', u'visibility': u'public', u'file': u'/v2/images/cac50405-f4d4-4715-b1f6-7f00ff5030e6/file', u'min_disk': 0, u'id': u'cac50405-f4d4-4715-b1f6-7f00ff5030e6', u'size': 25165824, u'name': u'cirros-0.3.1-x86_64-uec', u'checksum': u'f8a2eeee2dc65b3d9b6e63678955bd83', u'created_at': u'2013-05-28T00:44:21Z', u'disk_format': u'ami', u'protected': False, u'schema': u'/v2/schemas/image'} 複製代碼
將一個映像上傳到 glance
清單 23 中的示例展現瞭如何使用 glance API 上傳一個文件。這裏須要使用該 API 的第 1 版建立一個映像,由於 Python API 綁定還未實現第 2 版的 create 方法。
清單 23. 將一個映像上傳到 glance
import keystoneclient.v2_0.client as ksclient import glanceclient creds = get_keystone_creds() keystone = ksclient.Client(**creds) glance_endpoint = keystone.service_catalog.url_for(service_type='image', endpoint_type='publicURL') glance = glanceclient.Client('1',glance_endpoint, token=keystone.auth_token) with open('/tmp/cirros-0.3.0-x86_64-disk.img') as fimage: glance.images.create(name="cirros", is_public=True, disk_format="qcow2", container_format="bare", data=fimage) 複製代碼
[size=1.5em]後續步驟
本文僅簡短概述了 OpenStack Python API 公開的功能。可經過多種方式進一步瞭解這些 API 的工做原理。
官方 API 文檔
OpenStack 項目維護着全部 OpenStack Python API 的文檔。全部這些 API 都擁有每一個模塊、類和方法的自動生成的文檔。一些 API 的文檔中包含使用示例,而其餘文檔沒有。
Introspect the API
瞭解 API 的一種最佳方式是在一個交互式命令行 Python 解釋器中使用它們。bpython 解釋器是一個加強的 Python 解釋器,會在您鍵入時顯示有效的方法名稱,還會自動顯示一個函數的文檔字符串(參見圖 1)。
圖 1. bpython 的自動幫助顯示界面
查閱 CLI 源代碼
Python 的一個優點在於它的可讀性,沒有任何方法可以比閱讀源代碼更好地瞭解 API。全部包都託管在 openstack 小組中的 github 上。例如,要獲取 nova API 源代碼的副本,可運行如下命令:
git clone http://github.com/openstack/python-novaclient 複製代碼
由於這些命令行客戶端是使用該 API 實現的,因此每一個包都提供了一個示例應用程序。
對 於 novaclient API,最有趣的文件包含在 novaclient/v1_1 目錄中,該目錄包含造成此 API 的 Python 類。shell 上的命令行命令被實現爲 novaclient/v1_1/shell.py 中的 do_* 方法。例如,nova flavor-list 被實現爲 do_flavor_list 方法,該方法最終會調用 Client.flavors.list API 方法。
查閱其餘使用 Python API 的應用程序
其 他一些應用程序也使用了 OpenStack Python API。OpenStack Dashboard徹底使用 Python API 與各類 OpenStack 服務進行通訊。它是使用 Python API 的應用程序的一個很好的例子。具體來說,您能夠查看 openstack_dashboard/api 目錄,看看該儀表板是如何使用 Python API 的。
OpenStack Client用於將現有客戶端上的功能統一到單個命令行接口中。它使用了來自其餘全部項目的 Python API。
Heat 項目是一個設計爲使用 OpenStack 的業務流程層,它使用了這些 API。具體來說,請查看 heat/engine/clients.py 文件。
Ansible 是一個基於 Python 的配置管理工具,擁有多個使用 Python API 的 OpenStack 模塊。具體來說,請查看 library/cloud 目錄,其中包含 Ansible OpenStack 模塊。
瞭解 Python API 的工做原理後,很難想像再返回使用 REST API 或命令行工具構建您的 OpenStack 自動化腳本的情形。