删除云服务器
# coding: utf8
import json
import re
import requests
import sys
class ExecError(Exception):
pass
class ServerAction(object):
def __init__(self, openstack_auth, user, password, project_info, region, domain=None,
notify=None):
self.version = \'v3\'
self.keystone_url = openstack_auth
self.region = region
self.user = user
self.password = password
if isinstance(project_info, str):
self.project_id = project_info
else:
self.project_id = getopenstack.Get_infos(project_info).get_project()[\'Y_systemID\']
self.domain = domain
self.notify = notify
self.token = self.get_token()
# print self.endpoints
def get_token(self):
if self.version>= \'v3\':
data = {"auth": {"identity": {"methods": ["password"], "password":
{"user": {"name": self.user, "password": self.password, "domain": {
"name": self.domain}}}},
"scope": {"project": {"name": self.project_id}}}}
url = self.keystone_url + \'/{}/auth/tokens\'.format(self.version)
else:
data = {"auth": {"tenantName": str(self.project_id), "passwordCredentials":
{"username": str(self.user), "password": str(self.password)}}}
url = self.keystone_url + \'/{}/tokens\'.format(self.version)
data = json.dumps(data)
if self.version >= \'v3\':
res = requests.post(url, data=data)
if res.status_code == 201:
content = json.loads(res.content)
self.endpoints = content[\'token\'][\'catalog\']
self.tenant_id = content[\'token\'][\'project\'][\'id\']
if self.notify:
print \'身份认证请求成功\'
return res.headers[\'X-Subject-Token\']
else:
raise ExecError(\'身份认证请求失败\')
else:
status, res = fetch_res(url, action=\'post\', data=data, get_status=True, use_token=None)
if status == 200:
res = json.loads(res)
self.endpoints = res[\'access\'][\'serviceCatalog\']
self.tenant_id = res[\'token\'][\'project\'][\'id\']
res = res[\'access\'][\'token\'][\'id\']
if self.notify:
print \'身份认证请求成功\'
return res
else:
raise ExecError(\'身份认证请求失败\')
def post_action(self, data, type=\'action\', add_url=None):
if type == \'action\':
url = self.server_url
else:
url = self.get_host(type=type)
if add_url:
url = url.strip(\'https://\')
url = \'https://\' + url.split(\'/\')[0] + \'/v1/{}\'.format(self.tenant_id)
url += add_url
data = json.dumps(data)
print data, url
return fetch_res(url, use_token=self.token, action=\'post\', data=data, get_status=True)
def delete_action(self, type=None, add_url=\'\'):
url = self.get_host(type=type)
if add_url:
url += add_url
return fetch_res(url, use_token=self.token, action=\'delete\',
get_status=True)
def get_action(self, type=None, add_url=\'\'):
url = self.get_host(type=type)
if add_url:
url += add_url
return fetch_res(url, use_token=self.token, action=\'get\',
get_status=True)
def put_action(self, data, type=None, add_url=\'\'):
url = self.get_host(type=type)
if add_url:
url += add_url
data = json.dumps(data)
return fetch_res(url, use_token=self.token, action=\'put\', data=data,
get_status=True)
def get_host(self, type=None):
hosts = {}
for endpoint in self.endpoints:
# print endpoint
for i in endpoint[\'endpoints\']:
if i[\'region\'] == self.region or i[\'region\'] == \'*\':
try:
if self.version>= \'v3\':
url = i[\'url\']
else:
url = i[\'url\']
except:
url = \'\'
hosts.update({endpoint[\'name\']: url})
if hosts[type] == \'\':
print \'url未取到\'
# print hosts
return hosts[type]
def fetch_res(url, use_token=None, action=\'get\', data=None, get_content=False, get_status=False):
if use_token:
header = {\'X-Auth-Token\': use_token, \'Content-Type\': \'application/json\'}
else:
header = {\'Content-Type\': \'application/json\'}
res = getattr(requests, action.lower())(url, headers=header, data=data)
if get_status:
return res.status_code, res.content
if get_content:
return res.content
else:
if res.status_code != 200:
raise ExecError(\'请求发送失败:{}\'.format(res.content))
else:
return res.content
def del_vm(openstack_auth=None, project_info=None, domain=None,
user=None, password=None, region=None,
server_id=None, delete_publicip=None, delete_volume=None,
**kwargs):
try:
if delete_publicip==\'true\':
delete_publicip=True
else:
delete_publicip=False
if delete_volume==\'true\':
delete_volume = True
else:
delete_volume = False
data = {
"servers": [
{
"id": server_id
}
],
"delete_publicip": delete_publicip,
"delete_volume": delete_volume
}
print data
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain, notify=True). \
post_action(data, type=\'nova\', add_url=\'/cloudservers/delete\')
if status == 200:
print \'正在删除……\'
while 1:
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain, notify=False). \
get_action(type=\'nova\',
add_url=\'/servers/{server_id}\'.format(server_id=server_id))
if status == 200:
continue
elif status == 404 and json.loads(res).has_key("itemNotFound"):
return {\'success\': True, \'message\': \'云服务器删除成功\'}
else:
return {\'success\': False, \'message\': \'云服务器删除失败:{}\'.format(res)}
else:
return {\'success\': False, \'message\': \'云服务器删除失败:{}\'.format(res)}
except Exception as e:
return {\'success\': False, \'message\': \'云服务器删除失败:{}\'.format(e)}
if __name__ == \'__main__\':
vm_info = del_vm(openstack_auth=AUTH_URL, project_info=project_name,
domain=domain, user=user, password=password,
region=region, server_id=server_id, delete_volume=delete_volume,
delete_publicip=delete_publicip)
print vm_info[\'message\']
if not vm_info[\'success\']:
ExitCode = -1
创建虚拟私有云
def create_vpc(openstack_auth=None, project_info=None, domain=None, user=None, password=None,
region=None,vpc_name=None,cidr=None,
**kwargs):
try:
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain).get_action(type=\'neutron\')
#print status, res
vpc_id = None
if status == 200:
vpcs=json.loads(res)[\'vpcs\']
for vpc in vpcs:
if vpc[\'name\']==vpc_name:
vpc_id=vpc[\'id\']
if vpc_id:
return {\'success\': True, \'message\': \'虚拟私有云id为:{}\'.format(vpc_id),\'outputParam\': vpc_id}
data={"vpc":
{
"name": vpc_name,
"cidr": cidr
}
}
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain).post_action(data,type=\'neutron\')
#print status, res
if status == 200:
vpc_id=json.loads(res)[\'vpc\'][\'id\']
return {\'success\': True, \'message\': \'虚拟私有云id为:{}\'.format(vpc_id), \'outputParam\': vpc_id}
else:
return {\'success\': False, \'message\': \'虚拟云创建失败:{}\'.format(res)}
except Exception as e:
return {\'success\': False, \'message\': \'虚拟云创建失败:{}\'.format(e)}
获取实例IP
def get_vm(openstack_auth=None, project_info=None, domain=None,user=None,password=None,
region=None,vmname=None,vpc_id=None,
**kwargs):
try:
status, res = ServerAction(openstack_auth, user,password, project_info,region,
domain=domain,notify=True).get_action(type=\'nova\',add_url=\'/servers\')
#print status, res
if status == 200:
servers = json.loads(res)[\'servers\']
for i in servers:
if i[\'name\']==vmname:
server_id=i[\'id\']
if server_id:
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain, notify=True).get_action(type=\'nova\',
add_url=\'/servers/{}\'.format(server_id))
if status == 200:
ips = json.loads(res)[\'server\'][\'addresses\'].get(vpc_id, None)
if ips:
ip = ips[0][\'addr\']
else:
ip = None
if ip:
return {\'success\': True, \'message\': \'实例ip为:{}\'.format(ip),
\'outputParam\': ip,\'id\':server_id}
else:
return {\'success\': False, \'message\': \'查询实例ip失败:{}\'.format(res)}
else:
return {\'success\': False, \'message\': \'查询实例ip失败:{}\'.format(res)}
except Exception as e:
return {\'success\': False, \'message\': \'查询实例ip失败:{}\'.format(e)}
虚拟机启停
def stop_vm(openstack_auth=None, project_info=None,
domain=None, user=None, password=None, region=None, server_id=None, **kwargs):
try:
data={"os-stop": {}}
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain,notify=True). \
post_action(data, type=\'nova\',
add_url=\'/servers/{server_id}/action\'.format(server_id=server_id))
if status == 200:
return {\'success\': True, \'message\': \'虚拟机关闭成功\'}
elif status == 202:
while 1:
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain,notify=False). \
get_action(type=\'nova\',
add_url=\'/servers/{server_id}\'.format(server_id=server_id))
server_status = json.loads(res)[\'server\'][\'status\']
if status==200:
if server_status==\'ACTIVE\':
continue
elif server_status==\'SHUTOFF\':
return {\'success\': True, \'message\': \'虚拟机关闭成功\'}
else:
return {\'success\': False, \'message\': \'虚拟机关闭失败:{}\'.format(res)}
else:
return {\'success\': False, \'message\': \'虚拟机关闭失败:{}\'.format(res)}
else:
return {\'success\': False, \'message\': \'虚拟机关闭失败:{}\'.format(res)}
except Exception as e:
return {\'success\': False, \'message\': \'虚拟机关闭失败:{}\'.format(e)}
创建子网
def create_subnet(openstack_auth=None, project_info=None, domain=None, user=None, password=None,
region=None,vpc_id=None,cidr=None,availability_zone=None,
subnet_name=None,gateway_ip=None,primary_dns=None,secondary_dns=None,
dhcp_enable=None,subnet_id=None,availability_zone_order=None,
**kwargs):
try:
subnet_id=None
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain).\
get_action(type=\'neutron\',add_url=\'/subnets?vpc_id={}\'.format(vpc_id))
# print status, res
if status == 200:
subnets = json.loads(res)[\'subnets\']
# print res
for subnet in subnets:
if subnet[\'name\'] == subnet_name:
subnet_id = subnet[\'id\']
if subnet_id:
return {\'success\': True, \'message\': \'虚拟云子网id为:{}\'.format(subnet_id),
\'outputParam\': subnet_id}
availability_zone = \'{}{}\'.format(region, chr(ord(\'a\') - 1 + int(availability_zone_order) % 26))
data={"subnet":
{
"name": subnet_name,
"cidr": cidr,
"gateway_ip": gateway_ip,
"dhcp_enable": dhcp_enable,
"availability_zone":availability_zone,
"vpc_id":vpc_id
}
}
if primary_dns:
data.update({"primary_dns":primary_dns})
if secondary_dns:
data.update({"secondary_dns":secondary_dns})
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain).post_action(data,type=\'neutron\')
#print status, res
if status == 200:
subnet_id=json.loads(res)[\'subnet\'][\'id\']
return {\'success\': True, \'message\': \'虚拟云子网id为:{}\'.format(subnet_id), \'outputParam\': subnet_id}
else:
return {\'success\': False, \'message\': \'虚拟云子网id创建失败:{}\'.format(res)}
except Exception as e:
return {\'success\': False, \'message\': \'虚拟云子网id创建失败:{}\'.format(e)}
查找可用分区
def get_availibility_zone_name(openstack_auth=AUTH_URL,project_info=project_name,
domain=domain,user=user,password=password,region=region,
availibility_zone_order=None,**kwargs):
try:
status, res = ServerAction(openstack_auth, user,password, project_info,region,
domain=domain).get_action(type=\'nova\',add_url=\'/os-availability-zone\')
#print status, res
if status == 200:
zones = json.loads(res)[\'availabilityZoneInfo\']
zone_name_req=\'{}{}\'.format(region , chr(ord(\'a\') - 1 + int(availibility_zone_order) % 26))
print zone_name_req
for zone in zones:
if zone[\'zoneName\']==zone_name_req and zone[\'zoneState\'][\'available\']:
zone_name=zone[\'zoneName\']
return {\'success\': True, \'message\': \'可用分区为:{}\'.format(zone_name), \'outputParam\': zone_name}
return {\'success\': False, \'message\': \'查找可用分区失败:{}\'.format(zones)}
else:
return {\'success\': False, \'message\': \'查找可用分区失败:{}\'.format(res)}
except Exception as e:
return {\'success\': False, \'message\': \'查找可用分区失败:{}\'.format(e)}
获取镜像
def get_image_id(openstack_auth=None,project_info=None,
domain=None,user=None,password=None,region=None,image_name=None,**kwargs):
try:
image_id=None
image_name=image_name.strip()
status, res = ServerAction(openstack_auth, user,password, project_info,region,
domain=domain).\
get_action(type=\'glance\',add_url=\'/v2/images?status=active&name={}\'.format(image_name))
#print status, res
if status == 200:
# print res
image_id = json.loads(res)[\'images\'][0][\'id\']
if image_id:
return {\'success\': True, \'message\': \'镜像id为:{}\'.format(image_id), \'outputParam\': image_id}
else:
return {\'success\': False, \'message\': \'查找镜像失败:{}\'.format(res)}
except Exception as e:
return {\'success\': False, \'message\': \'查找镜像失败:{}\'.format(e)}
获取虚拟机规格参数
def get_flavor_id(openstack_auth=AUTH_URL,project_info=project_name,
domain=domain,user=user,password=password,region=region,
minDisk=None,minRam=None,vcpus=None,flavor_name=None,**kwargs):
try:
add_url = \'/flavors\'
if minDisk or minRam:
add_url+=\'/detail?is_public=true&\'
if minDisk:
add_url +=\'minDisk=0&\'#.format(minDisk)
if minRam:
add_url += \'minRam={}\'.format(minRam)
add_url=add_url.strip(\'&\')
status, res = ServerAction(openstack_auth, user,password, project_info,region,
domain=domain).get_action(type=\'nova\',add_url=add_url)
#print status, res
if status == 200:
flavors = json.loads(res)[\'flavors\']
flavor_names=[]
for flavor in flavors:
flavor_names.append(flavor[\'name\'])
if flavor_name and flavor[\'name\']==flavor_name:
flavor_id=flavor[\'id\']
return {\'success\': True, \'message\': \'规格id为:{}\'.format(flavor_id), \'outputParam\': flavor_id}
flavor_infos={}
flavor_infos1={}
for flavor in flavors:
if flavor[\'vcpus\']==int(vcpus) and flavor[\'OS-FLV-EXT-DATA:ephemeral\']==0:
flavor_infos.update({flavor[\'id\']:flavor[\'name\']})
if flavor[\'vcpus\']>int(vcpus) and flavor[\'OS-FLV-EXT-DATA:ephemeral\']==0:
flavor_infos1.update({flavor[\'id\']:flavor[\'name\']})
if flavor_infos:
flavor_id=min(flavor_infos.items(), key=lambda x: x[1])[0]
return {\'success\': True, \'message\': \'规格id为:{}\'.format(flavor_id),
\'outputParam\': flavor_id}
if flavor_infos1:
flavor_id=min(flavor_infos1.items(), key=lambda x: x[1])[0]
return {\'success\': True, \'message\': \'规格id为:{}\'.format(flavor_id),
\'outputParam\': flavor_id}
return {\'success\': False, \'message\': \'查找规格失败,符合标准的有以下规格:{}\'.format(\',\'.join(flavor_names))}
else:
return {\'success\': False,\'message\': \'查找规格失败:{}\'.format(res)}
except Exception as e:
return {\'success\': False, \'message\': \'查找规格失败:{}\'.format(e)}
查找弹性ip
def get_publicip_id(openstack_auth=None, project_info=None,
domain=None, user=None, password=None, region=None,
**kwargs):
try:
publicip_id = None
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain). \
get_action(type=\'neutron\', add_url=\'/publicips\')
#print status, res
if status == 200:
res = json.loads(res)
for i in res[\'publicips\']:
if i[\'status\'] == \'DOWN\':
publicip_id = i[\'id\']
public_ip = i[\'public_ip_address\']
return {\'success\': True,
\'message\': \'弹性ip的id为:{},ip为{}\'.format(publicip_id, public_ip),
\'outputParam\': publicip_id, \'ip\': public_ip}
data = {"publicip": {"type": "5_bgp"},
"bandwidth": {"name": int(time.time()), "size": 1, "share_type": "PER"}}
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain). \
post_action(data, type=\'neutron\', add_url=\'/publicips\')
print status, res
if status == 200:
# print res
publicip_id = json.loads(res)[\'publicip\'][\'id\']
public_ip = json.loads(res)[\'publicip\'][\'public_ip_address\']
if publicip_id:
return {\'success\': True, \'message\': \'弹性ip的id为:{},ip为{}\'.
format(publicip_id, public_ip),
\'outputParam\': publicip_id, \'ip\': public_ip}
else:
return {\'success\': False, \'message\': \'查找弹性ip失败:{}\'.format(res)}
except Exception as e:
return {\'success\': False, \'message\': \'查找弹性ip失败:{}\'.format(e)}
创建云服务器
def create_vm(openstack_auth=None, project_info=None, domain=None, user=None, password=None,
region=None,
image_id=None, flavor_id=None, vm_name=None, adminPass=None, publicip_id=None,
subnet_id=None,
ip_address=None, vpc_id=None, volume_type=None, charge_mode=None,
availibility_zone_order=None, data_volume=None,
**kwargs):
try:
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain, notify=True).get_rest_action(type=\'nova\',
add_url=\'/servers\')
#print status, res
if status == 200:
servers = json.loads(res)[\'servers\']
for i in servers:
if i[\'name\'] == vm_name:
return {\'success\': False, \'message\': \'创建实例失败:该虚拟机名称已存在\'}
availibility_zone = \'{}{}\'.format(region, chr(ord(\'a\') - 1 + int(availibility_zone_order) % 26))
nics = {"subnet_id": subnet_id}
if ip_address:
nics.update({"ip_address": ip_address})
data = {"imageRef": image_id,
"flavorRef": flavor_id,
"name": vm_name,
"adminPass": adminPass,
"availability_zone": availibility_zone,
"vpcid": vpc_id,
"nics": [nics],
"key_name": "",
"personality": [],
"root_volume": {"volumetype": volume_type},
"extendparam": {"chargingMode": int(charge_mode)},
"count": 1,
"data_volumes": [{"volumetype": volume_type, "size": int(data_volume)}]
# "security_groups": [
# {
# "id": "7ec29785-2892-40fb-a572-12f7a012a0d4"
# }]
}
if publicip_id:
data.update({"publicip": {"id": publicip_id}})
data = {"server": data}
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain, notify=True).post_action(data, type=\'nova\',
add_url=\'/cloudservers\')
if status == 200:
print \'云服务器正在创建……\'
job_id = json.loads(res)[\'job_id\']
while status == 200:
status, res = ServerAction(openstack_auth, user, password, project_info, region,
domain=domain, notify=False).get_action(type=\'nova\',
add_url=\'/jobs/{}\'.format(
job_id))
if json.loads(res)[\'status\'] not in (\'RUNNING\', \'INIT\'):
break
# print status, res
if json.loads(res)[\'status\'] == \'SUCCESS\':
server_id = json.loads(res)[\'entities\'][\'sub_jobs\'][0][\'entities\'][\'server_id\']
return {\'success\': True, \'message\': \'实例创建成功,id为:{}\'.format(server_id),
\'outputParam\': server_id}
else:
return {\'success\': False, \'message\': \'创建实例失败:{}\'.format(res)}
else:
return {\'success\': False, \'message\': \'创建实例失败:{}\'.format(res)}
except Exception as e:
return {\'success\': False, \'message\': \'创建实例失败:{}\'.format(e)}