#coding=utf8
import json
import re
import requests
class ExecError(Exception):
pass
class ServerAction(object):
def __init__(self,openstack_auth,vm_info=None,volume_info=None):
#openstack_auth=openstack_auth.encode('utf8')
openstack = getopenstack.Get_infos(openstack_auth).get_openstack()
self.token = openstack['token']
self.server_url = openstack['nova_host'] + '/servers'
if vm_info:
self.vmid = getopenstack.Get_infos(vm_info).get_vm()['Y_systemID']
self.action_url = '{}/{}/action'.format(self.server_url, self.vmid)
self.volume_url = openstack['nova_host'] + '/os-volumes'
def post_action(self,data,type='action',add_url=None):
if type=='server':
url=self.server_url
elif type=='action':
url=self.action_url
elif type=='volume':
url=self.volume_url
if add_url:
url+=add_url
data = json.dumps(data)
return openstacklib.fetch_res(url, use_token=self.token, action='post',
data=data,get_status=True)
def delete_action(self):
server_url = self.server_url+'/'+self.vmid
return openstacklib.fetch_res(server_url, use_token=self.token, action='delete',
get_status=True)
def put_action(self,data):
data = json.dumps(data)
server_url = self.server_url+'/'+self.vmid
return openstacklib.fetch_res(server_url, use_token=self.token, action='put', data=data,
get_status=True)
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}
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 create_vm(openstack_auth=None,flavor_info=None, security_info=None,zone_info=None,
vmname=None,options=None,
**kwargs):
'''
:param openstack:
:param vmname:
:param image:
:param flavor: flavors 是用来定义一个nova计算实例的计算,存储能力的概念,也就是一台服务器可以获取的硬件参数。
:param options:
:param network:
:param security_group:
:param availability_zone:
:param kwargs:
:return:
'''
try:
openstack=getopenstack.Get_infos(openstack_auth).get_openstack()
flavor = getopenstack.Get_infos(flavor_info).get_flavor()['Y_systemID']
image= getopenstack.Get_infos(flavor_info).get_images()['Y_systemID']
availability_zone=getopenstack.Get_infos(zone_info).get_source()['Y_systemID']
if security_info:
security_group=getopenstack.Get_infos(security_info).get_images()
value = {"name": vmname, "imageRef": image, "flavorRef": flavor,
"availability_zone":availability_zone}
if options:
value.update(options)
data={"server": value}
status, res = ServerAction(openstack_auth).post_action(data,type='server')
if status==202:
return {'success': True, 'message': '实例创建成功'}
else:
return {'success': False, 'message': '创建实例失败:{}'.format(res)}
except Exception as e:
return {'success': False, 'message': '创建实例失败:{}'.format(e)}
def start_vm(openstack_auth=None, **kwargs):
try:
utils.logger.info('{}'.format(openstack_auth))
openstack = getopenstack.Get_infos(openstack_auth).get_openstack()
#TODO:tenant name and password
#tenantName=getopenstack.Get_infos(openstack_auth).get_openstack()
data={"auth": {"tenantName": "demo", "passwordCredentials":{"username": openstack['user'], "password": openstack['password']+'78'}}}
utils.logger.info('{} {}'.format(openstack['keystone_host']+'/tokens', data))
data=json.dumps(data)
status,res=fetch_res(openstack['keystone_host']+'/tokens', action='post', data=data, get_status=True)
print status,res
utils.logger.info('{} {}'.format(status,res))
if status==200:
return {'success': True, 'message': '成功'}
except Exception as e:
return {'success':False,'message':'启动vm实例失败:{}'.format(e)}
def start_vm_new(openstack_auth=None, vm_info=None, **kwargs):
try:
data={"os-start": None}
status, res = ServerAction(openstack_auth, vm_info=vm_info).post_action(data)
if status==202:
return {'success': True, 'message': '启动vm实例成功'}
else:
return {'success': False, 'message': '启动vm实例失败:{}'.format(res)}
except Exception as e:
return {'success':False,'message':'启动vm实例失败:{}'.format(e)}
def change_vm(openstack_auth=None,vm_info=None,config=None,**kwargs):
try:
status, res = ServerAction(openstack_auth, vm_info=vm_info).put_action(config)
if status == 200:
return {'success': True, 'message': '修改vm实例成功'}
else:
return {'success': False, 'message': '修改vm实例失败:{}'.format(res)}
except Exception as e:
return {'success':False,'message':'修改vm实例失败:{}'.format(e)}
def del_vm(openstack_auth=None,vm_info=None,**kwargs):
try:
status, res = ServerAction(openstack_auth, vm_info=vm_info).delete_action()
if status==204:
return {'success': True, 'message': '删除vm实例成功'}
else:
return {'success': False, 'message': '删除vm实例失败:{}'.format(res)}
except Exception as e:
return {'success':False,'message':'删除vm实例失败:{}'.format(e)}
def restart_vm(openstack_auth=None,vm_info=None,**kwargs):
try:
data = {"reboot": {"type": "HARD"}}
status, res = ServerAction(openstack_auth, vm_info=vm_info).post_action(data)
if status == 202:
return {'success': True, 'message': '重启vm实例成功'}
else:
return {'success': False, 'message': '重启vm实例失败:{}'.format(res)}
except Exception as e:
return {'success':False,'message':'重启vm实例失败:{}'.format(e)}
def stop_vm(openstack_auth=None,vm_info=None, **kwargs):
try:
data= {"os-stop": None}
status,res=ServerAction(openstack_auth,vm_info=vm_info).post_action(data)
if status == 202:
return {'success': True, 'message': '停止vm实例成功'}
else:
return {'success': False, 'message': '停止vm实例失败:{}'.format(res)}
except Exception as e:
return {'success':False,'message':'停止vm实例失败:{}'.format(e)}
def create_vm_snapshot(openstack_auth=None,vm_info=None,name=None,**kwargs):
try:
data = {"createImage": {"name": name}}
status, res = ServerAction(openstack_auth, vm_info=vm_info).post_action(data)
if status==200:
return {'success': True, 'message': '创建快照成功'}
else:
return {'success': False, 'message': '创建快照失败:{}'.format(res)}
except Exception as e:
return {'success':False,'message':'创建快照失败:{}'.format(e)}
def resize_vm(openstack_auth=None,vm_info=None,flavor_info=None,**kwargs):
try:
flavor_id=getopenstack.Get_infos(flavor_info).get_flavor()['Y_systemID']
data={"resize": {"flavorRef": flavor_id}}
status, res = ServerAction(openstack_auth, vm_info=vm_info).post_action(data)
if status != 202:
return {'success': False, 'message': '调整虚拟机失败:{}'.format(res)}
data = json.dumps({"confirmResize" : None})
status, res = ServerAction(openstack_auth, vm_info=vm_info).post_action(data)
if res==204:
return {'success': True, 'message': '调整虚拟机成功'}
else:
return {'success': False, 'message': '调整虚拟机失败:{}'.format(res)}
except Exception as e:
return {'success': False, 'message': '调整虚拟机失败:{}'.format(e)}
def create_volumn(openstack_auth=None,name=None,description=None,size=None,**kwargs):
'''
:param openstack:
:param availability_zone:
:param name:
:param description:
:param size: 单位GB
:param kwargs:
:return:
'''
try:
data= {"volume": {"size": size,"display_name": name, "display_description": description}}
status, res = ServerAction(openstack_auth).post_action(data,type='volume')
if status == 202:
return {'success': True, 'message': '创建存储卷成功'}
else:
return {'success': False, 'message': '创建存储卷失败:{}'.format(res)}
except Exception as e:
return {'success': False, 'message': '创建存储卷失败:{}'.format(e)}
def attach_volumn(openstack_auth=None,vm_info=None,volume_info=None,mountpoint=None,**kwargs):
try:
vmid = getopenstack.Get_infos(vm_info).get_vm()['Y_systemID']
volume_id= getopenstack.Get_infos(volume_info).get_vm()['Y_systemID']
data = {"volumeId": volume_id}
if mountpoint:
data["device"] = mountpoint
data = { "volumeAttachment": data}
status, res = ServerAction(openstack_auth).post_action(
data, type='server',add_url='/{}/os-volume_attachments'.format(vmid))
if status == 200:
return {'success': True, 'message': '挂载卷成功'}
else:
return {'success': False, 'message': '挂载卷失败:{}'.format(res)}
except Exception as e:
return {'success':False,'message':'挂载卷失败:{}'.format(e)}
def migrate_server(openstack_auth=None,vm_info=None,**kwargs):
try:
data = {"migrate": None}
status, res = ServerAction(openstack_auth, vm_info=vm_info).post_action(data)
# TODO:判断机器处于运行状态才算是迁移成功
if status == 202:
return {'success': True, 'message': '迁移成功'}
else:
return {'success': False, 'message': '迁移失败:{}'.format(res)}
except Exception as e:
return {'success': False, 'message': '迁移失败:{}'.format(e)}
def migrate_server_live(openstack_auth=None,vm_info=None,hypervisor_info=None,**kwargs):
try:
host = getopenstack.Get_infos(hypervisor_info).get_hypervisor()['Y_systemID']
#host为hostname
data = {"os-migrateLive": {"host": host,
"block_migration": True,"disk_over_commit":True}}
status, res = ServerAction(openstack_auth, vm_info=vm_info).post_action(data)
if status == 202:
return {'success': True, 'message': '热迁移成功'}
else:
return {'success': False, 'message': '热迁移失败:{}'.format(res)}
except Exception as e:
return {'success': False, 'message': '热迁移失败:{}'.format(e)}
def remove_fix_ip(openstack_auth=None,vm_info=None,publicnet_info=None,**kwargs):
try:
public_net = getopenstack.Get_infos(publicnet_info).get_publicnet()
data={"removeFixedIp": {"address": "10.1.57.3"}}
status, res = ServerAction(openstack_auth, vm_info=vm_info).post_action(data)
if status == 202:
return {'success': True, 'message': '移除指定端口成功'}
else:
return {'success': False, 'message': '移除指定端口失败:{}'.format(res)}
except Exception as e:
return {'success': False, 'message': '移除指定端口失败:{}'.format(e)}
def add_fix_ip(openstack_auth=None, vm_info=None, publicnet_info=None, **kwargs):
try:
public_net = getopenstack.Get_infos(publicnet_info).get_publicnet()
data = {"addFixedIp": {"networkId": public_net['Y_systemID']}}
status, res = ServerAction(openstack_auth, vm_info=vm_info).post_action(data)
if status == 202:
return {'success': True, 'message': '添加指定地址成功'}
else:
return {'success': False, 'message': '添加指定地址失败:{}'.format(res)}
except Exception as e:
return {'success': False, 'message': '添加指定地址失败:{}'.format(e)}