案例描述

本案例基于Huawei Cloud API的Python SDKV3模块,实现公有云的自动化运维开发,并通过Python args模块和http.server模块,实现公有云资源命令行管理工具和公有云资源服务的封装。

案例实施

案例准备

准备有资金的华为公有云账号,使用华为公有云环境。

案例实施

容器集群创建

基于在Huawei Cloud API的云容器引擎CCE Python模块,使用以下信息,在/root目录下手动编写cce_cluser.yaml文件。

云服务器的/root/目录下编写cce_cluster_manager.py 文件,编码实现读取cce_cluser.yaml,创建“按需计费”的CCE容器引擎集群(Cluster),创建后根据名称查询该集群(Cluster)的详细信息,通过控制台以Json格式输出该集群的信息。

创建CCE集群的信息如下,其他必要信息不限。

  • CCE名称:chinaskillscce2022。
  • 按需计费:集群版本为v1.21。
  • 集群规模:节点数50。
  • 网络模式:VPC网络。

编写cce_cluster_manager.py文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import time

from huaweicloudsdkcce.v3 import *

#CCE 3.0
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkcce.v3.region.cce_region import CceRegion
from huaweicloudsdkcore.exceptions import exceptions
from huaweicloudsdkcce.v3 import *

def get_aksk_v3_cce_token():
ak = "DQVNQ7NHZCRS9XFCJAME"
sk = "jGYmdH66dfittUCEnlr4s9gJjb6xxN4P3tuyPl4j"
# EZA2ZDBZANMYYEHUHYBD
# GMK5KA5qYRmQiuaIpTyFay6QbZ1pohYGPBmAGklY
token = BasicCredentials(ak, sk)
client = CceClient.new_builder() \
.with_credentials(token) \
.with_region(CceRegion.value_of("cn-north-4")) \
.build()
return client

class Cluster_Manager:
def __init__(self,client):
self.client = client


def delete_same_cluster(self,name):
client = self.client
req = ListClustersRequest()
resp = client.list_clusters(req)
for cluster in resp.items:
if cluster.metadata.name == name:
clusterId = cluster.metadata.uid
delete_req = DeleteClusterRequest()
delete_req.cluster_id = clusterId
delete_req.delete_efs = "true"
delete_req.delete_evs = "true"
delete_req.delete_net = "true"
delete_req.delete_obs = "true"
delete_req.delete_sfs = "true"
delete_resp = client.delete_cluster(delete_req)
print(f"删除集群成功:{delete_resp}")
return ""

def create_cluster(self):
client = self.client
req = CreateClusterRequest()
metadataBody = ClusterMetadata(
name="test-cluster"
)
hostNetwork = HostNetwork(
vpc="178938e4-fb8b-4491-831b-440e3f8d24fa",
subnet="8c9a2894-acc8-4e41-a451-fe11b84e2b9f",
)
Cidrs = [
ContainerCIDR(
cidr="10.0.0.0/16"
)
]
containetNetwork = ContainerNetwork(
mode="vpc-router",
cidrs=Cidrs,
)
SpecBody = ClusterSpec(
category="CCE",
type="VirtualMachine",
flavor="cce.s1.small",
version="v1.21",
host_network=hostNetwork,
container_network=containetNetwork,
kube_proxy_mode="iptables",

)
req.body = Cluster(
kind="Cluster",
api_version="v3",
metadata=metadataBody,
spec=SpecBody,
)

result = client.create_cluster(req)
print(f"创建的集群信息为:{result}")

def list_cluster(self):
client = self.client
req = ListClustersRequest()
req.detail = "true"
req.status = "Available"
req.type = "VirtualMachine"
req.version = "v1.21"
result = client.list_clusters(req)
print(f"获取到当前项目下的集群信息为:{result}")

def get_clusterId_by_name(self,name):
client = self.client
req = ListClustersRequest()
resp = client.list_clusters(req)
for cluster in resp.items:
if cluster.metadata.name == name:
clusterId = cluster.metadata.uid
print(f"集群的ID为:{clusterId}")
return ""

def show_cluster(self,clusterId):
client = self.client
req = ShowClusterRequest()
req.detail = "true"
req.cluster_id = clusterId
result = client.show_cluster(req)
print(f"展示当前集群的信息为:{result}")



if __name__ == "__main__":
cluster_m = Cluster_Manager(get_aksk_v3_cce_token())

# delete_same = cluster_m.delete_same_cluster("test-cluster")
# time.sleep(60) #执行删除操作后,睡眠1分钟,因为需要1分钟的时间来将集群彻底删除。
#
# create_cluster = cluster_m.create_cluster()
# time.sleep(480) #睡眠8分钟,这段时间,在创建集群。需要等集群创建完成之后,才能获取到信息。

