一、 准备
来到天翼云官网(中国电信-天翼云,云网融合,安全可信,专享定制),注册相应账号。
点击“文档”,后选择“弹性云主机”
分别点击“API参考”、“调用前必知”,我们看到“概述”、“终端节点”、“请求状态码”
我们从这三部分得知相应信息:
① 目前支持的资源池(以当前为例,选择华东1);
② 终端节点为ctecs-global.ctapi.ctyun.cn;
③ API请求出现的状态码代表的含义。
点击“如何调用API”,我们看到“构造请求”、“认证鉴权”
从这两部分信息得知重要信息:
① 请求URI格式为{URI-scheme}://{Endpoint}/{resource-path}?{query-string};
② 需要使用AK SK信息。
AK、SK信息我们点击右上角“个人中心”,进入界面后,分别点击的“安全设置”、“用户AccessKey”、“查看”
二、 使用OpenAPI
1、 python调用示例模板
# -*- coding: utf8 -*- if sys.version_info.major == 2: reload(sys) reload(sys) METHOD_GET = 'GET'
return '&'.join(str_list)
# 计算鉴权密钥 signature_base64 = base64_of_hmac(hmac_sha256(k_date, signature_str))
url = url + "?" + encodeQueryStr(query) print_log('返回状态码: %s' % res.status_code)
return afterQuery
for param in params: |
通过该示例,我们只需知道自己的用户AK、SK,以及要调用的OpenAPI信息(包括uri、请求方式和参数),便可调用天翼云OpenAPI了。
2、 创建云主机参数准备
创建云主机所需信息较多,我们通过官网文档找出关键信息。
我们打开创建云主机的OpenAPI文档,摘取出重要的三个信息:
① URI为 /v4/ecs/create-instance
② 请求方式为POST
③ 参数包括必填参数与非必填参数,这里我们以最简单的例子使用必填参数来创建(如有需求,可按照必填参数方式增加对应参数)
必填参数一部分是需要我们自行填写,还有一部分需要我们通过其他方式进行查询
自行填写参数:
参数 |
类型 |
说明 |
clientToken |
String |
保证幂等性的参数,可自行填写 |
instanceName |
String |
云主机名称,可自行填写 |
displayName |
String |
展示名称,可自行填写 |
imageType |
Integer |
镜像类型,这里选择共有镜像,即1 |
bootDiskType |
String |
系统盘类型,这里选SATA,普通云盘 |
bootDiskSize |
Integer |
系统盘大小,这里使用最小值40 |
onDemand |
Boolean |
包周期还是按需,这里我们选用按需(true) |
extIP |
String |
是否使用弹性公网IP,这里选择不使用(“0”) |
需要再查询的参数:
参数 |
类型 |
说明 |
regionID |
String |
资源池ID,需要查询 |
azName |
String |
可用区名称,需要查询 |
flavorID |
String |
规格ID,需要查询 |
imageID |
String |
镜像ID,需要查询共有镜像 |
vpcID |
String |
虚拟私有云ID,需要查询 |
networkCardList |
String |
网卡列表,需要查子网ID(subnetID) |
3、 调用OpenAPI查询参数信息
部分参数我们需要通过调用其他OpenAPI来查询或创建出相应资源。
(1)regionID
找到天翼云OpenAPI弹性云主机文档,点击“资源池信息”、“资源池列表查询”
还是得到重要的三个信息:
① URI: /v4/region/list-regions
② GET请求
③ 无需参数
由此我们可以按照上述python方法进行调用:
# get方法调用 res_list_regions = get("https://ctecs-global.ctapi.ctyun.cn/v4/region/list-regions", query='', params={}) |
得到结果:
[2023-05-23 10:10:09.770222]: 返回状态码: 200 [2023-05-23 10:10:09.771228]: 返回: {'returnObj': {'regionList': [{'isMultiZones': False, 'regionParent': '湖南', 'regionID': '6f925df23a3811e9948d0242ac110002', 'regionType': 'openstack', 'zoneList': [], 'regionName': '郴州'}, ... # 省略 , 'errorCode': '', 'message': '', 'description': '', 'statusCode': 800} |
使用python进行筛选结果:
regionList = res_list_regions.json().get("returnObj").get("regionList") region_huadong = list(filter(lambda x: x.get("regionName") == "华东1", regionList)) print("华东1: ", region_huadong) region_id_huadong = region_huadong[0].get("regionID") print("华东1 regionID: ", region_id_huadong) |
得到结果:
华东1: [{'isMultiZones': True, 'regionParent': '华东', 'regionID': 'bb9fdb42056f11eda1610242ac110002', 'regionType': 'openstack', 'zoneList': ['cn-huadong1-jsnj1A-public-ctcloud', 'cn-huadong1-jsnj2A-public-ctcloud', 'cn-huadong1-jsnj3A-public-ctcloud'], 'regionName': '华东1'}] 华东1 regionID: bb9fdb42056f11eda1610242ac11000 |
(2)azName
同样的方式在天翼云官网文档中,找到资源池可用区查询
得到重要的三个信息:
① URI: /v4/region/get-zones
② GET请求
③ 参数regionID
调用OpenAPI查询:
res_get_zones = get("https://ctecs-global.ctapi.ctyun.cn/v4/region/get-zones", query='', params=dict(regionID=region_id_huadong)) |
结果:
[2023-05-23 10:22:03.018835]: 返回状态码: 200 [2023-05-23 10:22:03.018835]: 返回: {'returnObj': {'zoneList': [{'name': 'cn-huadong1-jsnj1A-public-ctcloud', 'azDisplayName': '可用区1'}, {'name': 'cn-huadong1-jsnj2A-public-ctcloud', 'azDisplayName': '可用区2'}, {'name': 'cn-huadong1-jsnj3A-public-ctcloud', 'azDisplayName': '可用区3'}]}, 'errorCode': '', 'message': '', 'description': '', 'statusCode': 800} |
取出相应结果:
# 这里我们选取可用区1 zoneList = res_get_zones.json().get("returnObj").get("zoneList") zone1 = list(filter(lambda x: x.get("azDisplayName") == '可用区1', zoneList)) print("可用区1: ", zone1) az_name1 = zone1[0].get("name") print("可用区1 azName: ", az_name1) |
结果:
res_get_zones = get("https://ctecs-global.ctapi.ctyun.cn/v4/region/get-zones", query='', params=dict(regionID=region_id_huadong)) |
(3)flavorID
找到资源池可用区查询,得到重要的三个信息:
① URI: /v4/ecs/flavor/list
② POST请求
③ 参数regionID、azName
调用OpenAPI查询:
query_flavor_params = dict(regionID=region_id_huadong, azName=az_name1) res_flavor_list = post("https://ctecs-global.ctapi.ctyun.cn/v4/ecs/flavor/list", query='', params=query_flavor_params) |
结果:
[2023-05-23 14:40:38.974314]: 返回状态码: 200 [2023-05-23 14:40:38.974732]: 返回: {'returnObj': {'flavorList': [{'flavorID': '34e1b6f6-e974-1575-20b2-172ba0e0bf83', 'flavorName': 's7.small.1', 'flavorCPU': 1, 'flavorRAM': 1, 'baseBandwidth': 0.1, 'bandwidth': 0.8, 'flavorSeries': 's', 'nicMultiQueue': 1, 'pps': 10, 'flavorType': 'CPU_S7', 'cpuInfo': 'x86', 'gpuVendor': None, 'videoMemSize': None, 'gpuType': None, 'gpuCount': None}, ..., # 省略 'videoMemSize': 24, 'gpuType': 'A10', 'gpuCount': 1}]}, 'details': '', 'message': 'SUCCESS', 'description': '成功', 'statusCode': 800} |
我们选用规格s7.small.1
flavorList = res_flavor_list.json().get("returnObj").get("flavorList") s7_flavor = list(filter(lambda x: x.get("flavorName") == "s7.small.1", flavorList)) print("s7.small.1 信息:", s7_flavor) s7_flavor_id = s7_flavor[0].get("flavorID") |
结果:
s7.small.1 信息: [{'flavorID': '34e1b6f6-e974-1575-20b2-172ba0e0bf83', 'flavorName': 's7.small.1', 'flavorCPU': 1, 'flavorRAM': 1, 'baseBandwidth': 0.1, 'bandwidth': 0.8, 'flavorSeries': 's', 'nicMultiQueue': 1, 'pps': 10, 'flavorType': 'CPU_S7', 'cpuInfo': 'x86', 'gpuVendor': None, 'videoMemSize': None, 'gpuType': None, 'gpuCount': None}] s7.small.1规格的flavorID为: 34e1b6f6-e974-1575-20b2-172ba0e0bf83 |
(4)imageID
我们切换产品列表,切换产品时,勿忘查询终端节点,镜像服务的终端节点为:ctimage-global.ctapi.ctyun.cn
选择“镜像服务”,分别点击“API”、“信息查询功能”、“查询可以使用的镜像资源”
得到重要的三个信息:
① URI: /v4/image/list
② GET请求
③ 参数regionID、azName、visibility(由于之前选用了公共镜像类型,所以这里查询要限制查询镜像类型,公共镜像为1)
调用OpenAPI查询:
image_list_params = dict(regionID=region_id_huadong, azName=az_name1, visibility=1) res_image_list = get("https://ctimage-global.ctapi.ctyun.cn/v4/image/list", query='', params=image_list_params) |
结果:
[2023-05-23 14:53:46.538614]: 返回状态码: 200 [2023-05-23 14:53:46.538614]: 返回: {'returnObj': {'images': [ ... # 省略 {'architecture': 'x86_64', 'azName': None, 'bootMode': 'bios', 'containerFormat': 'bare', 'createdTime': 1664276810, 'description': '', 'destinationUser': None, 'diskFormat': 'raw', 'diskID': None, 'diskSize': 40, 'imageClass': 'ECS', 'imageID': 'e8929d7e-6cfd-4a03-bf76-1bc7f2aeb883', 'imageName': 'CentOS8.1 64位', 'imageType': None, 'maximumRAM': None, 'minimumRAM': None, 'osDistro': 'centos', 'osType': 'linux', 'osVersion': '8.1', 'projectID': None, 'sharedListLength': None, 'size': 42949672960, 'sourceServerID': None, 'sourceUser': None, 'status': 'active', 'tags': None, 'updatedTime': None, 'visibility': 'public'}], 'pageNo': 1, 'pageSize': 10, 'totalCount': 38}, 'errorCode': '', 'message': '', 'description': '', 'statusCode': 800} |
我们选用镜像为CentOS7.8 64位的镜像
imageList = res_image_list.json().get("returnObj").get("images") centos7_image = list(filter(lambda x: x.get("imageName") == "CentOS7.8 64位", imageList)) print("CentOS7.8 64位的镜像信息:", centos7_image) centos7_8_image_id = centos7_image[0].get("imageID") print("CentOS7.8 64位镜像的imageID为:", centos7_8_image_id) |
结果:
CentOS7.8 64位的镜像信息: [{'architecture': 'x86_64', 'azName': None, 'bootMode': 'bios', 'containerFormat': 'bare', 'createdTime': 1664232729, 'description': '', 'destinationUser': None, 'diskFormat': 'raw', 'diskID': None, 'diskSize': 40, 'imageClass': 'ECS', 'imageID': '6e95ed90-b8b6-40ee-ae38-d851b6dc35e4', 'imageName': 'CentOS7.8 64位', 'imageType': None, 'maximumRAM': None, 'minimumRAM': None, 'osDistro': 'centos', 'osType': 'linux', 'osVersion': '7.8', 'projectID': None, 'sharedListLength': None, 'size': 42949672960, 'sourceServerID': None, 'sourceUser': None, 'status': 'active', 'tags': None, 'updatedTime': None, 'visibility': 'public'}] CentOS7.8 64位镜像的imageID为: 6e95ed90-b8b6-40ee-ae38-d851b6dc35e4 |
(5)vpcID、subnetID
如果我们没有VPC和子网时,我们需要先创建VPC和子网:
我们切换产品列表至虚拟私有云,切换产品时,勿忘查询终端节点,虚拟私有云的终端节点为:ctvpc-global.ctapi.ctyun.cn
选择“镜像服务”,分别点击“API”、“VPC”、“创建VPC”
得到重要的三个信息:
① URI: /v4/vpc/create
② POST请求
③ 参数regionID、azName、clientToken、name、CIDR
调用OpenAPI创建(这里clientToken与name我们自定义,CIDR按照文档选用192.168.0.0/16)
vpc_create_params = dict(regionID=region_id_huadong, azName=az_name1, clientToken="createVPC0523", name="vpc-0523", CIDR="192.168.0.0/16") res_vpc_create = post("https://ctvpc-global.ctapi.ctyun.cn/v4/vpc/create", query="", params=vpc_create_params) |
结果:
[2023-05-23 15:31:40.438960]: 返回状态码: 200 [2023-05-23 15:31:40.438960]: 返回: {'statusCode': 800, 'errorCode': 'SUCCESS', 'message': 'success', 'description': '成功', 'returnObj': {'vpcID': 'vpc-hnkpq1dn46'}} 'destinationUser': None, 'diskFormat': 'raw', 'diskID': None, 'diskSize': 40, 'imageClass': 'ECS', 'imageID': 'e8929d7e-6cfd-4a03-bf76-1bc7f2aeb883', 'imageName': 'CentOS8.1 64位', 'imageType': None, 'maximumRAM': None, 'minimumRAM': None, 'osDistro': 'centos', 'osType': 'linux', 'osVersion': '8.1', 'projectID': None, 'sharedListLength': None, 'size': 42949672960, 'sourceServerID': None, 'sourceUser': None, 'status': 'active', 'tags': None, 'updatedTime': None, 'visibility': 'public'}], 'pageNo': 1, 'pageSize': 10, 'totalCount': 38}, 'errorCode': '', 'message': '', 'description': '', 'statusCode': 800} |
subnet同理,打开创建子网
得到重要的三个信息:
① URI: /v4/vpc/create-subnet
② POST请求
③ 参数regionID、vpcID、clientToken、name、CIDR
调用OpenAPI创建(这里clientToken与name我们自定义,CIDR按照文档选用192.168.1.0/24)
subnet_create_params = dict(regionID=region_id_huadong, clientToken="createSubnet0523", name="subnet-0523", CIDR="192.168.1.0/24", vpcID='vpc-hnkpq1dn46') res_subnet_create = post("https://ctvpc-global.ctapi.ctyun.cn/v4/vpc/create-subnet", query="", params=subnet_create_params) |
结果:
[2023-05-23 15:36:52.879846]: 返回状态码: 200 [2023-05-23 15:36:52.879846]: 返回: {'statusCode': 800, 'errorCode': 'SUCCESS', 'message': 'success', 'description': '成功', 'returnObj': {'subnetID': 'subnet-v47niplom1'}} |
如果已有对应VPC,可以查询VPC列表来拿到对应vpcID和subnetID
得到重要的三个信息:
① URI: /v4/vpc/list
② GET请求
③ 参数regionID、azName
调用OpenAPI查询:
vpc_list_params = dict(regionID=region_id_huadong, azName=az_name1) res_vpc_list = get("https://ctvpc-global.ctapi.ctyun.cn/v4/vpc/list", query="", params=vpc_list_params) |
结果:
[2023-05-23 15:10:45.332877]: 返回状态码: 200 [2023-05-23 15:10:45.332877]: 返回: {'statusCode': 800, 'errorCode': 'SUCCESS', 'message': 'success', 'description': '成功', 'returnObj': {'vpcs': [{'vpcID': 'vpc-xdgj37uuxc', 'name': 'cndc-hub-test-5-sh', 'description': '', 'CIDR': '10.0.0.0/24', 'ipv6Enabled': False, 'secondaryCIDRs': [], 'subnetIDs': ['subnet-80oyaklfdu'], 'natGatewayIDs': [], 'ipv6CIDRS': []}, ... # 省略 ]}, 'currentCount': 10, 'totalCount': 62, 'totalPage': 7} |
我们选用第一个VPC和其中一个subnet
vpcList = res_vpc_list.json().get("returnObj").get("vpcs") vpc_id = vpcList[0].get("vpcID") print("vpcID:", vpc_id) subnet_id = vpcList[0].get("subnetIDs")[0] print("subnetID:", subnet_id) |
结果:
vpcID: vpc-xdgj37uuxc subnetID: subnet-80oyaklfdu |
网卡networkCardList参数组装为:
network_card_list = [{"subnetID": subnet_id, "isMaster": true}] |
4、 创建云主机
至此,我们的参数已经全部查询完毕,组装一下:
create_instance_params = { # 自行填写参数 "clientToken": "createInstance0523", "instanceName": "api-create0523", "displayName": "ecm-0523", "imageType": 1, "bootDiskType": "SATA", "bootDiskSize": 40, "onDemand": True, "extIP": "0", # 查询参数 "regionID": region_id_huadong, "azName": az_name1, "flavorID": s7_flavor_id, "imageID": centos7_8_image_id, "vpcID": vpc_id, "networkCardList": [{"subnetID": subnet_id, "isMaster": True}] } |
调用OpenAPI进行创建:
res_create_instance = post("https://ctecs-global.ctapi.ctyun.cn/v4/ecs/create-instance", query='', params=create_instance_params) |
结果:
[2023-05-23 15:50:56.545144]: 返回状态码: 200 [2023-05-23 15:50:56.545144]: 返回: {'returnObj': {'masterResourceID': 'ee872731d881406d9f08d8ac073d2b6a', 'masterOrderNO': '20230523155045331859', 'regionID': 'bb9fdb42056f11eda1610242ac110002', 'masterOrderID': '853b6238f93e11edb0b10242ac110007'}, 'details': '', 'message': 'success', 'description': '成功', 'statusCode': 800} |
5、 查看结果
对于创建的云主机,我们可以通过三种方式来看是否创建成功
(1) 控制台查看
最简单的就是登录天翼云官网,选择“控制中心”,资源池选择“华东”->“华东1”,然后点击“弹性云主机”
我们可以看到,展示名称ecm-0523的云主机处于“运行中”状态,此时说明云主机已创建成功。
(2) OpenAPI查询云主机列表
官网文档找到查询云主机列表
得到重要的三个信息:
① URI: /v4/ecs/list-instances
② POST请求
③ 请求参数:regionID、azName、resourceID/instanceName(作为筛选条件)
a. 通过填写创建云主机时拿到的masterResourceID来查询(推荐)
instance_list_params = dict(regionID=region_id_huadong, azName=az_name1, resourceID="ee872731d881406d9f08d8ac073d2b6a") res_instance_list = post("https://ctecs-global.ctapi.ctyun.cn/v4/ecs/list-instances", query='', params=instance_list_params) |
b. 通过限制云主机名称来查询云主机
instance_list_params = dict(regionID=region_id_huadong, azName=az_name1, instanceName="api-create0523") res_instance_list = post("https://ctecs-global.ctapi.ctyun.cn/v4/ecs/list-instances", query='', params=instance_list_params) |
结果:
[2023-05-23 16:01:30.784235]: 返回状态码: 200 [2023-05-23 16:01:30.784235]: 返回: {'returnObj': {'currentCount': 1, 'totalCount': 1, 'totalPage': 1, 'results': [{'azName': 'cn-huadong1-jsnj1A-public-ctcloud', 'displayName': 'ecm-0523', 'instanceName': 'api-create0523', 'osType': 5, 'instanceStatus': 'running', ... # 省略 }]}, 'details': '', 'message': 'SUCCESS', 'description': '成功', 'statusCode': 800} |
可以看出该云主机已存在,且云主机状态为running(运行中)
(3) OpenAPI查询订单状态
官网文档中也提供了根据订单号查资源ID的方式,选择“弹性云主机”、“公共接口”,点击“根据订单号查询Uuid”
得到重要的三个信息:
① URI: /v4/order/queryUuid
② GET请求
③ 参数masterOrderId
调用OpenAPI查询:
query_order_params = dict(masterOrderId="853b6238f93e11edb0b10242ac110007") res_query_order = get("https://ctecs-global.ctapi.ctyun.cn/v4/order/queryUuid", query='', params=query_order_params) |
结果:
[2023-05-23 16:29:29.481958]: 返回状态码: 200 [2023-05-23 16:29:29.481958]: 返回: {'returnObj': {'resourceType': 'VM', 'resourceUUID': ['a905aba2-3052-60f6-ec37-aa45c9b6da25'], 'orderStatus': '3'}, 'errorCode': '', 'message': '', 'description': '', 'statusCode': 800} |
可以看出订单状态为3,对照订单状态枚举表,得知为“完成”
三、 总结
本文介绍了如何调用天翼云OpenAPI来创建云主机,通过官网文档,我们可以很好地找到对应参数,并且也可以通过OpenAPI进行查询。比较贴心的是,目前创建云主机的文档参数说明中已增加了相应需要查找的参数的OpenAPI文档超链接。可以很好的指导我们调用天翼云OpenAPI。