def insert_log(*argv, **kwargs): user = user_service.get_user() res = func(*argv, **kwargs) try: tmp = json.loads(res.data) except: return res if tmp["code"] == ErrorCode.SUCCESS: operation_result = "SUCCESS" elif tmp["code"] == ErrorCode.SUCCESS_PART: operation_result = "SUCCESS_PART" else: operation_result = "FAILED" client_ip = request.headers.get('X-Forwarded-For', '') insert_data = { "operator": user["user_id"], "operator_ip": client_ip, "operation_object": operation_object, "operation_action": operation_action, "operation_date": time_helper.get_datetime_str(), "operation_result": operation_result, "extra_data": "" } OperationService().insert_operation(insert_data) return res
def insert_log(*argv, **kwargs): user = user_service.get_user() res = func(*argv, **kwargs) instance_data = "" try: tmp = json.loads(res.data) instance_data += (';').join( Global_define().get_value('vm_list')) except: return res if tmp["code"] == ErrorCode.SUCCESS: operation_result = "SUCCESS" elif tmp["code"] == ErrorCode.SUCCESS_PART: operation_result = "SUCCESS_PART" else: operation_result = "FAILED" try: instance_data += " ErrorMsg:" + tmp["msg"] except: pass client_ip = request.headers.get('X-Forwarded-For', '') insert_data = { "operator": user["user_id"], "operator_ip": client_ip, "operation_object": operation_object, "operation_action": operation_action, "operation_date": time_helper.get_datetime_str(), "operation_result": operation_result, "extra_data": "" + instance_data } OperationService().insert_operation(insert_data) return res
def insert_log(*argv, **kwargs): user = user_service.get_user() res = func(*argv, **kwargs) datacenter_data = "" try: tmp = json.loads(res.data) if operation_action == OperationAction.ADD: # 新增机房 area_id = json.dumps(kwargs['area_id']) name = request.values.get('name') address = request.values.get('address') description = request.values.get('description') dc_type = request.values.get('dc_type') province = request.values.get('province') datacenter_data += "name:" + name + "," + "area_id:" + area_id + "," + "dc_type:" + dc_type + "," \ + "province:" + province + "," + "address:" + address + "," \ + "description:" + description + ";" elif operation_action == OperationAction.ALTER: # 修改机房 datacenter_id = json.dumps(kwargs['datacenter_id']) name = request.values.get('name') province = request.values.get('province') address = request.values.get('address') description = request.values.get('description') datacenter_data += "name:" + name + "," + "datacenter_id:" + datacenter_id + "," \ + "province:" + province + "," + "address:" + address + "," \ + "description:" + description + ";" elif operation_action == OperationAction.DELETE: # 删除机房 datacenter_ids = request.values.get('datacenter_ids') datacenter_data += "datacenter_ids:" + datacenter_ids + ";" else: pass except: return res if tmp["code"] == ErrorCode.SUCCESS: operation_result = "SUCCESS" elif tmp["code"] == ErrorCode.SUCCESS_PART: operation_result = "SUCCESS_PART" else: operation_result = "FAILED" try: datacenter_data += " ErrorMsg:" + tmp["msg"] except: pass client_ip = request.headers.get('X-Forwarded-For', '') insert_data = { "operator": user["user_id"], "operator_ip": client_ip, "operation_object": operation_object, "operation_action": operation_action, "operation_date": time_helper.get_datetime_str(), "operation_result": operation_result, "extra_data": "" + datacenter_data } OperationService().insert_operation(insert_data) return res
def insert_log(*argv, **kwargs): user = user_service.get_user() res = func(*argv, **kwargs) ip_data = "" try: tmp = json.loads(res.data) if operation_action == OperationAction.IP_APPLY: # 申请IP env = request.values.get('env') net_area = request.values.get('net_area') net_name = request.values.get('segment') cluster_id = request.values.get('cluster_id') opuser = request.values.get('opUser') sys_code = request.values.get('sys_code') datacenter = request.values.get('datacenter') ip_data += "env:" + env + "," + "net_area:" + net_area + "," \ + "net_name:" + net_name + "," + "cluster_id:" + cluster_id + "," \ + "opuser:"******"," + "sys_code:" + sys_code + "," \ + "datacenter:" + datacenter + "," + "vip:" + tmp["data"]["vip"] + ";" elif request.values.get( 'ip_address'): # 初始化IP、取消初始化IP、保留IP、取消保留IP ip_address = request.values.get('ip_address') ip_data += "ip_address:" + ip_address + ";" elif request.values.get('begin_ip') and request.values.get( 'end_ip'): # 批量操作(4种) begin_ip = request.values.get('begin_ip') end_ip = request.values.get('end_ip') ip_data += "begin_ip:" + begin_ip + "," + "end_ip:" + end_ip + ";" else: pass except: return res if tmp["code"] == ErrorCode.SUCCESS: operation_result = "SUCCESS" elif tmp["code"] == ErrorCode.SUCCESS_PART: operation_result = "SUCCESS_PART" else: operation_result = "FAILED" try: ip_data += " ErrorMsg:" + tmp["msg"] except: pass client_ip = request.headers.get('X-Forwarded-For', '') insert_data = { "operator": user["user_id"], "operator_ip": client_ip, "operation_object": operation_object, "operation_action": operation_action, "operation_date": time_helper.get_datetime_str(), "operation_result": operation_result, "extra_data": "" + ip_data } OperationService().insert_operation(insert_data) return res
def insert_log(*argv, **kwargs): user = user_service.get_user() res = func(*argv, **kwargs) hostpool_data = "" try: tmp = json.loads(res.data) if operation_action == OperationAction.ADD: # 新增集群 net_area_id = json.dumps(kwargs['net_area_id']) least_host_num = request.values.get('least_host_num') name = request.values.get('name') hostpool_data += "name:" + name + "," + "net_area_id:" + net_area_id + "," \ + "least_host_num:" + least_host_num + ";" elif operation_action == OperationAction.ALTER: # 修改集群 name = request.values.get('name') least_host_num = request.values.get('least_host_num') hostpool_id = json.dumps(kwargs['hostpool_id']) hostpool_data += "name:" + name + "," + "hostpool_id:" + hostpool_id + "," \ + "least_host_num:" + least_host_num + ";" elif operation_action == OperationAction.DELETE: # 删除集群 hostpool_ids = request.values.get('hostpool_ids') hostpool_data += "net_area_ids:" + hostpool_ids + ";" else: pass except: return res if tmp["code"] == ErrorCode.SUCCESS: operation_result = "SUCCESS" elif tmp["code"] == ErrorCode.SUCCESS_PART: operation_result = "SUCCESS_PART" else: operation_result = "FAILED" try: hostpool_data += " ErrorMsg:" + tmp["msg"] except: pass client_ip = request.headers.get('X-Forwarded-For', '') insert_data = { "operator": user["user_id"], "operator_ip": client_ip, "operation_object": operation_object, "operation_action": operation_action, "operation_date": time_helper.get_datetime_str(), "operation_result": operation_result, "extra_data": "" + hostpool_data } OperationService().insert_operation(insert_data) return res
def datacenter_list(): params = { 'page_size': request.values.get('page_size', 20), 'page_no': request.values.get('page_no', 1), } # 通过user_id,传回该user所拥有权限的所有datacenter list total_nums, data = datacenter.user_datacenter_list( get_user()['user_id'], current_user_all_area_ids(), **params) resp = DatacenterListResp() resp.total = total_nums for i in data: _datacenter_info = datacenter_info.DataCenterInfo().init_from_db(i) resp.rows.append(_datacenter_info) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=resp.to_json())
def insert_log(*argv, **kwargs): user = user_service.get_user() res = func(*argv, **kwargs) area_data = "" try: tmp = json.loads(res.data) if operation_action == OperationAction.ADD: # 新增区域 name = request.values.get('name') manager = request.values.get('manager') parent_id = request.values.get('parent_id') area_data += "name:" + name + "," + "manager:" + manager + "," + "parent_id:" + parent_id + ";" elif operation_action == OperationAction.ALTER: # 修改区域 name = request.values.get('name') manager = request.values.get('manager') area_id = json.dumps(kwargs['area_id']) area_data += "name:" + name + "," + "manager:" + manager + "," + "area_id:" + area_id + ";" elif operation_action == OperationAction.DELETE: # 删除区域 area_ids = request.values.get('area_ids') area_data += "area_ids:" + area_ids + ";" else: pass except: return res if tmp["code"] == ErrorCode.SUCCESS: operation_result = "SUCCESS" elif tmp["code"] == ErrorCode.SUCCESS_PART: operation_result = "SUCCESS_PART" else: operation_result = "FAILED" try: area_data += " ErrorMsg:" + tmp["msg"] except: pass client_ip = request.headers.get('X-Forwarded-For', '') insert_data = { "operator": user["user_id"], "operator_ip": client_ip, "operation_object": operation_object, "operation_action": operation_action, "operation_date": time_helper.get_datetime_str(), "operation_result": operation_result, "extra_data": "" + area_data } OperationService().insert_operation(insert_data) return res
def group_list(): ''' 查询组列表,不传参直接返回所有group列表,传参owner或者group_name筛选group列表 ''' search = request.values.get('search') params = { 'WHERE_AND': { '=': { 'isdeleted': '0' }, 'like': { 'name': None, 'owner': None, 'user_id': None } }, 'page_size': request.values.get('page_size', 20), 'page_no': request.values.get('page_no', 1), } if search: json_search = json.loads(search) owner = json_search.get('owner') if owner: params['WHERE_AND']['like']['owner'] = '%' + owner + '%' group_name = json_search.get('group_name') if group_name: params['WHERE_AND']['like']['name'] = '%' + group_name + '%' user_id = json_search.get('user_id') if user_id: params['WHERE_AND']['like']['user_id'] = '%' + user_id + '%' # 超级管理员组内的成员可以看到所有组 user_groups_num, user_groups_data = user_g_s.UserGroupService().get_allgroup_user(get_user()['user_id']) super_group_flag = False for _user_group in user_groups_data: if _user_group['group_name'] == "supergroup": super_group_flag = True break total_nums, data = group.user_group_list(get_user()['user_id'], is_super_group=super_group_flag, **params) resp = GroupListResp() resp.total = total_nums for i in data: _user_info = group_info.GroupInitInfo().init_from_db(i) resp.rows.append(_user_info) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=resp.to_json())
def net_area_list(): ''' :return: 这个接口返回3个字段,网络区域的名称,网络区域所属的机房名称,网络区域下所有的集群数量 ''' kwargs = { 'page_size': request.values.get('page_size', 20), 'page_no': request.values.get('page_no', 1), } total_nums, data = net_area.user_net_area_list(get_user()['user_id'], **kwargs) resp = NetAreaListResp() resp.total = total_nums for i in data: _net_area_info = net_area_info.NetAreaInfo().net_area_info(i) dict = classToDict(_net_area_info) net_area_id = i['net_area_id'] res,imagecache_list = imca_s.get_imagecache_list_by_net_area_id(net_area_id) if res: dict["imagecache_list"] = imagecache_list else: dict["imagecache_list"] = "获取失败" resp.rows.append(dict) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=resp.to_json())
def delete_group(group_id): ''' 删除用户组的流程:查询instance_group表,如果group在表中,就在tb_group表中将group的isdeleted改为1, 然后在user_group表中删除所有group_id的行,在access表中删除group信息 如果group不在instance_group表中,则直接删除group ''' def _check_ins_exist_in_group(group_id): ''' 检查组下是否有VM :param group_id: :return: ''' instances = ins_s.get_instances_in_group(group_id) if len(instances) > 0: return True return False if not group_id: logging.info('no group_id when delete group') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) group_num, group_data = group_s.GroupService().get_group_info(group_id) if group_num <= 0: logging.error('no group %s info in db when delete group', group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 只能超级管理员组成员和组所有者才能删除,超级管理员组ID为1 user_group_ids = current_user_group_ids() if group_data[0]['owner'] != get_user( )['user_id'] and 1 not in user_group_ids: logging.error( 'only allow super group member or group owner %s to delete group %s', group_data[0]['owner'], group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='您没有权限删除该应用组!') # 该应用组下没有VM才能删除 if _check_ins_exist_in_group(group_id): logging.error( 'no allow delete group %s which has vms when delete group', group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='该应用组分配有虚拟机,不能删除该组!') # 删除access中所有group_id的数据,然后插入前端提交的数据 delete_access = access.delete_access_info(group_id) if delete_access < 0: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) rest = ins_g_s.InstanceGroupService().query_data( where_field="group_id", where_field_value=group_id) # 如果instance_group表中没有group_id,就直接在group表中删除它 if not rest: group.delete_group(group_id) else: update_data = {'isdeleted': '1', 'deleted_at': get_datetime_str()} where_data = { 'id': group_id, } ret = group_s.update_group_info(update_data, where_data) if ret < 0: logging.error("update group error, update_data:%s, where_data:%s", str(update_data), str(where_data)) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 不管group在不在Instance_group表中,都删除它下面的所有用户 delete_users = user_g_s.delete_users_in_group(group_id) if delete_users < 0: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def update_group(group_id): ''' 修改应用组信息 :param group_id: :return: ''' name_n = request.values.get('name') owner_n = request.values.get('owner') cpu_n = request.values.get('cpu') mem_n = request.values.get('mem') disk_n = request.values.get('disk') vm_n = request.values.get('vm') area_str_n = request.values.get('area_str') role_id_c = request.values.get('role_id') p_cluster_id = request.values.get('p_cluster_id') if not cpu_n or not mem_n or not disk_n or not vm_n or not area_str_n or not role_id_c: logging.info('param is invalid when update group') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) group_num_c, group_data_c = group_s.GroupService().get_group_info(group_id) if group_num_c <= 0: logging.error('no group %s info when update group', group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) update_data = { 'cpu': cpu_n, 'mem': mem_n, 'disk': disk_n, 'vm': vm_n, 'updated_at': get_datetime_str() } # 只能超级管理员组成员和组所有者才能修改组名和所有者,超级管理员组ID为1 user_group_ids = current_user_group_ids() if group_data_c[0]['owner'] != get_user( )['user_id'] and 1 not in user_group_ids: if name_n or owner_n: logging.error( 'only allow super group member or group owner %s to update group %s name or owner', group_data_c[0]['owner'], group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='您没有权限修改该应用组的组名和所有者!') if name_n: if group_data_c[0]['name'] != name_n and _check_duplicated_group_name( name_n): logging.error('duplicated group name %s when update group', name_n) return json_helper.format_api_resp(code=ErrorCode.DUPLICATED_ERR, msg="应用组名不能重复,请更改应用组名!") update_data['name'] = name_n if owner_n: # 新所有者一定要在该应用组里 group_user_num, group_user_data = user_g_s.UserGroupService( ).get_alluser_group(group_id) in_group_flag = False for _group in group_user_data: if _group['user_id'] == owner_n: in_group_flag = True break if not in_group_flag: logging.error( 'new owner %s must exist in group %s when update group', owner_n, group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='应用组新所有者必须属于该组,请先添加入组!') update_data['owner'] = owner_n if p_cluster_id: update_data['p_cluster_id'] = p_cluster_id where_data = { 'id': group_id, } ret = group_s.update_group_info(update_data, where_data) if ret < 0: logging.error("update group error, update_data:%s, where_data:%s", str(update_data), str(where_data)) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 删除access中所有group_id的数据,然后插入前端提交的数据 delete_access = access.delete_access_info(group_id) if delete_access < 0: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) ret_result = access_service.add_access_list(int(group_id), int(role_id_c), str(area_str_n)) if ret_result < 0: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def instance_list(): ''' 获取虚机列表 :return: ''' params = { 'WHERE_AND': { '=': { 'status': None }, 'like': { 'name': None, 'uuid': None, 'owner': None }, 'in': { 'id': None } }, 'search_in_flag': 0, 'page_size': request.values.get('page_size'), 'page_no': request.values.get('page_no'), } logging.info('-------------------------------1') ip_search_type = "" search = request.values.get('search') if search: json_search = json.loads(search) name = json_search.get('name') if name: params['WHERE_AND']['like']['name'] = '%' + name + '%' uuid = json_search.get('uuid') if uuid: params['WHERE_AND']['like']['uuid'] = '%' + uuid + '%' instance_id_list_all = [] ip_address = json_search.get('ip_address') if ip_address: ip_search_type = json_search.get("ip_search_type") params['search_in_flag'] = 1 # 先模糊查询IP地址对应的实例ID search_ip_data = ins_s.get_instances_by_fuzzy_ip( ip_address, ip_search_type) instance_id_list = [i['instance_id'] for i in search_ip_data] instance_id_list_all.append(instance_id_list) # if instance_id_list: # params['WHERE_AND']['in']['id'] = tuple(instance_id_list) host_ip = json_search.get('host_ip') if host_ip: params['search_in_flag'] = 1 # 先模糊查询host IP对应的实例ID search_ip_data = ins_s.get_instances_by_fuzzy_host_ip(host_ip) instance_id_list = [i['instance_id'] for i in search_ip_data] instance_id_list_all.append(instance_id_list) # if instance_id_list: # params['WHERE_AND']['in']['id'] = tuple(instance_id_list) status = json_search.get('status') if status: params['WHERE_AND']['=']['status'] = status owner = json_search.get('owner') if owner: params['WHERE_AND']['like']['owner'] = '%' + owner + '%' group_name = json_search.get('group_name') if group_name: params['search_in_flag'] = 1 # 先模糊查询应用组对应的实例ID search_group_data = ins_s.get_instances_by_fuzzy_group_name( group_name) instance_id_list = [i['instance_id'] for i in search_group_data] instance_id_list_all.append(instance_id_list) # if instance_id_list: # params['WHERE_AND']['in']['id'] = tuple(instance_id_list) # 新增关联表查询是需要编写以下逻辑 if instance_id_list_all: if len(instance_id_list_all) == 1: params['WHERE_AND']['in']['id'] = tuple( instance_id_list_all[0]) if len(instance_id_list_all) == 2: params['WHERE_AND']['in']['id'] = tuple( list( set(instance_id_list_all[0]).intersection( set(instance_id_list_all[1])))) if len(instance_id_list_all) == 3: r1 = list( set(instance_id_list_all[0]).intersection( set(instance_id_list_all[1]))) r2 = list(set(r1).intersection(set(instance_id_list_all[2]))) params['WHERE_AND']['in']['id'] = tuple(r2) logging.info('-------------------------------2') # 系统管理员能看到其组所在区域的所有VM role_ids = current_user_role_ids() # 系统管理员 if 1 in role_ids: is_admin = True else: is_admin = False logging.info('-------------------------------3{}'.format( get_user()['user_id'])) total_nums, data = instance.user_instance_list(get_user()['user_id'], is_admin, ip_search_type, **params) logging.info('-------------------------------77{}'.format(total_nums)) resp = InstanceListResp() resp.total = total_nums logging.info('-------------------------------4') for i in data: _instance_info = instance_info.InstanceInfo().user_instance(i) _instance_group = ins_s.get_group_of_instance(i['id']) if _instance_group: _instance_info.app_group = _instance_group['name'] _instance_info.app_group_id = _instance_group['group_id'] resp.rows.append(_instance_info) resp = resp.to_json() logging.info('-------------------------------5{}'.format(resp)) if ip_search_type: resp["rows"].sort(lambda x, y: cmp( ''.join([i.rjust(3, '0') for i in x['ip_address'].split('.')]), ''. join([i.rjust(3, '0') for i in y['ip_address'].split('.')]))) if params.get('page_no') and params.get('page_size'): page_no = int(params['page_no']) page_size = int(params['page_size']) resp["rows"] = resp["rows"][(page_no - 1) * page_size:page_no * page_size] return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=resp)
def instance_hot_migrate(instance_id, host_id): ''' 虚拟机迁移 :param instance_id: :param host_id: :return: ''' speed_limit = request.values.get('speed_limit') if not instance_id or not host_id or not speed_limit or int( speed_limit) < 0: logging.info('the params is invalid when migrate instance') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="参数错误") host_data_s = ins_s.get_host_of_instance(instance_id) if not host_data_s: logging.error( 'instance %s of host is not exist in db when migrate instance', str(instance_id)) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) host_data_d = host_s.HostService().get_host_info(host_id) if not host_data_d: logging.error( 'target host %s is not exist in db when migrate instance', str(instance_id)) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) if host_data_d['typestatus'] == HostTypeStatus.LOCK or host_data_d[ 'typestatus'] == HostTypeStatus.MAINTAIN: logging.error( 'target host %s is in invalid status %s when migrate instance', host_id, host_data_d['typestatus']) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='不能迁移到锁定或维护的主机上') ins_flavor_data = ins_s.get_flavor_of_instance(instance_id) if not ins_flavor_data: logging.error('hot migrate can not get instance %s flavor info' % str(instance_id)) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='无法获取被迁移虚拟机的基础配置信息') ins_group = ins_g_s.InstanceGroupService().get_instance_group_info( instance_id) if not ins_group: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="无法获取虚拟机所在应用组信息") data_disk_status, data_disk_size = ins_s.get_data_disk_size_of_instance( instance_id) if not data_disk_status: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="无法获取被迁移虚拟机磁盘配置信息") instance_disk_size = int( ins_flavor_data['root_disk_gb']) + int(data_disk_size) # 获取物理机所在资源池可用物理机数量 all_hosts_nums, all_hosts_data = host_s.HostService( ).get_available_hosts_of_hostpool(host_data_d["hostpool_id"]) if all_hosts_nums < 1: return False, '集群物理机资源不足,无法满足虚拟机迁移' host_data_d_before_match = [] host_data_d_before_match.append(host_data_d) # 过滤host # 这里不核对host的cpu型号 hosts_after_filter = host_s_s.migrate_filter_hosts( host_data_d_before_match, int(all_hosts_nums)) if len(hosts_after_filter) == 0: logging.info('no available host when get migrate host') return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="集群内其他物理机cpu、内存使用率超过阀值,暂时不能迁移") # VM分配给HOST看是否满足迁移 vm = { "vcpu": ins_flavor_data['vcpu'], "mem_MB": ins_flavor_data['memory_mb'], "disk_GB": instance_disk_size, } host_after_match = host_s_s.migrate_match_hosts(hosts_after_filter, vm, ins_group['group_id'], least_host_num=1, max_disk=2000) if len(host_after_match) == 0: logging.info('no available host when get migrate host') return json_helper.format_api_resp( code=ErrorCode.SYS_ERR, msg="集群内其他物理机cpu、内存资源不足或者应用互斥,暂时不能迁移") # 不能本身 if host_data_s['id'] == host_id: logging.error('no allow migrate to the same host %s', host_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="不能迁移到原主机上") ins_data_s = ins_s.InstanceService().get_instance_info(instance_id) if not ins_data_s: logging.error('instance %s is not exist in db when migrate instance') return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 排除非法状态,vm只能在开机状态下才能热迁移 if ins_data_s['status'] != VMStatus.STARTUP or ins_data_s[ 'typestatus'] != VMTypeStatus.NORMAL: logging.error( 'instance status %s, typestatus %s is invalid when migrate instance', ins_data_s['status'], ins_data_s['typestatus']) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='只能在关机状态下执行热迁移') # 检测目标主机是否有迁入VM if not _check_has_migrate(host_id): logging.error( 'dest host %s has other migrating instance when migrate instance', host_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='目标主机现有正在迁入的虚机,不能迁移到该主机') # 将VM状态改为热迁移中 update_data = { 'status': VMStatus.MIGRATE, # 热迁移中 'updated_at': get_datetime_str() } where_data = {'id': instance_id} ret = ins_s.InstanceService().update_instance_info(update_data, where_data) if ret != 1: logging.error( 'update instance status error when cold migrate, update_data:%s, where_data:%s', update_data, where_data) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) ins_data = ins_s.InstanceService().get_instance_info(instance_id) # 新增一个instance_dsthost记录,dsthost为目标host的ip # 迁移过程中失败则删除这条新增的Instance_dsthost记录,迁移成功之后则删除Instance_srchost记录 # 迁移过程中前端vm页面不会显示这条新增的记录 instance_host_data = { 'instance_id': instance_id, 'instance_name': ins_data['name'], 'host_id': host_id, 'host_name': host_data_d['name'], 'isdeleted': '0', 'created_at': get_datetime_str() } ret_h = ins_h_s.InstanceHostService().add_instance_host_info( instance_host_data) if ret_h.get('row_num') <= 0: logging.error( 'add instance host info error when hot migrate, %instance_id,%host_id' ) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 在instance_migrate表中增加一条数据 insert_data = { 'instance_id': instance_id, 'src_host_id': host_data_s['id'], 'dst_host_id': host_id, 'migrate_status': MigrateStatus.DOING, 'created_at': get_datetime_str() } ret_m = ins_m_s.InstanceMigrateService().add_instance_migrate_info( insert_data) if ret_m.get('row_num') <= 0: logging.error( 'add instance migrate info error when cold migrate, insert_data:%s', insert_data) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 发送异步消息到队列 data = { "routing_key": "INSTANCE.HOTMIGRATE", "send_time": get_datetime_str(), "data": { "request_id": ins_s.generate_req_id(), "user_id": get_user()['user_id'], "migrate_tab_id": ret_m.get('last_id'), "task_id": ins_s.generate_task_id(), "speed_limit": speed_limit, "ins_data_s": { "id": ins_data_s['id'], "uuid": ins_data_s['uuid'], "name": ins_data_s['name'] }, "host_data_d": { "id": host_data_d['id'], "name": host_data_d['name'], "ipaddress": host_data_d['ipaddress'] }, "host_data_s": { "id": host_data_s['id'], "name": host_data_s['name'], "ipaddress": host_data_s['ipaddress'], "sn": host_data_s['sn'] } } } # todo:这里有可能发送不成功 ret_kafka = send_async_msg(KAFKA_TOPIC_NAME, data) return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def instance_configure(instance_id): ''' 虚机修改配置 规则: 热修改(开机状态):cpu disk 加 冷修改(关机状态):cpu mem 加减 disk 加 :param instance_id: :return: ''' n_flavor_id = request.values.get('flavor_id') n_app_info = request.values.get('app_info') n_owner = request.values.get('owner') n_group_id = request.values.get('group_id') n_net_conf_list_req = request.values.get('net_status_list') # start n_extend_list_req = request.values.get('extend_list') n_qemu_ga_update_req = request.values.get('qemu_ga_update') c_system = '' c_version = None # end if not instance_id or not n_flavor_id or not n_group_id: logging.error('params is invalid when change instance configure') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) ins_data = ins_s.InstanceService().get_instance_info(instance_id) ###################################add 2017/09/29#############################3 uuid = ins_data['uuid'] user_id = get_user()['user_id'] request_id = ins_s.generate_req_id() if not ins_data: logging.error('the instance %s is not exist in db when change instance configure', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # --------------------edit 2017/11/13----------------------- if ins_data['create_source'] == '0': ins_images_data = ins_s.get_images_of_instance(instance_id) if ins_images_data: c_system = ins_images_data[0]['system'] else: ins_images_data = v2v_ins_s.V2VInstanceService().get_v2v_instance_info(instance_id) if ins_images_data: c_system = ins_images_data['os_type'] ins_status = ins_data['status'] # 获取虚拟机所在物理机信息 host_data = ins_s.get_host_of_instance(instance_id) ins_datacenter_info = ins_s.get_datacenter_of_instance(instance_id) if not host_data or not ins_datacenter_info: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="无法获取虚拟机所在物理机信息、机房信息") ins_data['dc_type'] = ins_datacenter_info['dc_type'] # 新flavor信息 n_flavor_data = fla_s.FlavorService().get_flavor_info(n_flavor_id) if not n_flavor_data: logging.error('flavor %s is invalid in db when change instance configure', n_flavor_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='新的配置数据有误,无法修改配置') # 虚机现有flavor信息 c_flavor_data = ins_s.get_flavor_of_instance(instance_id) if not c_flavor_data: logging.error('instance %s flavor is invalid in db when change instance configure', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) c_group_data = ins_s.get_group_of_instance(instance_id) if c_group_data and int(c_group_data['group_id']) != int(n_group_id): # 检查新应用组的配额 is_group_enough, req_msg = _check_change_group_quota(n_group_id, n_flavor_data, c_flavor_data) if not is_group_enough: logging.error('new group %s quota is not enough to change new flavor', n_group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=req_msg) params = {} if json_helper.loads(n_extend_list_req): # 检查当前应用组的配额 is_group_enough, req_msg = _check_change_group_quota(n_group_id, n_flavor_data, c_flavor_data, json_helper.loads(n_extend_list_req)) if not is_group_enough: logging.error('new group %s quota is not enough to change new flavor', n_group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=req_msg) # 检查物理机当前使用率情况是否满足扩容 is_host_available, ret_msg = __check_host_capacity(host_data, n_flavor_data, c_flavor_data , json_helper.loads(n_extend_list_req)) if not is_host_available: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_msg) vmname = ins_data['name'] uuid = '' host_ip = '' n_extend_list_req = json_helper.loads(n_extend_list_req) try: uuid = ins_data['uuid'] host_ip = ins_s.get_hostip_of_instance(instance_id) except: pass connect_instance = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=ins_data['name']) if not connect_instance: pass # 添加扩容开始action ins_a_s.update_instance_status(VMStatus.CONFIGURE_ING, instance_id) ins_a_s.add_disk_extend_action_to_database(uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_EXTEND, ActionStatus.START, 'start') # 满足扩容条件 if n_qemu_ga_update_req: if c_system.strip() == 'linux': flag, msg = connect_instance.exec_qemu_command( "cat /proc/self/mounts | grep -w / | grep -v rootfs | awk '{print $3}'") if not flag: c_version = None c_version = CentOS_Version.CentOS_6 if msg.strip() == 'ext4' else CentOS_Version.CentOS_7 flag, result = ins_a_s.extend_mount_size(n_extend_list_req, host_ip, vmname, uuid, c_version, instance_id) elif c_system.strip() == 'windows': flag, result = ins_a_s.extend_dev_size(n_extend_list_req, host_ip, vmname, uuid, instance_id) else: flag = False if flag: msg = "扩容成功" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_EXTEND, ActionStatus.SUCCSESS, msg) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) else: msg = "扩容失败,{}".format(result) ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_EXTEND, ActionStatus.FAILD, msg) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, msg=msg) else : # 非linux系统,关机状态,qemu-guest-agent没有更新成功 msg = "非linux系统,扩容失败" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_EXTEND, ActionStatus.FAILD, msg) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, msg=msg) else: pass if c_flavor_data['vcpu'] != n_flavor_data['vcpu'] or c_flavor_data['memory_mb'] != n_flavor_data['memory_mb']: # 检查当前应用组的配额 is_group_enough, req_msg = _check_change_group_quota(n_group_id, n_flavor_data, c_flavor_data) if not is_group_enough: logging.error('new group %s quota is not enough to change new flavor', n_group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=req_msg) # 检查物理机当前使用率情况是否满足扩容 is_host_available, ret_msg = __check_host_capacity(host_data, n_flavor_data, c_flavor_data) if not is_host_available: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_msg) # 关机状态 if ins_status == VMStatus.SHUTDOWN: pass elif ins_status == VMStatus.STARTUP: # 开机状态 # cpu只能增 if c_flavor_data['vcpu'] > n_flavor_data['vcpu']: logging.error('vcpu only be increase in startup status, now vcpu %s > new vcpu %s', c_flavor_data['vcpu'], n_flavor_data['vcpu']) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='开机状态下,CPU数量只能增加不能减少') # 内存不能修改 if c_flavor_data['memory_mb'] != n_flavor_data['memory_mb']: logging.error('memory only no allow be change in startup status, now mem %s, new mem %s', c_flavor_data['memory_mb'], n_flavor_data['memory_mb']) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='开机状态下,不能修改内存容量') else: logging.error('instance status %s is invalid when change instance configure', ins_status) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='只能在开机或关机状态下修改配置') if n_flavor_data['vcpu'] == c_flavor_data['vcpu']: pass else: params['new_vcpu'] = n_flavor_data['vcpu'] params['old_vcpu'] = c_flavor_data['vcpu'] new_mem = n_flavor_data['memory_mb'] old_mem = c_flavor_data['memory_mb'] if new_mem == old_mem: pass else: # 检查内存是否超分 if not _check_mem_allocation(instance_id, new_mem, old_mem): logging.error('instance %s mem has over allocation, new mem %s, old mem %s', instance_id, new_mem, old_mem) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='物理内存不能超分') params['new_mem'] = new_mem params['old_mem'] = old_mem # 检查网络配置是否需要修改 n_net_conf_list = json_helper.loads(n_net_conf_list_req) if n_net_conf_list: params['net_status_list'] = n_net_conf_list # 没有一个指标可以修改 if not params: logging.error('vcpu, mem, disk no one can change when change instance configure') else: host_ip = ins_s.get_hostip_of_instance(ins_data['id']) if not host_ip: logging.error('instance %s has no host ip when change instance configure', ins_data['id']) ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) ret_flavor = ins_a_s.change_instance_configure(host_ip, ins_data, c_flavor_data['flavor_id'], n_flavor_id, ins_status, **params) if not ret_flavor: ins_a_s.update_instance_status(VMStatus.STARTUP, instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) update_data_i = { 'app_info': n_app_info, 'owner': n_owner, 'updated_at': get_datetime_str() } where_data_i = { 'id': instance_id } ret_i = ins_s.InstanceService().update_instance_info(update_data_i, where_data_i) # if ret_i != 1: # logging.error('update instance info error when configure, update_data:%s, where_data:%s', # update_data_i, where_data_i) # return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) update_data_g = { 'group_id': n_group_id, 'updated_at': get_datetime_str() } where_data_g = { 'instance_id': instance_id } ret_g = ins_g_s.InstanceGroupService().update_instance_group_info(update_data_g, where_data_g) # if ret_g != 1: # logging.error('update group info error when configure, update_data:%s, where_data:%s', # update_data_g, where_data_g) # return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # if 'disk_gb_list' in params: # return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg='硬盘扩容任务发送成功') return json_helper.format_api_resp(code=ErrorCode.SUCCESS, msg='修改配置成功')
def insert_log(*argv, **kwargs): user = user_service.get_user() res = func(*argv, **kwargs) instance_data = "" try: tmp = json.loads(res.data) # 根据不同action拼接extra_data if request.values.get('instance_ids'): # 删除VM、开机、关机 try: # instance_ids = json.dumps(request.values.get('instance_ids')) ins_ids = request.values.get('instance_ids') ins_ids_list = ins_ids.split(',') for _ins_id in ins_ids_list: _ins_data = ins_s.InstanceService( ).get_instance_info(_ins_id) instance_data += "name:" + _ins_data[ 'name'] + "," + "uuid:" + _ins_data[ 'uuid'] + "; " except: pass elif operation_action == OperationAction.ADD: # 创建VM try: hostpool_id = json.dumps(kwargs['hostpool_id']) image_name = request.values.get('image_name') flavor_id = request.values.get('flavor_id') count = request.values.get('count') app_info = request.values.get('app_info') group_id = request.values.get('group_id') owner = request.values.get('owner') instance_data += "hostpool_id:" + hostpool_id + "," + "image_name:" + image_name + "," \ + "flavor_id:" + flavor_id + "," + "count:" + count + "," \ + "app_info:" + app_info + "," + "group_id:" + group_id + "," \ + "owner:" + owner + ";" except: pass elif operation_action == OperationAction.MIGRATE or operation_action == OperationAction.HOT_MIGRATE: # 冷迁移、热迁移 try: _ins_id = json.dumps(kwargs['instance_id']) _host_id = json.dumps(kwargs['host_id']) host_data_d = host_s.HostService().get_host_info( _host_id) # host_data_s = ins_s.get_host_of_instance(_ins_id) # str(host_data_s['name']) _ins_data = ins_s.InstanceService().get_instance_info( _ins_id) # TODO: add src_host instance_data += "name:" + _ins_data['name'] + "," + "uuid:" + _ins_data['uuid'] + "," \ + "src_host:" + "," + "dst_host:" + str(host_data_d['name']) + ";" except: pass elif operation_action == OperationAction.CLONE_CREATE: # 克隆创建 try: _ins_id = request.values.get('instance_id') _ins_data = ins_s.InstanceService().get_instance_info( _ins_id) instance_data += "name:" + _ins_data[ 'name'] + "," + "uuid:" + _ins_data['uuid'] + "; " except: pass elif operation_action == OperationAction.ALTER: # 修改VM配置 try: _flavor_id = request.values.get('flavor_id') # _disk_gb_list_req = request.values.get('disk_gb_list') _app_info = request.values.get('app_info') _owner = request.values.get('owner') _group_id = request.values.get('group_id') _net_conf_list_req = request.values.get( 'net_status_list') # _ins_id = request.values.get('instance_id') _ins_id = json.dumps(kwargs['instance_id']) _extend_list_req = request.values.get('extend_list') # _qemu_ga_update_req = request.values.get('qemu_ga_update') _ins_data = ins_s.InstanceService().get_instance_info( _ins_id) instance_data += "name:" + _ins_data['name'] + "," + "uuid:" + _ins_data['uuid'] + "," \ + "owner:" + _owner + "," + "group_id:" + _group_id + "," \ + "flavor_id:" + _flavor_id + "," + "app_info:" + _app_info + "," \ + "extend_list:" + _extend_list_req + "," \ + "net_conf_list_req:" + _net_conf_list_req + ";" except: pass elif kwargs: # 克隆备份 try: _ins_id = json.dumps(kwargs['instance_id']) _ins_data = ins_s.InstanceService().get_instance_info( _ins_id) instance_data += "name:" + _ins_data[ 'name'] + "," + "uuid:" + _ins_data['uuid'] + "; " except: pass else: pass except: return res if tmp["code"] == ErrorCode.SUCCESS: operation_result = "SUCCESS" elif tmp["code"] == ErrorCode.SUCCESS_PART: operation_result = "SUCCESS_PART" else: operation_result = "FAILED" try: instance_data += " ErrorMsg:" + tmp["msg"] except: pass client_ip = request.headers.get('X-Forwarded-For', '') insert_data = { "operator": user["user_id"], "operator_ip": client_ip, "operation_object": operation_object, "operation_action": operation_action, "operation_date": time_helper.get_datetime_str(), "operation_result": operation_result, "extra_data": "" + instance_data } OperationService().insert_operation(insert_data) return res
def instance_create_from_other_platform_with_ip(): ''' 外部平台虚拟机创建 :return: ''' _init_log('instanc_create_request_from_other_platform') data_from_other_platform = request.data logging.info(data_from_other_platform) data_requset = json_helper.loads(data_from_other_platform) image_name = data_requset['image'] vcpu = data_requset['vcpu'] mem_mb = data_requset['mem_MB'] disk_gb = data_requset['disk_GB'] count = data_requset['count'] sys_code = data_requset['sys_code'] opuser = data_requset['opUser'] taskid_vs = data_requset['taskid'] req_env = data_requset['env'] req_net_area = data_requset['net_area'] req_datacenter = data_requset['datacenter'] task_id_kvm = ins_s.generate_task_id() sys_opr_name = data_requset['Op_Main_Engineer_Primary'] sys_opr_id = data_requset['Op_Main_Engineer_Prim'] cluster_id = data_requset['cluster_id'] vip_needed = data_requset['vip_needed'] # 是否需要vip,0为不需要,1需要 vm_ip_info = data_requset['vm_info'] vip_info = data_requset['vip_info'] api_origin = data_requset[ 'apiOrigin'] # api名称,维石为vishnu, 软负载为sfslb, 其他的需要定义 # 前端暂时不是传虚拟机root密码过来 password = None app_info = data_requset['application_info'] # hostpool_id = int(data_requset['hostpool_id']) # 特殊类型应用,返回集群id hostpool_id = '' logging.info('task %s : check params start when create instance', task_id_kvm) if not taskid_vs or not api_origin: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of taskid or api_origin when create ' 'instance') # 判断工单是否为失败重做 check_job_data = { 'WHERE_AND': { '=': { 'taskid_api': taskid_vs }, }, } ret_job_num, ret_job_data = request_r_s.RequestRecordService( ).request_db_query_data(**check_job_data) if ret_job_num == 1: for _job_data in ret_job_data: if _job_data['task_status'] == '0': return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='task is now doing, wait a moment, ' 'do not repeat create') elif _job_data['task_status'] == '1': # 将request_record数据库表中“task_status”、“response_to_api”重置为0重启任务 update_db_time = get_datetime_str() _update_data = { 'task_status': '0', 'response_to_api': '0', 'finish_time': update_db_time, 'request_status_collect_time': update_db_time, } _where_data = { 'taskid_api': taskid_vs, } ret = request_r_s.RequestRecordService().update_request_status( _update_data, _where_data) if ret <= 0: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='update request status failed, ' 'please call kvm system manager ' 'or retry create again') return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.SUCCEED, detail='start to recreate vm') elif _job_data['task_status'] == '2': threads = [] # 将request_record数据库表中“task_status”、“response_to_api”重置为0重启任务 update_db_time = get_datetime_str() _update_data = { 'task_status': '0', 'response_to_api': '0', 'finish_time': update_db_time, 'request_status_collect_time': update_db_time, } _where_data = { 'taskid_api': taskid_vs, } ret = request_r_s.RequestRecordService().update_request_status( _update_data, _where_data) if ret <= 0: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='update request status failed, ' 'please call kvm system manager ' 'or retry create again') # 找到工单对应的虚拟机,发送task_id、request_id到kafka重新创建 ins_params = { 'WHERE_AND': { "=": { 'task_id': _job_data['taskid_kvm'], 'isdeleted': '0', 'status': '100' } }, } ins_num, ins_data = ins_s.InstanceService().query_data( **ins_params) if ins_num > 0: for per_ins_data in ins_data: kafka_send_thread = threading.Thread( target=instance_msg_send_to_kafka, args=( per_ins_data['task_id'], per_ins_data['request_id'], )) threads.append(kafka_send_thread) kafka_send_thread.start() # 判断多线程是否结束 for t in threads: t.join() return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.SUCCEED, detail='start to recreate vm') if api_origin == ApiOriginString.VISHNU: api_origin = ApiOrigin.VISHNU elif api_origin == ApiOriginString.SFSLB: api_origin = ApiOrigin.SFSLB elif api_origin == ApiOriginString.FWAF: api_origin = ApiOrigin.FWAF else: api_origin = ApiOrigin.VISHNU if vip_needed == '1' and len(vip_info) <= 0: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of vip datas when create instance') # 校验前端vip是否存在数据库中且ip为预保留状态 if vip_needed == '1': vip_available = 0 vip_info_list = [] for per_vip in vip_info: per_vip_info = ip_service.IPService().get_ip_by_ip_address( per_vip['ip']) if per_vip_info and per_vip_info[ 'status'] == IPStatus.PRE_ALLOCATION: vip_info_list.append(per_vip_info) vip_available += 1 if vip_available != len(vip_info): return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='vip nums from vishnu not equal apply vip nums ' 'when create instance') # 校验前端ip是否存在数据库中且ip为预保留状态 ip_available = 0 ip_info_list = [] for per_ip in vm_ip_info: per_ip_info = ip_service.IPService().get_ip_by_ip_address(per_ip['ip']) if per_ip_info and per_ip_info['status'] == IPStatus.PRE_ALLOCATION: ip_info_list.append(per_ip_info) ip_available += 1 if ip_available != int(count): return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='vm ip nums from vishnu not equal apply vm nums ' 'when create instance') # 获取ip对应的网段信息 segment_info = segment_service.SegmentService().get_segment_info( ip_info_list[0]['segment_id']) if not segment_info: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='can not find segment infomation for ip ' 'when create instance') # 根据维石平台输入的虚拟机cpu、内存选择模板 if not vcpu or not mem_mb: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of vcpu or mem_MB when create instance') flavor_query = flavor_service.get_flavor_by_vcpu_and_memory(vcpu, mem_mb) if not flavor_query: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='can not get flavor information when create instance') flavor_id = flavor_query['id'] # 根据维石平台输入的环境、网络区域查找对应的物理集群 if not req_env or not req_net_area: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of req_net_area or req_env ' 'when create instance') if not hostpool_id: hostpool_query = hostpool_service.get_hostpool_info_by_name( str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), req_datacenter, req_net_area) if not hostpool_query: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='can not get host_pool information ' 'when create instance') hostpool_id = hostpool_query['hostpool_id'] # 根据维石平台输入的系统运维人员工号维护对应应用组信息 if not sys_opr_id or not cluster_id: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of sys_opr_name, sys_opr_id ' 'or cluster_id when create instance') ret_group, group_id = _user_group_check( str(DataCenterTypeForVishnu.TYPE_DICT[req_env]), sys_code, sys_opr_name, sys_opr_id, cluster_id) if not ret_group: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail=group_id) if not hostpool_id or not image_name or not flavor_id or not disk_gb or not group_id \ or not count or int(count) < 1: logging.error('task %s : params are invalid when create instance', task_id_kvm) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='empty input of image_name, disk_gb ' 'or count when create instance') if int(count) > int(INSTANCE_MAX_CREATE): logging.error( 'task %s : create count %s > max num %s when create instance', task_id_kvm, count, INSTANCE_MAX_CREATE) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='批量创建最大实例数不能超过32个') logging.info('task %s : check params successful when create instance', task_id_kvm) # 数据盘最少50GB # 这里只是一个数据盘,后面有多个数据盘 vm_disk_gb = int(disk_gb) if int(disk_gb) > DATA_DISK_GB else DATA_DISK_GB # 获取主机列表(不包括锁定、维护状态) logging.info( 'task %s : get all hosts in hostpool %s start when create instance', task_id_kvm, hostpool_id) all_hosts_nums, all_hosts_data = host_s.HostService( ).get_available_hosts_of_hostpool(hostpool_id) # 可用物理机数量不足 least_host_num = hostpool_service.HostPoolService().get_least_host_num( hostpool_id) if all_hosts_nums < least_host_num or all_hosts_nums < 1: logging.error( 'task %s : available host resource not enough when create instance', task_id_kvm) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='集群不够资源,无法创建实例') logging.info( 'task %s : get all hosts in hostpool %s successful, all hosts nums %s when create instance', task_id_kvm, hostpool_id, all_hosts_nums) # 过滤host logging.info('task %s : filter hosts start when create instance', task_id_kvm) hosts_after_filter = host_s_s.filter_hosts(all_hosts_data) if len(hosts_after_filter ) == 0 or len(hosts_after_filter) < least_host_num: logging.error('task %s : no available host when create instance', task_id_kvm) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='没有适合的主机,无法创建实例') logging.info('task %s : filter hosts successful when create instance', task_id_kvm) logging.info('task %s : get need info start when create instance', task_id_kvm) # 获取flavor信息 flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id) if not flavor_info: logging.error( 'task %s : flavor %s info not in db when create instance', task_id_kvm, flavor_id) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='实例规格数据有误,无法创建实例') # VM分配给HOST logging.info('task %s : match hosts start when create instance', task_id_kvm) vm = { "vcpu": flavor_info['vcpu'], "mem_MB": flavor_info['memory_mb'], "disk_GB": flavor_info['root_disk_gb'] + vm_disk_gb, # 系统盘加数据盘 "group_id": group_id, "count": count } host_list = host_s_s.match_hosts(hosts_after_filter, vm, least_host_num=least_host_num, max_disk=2000) host_len = len(host_list) if host_len == 0: logging.error( 'task %s : match host resource not enough when create instance', task_id_kvm) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='没有适合的主机,无法创建实例') logging.info('task %s : match hosts successful when create instance', task_id_kvm) # 获取hostpool的net area信息 hostpool_info = hostpool_service.HostPoolService().get_hostpool_info( hostpool_id) if not hostpool_info: logging.error( 'task %s : hostpool %s info not in db when create instance', task_id_kvm, hostpool_id) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='物理机池所属网络区域信息有误,无法创建实例') net_area_id = hostpool_info['net_area_id'] logging.info('task %s : get need info successful when create instance', task_id_kvm) # 组配额控制 logging.info('task %s : check group quota start when create instance', task_id_kvm) is_quota_enough, quota_msg = check_group_quota(group_id, flavor_info, vm_disk_gb, count) if not is_quota_enough: logging.error( 'task %s : group %s is no enough quota when create instance', task_id_kvm, group_id) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='资源组配额不足,无法创建实例') logging.info('task %s : check group quota successful when create instance', task_id_kvm) ips_list = ip_info_list segment_data = segment_info logging.info('task %s : check ip resource start when create instance', task_id_kvm) logging.info('task %s : get need 1 info start when create instance', task_id_kvm) # 获取镜像信息,一个image_name可能对应多个id image_nums, image_data = image_service.ImageService().get_images_by_name( image_name) if image_nums <= 0: logging.info('task %s : no image %s info in db when create instance', task_id_kvm, image_name) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='没有镜像资源,无法创建实例') # 获取集群所在的环境 vm_env = hostpool_service.get_env_of_hostpool(hostpool_id) # hostpool对应的机房名 dc_name = hostpool_service.get_dc_name_of_hostpool(hostpool_id) # 实例操作系统 instance_system = image_data[0]['system'] logging.info('task %s : get need 1 info successful when create instance', task_id_kvm) # 获取虚机名资源 logging.info( 'task %s : check instance name resource start when create instance', task_id_kvm) is_name_enough, instance_name_list = _check_instance_name_resource( vm_env, dc_name, instance_system, count) if not is_name_enough: logging.error( 'task %s : datacenter %s has no enough instance name resource', task_id_kvm, dc_name) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='主机名资源不足,无法创建实例') logging.info( 'task %s : check instance name resource successful when create instance', task_id_kvm) # 如果需要vip,分配第‘count + 1’个同时记录vip_info表格 if vip_needed == '1': for per_avalible_vip in vip_info_list: # 标记ip已使用 update_vip_data = {'status': IPStatus.USED} where_vip_data = {'id': per_avalible_vip['id']} ret_mark_ip = ip_service.IPService().update_ip_info( update_vip_data, where_vip_data) if ret_mark_ip <= 0: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail="标记ip为已使用状态失败,请重新申请") # 录入vip信息到数据库中 insert_vip_data = { 'ip_id': per_avalible_vip['id'], 'cluster_id': cluster_id, 'apply_user_id': opuser, 'sys_code': sys_code, 'isdeleted': '0', 'created_at': get_datetime_str() } ret_vip = vip_service.VIPService().add_vip_info(insert_vip_data) if ret_vip.get('row_num') <= 0: return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail="录入ip信息失败,请联系系统管理员") # 挂载点 if instance_system == 'linux': mount_point = '/app' else: mount_point = 'E' logging.info('task %s : create thread start when create instance', task_id_kvm) user_id = get_user()['user_id'] all_threads = [] for i in range(int(count)): instance_name = str(instance_name_list[i]) ip_data = ips_list[i] # 轮询host index = i % host_len vm_host = host_list[index] create_ins_t = threading.Thread( target=_create_instance_info, args=(task_id_kvm, instance_name, app_info, sys_opr_id, password, flavor_id, group_id, vm_host, flavor_info, image_data, ip_data, vm_disk_gb, mount_point, instance_system, net_area_id, segment_data, vm_env, user_id, cluster_id), name='thread-instance-create-' + task_id_kvm) all_threads.append(create_ins_t) create_ins_t.start() for thread in all_threads: thread.join() logging.info('task %s : create thread successful when create instance', task_id_kvm) # 录入外应用的taskid到工单表格中 time_now_for_insert_request_to_db = get_datetime_str() request_info_data = { "taskid_api": taskid_vs, "api_origin": api_origin, "taskid_kvm": task_id_kvm, "vm_count": count, "user_id": opuser, "start_time": time_now_for_insert_request_to_db, "task_status": "0", # 代表任务执行中 "response_to_api": "0", "istraceing": "0", "request_status_collect_time": time_now_for_insert_request_to_db } request_record_db_ret = request_r_s.RequestRecordService( ).add_request_record_info(request_info_data) if request_record_db_ret.get('row_num') <= 0: logging.error( 'task %s : can not add request record information to db when create instance', task_id_kvm) return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.FAILED, detail='录入工单信息到数据库失败') return json_helper.format_api_resp_msg_to_vishnu( req_id=taskid_vs, job_status=VsJobStatus.SUCCEED, detail='start to create vm')
def instance_delete(): ''' 虚机删除 关机超过一天才能删除 :return: ''' request_from_vishnu = False if get_user()['user_id'] == 'vishnu': is_admin = True request_from_vishnu = True else: # 判断操作用户身份 role_ids = current_user_role_ids() # 系统管理员 if 1 in role_ids: is_admin = True else: is_admin = False permission_limited = False ins_ids = request.values.get('instance_ids') if not ins_ids: logging.info('no instance_ids when delete instance') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) ins_ids_list = ins_ids.split(',') # 操作的instance数 all_num = len(ins_ids_list) if all_num > int(INSTANCE_MAX_DELETE): logging.info('delete nums %s is greater than max %s', all_num, INSTANCE_MAX_DELETE) return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) fail_num = 0 for _ins_id in ins_ids_list: # 查询虚拟机对应环境信息,应用管理员不能删除非DEV环境虚拟机 ins_group = ins_s.get_group_of_instance(_ins_id) if not ins_group: logging.error( 'instance %s group data is no exist in db when delete instance', str(_ins_id)) fail_num += 1 continue else: if not is_admin and int( ins_group['dc_type']) != DataCenterType.DEV: permission_limited = True fail_num += 1 continue _ins_data = ins_s.InstanceService().get_instance_info(_ins_id) if _ins_data: # 维石只能删除克隆备份的虚拟机 if request_from_vishnu and 'clone' not in _ins_data['name']: fail_num += 1 continue _ret_del = ins_a_s.delete_instance(_ins_data, _ins_data['status']) if not _ret_del: fail_num += 1 continue else: logging.error( 'the instance is not exist in db when delete instance') fail_num += 1 continue # 全失败 if fail_num == all_num: logging.error("delete instance all failed") if permission_limited: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="非DEV环境虚拟机请联系系统组删除") elif request_from_vishnu: return json_helper.format_api_resp(code=ErrorCode.SUCCESS) else: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) # 部分成功 if 0 < fail_num < all_num: logging.error("delete instance part failed") if permission_limited: return json_helper.format_api_resp( code=ErrorCode.SUCCESS_PART, msg="部分虚拟机删除成功, 非DEV环境虚拟机请联系系统组删除") elif request_from_vishnu: return json_helper.format_api_resp(code=ErrorCode.SUCCESS) else: return json_helper.format_api_resp(code=ErrorCode.SUCCESS_PART, msg="部分虚拟机删除成功") return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def insert_log(*argv, **kwargs): user = user_service.get_user() res = func(*argv, **kwargs) host_data = "" try: tmp = json.loads(res.data) # 根据不同action拼接extra_data if operation_action == OperationAction.DELETE: # 删除HOST try: all_host_id = request.values.get("host_id") for _host_id in all_host_id.split(','): _host_data = host_service.HostService( ).get_host_info(_host_id) host_data += "name:" + _host_data['name'] + "," + "sn:" + _host_data['sn'] + "," + \ "ipaddress:" + _host_data['ipaddress'] + "; " except: pass elif operation_action == OperationAction.ADD: # 新增HOST try: name = request.values.get('name') # 序列号 sn = request.values.get('sn') ip_address = request.values.get('ip_address') hold_mem_gb = request.values.get('hold_mem_gb') manage_ip = request.values.get('manage_ip') hostpool_id = json.dumps(kwargs['hostpool_id']) host_data += "name:" + name + "," + "sn:" + sn + "," + "ip_address:" + ip_address + "," \ + "manage_ip:" + manage_ip + "," + "hold_mem_gb:" + hold_mem_gb + "," \ + "hostpool_id:" + str(hostpool_id) + ";" except: pass elif operation_action == OperationAction.OPERATE: # 操作HOST try: all_host_id = request.values.get("host_id") flag = request.values.get("flag") if int(flag) == 0: action = "开机" elif int(flag) == 1: action = "硬关机" elif int(flag) == 2: action = "软关机" elif int(flag) == 3: action = "硬重启" elif int(flag) == 4: action = "软重启" else: pass for _host_id in all_host_id.split(','): _host_data = host_service.HostService( ).get_host_info(_host_id) host_data += "name:" + _host_data['name'] + "," + "sn:" + _host_data['sn'] + "," + \ "ipaddress:" + _host_data['ipaddress'] + "," + "action:" + action + "; " except: pass elif operation_action == OperationAction.ALTER: # 更新HOST name = request.values.get('name') ip_address = request.values.get('ip_address') hold_mem_gb = request.values.get('hold_mem_gb') manage_ip = request.values.get('manage_ip') host_data += "name:" + name + "," + "ipaddress:" + ip_address + ","\ + "manage_ip:" + manage_ip + "," + "hold_mem_gb:" + hold_mem_gb + "; " elif kwargs['host_id']: # 锁定、维护 try: flag = request.values.get("flag") if operation_action == OperationAction.LOCK: if int(flag) == 0: action = "解除锁定" elif int(flag) == 1: action = "锁定" else: pass elif operation_action == OperationAction.MAINTAIN: if int(flag) == 0: action = "结束维护" elif int(flag) == 2: action = "维护" else: pass else: pass _host_id = json.dumps(kwargs['host_id']) _host_data = host_service.HostService().get_host_info( _host_id) host_data += "name:" + _host_data['name'] + "," + "sn:" + _host_data['sn'] + "," + \ "ipaddress:" + _host_data['ipaddress'] + "," + "action:" + action + "; " except: pass else: pass except: return res if tmp["code"] == ErrorCode.SUCCESS: operation_result = "SUCCESS" elif tmp["code"] == ErrorCode.SUCCESS_PART: operation_result = "SUCCESS_PART" else: operation_result = "FAILED" try: host_data += " ErrorMsg:" + tmp["msg"] except: pass client_ip = request.headers.get('X-Forwarded-For', '') insert_data = { "operator": user["user_id"], "operator_ip": client_ip, "operation_object": operation_object, "operation_action": operation_action, "operation_date": time_helper.get_datetime_str(), "operation_result": operation_result, "extra_data": "" + host_data } OperationService().insert_operation(insert_data) return res
def extend_disk(instance_id): """ 扩展磁盘接口 :param instance_id: :return: """ c_system = '' c_version = None qemu_ga_update = False mount_point_list = [] if not instance_id: logging.info('no instance id when get configure info') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="参数错误") ins_data = ins_s.InstanceService().get_instance_info(instance_id) uuid = ins_data['uuid'] user_id = get_user()['user_id'] request_id = ins_s.generate_req_id() host_ip = ins_s.get_hostip_of_instance(instance_id) if not ins_data or not host_ip: data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} logging.info('instance %s data is no exist in db when get configure info', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, data=data_params, msg='数据库查询错误') if ins_data['create_source'] == '0': ins_images_data = ins_s.get_images_of_instance(instance_id) if ins_images_data: c_system = ins_images_data[0]['system'] c_version = ins_images_data[0]['version'] else: ins_images_data = v2v_ins_s.V2VInstanceService().get_v2v_instance_info(instance_id) if ins_images_data: c_system = ins_images_data['os_type'] if ins_images_data['os_version'] and '6.6' in ins_images_data['os_version']: c_version = '6.6' elif ins_images_data['os_version'] and '7.2' in ins_images_data['os_version']: c_version = '7.2' # 更新qemu-guest-agent action到数据库,zitong wang 29th,9,2017 ins_a_s.add_disk_display_action_to_database(uuid, request_id, user_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY, ActionStatus.START, 'start') # 更新qemu-guest-agent,获取所有挂载点的信息,add by zitongwang in 21th,9,2017 if c_system == "linux" and c_version: c_version = CentOS_Version.CentOS_7 if c_version >= '7.0' else CentOS_Version.CentOS_6 ins_a_s.add_disk_display_action_to_database(uuid, request_id, user_id, InstaceActions.INSTANCE_UPDATE_QEMU_AGENT, ActionStatus.START, 'start') # 更新qemu-ga版本 vmManager.update_qemu_ga_instance(c_version,host_ip,ins_data['name']) connect_instance = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=ins_data['name']) if not connect_instance: data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} msg = "libvirt连接建立失败,无法使用libvirt管理虚拟机" ins_a_s.add_disk_display_action_to_database(uuid, request_id, ActionStatus.FAILD, InstaceActions.INSTANCE_LIBVIRT_ERROR, msg) return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, data=data_params, msg=msg) # 重新建立连接判断是否更新成功 flag, msg = connect_instance.test_update_command() qemu_ga_update = flag if flag: # 更新action数据库状态:更新成功 _message = "qemu_agent update successfully" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_UPDATE_QEMU_AGENT, ActionStatus.SUCCSESS, _message) # 针对v2v机器,pvs显示的LV名称有问题 connect_instance.exec_qemu_command("pvscan") # 获得所有挂载点信息 command = "lsblk -r | awk '{print $7}' | awk NF | grep '^/' | grep -v '^/boot'" flag, msg = connect_instance.exec_qemu_command(command) mount_point = msg.splitlines() # 获取挂载点文件系统,大小,类型,挂载点信息 command = "lsblk -r | awk '{print $1" + "\\\" " + "\\\"" + "$4" + "\\\" " + "\\\"" + "$6" + "\\\" " + "\\\"" + "$7}'" flag, msg = connect_instance.exec_qemu_command(command) parts_info = msg.split('\n') parts_info.pop() mount_point_list = [] mount_list = [] for mount in mount_point: disk_info = {} mount_data = filter(lambda x: x.split(' ')[-1] == mount, parts_info) data = mount_data[0].split(' ') disk_info['mount_point'] = data[-1] # 存在数据就返回 if disk_info['mount_point'] in mount_list: continue else: mount_list.append(disk_info['mount_point']) disk_info['mount_partition_name'] = data[0] disk_info['mount_point_size'] = float(data[1][0:-1]) if data[1][-1].endswith('G') else float( data[1][0:-1]) / 1024 disk_info['mount_partition_type'] = data[2] command = "df -P '%s'| awk 'NR==2 {print $5}'" % mount flag, msg = connect_instance.exec_qemu_command(command) disk_info['mount_point_use'] = msg.strip() mount_point_list.append(disk_info) data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} _message = "linux os disk information display successfully" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY, ActionStatus.SUCCSESS, _message) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=data_params) else: # 更新qmeu-ga失败 _message = "qemu_agent update failed" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_UPDATE_QEMU_AGENT, ActionStatus.FAILD, _message) data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, data=data_params, msg='qemu update fail') elif c_system == "windows": connect_instance = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=ins_data['name']) disk_info = connect_instance.get_configure_disk_device(uuid) storage_instance = vmManager.libvirt_get_connect(host_ip, conn_type='storage', vmname=ins_data['name'], poolname=uuid) mount_point_list = [] for x in disk_info: d = {} block_info = storage_instance.get_disk_size(x['image']) d.setdefault('mount_point', x['dev']) d.setdefault('mount_point_size', '%.1f' % (float(block_info[0]) / 1073741824)) d.setdefault('mount_point_use', '%.2f' % (float(block_info[1]) / block_info[0] * 100)) d.setdefault('mount_partition_name', "") d.setdefault('mount_partition_type', "") mount_point_list.append(d) qemu_ga_update = True data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} _message = "disk information display successfully" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY, ActionStatus.SUCCSESS, _message) return json_helper.format_api_resp(code=ErrorCode.SUCCESS, data=data_params, msg=_message) else: data_params = {'mount_point_list': mount_point_list, "qemu_ga_update": qemu_ga_update} _message = "os type unknown, please call kvm administrators" ins_a_s.update_disk_action_to_database(request_id, InstaceActions.INSTANCE_DISK_INFO_DISPLAY, ActionStatus.FAILD, _message) return json_helper.format_api_resp(code=ErrorCode.ALL_FAIL, data=data_params, msg=_message)
def insert_log(*argv, **kwargs): user = user_service.get_user() res = func(*argv, **kwargs) group_data = "" try: tmp = json.loads(res.data) # 根据不同action拼接extra_data if operation_action == OperationAction.ADD or operation_action == OperationAction.ALTER: # 创建组、修改组信息 try: name = request.values.get('name') owner = request.values.get('owner') p_cluster_id = request.values.get('p_cluster_id') role_id = request.values.get('role_id') cpu = request.values.get('cpu') mem = request.values.get('mem') disk = request.values.get('disk') vm = request.values.get('vm') area_str = request.values.get('area_str') group_data += "group_name:" + name + "," + "owner:" + owner + "," + "p_cluster_id:" + p_cluster_id \ + "," + "role_id:" + role_id + "," + "cpu:" + cpu + "," + "mem:" + mem + "," \ + "disk:" + disk + "," + "vm:" + vm + "," + "area_str:" + area_str + "; " except: pass elif operation_action == OperationAction.REMOVE_USER: # 移除用户 try: user_id = request.values.get('user_id') group_id = request.values.get('group_id') group_data += "user_id:" + user_id + "," + "group_id:" + group_id + ";" except: pass elif operation_action == OperationAction.ADD_INSIDE_USER or \ operation_action == OperationAction.ADD_OUTER_USER: # 新增域用户、新增外部用户 try: user_id = request.values.get('user_id') # group_name = request.values.get('group_name') group_id = json.dumps(kwargs['group_id']) group_data += "user_id:" + user_id + "," + "group_id:" + group_id + ";" except: pass elif operation_action == OperationAction.DELETE: # 删除组 try: group_data += "group_id:" + json.dumps( kwargs['group_id']) + "; " except: pass else: pass except: return res if tmp["code"] == ErrorCode.SUCCESS: operation_result = "SUCCESS" elif tmp["code"] == ErrorCode.SUCCESS_PART: operation_result = "SUCCESS_PART" else: operation_result = "FAILED" try: group_data += " ErrorMsg:" + tmp["msg"] except: pass client_ip = request.headers.get('X-Forwarded-For', '') insert_data = { "operator": user["user_id"], "operator_ip": client_ip, "operation_object": operation_object, "operation_action": operation_action, "operation_date": time_helper.get_datetime_str(), "operation_result": operation_result, "extra_data": "" + group_data } OperationService().insert_operation(insert_data) return res
def import_excel_esx(): ''' 批量导入excel :return: ''' f = request.files['file'] # 判断是excel文件 file_name = f.filename (file_shortname, file_suffix) = os.path.splitext(file_name) if file_suffix != ".xls" and file_suffix != ".xlsx": return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="v2v批量操作只支持excel文件,请选择excel文件") xls_data = get_data(f) xls_noempty_data = 0 for sheet_n in xls_data.keys(): # 只处理一个sheet数据 if xls_data[sheet_n]: all_data_list = xls_data[sheet_n] xls_noempty_data += 1 break if xls_noempty_data == 0: return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="不能上传空excel文件") all_data_num = len(all_data_list) if all_data_num < 2: return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="请填写相关v2v信息后再提交该excel文件") user_id = get_user()['user_id'] # todo:处理空列 threads = [] for i, row in enumerate(all_data_list): # 默认第一行是标题,跳过 if i == 0: continue _check_thread = threading.Thread(target=_check_task, args=(i, row, user_id)) threads.append(_check_thread) _check_thread.start() # 判断多线程是否结束 for t in threads: t.join() return_msg_list = [] while not q.empty(): return_msg_list.append(q.get()) # 检测返回值有无错误信息 v2v_list = [] return_error_num = 0 return_error_msg_list = [] for _return_msg in return_msg_list: if _return_msg[0] is False: return_error_num += 1 return_error_msg_list.append(_return_msg[1]) else: v2v_list.append(_return_msg[1]) # 只要有一个任务有错误,就返回 if return_error_num > 0: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg="任务检测有错误,无法进行v2v操作", data=return_error_msg_list) error_num = 0 total_num = len(v2v_list) # 将入参的list按照group_id进行list分组 group_list = _task_into_list(v2v_list) # 针对group分组后的list套用host筛选算法 for task_list in group_list: tag1, res1 = _cal_group_host(task_list) # 算法分配失败 if not tag1: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=res1) else: # host筛选完成,进行入库操作 for task in task_list: tag2, res2 = _task_esx_intodb(task) # 入库失败 if not tag2: error_num += 1 # 统计总错误数 if error_num == total_num: message = "全部失败" return_code = ErrorCode.ALL_FAIL elif error_num == 0: message = "全部成功" return_code = ErrorCode.SUCCESS else: message = "部分成功" return_code = ErrorCode.SUCCESS_PART return json_helper.format_api_resp(code=return_code, msg=message)
def export_host_excel(): params = { 'WHERE_AND': { '=': { 'status': None }, 'like': { 'name': None, 'sn': None, 'ip_address': None, 'manage_ip': None }, 'in': { 'id': None } }, 'search_in_flag': 0, 'page_size': request.values.get('page_size'), 'page_no': request.values.get('page_no'), } search = request.values.get('search') if search: json_search = json.loads(search) name = json_search.get('name') if name: params['WHERE_AND']['like']['name'] = '%' + name + '%' sn = json_search.get('sn') if sn: params['WHERE_AND']['like']['sn'] = '%' + sn + '%' ip_address = json_search.get('ip_address') if ip_address: params['WHERE_AND']['like']['ip_address'] = '%' + ip_address + '%' manage_ip = json_search.get('manage_ip') if manage_ip: params['WHERE_AND']['like']['manage_ip'] = '%' + manage_ip + '%' status = json_search.get('status') if status: params['WHERE_AND']['=']['status'] = status hostpool_name = json_search.get('hostpool_name') if hostpool_name: params['search_in_flag'] = 1 # 先模糊查询hostpool name对应的HOST ID search_hostpool_data = host_s.get_hosts_by_fuzzy_hostpool_name(hostpool_name) host_id_list = [i['host_id'] for i in search_hostpool_data] if host_id_list: params['WHERE_AND']['in']['id'] = tuple(host_id_list) total_nums, data = host.user_host_list(get_user()['user_id'], **params) # 生成excel excel_data = OrderedDict() sheet_1 = [] # 标题行 row_title_data = [u"序列号(主键)", u"主机名", u"IP地址", u"状态", u"业务状态", u"集群", u"网络区域", u"所在机房", u"机房类型", u"管理IP", u"VM数量", u"保留内存", u"内存分配率(%)"] sheet_1.append(row_title_data) for i in data: _row_data = [ i['sn'], i['host_name'], i['ipaddress'], unicode(HostStatusMsg.MSG_DICT.get(i['status'], '')), unicode(HostTypeStatusMsg.MSG_DICT.get(i['typestatus'], '')), i['hostpool_name'], i['net_area_name'], i['datacenter_name'], unicode(DataCenterTypeMsg.MSG_DICT.get(int(i['dc_type']), '')), i['manage_ip'], ins_s.get_instances_nums_in_host(i['host_id']), i['hold_mem_gb'], host_s_s.get_host_mem_assign_percent(i), ] sheet_1.append(_row_data) excel_data.update({u"hosts": sheet_1}) io = StringIO.StringIO() save_data(io, excel_data) response = make_response(io.getvalue()) response.headers["Content-Disposition"] = "attachment; filename=物理机信息.xls" return response
def instance_create(hostpool_id): ''' 创建虚机 :param hostpool_id: :return: ''' image_name = request.values.get('image_name') flavor_id = request.values.get('flavor_id') disk_gb = request.values.get('disk_gb') count = request.values.get('count') app_info = request.values.get('app_info') group_id = request.values.get('group_id') owner = request.values.get('owner') password = request.values.get('password') task_id = ins_s.generate_task_id() logging.info( '创建VM 步骤1:检查参数 task %s : check params start when create instance', task_id) if not hostpool_id or not image_name or not flavor_id or not disk_gb or not group_id \ or not count or int(count) < 1: logging.error( '创建VM 步骤1:检查参数失败 参数错误 task %s : params are invalid when create instance', task_id) return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg='参数错误') if int(count) > int(INSTANCE_MAX_CREATE): logging.error( '创建VM 步骤1:检查参数失败 批量创建数超过最大数 ' 'task %s : create count %s > max num %s when create instance', task_id, count, INSTANCE_MAX_CREATE) return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg='批量创建最大实例数不能超过' + INSTANCE_MAX_CREATE + '个') owner_exist = user_s.UserService().check_userid_exist(owner) if not owner_exist: logging.error( '创建VM 步骤1:检查参数失败 应用管理员工号不存在 ' 'task %s : no such user %s in db when create instance', task_id, owner) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='应用管理员工号不存在,无法创建实例') logging.info( '创建VM 步骤1:检查参数成功 task %s : check params successful when create instance', task_id) # 数据盘最少50GB # todo:这里只是一个数据盘,后面有多个数据盘 vm_disk_gb = int(disk_gb) if int(disk_gb) > DATA_DISK_GB else DATA_DISK_GB # 获取主机列表(不包括锁定、维护状态) logging.info( '创建VM 步骤2:获取集群所有HOST列表 ' 'task %s : get all hosts in hostpool %s start when create instance', task_id, hostpool_id) all_hosts_nums, all_hosts_data = host_s.HostService( ).get_available_hosts_of_hostpool(hostpool_id) # 可用物理机数量不足 least_host_num = hostpool_service.HostPoolService().get_least_host_num( hostpool_id) if all_hosts_nums < least_host_num or all_hosts_nums < 1: logging.error( '创建VM 步骤2:获取集群所有HOST列表失败 集群不够资源 ' 'task %s : available host resource not enough when create instance', task_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='集群不够资源,无法创建实例') logging.info( '创建VM 步骤2:获取集群所有HOST列表成功,总host数:%s ' 'task %s : get all hosts in hostpool %s successful, all hosts nums %s when create instance', all_hosts_nums, task_id, hostpool_id, all_hosts_nums) # 过滤host logging.info( '创建VM 步骤3:HOST过滤 task %s : filter hosts start when create instance', task_id) hosts_after_filter = host_s_s.filter_hosts(all_hosts_data) if len(hosts_after_filter ) == 0 or len(hosts_after_filter) < least_host_num: logging.error( '创建VM 步骤3:HOST过滤失败 没有合适主机 ' 'task %s : no available host when create instance', task_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='集群物理机资源无法满足你的申请需求,请联系系统组同事') logging.info( '创建VM 步骤3:HOST过滤成功 task %s : filter hosts successful when create instance', task_id) # 获取flavor信息 logging.info( '创建VM 步骤4:获取必需信息 task %s : get need info start when create instance', task_id) flavor_info = flavor_service.FlavorService().get_flavor_info(flavor_id) if not flavor_info: logging.error( '创建VM 步骤4:获取必需信息失败 实例规格数据有误 ' 'task %s : flavor %s info not in db when create instance', task_id, flavor_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='实例规格数据有误,无法创建实例') # VM分配给HOST logging.info( '创建VM 步骤5:HOST分配 task %s : match hosts start when create instance', task_id) vm = { "vcpu": flavor_info['vcpu'], "mem_MB": flavor_info['memory_mb'], "disk_GB": flavor_info['root_disk_gb'] + vm_disk_gb, # 系统盘加数据盘 "group_id": group_id, "count": count } host_list = host_s_s.match_hosts(hosts_after_filter, vm, least_host_num=least_host_num, max_disk=2000) host_len = len(host_list) if host_len == 0: logging.error( '创建VM 步骤5:HOST分配失败 没有合适主机 ' 'task %s : match host resource not enough when create instance', task_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='集群物理机资源无法满足你的申请需求,请联系系统组同事') logging.info( '创建VM 步骤5:HOST分配成功 task %s : match hosts successful when create instance', task_id) # 获取hostpool的net area信息 hostpool_info = hostpool_service.HostPoolService().get_hostpool_info( hostpool_id) if not hostpool_info: logging.error( '创建VM 步骤6:获取必需信息失败 物理机池所属网络区域信息有误 ' 'task %s : hostpool %s info not in db when create instance', task_id, hostpool_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='物理机池所属网络区域信息有误,无法创建实例') net_area_id = hostpool_info['net_area_id'] logging.info( '创建VM 步骤6:获取必需信息成功 task %s : get need info successful when create instance', task_id) # 组配额控制 logging.info( '创建VM 步骤7:检查组配额 task %s : check group quota start when create instance', task_id) is_quota_enough, quota_msg = check_group_quota(group_id, flavor_info, vm_disk_gb, count) if not is_quota_enough: logging.error( '创建VM 步骤7:检查组配额失败 配额不足 ' 'task %s : group %s is no enough quota when create instance', task_id, group_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=quota_msg) logging.info( '创建VM 步骤7:检查组配额成功 task %s : check group quota successful when create instance', task_id) logging.info( '创建VM 步骤8:获取必需信息 task %s : get need 1 info start when create instance', task_id) # 获取镜像信息,一个image_name可能对应多个id image_nums, image_data = image_service.ImageService().get_images_by_name( image_name) if image_nums <= 0: logging.info( '创建VM 步骤8:获取必需信息失败 镜像资源不足 ' 'task %s : no image %s info in db when create instance', task_id, image_name) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='没有镜像资源,无法创建实例') # 实例操作系统 instance_system = image_data[0]['system'] logging.info( '创建VM 步骤8:获取必需信息成功 ' 'task %s : get need 1 info successful when create instance', task_id) # 获取集群所在的环境 vm_env = hostpool_service.get_env_of_hostpool(hostpool_id) # hostpool对应的机房名 dc_name = hostpool_service.get_dc_name_of_hostpool(hostpool_id) # 获取集群所在网络区域名 net_area_name = hostpool_service.get_level_info_by_id(hostpool_id).get( 'net_area_name', '') # 获取虚机名资源 logging.info( '创建VM 步骤9:获取主机名资源 ' 'task %s : check instance name resource start when create instance', task_id) is_name_enough, instance_name_list = _check_instance_name_resource( vm_env, dc_name, instance_system, count) if not is_name_enough: logging.error( '创建VM 步骤9:获取主机名资源失败 主机名资源不足 ' 'task %s : datacenter %s has no enough instance name resource', task_id, dc_name) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='主机名资源不足,无法创建实例') logging.info( '创建VM 步骤9:获取主机名资源成功 ' 'task %s : check instance name resource successful when create instance', task_id) # 获取IP资源,先判断是否有人也在分配IP资源,有则等待1s,时间之后再优化 ip_lock_unused = False while not ip_lock_unused: ret_ip_lock_status = ip_l_s.IpLockService().get_ip_lock_info('ip') if not ret_ip_lock_status: logging.error( '创建VM 步骤10:检查IP时无法获取资源锁状态' 'task %s : check ip resource can not get lock', task_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg='检查IP时无法获取资源锁状态') if ret_ip_lock_status['istraceing'] == IpLockStatus.USED: time.sleep(1) else: ip_lock_unused = True # 更新ip_lock表istraceing字段为1 ret_ip_lock_used_status, ret_ip_lock_used_datas = __update_ip_lock_used() if not ret_ip_lock_used_status: logging.error(ret_ip_lock_used_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_used_datas) try: ret_ips_status, ret_ips_data, ret_segment = __check_ip_resource( vm_env, dc_name, net_area_name, count) except Exception as e: _msg = '创建VM 步骤10:检查IP资源是否足够出现异常task_id %s: check ip resource exception when instance create,err:%s' % ( task_id, e) logging.error(_msg) ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=_msg) if not ret_ips_status: ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ips_data) # 更新ip_lock表istraceing字段为0 ret_ip_lock_unused_status, ret_ip_lock_unused_datas = __update_ip_lock_unused( ) if not ret_ip_lock_unused_status: logging.error(ret_ip_lock_unused_datas) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR, msg=ret_ip_lock_unused_datas) ips_list = ret_ips_data segment_data = ret_segment logging.info( '创建VM 步骤10:检查IP资源成功 task %s : check ip resource successful when create instance', task_id) # 挂载点 if instance_system == 'linux': mount_point = '/app' else: mount_point = 'E' logging.info( '创建VM 步骤11:多线程发送创建信息 task %s : create thread start when create instance', task_id) user_id = get_user()['user_id'] all_threads = [] for i in range(int(count)): instance_name = str(instance_name_list[i]) ip_data = ips_list[i] # 轮询host index = i % host_len vm_host = host_list[index] create_ins_t = threading.Thread( target=_create_instance_info, args=(task_id, instance_name, app_info, owner, password, flavor_id, group_id, vm_host, flavor_info, image_data, ip_data, vm_disk_gb, mount_point, instance_system, net_area_id, segment_data, vm_env, user_id), name='thread-instance-create-' + task_id) all_threads.append(create_ins_t) create_ins_t.start() for thread in all_threads: thread.join() logging.info( '创建VM 步骤11:多线程发送创建信息成功 ' 'task %s : create thread successful when create instance', task_id) return json_helper.format_api_resp(code=ErrorCode.SUCCESS)
def export_instance_excel(): params = { 'WHERE_AND': { '=': { 'status': None }, 'like': { 'name': None, 'uuid': None, 'owner': None }, 'in': { 'id': None } }, 'search_in_flag': 0, 'page_size': request.values.get('page_size'), 'page_no': request.values.get('page_no'), } ip_search_type = '' search = request.values.get('search') if search: json_search = json.loads(search) name = json_search.get('name') if name: params['WHERE_AND']['like']['name'] = '%' + name + '%' uuid = json_search.get('uuid') if uuid: params['WHERE_AND']['like']['uuid'] = '%' + uuid + '%' ip_address = json_search.get('ip_address') if ip_address: ip_search_type = json_search.get("ip_search_type") params['search_in_flag'] = 1 # 先模糊查询IP地址对应的实例ID search_ip_data = ins_s.get_instances_by_fuzzy_ip( ip_address, ip_search_type) instance_id_list = [i['instance_id'] for i in search_ip_data] if instance_id_list: params['WHERE_AND']['in']['id'] = tuple(instance_id_list) host_ip = json_search.get('host_ip') if host_ip: params['search_in_flag'] = 1 # 先模糊查询host IP对应的实例ID search_ip_data = ins_s.get_instances_by_fuzzy_host_ip(host_ip) instance_id_list = [i['instance_id'] for i in search_ip_data] if instance_id_list: params['WHERE_AND']['in']['id'] = tuple(instance_id_list) status = json_search.get('status') if status: params['WHERE_AND']['=']['status'] = status owner = json_search.get('owner') if owner: params['WHERE_AND']['like']['owner'] = '%' + owner + '%' group_name = json_search.get('group_name') if group_name: params['search_in_flag'] = 1 # 先模糊查询应用组对应的实例ID search_group_data = ins_s.get_instances_by_fuzzy_group_name( group_name) instance_id_list = [i['instance_id'] for i in search_group_data] if instance_id_list: params['WHERE_AND']['in']['id'] = tuple(instance_id_list) # 系统管理员能看到其组所在区域的所有VM role_ids = current_user_role_ids() # 系统管理员 if 1 in role_ids: is_admin = True else: is_admin = False total_nums, data = instance.user_instance_list(get_user()['user_id'], is_admin, ip_search_type, **params) # 生成excel excel_data = OrderedDict() sheet_1 = [] # 标题行 row_title_data = [ u"主机名", u"IP地址", u"HOST IP", u"状态", u"应用管理员", u"所属应用组", u"应用系统信息", u"所属集群", u"机房类型" ] sheet_1.append(row_title_data) if ip_search_type: data = list(data) data.sort(lambda x, y: cmp( ''.join([i.rjust(3, '0') for i in x['ip_address'].split('.')]), ''. join([i.rjust(3, '0') for i in y['ip_address'].split('.')]))) for i in data: _instance_group = ins_s.get_group_of_instance(i['id']) if _instance_group: _instance_group_name = _instance_group['name'] else: _instance_group_name = None _row_data = [ i['instance_name'], i['ip_address'], i['host_ip'], unicode(VMStatusMsg.MSG_DICT.get(i['status'], '')), i['owner'], _instance_group_name, i['app_info'], i['hostpool_name'], unicode(DataCenterTypeMsg.MSG_DICT.get(int(i['dc_type']), '')), ] sheet_1.append(_row_data) excel_data.update({u"instances": sheet_1}) io = StringIO.StringIO() save_data(io, excel_data) response = make_response(io.getvalue()) response.headers["Content-Disposition"] = "attachment; filename=虚拟机信息.xls" return response
def console(): """ 虚拟机vnc控制台 :param instance_id: :return : """ """ if not instance_id: logging.info('no instance id when get configure info') return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR, msg="参数错误") ins_data = ins_s.InstanceService().get_instance_info(instance_id) host_ip = ins_s.get_hostip_of_instance(instance_id) if not ins_data or not host_ip: logging.info('instance %s data is no exist in db when get configure info', instance_id) return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) instance_name = ins_data['name'] connect_disk_device_get = vmManager.libvirt_get_connect(host_ip, conn_type='instance', vmname=instance_name) # result, data = vmManager.libvirt_get_vnc_port(connect_disk_device_get, instance_name) # if not result: # logging.info(data) # return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) """ console_server_host = request.host.split(':')[0] apple = request.query_string.decode().strip() peeledapple = apple.split('=') instance_uuid = peeledapple[1] if not instance_uuid or not console_server_host: return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) ins_info = InstanceService().get_instance_info_by_uuid(instance_uuid) if not ins_info: return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) kvm_host_ip = get_hostip_of_instance(ins_info['id']) if not kvm_host_ip: return json_helper.format_api_resp(code=ErrorCode.PARAM_ERR) # 连接libvirtd查询虚拟机console端口号 connect_instance = vmManager.libvirt_get_connect(kvm_host_ip, conn_type='instance', vmname=ins_info['name']) status, vnc_port = vmManager.libvirt_get_vnc_console( connect_instance, ins_info['name']) if not status: return json_helper.format_api_resp(code=ErrorCode.SYS_ERR) token = str(kvm_host_ip) + '-' + str(vnc_port) resp = make_response( render_template('console-vnc.html', vm_name=ins_info['name'], ws_host=console_server_host, ws_port=6080)) resp.set_cookie('token', token) # 添加操作记录: try.. except .. 部分 try: user = user_service.get_user() extra_data = "name:" + ins_info['name'] + "," + "uuid:" + peeledapple[1] add_operation_other(user["user_id"], OperationObject.VM, OperationAction.CONSOLE, "SUCCESS", extra_data) except: pass return resp
def export_hostpool_excel(): params = { 'page_size': request.values.get('page_size'), 'page_no': request.values.get('page_no'), } total_nums, data = hostpool.user_hostpool_list(get_user()['user_id'], **params) # 生成excel excel_data = OrderedDict() sheet_1 = [] # 标题行 row_title_data = [ u"集群名", u"网络区域", u"所在机房", u"机房类型", u"Host数量", u"Host数量下限", u"vm数量", u"CPU数(核)", u"CPU使用率(%)", u"MEM总量(MB)", u"MEM分配率(%)", u"MEM使用率(%)", u"可创建虚拟机数量(个)", u"可用ip数量(个)" ] sheet_1.append(row_title_data) for i in data: # 获取该集群下所有host的cpu、mem使用情况 _all_host_num, _all_host_data = host_s.HostService( ).get_hosts_of_hostpool(i['hostpool_id']) if _all_host_num > 0: _cpu_mem_used = get_cpu_mem_used(_all_host_data, i['hostpool_id']) _cpu_nums = _cpu_mem_used['cpu_all'] _cpu_used_per = _cpu_mem_used['cpu_used_per'] _mem_nums = _cpu_mem_used['mem_all'] _mem_assign_per = _cpu_mem_used['assign_mem_per'] _mem_used_per = _cpu_mem_used['mem_used_per'] _available_create_vm_nums = _cpu_mem_used[ 'available_create_vm_num'] else: _cpu_nums = 0 _cpu_used_per = 0 _mem_nums = 0 _mem_assign_per = 0 _mem_used_per = 0 _available_create_vm_nums = 0 # 获取集群可用ip数量 _available_ip_nums = __all_ip_available_num(i['datacenter_id'], i['net_area_id']) _row_data = [ i['hostpool_name'], i['net_area_name'], i['datacenter_name'], unicode(DataCenterTypeMsg.MSG_DICT.get(int(i['dc_type']), '')), host_s.HostService().get_hosts_nums_of_hostpool(i['hostpool_id']), i['least_host_num'], i['instances_nums'], _cpu_nums, _cpu_used_per, _mem_nums, _mem_assign_per, _mem_used_per, _available_create_vm_nums, _available_ip_nums, ] sheet_1.append(_row_data) excel_data.update({u"hostpools": sheet_1}) io = StringIO.StringIO() save_data(io, excel_data) response = make_response(io.getvalue()) response.headers["Content-Disposition"] = "attachment; filename=集群信息.xls" return response