list_cluster = cluster_m.list_cluster()
clusterId = cluster_m.get_clusterId_by_name("chinaskillscce2022")
show_cluster = cluster_m.show_cluster(clusterId)

------------------------------------------执行结果---------------------------------
python3 cce_cluster_manager.py
创建的集群信息为:{"kind": "Cluster", "apiVersion": "v3", "metadata": {"name": "test-cluster", "uid": "3134ac35-492b-11ed-94b1-0255ac1002cd", "annotations": {"jobid": "31557172-492b-11ed-94b1-0255ac1002cd", "resourceJobId": "31367b5c-492b-11ed-94b1-0255ac1002cd"}, "creationTimestamp": "2022-10-11 06:08:57.631041168 +0000 UTC", "updateTimestamp": "2022-10-11 06:08:57.63104138 +0000 UTC"}, "spec": {"category": "CCE", "type": "VirtualMachine", "flavor": "cce.s1.small", "version": "v1.21", "platformVersion": "cce.4.10", "hostNetwork": {"vpc": "600b8e93-fbaa-4119-87c2-87f0678dd189", "subnet": "2bfaefa7-bf01-4798-9c5c-a29fe989a24b"}, "containerNetwork": {"mode": "vpc-router", "cidr": "10.0.0.0/16", "cidrs": [{"cidr": "10.0.0.0/16"}]}, "eniNetwork": {}, "authentication": {"mode": "rbac", "authenticatingProxy": {}}, "billingMode": 0, "kubernetesSvcIpRange": "10.247.0.0/16", "kubeProxyMode": "iptables", "extendParam": {"orderID": ""}}, "status": {"phase": "Creating", "jobID": "31557172-492b-11ed-94b1-0255ac1002cd"}}
获取到当前项目下的集群信息为:{"kind": "Cluster", "apiVersion": "v3", "items": [{"kind": "Cluster", "apiVersion": "v3", "metadata": {"name": "test-cluster", "uid": "3134ac35-492b-11ed-94b1-0255ac1002cd", "annotations": {"activeNodesNumber": "0", "faultNodesNumber": "0", "installedAddonInstances": "[{\"addonTemplateName\":\"everest\",\"version\":\"1.3.17\",\"status\":\"installing\"},{\"addonTemplateName\":\"coredns\",\"version\":\"1.23.1\",\"status\":\"installing\"}]", "totalNodesCPU": "0", "totalNodesMemory": "0", "totalNodesNumber": "0"}, "labels": {"FeatureGates": "elbv3,"}, "creationTimestamp": "2022-10-11 06:08:57.631041 +0000 UTC", "updateTimestamp": "2022-10-11 06:14:01.876433 +0000 UTC"}, "spec": {"category": "CCE", "type": "VirtualMachine", "flavor": "cce.s1.small", "version": "v1.21", "platformVersion": "cce.4.10", "hostNetwork": {"vpc": "600b8e93-fbaa-4119-87c2-87f0678dd189", "subnet": "2bfaefa7-bf01-4798-9c5c-a29fe989a24b", "SecurityGroup": "a1ccd90a-c622-4060-a243-c6b59035bec0"}, "containerNetwork": {"mode": "vpc-router", "cidr": "10.0.0.0/16"}, "eniNetwork": {}, "authentication": {"mode": "rbac", "authenticatingProxy": {}}, "billingMode": 0, "masters": [{"availabilityZone": "cn-east-3a"}], "kubernetesSvcIpRange": "10.247.0.0/16", "kubeProxyMode": "iptables", "az": "cn-east-3a", "extendParam": {"alpha.cce/fixPoolMask": "", "kubernetes.io/cpuManagerPolicy": "", "upgradefrom": ""}, "supportIstio": true}, "status": {"phase": "Available", "endpoints": [{"url": "https://192.168.0.4:5443", "type": "Internal"}]}}]}

cce.cluster.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc
kind: Cluster
apiVersion: v3
metadata:
name: chinaskillscce2022
annotations:
cluster.install.addons.external/install: '[{"addonTemplateName":"icagent"}]'
spec:
category: CCE
flavor: cce.s2.small
version: v1.21
hostNetWork:
vpc: eb35f318-0cdb-4632-a068-414c2285a409
subnet: 0b51072e-0225-4f30-934e-106f684ca67a
containerNetWork:
mode: vpc-router
cidr: 10.10.0.0/16
kubernetesSvcIpRange: 10.247.0.0/16
description: ''
billingMode: 0
extendParam:
kubeProxyMode: iptables
alpha.cce/fixPoolMask: '25'
authentication:
mode: rbac
ipv6enable: false

ECS云主机管理的命令行工具开发

