#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)}