OpenStack API
soruce /etc/keystone/admin-openrc.sh
openstack user show admin
openstack project show admin =`openstack project list
openstack endpoint list
OpenStack 中调用任何API,在执行请求前都 要经过Keystone 认证,需要使用用户的证书来获取Authentication Token,证书包含了用户名、 密码和项目。在 openrc.sh 文件中可以找到它们。Token 允许用户不需要再次认证就能和其他 的serviceendpoints 交互。



HTTP Header X-Auth-Token:$token
x-subject-token


JSON 语法规则
- 数据为 键/值 对
- 数据由逗号分隔
- 大括号保存对象
- 方括号保存数组
有一个web api接口, 要求:调用时,需要将身份认证令牌“token”加到HTTP 头的“X-Token”字段中,以便验证调用者身份。 接口调用成功 以后,将返回Pos数据是否添加成功。 在实际调用时,应该怎样做此类请求呢?
openstack所有组件的相关认证都由Keystone组件来进行管理。在对openstackAPI进行测试时需要在请求头部分指定参数:X-Auth-Token和Content-Type。第一个参数的值为token,第二个参数的值为响应类型。
Token认证中,X-Subject-Token和X-Auth-Token的区别? 调用token接口,响应成功后在响应消息头中包含的“X-Subject-Token”的值即为Token值; 调用业务接口,在请求消息头中增加“X-Auth-Token”,“X-Auth-Token”的取值为前面从“X-Subject-Token”获取的Token。
Openstack X-auth-token 和 token
我使用这个外壳:(1)
curl -X POST http://192.168.100.10:5000/v2.0/tokens -d '{"auth":{"passwordCredentials":{"username": "admin", "password":"000000"}}}' -H "Content-type: application/json"
在 http.log 我找到一个实例:(2)
curl -i -X GET http://10.0.3.139:35357/v3/projects -H "User-Agent: python-keystoneclient" -H "Forwarded: for=10.0.3.139;by=python-keystoneclient" -H "X-Auth-Token: 04ef789a010c6f252a9f572347cac345
问:在(1)中,我可以得到一个长的 json 字符串。它包括 token.id 。但我不知道 (2) 中的 X-auth-token 和 token.id 有什么区别。
由于第一个查询是针对端口 5000 的端点,因此它正在返回一个用户令牌。
第二个查询针对端口 35357 的端点,通常设置为 Keystone 的管理端点。因此,该令牌将有所不同,而且该调用针对的是 /projects 而不是 /tokens。
您可以将 X-auth-token 作为后续 http 请求的标头传递,但要意识到管理员令牌和用户令牌提供对资源的不同访问权限。
Keystone 服务由 2 个端点提供,一个具有端口 5000,另一个是 35357。35357 端口提供与管理相关的操作,而端口 5000 提供通用 API 功能。
`令牌可以是有范围的(针对特定项目/域)或无范围的(仅使用用户名/密码生成)。当您使用 v2 api 请求令牌时,您会在响应中收到 tokenId,而在 v3 api 中,tokenId 在 key 的响应标头中:X-Subject-Token。`
您需要在每个 API 请求中提供 X-Auth-Token 。您还可以在 X-Auth-Token 标头中使用超级用户。keystone.conf 中存在超级用户令牌(admin_token 键)
Scope
A scope can be a Project/Tenant, or a Domain. Identity operations work on a Domain scope to create an authentication token, and then can operate on a Project scope. All other services operate in a Project scope.
范围
范围可以是项目/租户或域。身份操作在域范围内工作以创建身份验证令牌,然后可以在项目范围内进行操作。所有其他服务都在项目范围内运行
scope token
在keystone中scope token主要有以下几种类型:
- project-scoped token:该类型token表示用户对具体项目的访问权限,token信息主要包括用户可访问的服务目录、拥有的权限、以及项目信息。
- domain-scoped token:该类型token表示用户在域范围具有的权限,例如如果用户对域内具有管理员权限,则该用户就能管理域内的所有项目以及用户。跟project-scoped token不同的是project-scoped token包含了可访问项目信息,而domain-scoped token则包含了具有操作权限的域信息。
- trust-scoped token:当truster授予trustee一定的权限后,trustee可以使用该类型token来操作truster资源,该类型token信息包括truster的项目/域信息以及一系列权限,服务目录。
tokentoken即令牌,身份的凭证。在整个openstack项目中服务与服务之间的通信都需要token来进行身份认证,我们来举个例子:
如上图所示,一个用户需要创建一台虚拟机,用户首先要登入之后先拿到一个project_scope token 这个token包含了用户具有的角色以及服务列表,用户拿着这个令牌去请求nova服务,nova首先会去keystone认证该token是否有效,之后会向glance发送获取镜像的请求,glance接收请求后也会向之前的步骤一样去keystone认证token有效性,最终返回镜像给nova,nova再用镜像去给用户创建虚拟机。
另外需要说明的是token中包含用户所拥有的角色,nova和其他服务还会根据token中的role来判断用户是否有操作权限。
获取token的方式
1.通过openstack命令获取
加载环境变量。 [root@controller ~]# source admin-openrc 获取token [root@controller ~]# openstack token issue
2.通过curl获取
完整的curl命令如下,在该命令中,指定了用户名为admin,密码为ADMIN_PASS,domain的名字为default,project名字为admin。认证地址为IP_ADDRES。在使用的时候,这些参数都需要做对应的更改。
curl -i -X POST -H "Content-type: application/json" -d '{
"auth":{
"identity":{
"methods":["password"],
"password":{
"user":{
"id":"d99f1a888f2d4b7fa42a191fe408d954",
"password":"000000"
}
}
},"scope":{
"project":{
"id":"70c50f20ad754291805e5c7620b336bf"
}
}
}
}
' http://192.168.100.10:5000/v3/auth/tokens
curl 参数说明: -i :显示头信息 -X:指定请求方式为POST -H:指定请求头参数 -d:指定请求体参数 -s: 不显示错误输出
openstack 接入 用户名、密码验证,这有几点说明: 1.如果接入用户没有项目内(即没有租户,没有project),那么无法获得其他信息。 2.如果接入用户在项目内的角色不是管理员,同样没有权利获取其他信息 3.如果接入用户同时在多个项目内(在多个租户下),是否遍历所有信息;
curl -si -d @token-request.json -H "Content-type:application/json" http://controller:35357/v3/auth/tokens 其中: http://controller:35357/v3就是Keystone服务对外的AP1接口。 http://controller1:35357/v3/auth/tokens就是Keystone服务对外的获取令牌的API接口
openstack任何命令加上参数”--debug“即可看到当前命令使用的api端点。
例如:
[root@controller ~]# openstack user list --debug
//验证接入是否成功 curl -s -X POST http://192.168.122.106:5000/v2.0/tokens -H "Content-Type: application/json" -d '{"auth": {"tenantName": "admin", "passwordCredentials": {"username": "admin", "password": "000000"}}}' | python -m json.tool
//flavor $token->tokenid 项目id->项目id curl -s -H "X-Auth-Token: $token" http://controller:8774/v2/项目id/flavors | python -m json.tool //images curl -s -H "X-Auth-Token: $token" http://controller:8774/v2/项目id/images | python -m json.tool //servers instances curl -s -H "X-Auth-Token: $token" http://controller:8774/v2/项目id/servers | python -m json.tool
curl获取user
curl -s -H "X-Auth-Token:$token" http://controller:5000/v3/users | python -m json.tool
//project
curl -s -H "X-Auth-Token:$token" http://controller:5000/v3/projects | python -m json.tool
//network curl -s -H "X-Auth-Token: $token" http://controller:9696/v2.0/networks | python -m json.tool
//extensions curl -s -H "X-Auth-Token: $token" http://controller:9696/v2.0/extensions | python -m json.tool
//ports curl -s -H "X-Auth-Token: $token" http://controller:9696/v2.0/ports | python -m json.tool //floatingips curl -s -H "X-Auth-Token: $token" http://controller:9696/v2.0/floatingips | python -m json.tool //routers curl -s -H "X-Auth-Token: $token" http://controller:9696/v2.0/routers | python -m json.tool //subnetpools curl -s -H "X-Auth-Token: $token" http://controller:9696/v2.0/subnetpools | python -m json.tool //subnets curl -s -H "X-Auth-Token: $token" http://controller:9696/v2.0/subnets | python -m json.tool //Security group rules curl -s -H "X-Auth-Token: $token" http://controller:9696/v2.0/security-group-rules | python -m json.tool //Security groups curl -s -H "X-Auth-Token: $token" http://controller:9696/v2.0/security-groups | python -m json.tool //quotas curl -s -H "X-Auth-Token: $token" http://controller:9696/v2.0/quotas | python -m json.tool //search nova-compute curl -s -H "X-Auth-Token: $token" http://controller:8774/v2/项目id/os-services?binary=nova-compute | python -m json.tool
3.通过Postman获取
指定请求方法POST
指定访问地址
Body->raw 处添加请求信息

响应结果的Header中出现的参数X-Subject-Token即为token值

云主机
1、正常安装python3.6 2、pip3 install certifi-2019.11.28-py2.py3-none-any.whl 3、pip3 install urllib3-1.25.11-py3-none-any.whl 4、pip3 install idna-2.8-py2.py3-none-any.whl 5、pip3 install chardet-3.0.4-py2.py3-none-any.whl 6、pip3 install requests-2.24.0-py2.py3-none-any.whl tar -zxvf Python-api.tar.gz cd Python-api tar -zxvf python-3.6.8.tar.gz yum -y install python-3.6.8/packages/* pip3 install *.whl
基本使用方法
下面以OpenStack的创建连接为例,进行说明。为了使用OpenStack云,首 先需要使用凭证(credentials) 创建一 个到它的连接。连接的创建有3种方式: 使用OpenStack的类、 配置文集和环境变量。建议使用配置文件,因为相同的配 置可以跨工具和语言使用,兼容性较好。使用OpenStack Python SDK中的 connect()工厂函数创建连接:
def create_connection(auth_url, region, project_name, username, password):
return openstack.connect(
auth_url=auth_url, //auth_url
project_name=project_name, //项目名称
username=username, //用户名
password=password, //密码
region_name=region,
app_name='examples',
app_version='1.0',
)
完整案例代码如下所示:
import argparse
import os
import openstack
from openstack.config import loader
import sys
openstack.enable_logging(True, stream=sys.stdout)
#: 在配置文件中定义OpenStack 配置云密钥
#: 配置文件通常在$HOME/.config/openstack/clouds.yaml.
#: 配置信息将决定运行实例的位置,以及将使用说明样的资源默认值,来运行实例
TEST_CLOUD = os.getenv('OS_TEST_CLOUD', 'devstack-admin')
config = loader.OpenStackConfig()
cloud = openstack.connect(cloud=TEST_CLOUD)
class Opts(object):
def __init__(self, cloud_name='devstack-admin', debug=False):
self.cloud = cloud_name
self.debug = debug
# Use identity v3 API for examples.
self.identity_api_version = '3'
#: 获取资源值,resource_key:资源秘钥
def _get_resource_value(resource_key, default):
return config.get_extra_config('example').get(resource_key, default)
TEST_CLOUD = os.getenv('OS_TEST_CLOUD', 'devstack-admin')
config = loader.OpenStackConfig()
cloud = openstack.connect(cloud=TEST_CLOUD)
class Opts(object):
def __init__(self, cloud_name='devstack-admin', debug=False):
self.cloud = cloud_name
self.debug = debug
# Use identity v3 API for examples.
self.identity_api_version = '3'
def_get_resource_value(resource_key, default):
return config.get_extra_config('example').get(resource_key, default)
SERVER_NAME = 'openstacksdk-example'
IMAGE_NAME = _get_resource_value('image_name', 'cirros-0.4.0-x86_64-disk')
FLAVOR_NAME = _get_resource_value('flavor_name', 'm1.small')
NETWORK_NAME = _get_resource_value('network_name', 'private')
KEYPAIR_NAME = _get_resource_value('keypair_name', 'openstacksdk-example')
SSH_DIR = _get_resource_value(
'ssh_dir', '{home}/.ssh'.format(home=os.path.expanduser("~")))
PRIVATE_KEYPAIR_FILE = _get_resource_value(
'private_keypair_file', '{ssh_dir}/id_rsa.{key}'.format( ssh_dir=SSH_DIR, key=KEYPAIR_NAME))
EXAMPLE_IMAGE_NAME = 'openstacksdk-example-public-image'
def create_connection_from_config():
return openstack.connect(cloud=TEST_CLOUD)
def create_connection_from_args():
parser = argparse.ArgumentParser()
return openstack.connect(options=parser)
def create_connection(auth_url, region, project_name, username, password):
return openstack.connect(
auth_url=auth_url,
project_name=project_name,
username=username,
password=password,
region_name=region,
app_name='examples',
app_version='1.0', )
使用Python调用OpenStack API
了解OpenStack API 了解Python语法 使用Python编写代码, 调用OpenStack API 查询用户列表信息

运行CMD程序,进入restAPl.py文件所在的目录下,如图所示。
执行python restAPI.py命令,运行程序,python restAPI.py 成功获取到OpenStack平台的用户列表。
程序解读(restAPI.py文件)
import requests
import json
# 定义全局路径
os_auth_url = "http://xiandian"
# 定义请求体
body = {
"auth":{
"identity":{
"methods":["password"],
"password":{
"user":{
"id":"ef2b3098367943bfa85d0487bb3df24f",
"password":"000000"
}
}
},"scope":{
"project":{
"id":"e10e1ab80d654e5bbd3b4846f2609e4b"
}
}
}
}
# 设置请求头
headers = {}
headers["Content-Type"] = "application/json"
headers["Accept"] = "*/*"
# 获取token 值
def get_token():
# 获取tokens 的url
os_auth_url_token = os_auth_url + ":35357/v3/auth/tokens"
# 使用requests 模拟请求,返回json,获取token
result = requests.post(os_auth_url_token, headers=headers, data=json.dumps(body)).headers["X-Subject-Token"]
return result
def user_list():
# 获取users 的url
os_auth_url_users = os_auth_url + ':35357/v3/users'
# 调用get_token()方法,获取token 值,放进headers 中
headers["X-Auth-Token"] = get_token()
# 使用requests 模拟请求 返回users json
result = requests.get(os_auth_url_users, headers=headers).json()
print(result)
return result
# 调用user_list()方法
user_list()
Python调用OpenStack api
编写python代码创建flavor
编写python代码对接OpenStack API,完成flavor的创建。在all-in-one节点的/root目录下创建create_flavor.py文件,在该文件中编写python代码对接openstack api,要求在openstack私有云平台上创建一个云主机类型,名字为test、vcpu为1个、内存为1024m、硬盘为20G、ID为199999。执行完代码要求输出“云主机类型创建成功”。create_flavor.py的文件内容如下:
import requests,json,time
# *******************全局变量IP*****************************
#执行代码前,请修改controller_ip的IP地址,与指定router,IP可以input,也可以写成静态
controller_ip = input("请输入访问openstack平台控制节点IP地址:(xx.xx.xx.xx)\n")
try:
url = f"http://{controller_ip}:5000/v3/auth/tokens"
body =body={
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
"id": "d99f1a888f2d4b7fa42a191fe408d954",
"password": "000000"
}
}
},
"scope": {
"project": {
"id": "70c50f20ad754291805e5c7620b336bf"
}
}
}
}
headers = {
"Content-Type": "application/json",
}
Token = requests.post(url, data=json.dumps(body),headers=headers).headers['X-Subject-Token']
headers = {
"X-Auth-Token": Token
}
except Exception as e:
print(f"获取Token值失败,请检查访问云主机控制节点IP是否正确?输出错误信息如下:{str(e)}")
exit(0)
class flavor_api:
def __init__(self,handers:dict,resUrl:str):
self.headers=handers
self.resUrl=resUrl
#创建flavor类型
def create_flavor(self,flavor_name:str,ram,vcpus,disk,id):
self.headers['Content-Type']="application/json"
body={
"flavor":{
"name":flavor_name,
"ram":ram,
"vcpus":vcpus,
"disk":disk,
"id":id,
}
}
status_code = requests.post(self.resUrl, data=json.dumps(body), headers=self.headers).text
#获取flavor_id
def get_flavor_id(self,flavor_name:str):
result = json.loads(requests.get(self.resUrl,headers=self.headers).text)
for item in result['flavors']:
if(item['name']==flavor_name):
return item['id']
flavor_api=flavor_api(headers,f"http://{controller_ip}:8774/v2.1/flavors")
flavor_api.create_flavor(flavor_name="test",ram=1024,vcpus=1,disk=20,id=199999)
flavor_id = flavor_api.get_flavor_id(flavor_name="test")
print("云主机类型创建成功,flavor_id为:",flavor_id)
'''
#注意调用方法应该放在最前面!!!
'''
编写完python代码后,使用如下命令执行:
[root@openstack ~]# python3 create_flavor.py
请输入访问openstack平台控制节点IP地址:(xx.xx.xx.xx)
172.30.18.29
云主机类型创建成功,flavor_id为: 199999
正确执行,返回flavor的id为199999,使用命令查看flavor是否被成功创建,命令如下:
[root@openstack ~]# source /etc/keystone/admin-openrc.sh
[root@openstack ~]# openstack flavor list
+--------+------+------+------+-----------+-------+-----------+
| ID | Name | RAM | Disk | Ephemeral | VCPUs | Is Public |
+--------+------+------+------+-----------+-------+-----------+
| 199999 | test | 1024 | 20 | 0 | 1 | True |
+--------+------+------+------+-----------+-------+-----------+
确认创建flavor成功。
编写python代码创建镜像
编写python代码对接OpenStack API,完成镜像的上传。在all-in-one节点的/root目录下创建create_image.py文件,在该文件中编写python代码对接openstack api,要求在openstack私有云平台中上传镜像cirros-0.3.4-x86_64-disk.img,名字为cirros001,disk_format
为qcow2,container_format为bare。执行完代码要求输出“镜像创建成功,id为:xxxxxx”。create_image.py的文件内容如下:
import requests,json,time
# *******************全局变量IP*****************************
#执行代码前,请修改controller_ip的IP地址,与指定router,IP可以input,也可以写成静态
controller_ip = input("请输入访问openstack平台控制节点IP地址:(xx.xx.xx.xx)\n")
try:
url = f"http://{controller_ip}:5000/v3/auth/tokens"
body = {"auth": {"identity": {"methods": ["password"], "password": {
"user": {"domain": {"name": "demo"}, "name": "admin", "password": "000000"}}},
"scope": {"project": {"domain": {"name": "demo"}, "name": "admin"}}}}
headers = {
"Content-Type": "application/json",
}
Token = requests.post(url, data=json.dumps(body), headers=headers).headers['X-Subject-Token']
headers = {
"X-Auth-Token": Token
}
except Exception as e:
print(f"获取Token值失败,请检查访问云主机控制节点IP是否正确?输出错误信息如下:{str(e)}")
exit(0)
class glance_api:
def __init__(self, headers: dict, resUrl: str):
self.headers = headers
self.resUrl = resUrl
#创建glance镜像
def create_glance(self, image_name: str, container_format="bare", disk_format="qcow2"):
body = {
"container_format": container_format,
"disk_format": disk_format,
"name": image_name,
}
status_code = requests.post(self.resUrl, data=json.dumps(body), headers=self.headers).status_code
#获取glance镜像id
def get_glance_id(self,image_name:str):
result = json.loads(requests.get(self.resUrl,headers=self.headers).text)
for item in result['images']:
if(item['name']==image_name):
return item['id']
#上传glance镜像
def update_glance(self,image_name:str,file_path=""):
self.resUrl=self.resUrl+"/"+self.get_glance_id(image_name)+"/file"
self.headers['Content-Type'] = "application/octet-stream"
seatus_code = requests.put(self.resUrl,data=open(file_path,'rb').read(),headers=self.headers).status_code
glance_api = glance_api(headers,f"http://{controller_ip}:9292/v2/images")
glance_api.create_glance(image_name="cirros001") #调用glance-api中创建镜像方法
print("镜像创建成功,id为: ",glance_api.get_glance_id(image_name="cirros001"))
glance_api.update_glance(image_name="cirros001",file_path="./cirros-0.3.4-x86_64-disk.img")
执行代码,命令如下:
# python3 create_image.py
请输入访问openstack平台控制节点IP地址:(xx.xx.xx.xx)
172.30.18.29
镜像创建成功,id为: 714882f6-b6d4-4eb3-b655-8b63207755f0
可以看见执行代码成功,使用命令查看镜像是否上传成功,命令如下:
[root@allinone ~]# openstack image list
+--------------------------------------+-----------+--------+
| ID | Name | Status |
+--------------------------------------+-----------+--------+
| 714882f6-b6d4-4eb3-b655-8b63207755f0 | cirros001 | active |
+--------------------------------------+-----------+--------+
镜像是active状态,代码执行成功。
编写python代码创建用户
编写python代码对接OpenStack API,完成用户的上传。在all-in-one节点的/root目录下创建create_user.py文件,在该文件中编写python代码对接openstack api,要求在openstack私有云平台中创建用户chinaskill。具体代码如下:
import requests,json,time,os
#encoding=UTF-8
controller_ip = '172.30.18.29'
url = f"http://{controller_ip}:5000/v3/auth/tokens"
body={
"auth": {
"identity":{
"methods": ["password"]
,"password": {
"user": {
"domain": {
"name": "demo"
},
"name": "admin",
"password": "000000"
}
}
},
"scope": {
"project": {
"domain": {
"name": "demo"
},
"name": "admin"
}
}
}
}
headers = {
"Content-Type": "application/json",
}
Token = requests.post(url, data=json.dumps(body), headers=headers).headers['X-Subject-Token']
headers = {
"X-Auth-Token": Token
}
class openstack_role_api:
def __init__(self, handers: dict, resUrl: str):
self.headers = handers
self.resUrl = resUrl
def create_roles(self, role_name):
body = {
"role": {
"description": "My new role",
"name": role_name
}
}
status_code = requests.post(self.resUrl, data=json.dumps(body), headers=self.headers)
result = json.loads(requests.get(self.resUrl, headers=self.headers).text)
role_name = role_name
for i in result['roles']:
if i['name'] == role_name:
return f"角色 {role_name} 创建成功,ID为{i['id']}"
def get_role_id(self, role_name):
result = json.loads(requests.get(self.resUrl, headers=self.headers).text)
role_name = role_name
for i in result['roles']:
if i['name'] == role_name:
return (f"角色 {role_name} 的ID为{i['id']}")
def delete_role(self, role_name):
result = json.loads(requests.get(self.resUrl, headers=self.headers).text)
for i in result['roles']:
if i['name'] == role_name:
i = i['id']
status_code = requests.delete(f'http://{controller_ip}:5000/v3/roles/{i}', headers=self.headers)
return f"角色 {role_name} 已删除!"
def list_roles(self):
result = json.loads(requests.get(self.resUrl, headers=self.headers).text)
roles = []
for i in result['roles']:
if i['name'] not in roles:
roles.append(i['name'])
return "该平台的角色为:\n"+'\n'.join(roles)
class openstack_user_api:
def __init__(self, handers: dict, resUrl: str):
self.headers = handers
self.resUrl = resUrl
def create_users(self, user_name):
body = {
"user": {
"description": "API create user!",
"domain_id": "fa8baeb025724e1183b0416056378cc3",
"name": user_name
}
}
status_code = requests.post(self.resUrl, data=json.dumps(body), headers=self.headers).text
result = json.loads(requests.get(self.resUrl, headers=self.headers).text)
user_name = user_name
for i in result['users']:
if i['name'] == user_name:
return f"用户 {user_name} 创建成功,ID为{i['id']}"
def list_users(self):
result = json.loads(requests.get(self.resUrl, headers=self.headers).text)
roles = []
for i in result['users']:
if i['name'] not in roles:
roles.append(i['name'])
return "该平台的用户为:\n"+'\n'.join(roles)
def get_user_id(self, user_name):
result = json.loads(requests.get(self.resUrl, headers=self.headers).text)
user_name = user_name
for i in result['users']:
if i['name'] == user_name:
return (f"用户 {user_name} 的ID为{i['id']}")
def delete_user(self, user_name):
result = json.loads(requests.get(self.resUrl, headers=self.headers).text)
for i in result['users']:
if i['name'] == user_name:
i = i['id']
status_code = requests.delete(f'http://{controller_ip}:5000/v3/users/{i}', headers=self.headers)
return f"用户 {user_name} 已删除!"
openstack_role_api = openstack_role_api(headers, f"http://{controller_ip}:5000/v3/roles")
openstack_user_api = openstack_user_api(headers, f"http://{controller_ip}:5000/v3/users")
# print(openstack_role_api.create_roles("xxx"))
# print(openstack_role_api.list_roles())
# print(openstack_user_api.create_users("xxx"))
# print(openstack_user_api.list_users())
# print(openstack_user_api.delete_user("xxx"))
上面的详细代码定义了两个类,一个user类,一个role类,每个类下面有查询,创建,列出,删除四个函数,实例化一个类然后调用函数,例如创建用户chinaskill,就在代码的最下方调用create函数,具体如下:
print(openstack_user_api.create_users("chinaskill"))
执行代码,效果如下:
[root@allinone ~]# python3 create_user.py
用户 chinaskill 创建成功,ID为76372e3b4ef749b88871a65aa19824fc
使用命令查看用户列表,确定是否创建成功,命令如下:
[root@allinone ~]# openstack user list
+----------------------------------+-------------------+
| ID | Name |
+----------------------------------+-------------------+
| 0f8782af6a654d77b587e25a32f91f28 | cinder |
| 1ab30f77400448eba6b2d47e55084540 | demo |
| 2550fa93b1fe4cb582f1f46353b836d8 | ceilometer |
| 2d2a345336184b1ebbdf022f710084e8 | neutron |
| 48b816f9db9541b4bd9ca49ad453574c | glance |
| 76372e3b4ef749b88871a65aa19824fc | chinaskill |
| 765a16c99d7d42a4b69ff941f7791b54 | aodh |
| 788efa329f324b91a431ad56cd7b9a14 | nova |
| 7ecae98d16d54483b964c9c2548fd7bc | swift |
| 962612a3e7784df38d0c98fea1f30320 | heat |
| 9ee4731c00c24f659b8790be6b77bc8a | admin |
| d6fdd1e5e1a348e0b6c5b8c7f33ba5fa | placement |
| d957a578fed2452ab91bc651f2f1fb97 | heat_domain_admin |
| e91070fa751e49689963b566db999bee | gnocchi |
+----------------------------------+-------------------+
可以查看到chinaskill用户,python脚本执行成功。如果要调用其他功能,可按照上面的方法自行实验。
注:代码中的"domain_id": "fa8baeb025724e1183b0416056378cc3",需要改成实际执行环境中的domain_id。
非查询请求体
body={
"auth": {
"identity":{
"methods": ["password"]
,"password": {
"user": {
# "domain": {
# "name": "demo"
# },
# "name": "admin",
# "password": "000000"
}
}
},
"scope": {
"project": {
# "domain": {
# "name": "demo"
# },
# "name": "admin"
}
}
}
}
需查询请求体
body={
"auth": {
"identity": {
"methods": ["password"],
"password": {
"user": {
# "id": "d99f1a888f2d4b7fa42a191fe408d954",
# "password": "000000"
}
}
},
"scope": {
"project": {
# "id": "70c50f20ad754291805e5c7620b336bf"
}
}
}
}