使用已建好的运维开发环境,在/root/目录下创建ecs_manager.py脚本,完成ECS云主机管理,ecs_manager.py程序支持命令行参数执行。

提示说明:华为云主机支持安装所需Python库,需安装所开发程序所依赖的Python库。

(1)程序支持根据命令行参数,创建1个云主机。

创建待成功,再返回查询该云主机的信息,结果以Json格式输出到控制台。

参考执行实例如下:

1
python3 ecs_manager.py create --input '{ "name": " chinaskill001", "imagename": "CentOS 7.9 64bit"}'
  • 位置参数“create”,表示创建;
  • 参数“-i或–input”,格式为Json格式文本的云主机的名称、镜像名称2个信息。其他参数同上述开发环境云主机一致。

(2)支持查询给定具体名称的ECS云主机查询。

参考执行实例如下:

1
python3 ecs_manager.py get --name chinaskill001-o chinaskill001.json
  • 位置参数“get”,表示查询ECS;
  • 参数“-n或–name”支持指定名称ECS查询,类型为string。
  • 参数“-o或–output”支持查询该ECS信息输出到文件,格式为Json格式。

(3)程序支持查询目前区域账号下所有的ECS云主机。

参考执行实例如下:

1
python3 ecs_manager.py getall -o huawei_all_ecs.yaml
  • 位置参数“getall”,表示查询所有ECS云主机;
  • 参数“-o 或–output”支持输出到文件,格式为yaml格式。

(4)支持删除指定的名称的云主机。

参考执行实例如下:

1
python3 ecs_manager.py delete --name chinaskill001
  • 位置参数“delete”,表示删除一个ECS云主机;返回response,通过控制台输出。
  • 参数“-n或–name”支持指定名称查询,类型为string。

ces_create.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# coding: utf-8
from http import client
import json
from pydoc import cli
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkecs.v2.region.ecs_region import EcsRegion
from huaweicloudsdkcore.exceptions import exceptions
from huaweicloudsdkecs.v2 import *
import time

from huawei_ecs_server import get_server_id

#Token
def get_aksk_v3_ecs_token():
ak = "8MJITOJBPKNUTADFGCUA"
sk = "yehuP3rojiH0ucj1pnCev3VawVd4VwxDr1mCWLRh"
token = BasicCredentials(ak,sk)
client = EcsClient.new_builder().\
with_credentials(token).\
with_region(EcsRegion.value_of("cn-east-3")).build()
return client

class server_manager:
def __init__(self,client):
self.client = client

def create_server(self,name,imagename):
client = self.client
request = CreateServersRequest()

listPrePaidServerSecurityGroupSecurityGroupsServer = [
PrePaidServerSecurityGroup(
id="b46f7f8c-5e1d-4e85-91c6-1ee43ce7c9a5"
)
]
listPrePaidServerDataVolumeDataVolumesServer = [
PrePaidServerDataVolume(
volumetype="SSD",
size=50
)
]
rootVolumePrePaidServerRootVolume = PrePaidServerRootVolume(
volumetype="SSD",
size=100
)
bandwidthPrePaidServerEipBandwidth = PrePaidServerEipBandwidth(
size=10,
sharetype="PER"
)
eipPrePaidServerEip = PrePaidServerEip(
iptype="5_bgp",
bandwidth=bandwidthPrePaidServerEipBandwidth
)
publicipPrePaidServerPublicip = PrePaidServerPublicip(
eip=eipPrePaidServerEip,
delete_on_termination=True
)
listPrePaidServerNicNicsServer = [
PrePaidServerNic(
subnet_id="2bfaefa7-bf01-4798-9c5c-a29fe989a24b"
)
]
serverPrePaidServer = PrePaidServer(
image_ref=imagename,
flavor_ref="c7.xlarge.2",
name=name,
vpcid="600b8e93-fbaa-4119-87c2-87f0678dd189",
nics=listPrePaidServerNicNicsServer,
publicip=publicipPrePaidServerPublicip,
root_volume=rootVolumePrePaidServerRootVolume,
data_volumes=listPrePaidServerDataVolumeDataVolumesServer,
security_groups=listPrePaidServerSecurityGroupSecurityGroupsServer,
)
request.body = CreateServersRequestBody(
server=serverPrePaidServer
)
response = client.create_servers(request)
# time.sleep(10)
print(f"创建的云服务器信息为:{response}")
return response

def get_server_id(self,name):
client = self.client
req = ListServersDetailsRequest()
resp = client.list_servers_details(req)
for server in resp.servers:
if server.name == name:
return server.id

def get_server_detail(self,name):
client = self.client
req = ListServersDetailsRequest()
resp = client.list_servers_details(req)
strins = str(resp)
return strins

def getall_ecs(self):
client = self.client
req = ListServersDetailsRequest()
resp = client.list_servers_details(req)
strings = str(resp)
return strings

