コード例 #1
0
        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
コード例 #2
0
        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
コード例 #3
0
        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
コード例 #4
0
        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
コード例 #5
0
        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
コード例 #6
0
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())
コード例 #7
0
        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
コード例 #8
0
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())
コード例 #9
0
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())
コード例 #10
0
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)
コード例 #11
0
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)
コード例 #12
0
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)
コード例 #13
0
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)
コード例 #14
0
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='修改配置成功')
コード例 #15
0
        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
コード例 #16
0
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')
コード例 #17
0
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)
コード例 #18
0
        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
コード例 #19
0
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)
コード例 #20
0
        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
コード例 #21
0
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)
コード例 #22
0
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
コード例 #23
0
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)
コード例 #24
0
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
コード例 #25
0
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
コード例 #26
0
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