openstack api 使用, REST接口
參考:
https://docs.openstack.org/zh_CN/api-quick-start/
https://docs.openstack.org/keystone/pike/contributor/http-api.html
基礎: openstack環境, 下面是openstack api的接口;其中image是獲取鏡像的, compute是獲取實例, network是獲取網絡信息的, 其他請對照api查看
注意:
- 官網文檔中是用curl對接口進行調用的, 從認證到獲取image, servers寫的很詳細; 但都是基於http的, 如果用https的, curl加-k就可以了, 知道curl用法, 官網的內容就基本都能明白了. (官網鏈接里: API快速入門示例-認證和API請求流程)
- 官網文檔認證部分是用v3, 第2個鏈接是官網給出的v2, v3的區別
- v2, v3並不是每個接口都有這兩個版本, 有的只v2或者v1, 認證是v2,v3都有的; 官網api文檔結合自己openstack使用;
- v2, v3發送的json數據格式不同, v3的格式就從官網拿到的, 不要刪減格式中的元素; v2的官網沒看到, 可以自己搜搜
- 這篇文章介紹使用python requests , 調用v2, v3的認證接口, 及獲取主機, 映像, 網絡信息的接口; 認證部分v2,v3寫在一起了, 如果覺着亂, 就僅看一種就好, 主機, 映像,網絡的獲取是一樣的. 我的是python3.4
- 官網api, 如下圖, 每個接口都有注釋是v2, v3, 或是v1, 點擊進去也有詳細接口說明, 照着用就好
一. 認證
1. v2方式認證
import json import requests import urllib3 urllib3.disable_warnings() #這個是python3的處理方法, 沒有這個會出現個告警, python2, 看見告警, 就點那個鏈接進去, 把代碼粘過來就好 data_v2 = { "auth": { "passwordCredentials": { "password": "123456", "username": "admin" } } } tokens_url = "https://addr:5000/v2.0/tokens?nocatalog" identity_res = requests.post(tokens_url, verify=False, json=data_v2) identity_json = json.loads(identity_res.text) print(identity_json) token_id = identity_json.get("access").get("token").get("id")
post方法verify=False, 可以忽略https的證書認證
返回結果: 獲取到token id
{ "access": { "metadata": { "is_admin": 0, "roles": [] }, "serviceCatalog": [], "token": { "audit_ids": ["ypJ1ICc4RLygMfAb7DiZYw"], "expires": "2019-12-09T07:18:54Z", "id": "gAAAAABd7edO0F1cxsC52pUfx7d366xj3cJDgtCo2UQn1ODp4I5x7RgHWjdBexSIpMvOjnNKSka1voQ-u19d5GqHB11qI4f7OZH7hqGXjNuGsSnV8Qkxrp2Od_edeQNmIchoJkhQmB0qwt1iX4KIfqaWO_O0y2NEsA", "issued_at": "2019-12-09T06:18:54.000000Z" }, "user": { "id": "af0671ecc3fd49018d977cd010384ad9", "name": "admin", "roles": [], "roles_links": [], "username": "admin" } } }
使用token id獲取項目 id, 這里使用headers=tokens_header, 在查看官網文檔時curl, 使用-H, 因此requests時也需要使用header
tokens_header = {"X-Auth-Token": tokens_id} tenants_url = "https://addr:5000/v2.0/tenants" tenant_res = requests.get(tenants_url, headers=tokens_header, verify=False) tenant_json = json.loads(tenant_res.text) tenant_id = tenant_json.get("tenants")[0].get("id")
返回結果:
{ "tenants": [{ "description": "admin tenant", "enabled": True, "id": "e7e33f4c19074ab0b7c516922506e4c1", "name": "admin" } ], "tenants_links": [] }
通過項目id獲取項目token_id
#將json串重組, 添加tenant_id元素 data = data_v2.get("auth") data.update({"tenantId": tenant_id}) data_v2.update({"auth": data}) tokens_url = "https://addr:5000/v2.0/tokens?nocatalog" tenant_res = requests.post(tokens_url, verify=False, json=data_v2) tenant_json = json.loads(tenant_res.text) tenant_token_id = tenant_json.get("access").get("token").get("id")
返回結果:
{ "access": { "metadata": { "is_admin": 0, "roles": ["ecbc53d3d61f459d956900b59c48027e"] }, "serviceCatalog": [], "token": { "audit_ids": ["9y6YnS-wRReX--PhE9K5WQ"], "expires": "2019-12-09T07:18:54Z", "id": "gAAAAABd7edOo4ZWloMPVjOg7okktnUh9lfKHBNpWUaGIpckon98jVrfo72hhN9AtYwvEek_F-3QwhD8QYOfd3ZZX_x9Nb5q80mhY1TMtfu6MX_9xyFQDgy8mwkEvy01OjN8J8WpnebDFNVgjJWmGD0ypRIL_VMYEz9GdMYaXVG9KZJMOvCU8us", "issued_at": "2019-12-09T06:18:54.000000Z", "tenant": { "description": "admin tenant", "enabled": True, "id": "e7e33f4c19074ab0b7c516922506e4c1", "name": "admin" } }, "user": { "id": "af0671ecc3fd49018d977cd010384ad9", "name": "admin", "roles": [{ "name": "admin" } ], "roles_links": [], "username": "admin" } } }
2. V3認證方式
data_v3 = { "auth": { "identity": { "methods": ["password"], "password": { "user": { "domain": { "name": "default" }, "name": "admin", "password": "123456" } } }, "scope": { "project": { "domain": { "name": "default" }, "name": "admin" } } } }
domain在openstack的身份管理-項目可以看到, 項目列表有一列是域名; 當然如果有admin權限, admin登錄后, 身份管理下就有域名這一欄目; 上面json, methods的值是不用改的
tokens_url = "https://addr:5000/v3/auth/tokens?nocatalog" identity_res = requests.post(tokens_url, verify=False, json=data_v3) token_id = identity_res.headers.get("X-Subject-Token")
看官網文檔, 使用curl 獲取token時, 就會發現, v3方式獲取token時, token_id是在header里的
然后獲取項目id
tokens_header = {"X-Auth-Token": tokens_id} tenant_res = requests.get("https://addr:5000/v3/projects", headers=tokens_header, verify=False) tenant_json = json.loads(tenant_res.text) projects = tenant_json.get("projects") tenant_id = None for project in projects: if project.get("name") == "admin": tenant_id = project.get("id")
返回結果: projects 的json串, 從中拿一個項目的id
[{ "description": "test", "domain_id": "default", "enabled": True, "id": "0f50422b76ad460ba984d5b4de74a6c9", "is_domain": False, "links": { "self": "https://ip:5000/v3/projects/0f50422b76ad460ba984d5b4de74a6c9" }, "name": "test", "parent_id": "default" }, { "description": "admin tenant", "domain_id": "default", "enabled": True, "id": "e6e33f4c19074ab0b7c516922506e4c1", "is_domain": False, "links": { "self": "https:// ip:5000/v3/projects/e7e33f4c19074ab0b7c516922506e4c1" }, "name": "admin", "parent_id": "default" }]
再通過項目id, 獲取項目的token_id
tenant_id = get_tenant() data_v3.get("auth").get("scope").get("project").update({"id": tenant_id}) tokens_url = "https://addr:5000/v3/auth/tokens?nocatalog" tenant_res = requests.post(tokens_url, verify=False, json=data_v3) tenant_token_id = tenant_res.headers.get("X-Subject-Token")
二. 獲取主機信息
獲取虛擬主機只有v2, 這里用到上面的tenant_id, 和tenant_token_id
compute_url = "https://addr:8774/v2.1/" + tenant_id + "/servers/detail" #/servers可以拿到簡單的主機信息, 加上detail會有詳細信息輸出 tokens_header2 = {"X-Auth-Token": tenant_token_id} compute_res = requests.get(compute_url, headers=tokens_header2, verify=False) print(json.loads(compute_res.text))
返回結果: servers信息太長, 就不全貼出來了; 下面是一個主機的詳細信息
{ "servers": [{ "OS-DCF:diskConfig": "AUTO", "OS-EXT-AZ:availability_zone": "nova", "OS-EXT-SRV-ATTR:host": "node-46.domain.tld", "OS-EXT-SRV-ATTR:hypervisor_hostname": "node-46.domain.tld", "OS-EXT-SRV-ATTR:instance_name": "instance-0000001b", "OS-EXT-STS:power_state": 1, "OS-EXT-STS:task_state": null, "OS-EXT-STS:vm_state": "active", "OS-SRV-USG:launched_at": "2019-12-06T06:16:29.000000", "OS-SRV-USG:terminated_at": null, "accessIPv4": "", "accessIPv6": "", "addresses": { "\u5185\u7f51_admin_internal_net": [{ "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9c:c5:b1", "OS-EXT-IPS:type": "fixed", "addr": "192.168.1.26", "version": 4 }, { "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:9c:c5:b1", "OS-EXT-IPS:type": "floating", "addr": "192.168.2.30", "version": 4 } ] }, "config_drive": "True", "created": "2019-11-29T09:13:26Z", "flavor": { "id": "8dcfc279-9b2c-49a4-9308-4af960f4f66a", "links": [] }, "hostId": "0b03b88cf441997a9f87b37a2f292e9ab79286fefc992ed18d4151ca", "id": "c9459a94-df8f-455f-991f-b6ccbd36f3f2", "image": { "id": "119be129-98e8-4345-b5fa-0ec5405ae6a3", "links": [] }, "key_name": null, "links": [], "metadata": {}, "name": "wang_30", "os-extended-volumes:volumes_attached": [], "progress": 0, "security_groups": [{ "name": "default" } ]} "status": "ACTIVE", "tenant_id": "e7e33f4c19074ab0b7c516922506e4c1", "updated": "2019-12-06T06:16:50Z", "user_id": "af0671ecc3fd49018d977cd010384ad9" }]
三. 獲取映像信息
image_url = "https://addr:9292/v2/images" tokens_header2 = {"X-Auth-Token": tenant_token_id} image_res = requests.get(image_url, headers=tokens_header2, verify=False) print(json.loads(image_res.text))
返回結果: 下面也是一個映像的信息
{ "images": [{ "id": "374d46c8-2ad4-4af5-a034-346be3aae73e", "links": [{ "href": "", "rel": "self" }, { "href": "", "rel": "bookmark" }, { "href": "", "rel": "alternate", "type": "application/vnd.openstack.image" } ], "name": "Ubuntu-16" } }
ps: images還可以通過主機的接口進行獲取"https://addr:8774/v2.1/" + tenant_id + "/images
四. 獲取網絡信息
network_url2 = "https://addr:9696/v2.0/networks" tokens_header2 = {"X-Auth-Token": tenant_token_id} network_res = requests.get(network_url2, headers=tokens_header2, verify=False) print(json.loads(network_res.text))
返回結果: 同樣, 只貼一個網絡的信息
{ "networks": [{ "admin_state_up": true, "availability_zone_hints": [], "availability_zones": [], "created_at": "2019-11-27T03:37:06", "description": "", "dns_domain": "", "id": "b9758de3-7238-4e9f-9601-c798e7eb9be1", "ipv4_address_scope": null, "ipv6_address_scope": null, "is_default": false, "mtu": 1500, "name": "admin_net", "port_security_enabled": true, "provider:network_type": "flat", "provider:physical_network": "physnet1", "provider:segmentation_id": null, "router:external": true, "shared": false, "status": "ACTIVE", "subnets": ["0a0e3bd4-14ae-463e-9140-78b0a617d6c9"], "tags": [], "tenant_id": "e7e33f4c19074ab0b7c516922506e4c1", "updated_at": "2019-11-27T07:37:52" } }
轉載請注明出處