def get_server(self,id):
client = self.client
req = ShowServerRequest()
req.server_id = id
resp = client.show_server(req)
print(f"获取到的云服务器信息为:{resp}")
return resp

def delete_server(self,name):
client = self.client
request = DeleteServersRequest()
listServersbody = [
ServerId(
id=get_server_id(name)
)
]
request.body = DeleteServersRequestBody(
servers=listServersbody
)
response = client.delete_servers(request)
return response


if __name__ == "__main__":
server_m = server_manager(get_aksk_v3_ecs_token())
# create
# create_servers = server_m.create_server("chinaskill","f025bf3e-3173-4f2a-8f59-34aca5bd853d")

#detail
# list_details = server_m.get_server_detail("chinaskill001","chinaskill001.json")

# id
# id = server_m.get_server_id("chinaskill")
# print(f"云服务器的ID为:{id}")
# time.sleep(15)
# get
# show_server = server_m.get_server(id)
# time.sleep(20)

# delete
delete_servers = server_m.delete_server("chinaskill")

ecs_manager.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#encoding:utf-8
# coding: utf-8
#encoding:utf-8
import argparse
from ast import arg
from cgi import print_arguments
from cgitb import reset
import json,yaml
import ces_create
# get all user
print("-----------begin-----------------")
ecs_m = ces_create.server_manager(ces_create.get_aksk_v3_ecs_token())

def define_args(parser):
"""
定义程序支持的args
:return:
"""
# parser = argparse.ArgumentParser()

#增加控制命令(postion 位置参数,必须)
parser.add_argument('command',
help='Resource command name',
type=str)
# parser.add_argument('delete',
# help='delete a resource',
# type=str)
#可选参数(可有可无)
parser.add_argument('-n', '--name', # 可选参数,删除的名称
help='The Name of the resource', # 输入-h展示
type=str)
parser.add_argument('-i', '--input', # 可选参数,删除的名称
help='The input json format text ', # 输入-h展示
type=str)
parser.add_argument('-o', '--output', # 可选参数,删除的名称
help='The output file path ', # 输入-h展示
type=str)

def parse_args(parser):
args = parser.parse_args()
# print(args)
# print('Provided name value is %r.' % args.command)
# print('Provided name value is %r.' % args.name)
if args.command:
if args.command == "create":
print("create Cloud ECSserver")
create_ecs(args)
elif args.command == "getall":
print("Get All ECSserver")
getall_ecs(args)
elif args.command == "get":
print("Get ECSserver")
get_ecs(args)
elif args.command == "delete":
print("Delete ECSserver")
delete_ecs(args)
else:
print("Note support command name!")
def create_ecs(args):
print('Provided command value is %r.' % args.command)
print('Provided input value is %r.' % args.input)
# print('Provided output value is %r.' % args.output)\
ecs_dict = json.loads(args.input)
print(ecs_dict)
res = ecs_m.create_server(ecs_dict["name"],ecs_dict["imagename"])
print(res)

def get_ecs(args):
print('Provided command value is %r.' % args.command)
print('Provided input value is %r.' % args.input)
print('Provided output value is %r.' % args.output)
result = ecs_m.get_server_detail(args.name)
output_file = args.output
with open(output_file, 'w') as jsonfile:
json.dump(result, jsonfile, indent=4)
print(result)

def getall_ecs(args):
print('Provided command value is %r.' % args.command)
print('Provided input value is %r.' % args.input)
print('Provided output value is %r.' % args.output)
result = ecs_m.getall_ecs()
print(result)
output_file = args.output
configuration = json.loads(result)
with open(output_file,"w")as yamlfile:
yaml.dump(configuration,yamlfile)
print(result)

def delete_ecs(args):
print('Provided command value is %r.' % args.command)
print('Provided input value is %r.' % args.input)
print('Provided output value is %r.' % args.output)
result = ecs_m.delete_server()
print(result)

if __name__ == '__main__':
parser = argparse.ArgumentParser()
define_args(parser)
parse_args(parser)

ECS云主机管理与监控的Restful APIs HTTP服务封装

云服务器的/root/目录下编写huawei_ecs_server.py文件编写Python程序,实现华为ECS云主机管理与云主机操作系统性能远程监控。所有的资源申请区域为“华北-北京四”,所有服务封装成Restful APIs方式,host为127.0.0.1,端口8888,供外部检测。

提示说明:华为云主机支持安装所需Python库,需安装程序所依赖的Python库。

具体要求:

(1)POST /ecs/server 创建云主机,需要等待成功该云主机后,返回查询该云主机信息。request传输的数据为application/json,Json包含2个必备信息,名称、镜像名称。

Json数据格式案例如下:

