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" } }
转载请注明出处