1
{ "name": " cloud001", "imagename": "CentOS 7.9 64bit"}
  • 其他必备参数与开发环境云主机一致。Response的Body以Json格式,返回所创建成功的主机详细信息。

(2)GET /ecs/server/{name}查询云主机;Response的Body以yaml格式。

GET /ecs/server/{name}/os查询所指定ID云主机的操作系统信息;Response的Json格式返回。返回格式要求如下:

  • os_release:操作系统的版本系统。
  • cpu_util:CPU使用率%。
  • mem_util:内存使用率%。
  • disk_util:磁盘使用率%。

(3)DELETE /ecs/server/{name}删除云主机;Response的Body以Json格式。

os_remote_monitor.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import os
import paramiko

# coding: utf-8

from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkecs.v2.region.ecs_region import EcsRegion
from huaweicloudsdkcore.exceptions import exceptions
from huaweicloudsdkecs.v2 import *

# uname、hostname、cpu_util、mem_util、ip_address;
def create_remote_client(ip, port, name, pwd, timeout=30):
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# 连接
try:
client.connect(ip, port, name, pwd)
print('----------连接成功-----------------')
except:
print("----------连接失败-----------------")
return client

# 实时读取
def run_ssh_command(ssh_client, cmd):
try:
stdin, stdout, stderr = ssh_client.exec_command(cmd, get_pty=True)
#strip \n\r
return stdout.read().decode()
except Exception as e:
print("execute command %s error, error message is %s" % (cmd, e))



def getos_uname(client):
return run_ssh_command(client, "cat /etc/redhat-release").strip()
# return run_ssh_command(client, "cat /etc/redhat-release")

def getos_hostname(client):
return run_ssh_command(client, "hostname").strip()

def getos_cpu_util(client):
command_name = "vmstat 1 1|sed '1d'|sed '1d'|awk '{print $15}'"
# https: // blog.csdn.net / qq_37275405 / article / details / 119210527
result = run_ssh_command(client, command_name).strip()
return result + '%'
# 3次平均值
# cpu = "vmstat 1 3|sed '1d'|sed '1d'|awk '{print $15}'"
# stdin, stdout, stderr = ssh.exec_command(cpu)
# cpu = stdout.readlines()
# cpu_usage = str(round((100 - (int(cpu[0]) + int(cpu[1]) + int(cpu[2])) / 3), 2)) + '%‘
import pstats

def getos_mem_util(client):
# free | sed -n '2,2p'| awk '{print $2}' line and collumn
command = "cat /proc/meminfo|sed -n '1,4p'|awk '{print $2}'"
# [root @ ecs - 1049 ~] # cat /proc/meminfo|sed -n '1,4p'|awk '{print $2}'
# MemTotal: 3754864
# MemFree: 3136028
# MemAvailable: 3326468
# Buffers: 28172
# 3754864
# 3135860
# 3326272
# 28140

result = run_ssh_command(client, command)
mem = result.split("\r\n")
mem_total = round(int(mem[0]) / 1024)
mem_total_free = round(int(mem[1]) / 1024)
mem_usage = str(round(((mem_total - mem_total_free) / mem_total) * 100, 2)) + "%"
return mem_usage

def getos_ip_address(client):
result = run_ssh_command(client, "hostname -I")
return result.strip()

def getos_disk_util(client):
result = run_ssh_command(client, "df -h / | sed -n '2,2p' | awk '{print $5}'")
return result.strip()

def getos_info(client):

uname = getos_uname(client)
hostname = getos_hostname(client)
cpu_util = getos_cpu_util(client)
mem_util = getos_mem_util(client)
ip_addr = getos_ip_address(client)
disk_util = getos_disk_util(client)

osinfo = {
"os_release": uname,
"hostname": hostname,
"cpu_util": cpu_util,
"mem_util": mem_util,
"ip_addr": ip_addr,
"disk_util": disk_util
}
import json
json_str = json.dumps(osinfo, indent=4)
return json_str

def get_remote_server_os_info(ip, port, user, password):
client = create_remote_client(ip, port, user, password)
os_info = getos_info(client)
return os_info

if __name__ == '__main__':
os_info = get_remote_server_os_info("124.71.205.227",22,"root","Abc@1234")

print(os_info)
# 3.linux查看版本当前操作系统发行信息 cat /etc/issue 或 cat /etc/centos-release
# https://blog.csdn.net/qq_37275405/article/details/119210527

# [root@ecs-1049 ~]# df -h /
# Filesystem Size Used Avail Use% Mounted on
# /dev/sda1 40G 2.2G 36G 6% /
# command = "df -h / | sed -n "2,2p" | awk '{print $5}'"
# [root@ecs-1049 ~]# df -h / | sed -n "2,2p" | awk '{print $5}'
# 6%

# ----------连接成功-----------------
# {
# "os_release": "CentOS Linux release 7.9.2009 (Core)",
# "hostname": "ecs-1049",
# "cpu_util": "99%",
# "mem_util": "10.91%",
# "ip_addr": "192.168.0.238",
# "disk_util": "6%"
# }
#
# Process finished with exit code 0

huawei_ecs_server.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
import json

import flask
from flask import request, jsonify, Response
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkecs.v2.region.ecs_region import EcsRegion
from huaweicloudsdkcore.exceptions import exceptions
from huaweicloudsdkecs.v2 import *

from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkecs.v2.region.ecs_region import EcsRegion
from huaweicloudsdkcore.exceptions import exceptions
from huaweicloudsdkecs.v2 import *

from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkecs.v2.region.ecs_region import EcsRegion
from huaweicloudsdkcore.exceptions import exceptions
from huaweicloudsdkecs.v2 import *

import requests
# careful not to mix flask's request with requests!

import threading
import yaml
# create flask
PORT = 8888
app = flask.Flask(__name__)

@app.route('/ecs/server', methods=['POST'])
def create_server():
args = request.args
print(request.method)
content = request.get_data(as_text=True)
print(content)

return Response(yaml.dump(content), mimetype='application/yaml')

def show_server(id):
ak = "DQVNQ7NHZCRS9XFCJAME"
sk = "jGYmdH66dfittUCEnlr4s9gJjb6xxN4P3tuyPl4j"
credentials = BasicCredentials(ak, sk)

client = EcsClient.new_builder().with_credentials(credentials)\
.with_region(EcsRegion.value_of("cn-north-4")).build()
try:
request = ShowServerRequest()
request.server_id = id
response = client.show_server(request)
return response

except exceptions.ClientRequestException as e:
print(e.status_code)
print(e.request_id)
print(e.error_code)
print(e.error_msg)

def get_ipaddress(id):
ak = "DQVNQ7NHZCRS9XFCJAME"
sk = "jGYmdH66dfittUCEnlr4s9gJjb6xxN4P3tuyPl4j"

credentials = BasicCredentials(ak, sk) \

client = EcsClient.new_builder() \
.with_credentials(credentials) \
.with_region(EcsRegion.value_of("cn-north-4")) \
.build()

try:
request = ListServerInterfacesRequest()
request.server_id = id
response = client.list_server_interfaces(request)
print(response)
except exceptions.ClientRequestException as e:
print(e.status_code)
print(e.request_id)
print(e.error_code)
print(e.error_msg)

def get_server_id(name):
ak = "DQVNQ7NHZCRS9XFCJAME"
sk = "jGYmdH66dfittUCEnlr4s9gJjb6xxN4P3tuyPl4j"

credentials = BasicCredentials(ak, sk) \

client = EcsClient.new_builder() \
.with_credentials(credentials) \
.with_region(EcsRegion.value_of("cn-north-4")) \
.build()

try:
request = ListServersDetailsRequest()
response = client.list_servers_details(request)

print(response.servers)
for server in response.servers:
if server.name == name:
return server.id
except exceptions.ClientRequestException as e:
print(e.status_code)
print(e.request_id)
print(e.error_code)
print(e.error_msg)

# 路由 方法
@app.route('/ecs/server/<name>', methods=['GET'])
def get_server(name):
print(name)
id = get_server_id(name)
print(id)
if id:
# id = "523d290d-42fa-42cd-9cfc-cafde8707ce5"
data = show_server(id)
# print(data)
#json数据直接返回
return json.loads(str(data))
#如果yaml返回
# return Response(yaml.dump(data), mimetype='application/yaml')
else:
return "Not Exist!"

@app.route('/ecs/server/<name>', methods=['DELETE'])
def delete_server(name):
if name:
id = get_server_id(name)

def delete_server(id_info):
ak = "DQVNQ7NHZCRS9XFCJAME"
sk = "jGYmdH66dfittUCEnlr4s9gJjb6xxN4P3tuyPl4j"

credentials = BasicCredentials(ak, sk) \

client = EcsClient.new_builder() \
.with_credentials(credentials) \
.with_region(EcsRegion.value_of("cn-north-4")) \
.build()

try:
request = DeleteServersRequest()
listServersbody = [
ServerId(
id=id_info
)
]
request.body = DeleteServersRequestBody(
servers=listServersbody
)
response = client.delete_servers(request)
print(response)
except exceptions.ClientRequestException as e:
print(e.status_code)
print(e.request_id)
print(e.error_code)
print(e.error_msg)


import os_remote_monitor

@app.route('/ecs/server/<name>/os', methods=['GET'])
def get_server_os(name):
if name:
id = get_server_id(name)
if id:
ip = get_server_ip(id)
return os_remote_monitor.get_remote_server_os_info(ip,22,"root","Cloud2022")
else:
return {}

# coding: utf-8

def get_server_ip(id):

ak = "DQVNQ7NHZCRS9XFCJAME"
sk = "jGYmdH66dfittUCEnlr4s9gJjb6xxN4P3tuyPl4j"

credentials = BasicCredentials(ak, sk) \

client = EcsClient.new_builder() \
.with_credentials(credentials) \
.with_region(EcsRegion.value_of("cn-north-4")) \
.build()

try:
request = ShowServerRequest()
request.server_id = id
response = client.show_server(request)
#list
ips = list(response.server.addresses.values())[0]
for ip in ips:
if ip.os_ext_ip_stype == "floating":
return ip.addr

except exceptions.ClientRequestException as e:
print(e.status_code)
print(e.request_id)
print(e.error_code)
print(e.error_msg)

if __name__ == "__main__":

app.run(host='localhost', port='8888' , debug=True, use_reloader=True)

---------------------------------执行结果-----------------------------------------
[{"status": "ACTIVE", "updated": "2022-10-11T07:22:43Z", "auto_terminate_time": "", "hostId": "02165bdab1b973b122477b3a2312960a69ec9c2a8705f0537fbd581b", "OS-EXT-SRV-ATTR:host": "2165bdab1b973b122477b3a2312960a69ec9c2a8705f0537fbd581b", "addresses": {"600b8e93-fbaa-4119-87c2-87f0678dd189": [{"version": "4", "addr": "192.168.0.121", "OS-EXT-IPS:type": "fixed", "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:39:90:0a", "OS-EXT-IPS:port_id": "094b325b-6e0a-4161-937f-f6bb3f60bee3"}, {"version": "4", "addr": "124.71.205.227", "OS-EXT-IPS:type": "floating", "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:39:90:0a", "OS-EXT-IPS:port_id": "094b325b-6e0a-4161-937f-f6bb3f60bee3"}]}, "image": {"id": "f025bf3e-3173-4f2a-8f59-34aca5bd853d"}, "OS-EXT-STS:vm_state": "active", "OS-EXT-SRV-ATTR:instance_name": "instance-00da7649", "OS-EXT-SRV-ATTR:hypervisor_hostname": "2165bdab1b973b122477b3a2312960a69ec9c2a8705f0537fbd581b", "flavor": {"id": "c7.large.2", "name": "c7.large.2", "disk": "0", "vcpus": "2", "ram": "4096"}, "id": "d7747398-377b-4292-8529-20f62df56d82", "security_groups": [{"name": "Sys-FullAccess", "id": "b46f7f8c-5e1d-4e85-91c6-1ee43ce7c9a5"}], "OS-EXT-AZ:availability_zone": "cn-east-3a", "user_id": "e93823c6ea3d45429b3173aea1acdc8b", "name": "ecs-e364", "created": "2022-10-11T07:22:04Z", "tenant_id": "1ac80630a2494ca7bb05a7e0ebd82862", "OS-DCF:diskConfig": "MANUAL", "accessIPv4": "", "accessIPv6": "", "progress": 0, "OS-EXT-STS:power_state": 1, "config_drive": "", "metadata": {"image_name": "CentOS 7.9 64bit", "metering.resourcespeccode": "c7.large.2.linux", "charging_mode": "0", "vpc_id": "600b8e93-fbaa-4119-87c2-87f0678dd189", "os_type": "Linux", "metering.resourcetype": "1", "metering.image_id": "f025bf3e-3173-4f2a-8f59-34aca5bd853d", "os_bit": "64", "__support_agent_list": "hss,ces", "cascaded.instance_extrainfo": "pcibridge:1", "metering.imagetype": "gold"}, "OS-SRV-USG:launched_at": "2022-10-11T07:22:20.000000", "os-extended-volumes:volumes_attached": [{"id": "a2dc099c-1bc9-44bf-9496-6027a75f8091", "delete_on_termination": "true", "bootIndex": "0", "device": "/dev/sda"}], "description": "", "host_status": "UP", "OS-EXT-SRV-ATTR:hostname": "ecs-e364", "OS-EXT-SRV-ATTR:reservation_id": "r-flhxwpqc", "OS-EXT-SRV-ATTR:launch_index": 0, "OS-EXT-SRV-ATTR:kernel_id": "", "OS-EXT-SRV-ATTR:ramdisk_id": "", "OS-EXT-SRV-ATTR:root_device_name": "/dev/sda", "OS-EXT-SRV-ATTR:user_data": "IyEvYmluL2Jhc2gKZWNobyAncm9vdDokNiRQQ3pDUUVaNSRJUzFIbE5JbFBJN2VEUGg2WEpNNjJKTHcuclFpOG0uL1EvWUdNQUdKVjhsR2c3VmZ5VWhKTTRpcXpXVXI1MTBUVzROSnZoT2ZnRHlva0suMTdQZTNlLycgfCBjaHBhc3N3ZCAtZTs=", "locked": false, "tags": [], "os:scheduler_hints": {}, "enterprise_project_id": "0", "sys_tags": [{"key": "_sys_enterprise_project_id", "value": "0"}], "cpu_options": {}}]
d7747398-377b-4292-8529-20f62df56d82
{"server": {"status": "ACTIVE", "updated": "2022-10-11T07:22:43Z", "auto_terminate_time": "", "hostId": "02165bdab1b973b122477b3a2312960a69ec9c2a8705f0537fbd581b", "OS-EXT-SRV-ATTR:host": "2165bdab1b973b122477b3a2312960a69ec9c2a8705f0537fbd581b", "addresses": {"600b8e93-fbaa-4119-87c2-87f0678dd189": [{"version": "4", "addr": "192.168.0.121", "OS-EXT-IPS:type": "fixed", "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:39:90:0a", "OS-EXT-IPS:port_id": "094b325b-6e0a-4161-937f-f6bb3f60bee3"}, {"version": "4", "addr": "124.71.205.227", "OS-EXT-IPS:type": "floating", "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:39:90:0a", "OS-EXT-IPS:port_id": "094b325b-6e0a-4161-937f-f6bb3f60bee3"}]}, "image": {"id": "f025bf3e-3173-4f2a-8f59-34aca5bd853d"}, "OS-EXT-STS:vm_state": "active", "OS-EXT-SRV-ATTR:instance_name": "instance-00da7649", "OS-EXT-SRV-ATTR:hypervisor_hostname": "2165bdab1b973b122477b3a2312960a69ec9c2a8705f0537fbd581b", "flavor": {"id": "c7.large.2", "name": "c7.large.2", "disk": "0", "vcpus": "2", "ram": "4096"}, "id": "d7747398-377b-4292-8529-20f62df56d82", "security_groups": [{"name": "Sys-FullAccess", "id": "b46f7f8c-5e1d-4e85-91c6-1ee43ce7c9a5"}], "OS-EXT-AZ:availability_zone": "cn-east-3a", "user_id": "e93823c6ea3d45429b3173aea1acdc8b", "name": "ecs-e364", "created": "2022-10-11T07:22:04Z", "tenant_id": "1ac80630a2494ca7bb05a7e0ebd82862", "OS-DCF:diskConfig": "MANUAL", "accessIPv4": "", "accessIPv6": "", "progress": 0, "OS-EXT-STS:power_state": 1, "config_drive": "", "metadata": {"image_name": "CentOS 7.9 64bit", "metering.resourcespeccode": "c7.large.2.linux", "charging_mode": "0", "vpc_id": "600b8e93-fbaa-4119-87c2-87f0678dd189", "os_type": "Linux", "metering.resourcetype": "1", "metering.image_id": "f025bf3e-3173-4f2a-8f59-34aca5bd853d", "os_bit": "64", "__support_agent_list": "hss,ces", "cascaded.instance_extrainfo": "pcibridge:1", "metering.imagetype": "gold"}, "OS-SRV-USG:launched_at": "2022-10-11T07:22:20.000000", "os-extended-volumes:volumes_attached": [{"id": "a2dc099c-1bc9-44bf-9496-6027a75f8091", "delete_on_termination": "true", "bootIndex": "0", "device": "/dev/sda"}], "description": "", "host_status": "UP", "OS-EXT-SRV-ATTR:hostname": "ecs-e364", "OS-EXT-SRV-ATTR:reservation_id": "r-flhxwpqc", "OS-EXT-SRV-ATTR:launch_index": 0, "OS-EXT-SRV-ATTR:kernel_id": "", "OS-EXT-SRV-ATTR:ramdisk_id": "", "OS-EXT-SRV-ATTR:root_device_name": "/dev/sda", "OS-EXT-SRV-ATTR:user_data": "IyEvYmluL2Jhc2gKZWNobyAncm9vdDokNiRQQ3pDUUVaNSRJUzFIbE5JbFBJN2VEUGg2WEpNNjJKTHcuclFpOG0uL1EvWUdNQUdKVjhsR2c3VmZ5VWhKTTRpcXpXVXI1MTBUVzROSnZoT2ZnRHlva0suMTdQZTNlLycgfCBjaHBhc3N3ZCAtZTs=", "locked": false, "tags": [], "os:scheduler_hints": {}, "enterprise_project_id": "0", "sys_tags": [{"key": "_sys_enterprise_project_id", "value": "0"}], "cpu_options": {}}}