Example #1
0
def restore_disk_backup(payload):
    resource_id = payload.pop("resource_id", None)
    backup_id = payload.pop("backup_id")
    action = payload.pop("action")
    version = payload.pop("version")
    backup_info = DiskBackupModel.get_backup_by_id(backup_id=backup_id)
    backup_uuid = backup_info.uuid

    if resource_id is not None:
        try:
            resource_uuid = DisksModel.get_disk_by_id(disk_id=resource_id).uuid
        except Exception:
            error_info = "cannot find disk with disk_id " + resource_id
            return console_response(BackupErrorCode.RESTORE_RESOURCE_NOT_FOUND,
                                    error_info)
    else:
        payload.update({
            "action": "DescribeDiskBackup",
            "backup_id": backup_uuid
        })
        # resp = api.get(payload=payload, timeout=10)
        resp = api.get(payload=payload)
        if resp.get("code") != 0:
            return console_response(CommonErrorCode.REQUEST_API_ERROR,
                                    resp.get("msg"))
        elif resp["data"]["total_count"] <= 0:
            return console_response(
                BackupErrorCode.ASSOCIATE_DISK_NOT_FOUND,
                "the disk related to the backup cannot "
                "be found, may be it has already "
                "been deleted")
        resource_uuid = resp["data"]["ret_set"][0]["volume_id"]
        zone_record = ZoneModel.get_zone_by_name(payload["zone"])
        resource_record = DisksModel.get_disk_by_uuid(resource_uuid,
                                                      zone_record)
        if resource_record:
            resource_id = resource_record.disk_id
    payload.update({
        "action": action,
        "version": version,
        "disk_uuid": resource_uuid,
        "backup_id": backup_uuid
    })
    # resp = api.get(payload=payload, timeout=10)
    resp = api.get(payload=payload)

    msg = resp.get("msg")
    if msg is None:
        msg = "Success"
    code = 0
    if resp.get("code") != 0:
        code = CommonErrorCode.REQUEST_API_ERROR
    # source_backup_id is for record
    return console_response(code, msg, 1, [{
        "disk_id": resource_id,
        "backup_id": backup_id
    }], {"source_backup_id": resource_id})
Example #2
0
def waiting_disk_creating_and_restore(payload):
    disk_id = payload.pop("disk_id")
    backup_id = payload.pop("backup_id")
    version = payload.pop("version")

    disk_uuid = DisksModel.get_disk_by_id(disk_id).uuid
    # 默认尝试 每2秒查看1次,超时时间为20分钟
    try_time = 600
    create_succ = False
    while try_time > 0:
        payload.update({
            "action": "DescribeDisks",
            "version": version,
            "volume_id": disk_uuid
        })
        # describe_disk_resp = api.get(payload=payload, timeout=10)
        describe_disk_resp = api.get(payload=payload)
        if describe_disk_resp.get("code") == 0:
            status = describe_disk_resp["data"]["ret_set"][0]["status"]
            if status.strip() == 'available':
                create_succ = True
                break
            elif status.strip() == 'creating':
                if try_time > 1:
                    gevent.sleep(2)
            else:
                return console_response(DiskErrorCode.CREATE_DISK_FAILED,
                                        "create disk failed")
        else:
            if try_time > 1:
                logger("describe the status of disk failed, will try again")
                gevent.sleep(2)
        try_time -= 1
    if create_succ is True:
        logger.info(
            "create disk successfully, begin to restore from the backup")
        payload.update({
            "action": "RestoreDiskBackup",
            "backup_type": "disk",
            "resource_id": disk_id,
            "backup_id": backup_id,
            "version": version
        })

        return restore_disk_backup(payload)
    else:
        DisksModel.delete_disk(disk_id)
        logger.error("create disk failed,the billing should be deleted")
        return console_response(DiskErrorCode.CREATE_DISK_FAILED,
                                "create disk failed")
Example #3
0
def update_disk_backup_time(disk_id, logger):
    try:
        disk_ins = DisksModel.get_disk_by_id(disk_id=disk_id)
        disk_ins.backup_time = int(
            time.mktime(datetime.datetime.utcnow().timetuple()))
        disk_ins.save()
    except Exception as exp:
        logger.error("errors occur while save the last backup "
                     "time to disk table, %s" % str(exp))
Example #4
0
def sync_quota(resource, _payload):
    ret_set = []
    extra_infos = RESOURCE_TO_DESC_EXTRA_PARA.get(resource)
    func = RESOURCE_TO_DESC_FUN.get(resource)
    for extra_info in extra_infos:
        resp = func(dict(_payload, **extra_info))
        if resp.get("ret_code") != 0:
            logger.error("cannot get the resource list of %s" %
                         unicode(resource))
            return
        ret_set += resp.get("ret_set")

    if resource != "net":
        value = len(ret_set)
        # add logic for pre-pay
        resource_ids = []
        records = []
        pre_pay_num = 0
        if resource == 'disk':
            for disk_info in ret_set:
                resource_ids.append(disk_info.get('disk_id'))
            records = DisksModel.get_exact_disks_by_ids(resource_ids)
        elif resource == 'instance':
            for inst_info in ret_set:
                resource_ids.append(inst_info.get('instance_id'))
            records = InstancesModel.get_exact_instances_by_ids(resource_ids)
        elif resource == 'backup':
            for backup_info in ret_set:
                resource_ids.append(backup_info.get('backup_id'))
            records_fir = InstanceBackupModel.\
                get_exact_backups_by_ids(resource_ids)
            records_sec = DiskBackupModel.get_exact_backups_by_ids(
                resource_ids)
            for record in records_fir:
                records.append(record)
            for record in records_sec:
                records.append(record)
        elif resource == 'pub_ip':
            for ip_info in ret_set:
                resource_ids.append(ip_info.get('ip_id'))
            records = IpsModel.get_exact_ips_by_ids(resource_ids)
        if len(records) > 0:
            for record in records:
                if getattr(record, 'charge_mode') != "pay_on_time":
                    pre_pay_num += 1
        value -= pre_pay_num

        payload = deepcopy(_payload)
        q_type = RESOURCE_TO_GENERAL_QTYPE.get(resource, None)
        if q_type:
            payload.update({"quota_type": q_type})
            synchronize_visible_to_db(payload, value)
    # special quota sync
    if resource in SYNC_QUOTA_FUNC.keys():
        func = SYNC_QUOTA_FUNC.get(resource)
        func(ret_set, _payload["owner"], _payload["zone"])
Example #5
0
def create_disk_backup(payload):
    _backup_name = payload.pop("backup_name")  # 用于前端展示的备份的名称
    _resource_id = payload.pop("resource_id")
    _version = payload.get("version")
    _owner = payload.get("owner")
    _zone = payload.get("zone")
    _action = payload.get("action")
    charge_mode = payload.get("charge_mode")
    backup_id = payload["name"]

    resource_uuid = DisksModel.get_disk_by_id(disk_id=_resource_id).uuid
    # 获取备份硬盘信息
    cr = get_bakcup_disk_info(payload, resource_uuid, logger)
    if cr.get("ret_code") != 0:
        return cr
    else:
        disk_resp = cr["ret_set"][0]
    disk_type = disk_resp["data"]["ret_set"][0]["volume_type"]

    payload.pop("volume_id")
    payload.update({
        "disk_uuid":
        resource_uuid,
        "action":
        _action,
        "version":
        _version,
        "description":
        disk_resp["data"]["ret_set"][0]["volume_type"]
    })

    _resp = api.get(payload=payload)
    if _resp.get("code") == 0:
        uuid = _resp["data"]["ret_set"][0]["id"]
        _inst, err = DiskBackupModel.objects.create(zone=_zone,
                                                    owner=_owner,
                                                    backup_id=backup_id,
                                                    backup_name=_backup_name,
                                                    uuid=uuid,
                                                    backup_type="disk",
                                                    disk_type=disk_type,
                                                    charge_mode=charge_mode)
        if err is not None:
            return console_response(BackupErrorCode.SAVE_BACKUP_FAILED,
                                    str(err))
        # 更新硬盘备份时间
        update_disk_backup_time(_resource_id, logger)
        # source_backup_id is added for record action
        return console_response(
            0,
            "Success",
            1, [backup_id],
            action_record={"source_backup_id": _resource_id})
    else:
        return console_response(CommonErrorCode.REQUEST_API_ERROR,
                                _resp.get("msg"))
Example #6
0
def format_payload_disks(disks):
    disk_info = {}
    device_end = ord('b')
    for disk_id in disks:
        device_end += 1
        disk_inst = DisksModel.get_disk_by_id(disk_id)
        if disk_inst:
            device = "vd" + chr(device_end)
            disk_info[device] = disk_inst.uuid
    return disk_info
Example #7
0
def format_data_list(item, data_list, instance, payload):
    name_dict = {}
    item = str(item)
    new_data_list = []
    if item.startswith("CPU") or item.startswith("MEMORY"):
        new_data_list = [None]
    elif item.startswith("NET"):
        instance = dict(instance)
        net_info = instance.get("addresses")
        for net_name, net_detail in net_info.items():
            nets = list(net_detail)
            for net in nets:
                net = dict(net)
                ip_addr = net.get("addr")
                mac_addr = net.get("OS-EXT-IPS-MAC:mac_addr")
                addr_type = net.get("OS-EXT-IPS:type")
                if ip_addr in data_list and addr_type.strip() == "fixed":
                    new_data_list.append(mac_addr)
                    name_dict.update({mac_addr: ip_addr})
        new_data_list = set(new_data_list)
    elif item.startswith("SYS_DISK"):
        new_data_list = ["vda"]
    elif item.startswith("DATA_DISK"):
        instance = dict(instance)
        attached_disks = instance.get("os-extended-volumes:volumes_attached")
        for disk in attached_disks:
            disk = dict(disk)
            disk_uuid = disk.get("id")
            disk_info = DisksModel.get_disk_by_uuid(
                disk_uuid, ZoneModel.get_zone_by_name(payload.get("zone")))
            disk_id = disk_info.disk_id
            if disk_uuid in data_list:
                new_data_list.append(disk_uuid)
                name_dict.update({disk_uuid: disk_id})
    elif item.startswith("PUBLIC_IP"):
        instance = dict(instance)
        float_ip_info = instance.get("addresses")
        for net_name, net_detail in float_ip_info.items():
            nets = list(net_detail)
            for net in nets:
                net = dict(net)
                ip_addr = net.get("addr")
                addr_type = net.get("OS-EXT-IPS:type")
                if ip_addr in data_list and addr_type.strip() == "floating":
                    new_data_list.append(ip_addr)
                    name_dict.update({ip_addr: ip_addr})
        new_data_list = set(new_data_list)

    return new_data_list, name_dict
Example #8
0
def get_disks_info(volumes_attached, zone):
    zone_record = ZoneModel.get_zone_by_name(zone)
    disks = []
    for volume in volumes_attached:
        disk_uuid = volume["id"]
        disk_obj = DisksModel.get_disk_by_uuid(uuid=disk_uuid,
                                               zone=zone_record)
        if disk_obj:
            disk = {}
            disk["disk_id"] = disk_obj.disk_id
            disk["disk_name"] = disk_obj.name
            disk["create_datetime"] =\
                datetime_to_timestamp(disk_obj.create_datetime)
            disks.append(disk)
    return disks
Example #9
0
def get_resource_name(device_name):
    resource_name = device_name
    if device_name.startswith("d-"):
        resource_name = DisksModel.get_disk_by_id(device_name)
    elif device_name.startswith("i-"):
        resource_name = InstancesModel.get_instance_by_id(device_name)
    elif device_name.startswith("lb-"):
        resource_name = LoadbalancerModel.get_lb_by_id(device_name)
    elif device_name.startswith("lbl-"):
        resource_name = ListenersModel.get_lbl_by_id(device_name)
    elif device_name.startswith("rds-"):
        resource_name = RdsModel.get_rds_by_id(device_name)
    if isinstance(resource_name, BaseModel):
        resource_name = resource_name.name
    return resource_name
Example #10
0
def get_resource_inst_by_uuid(backup_type, uuid, zone, deleted=False):
    if backup_type == "disk":
        try:
            inst = DisksModel.get_disk_by_uuid(uuid=uuid,
                                               zone=zone,
                                               deleted=deleted)
            return inst
        except Exception as exp:
            return None
    else:
        try:
            inst = InstancesModel.get_instance_by_uuid(uuid=uuid,
                                                       deleted=deleted)
            return inst
        except Exception as exp:
            return None
Example #11
0
def resource_id_validator(value):
    if not value.startswith(settings.INSTANCE_PREFIX) and \
            not value.startswith(settings.DISK_PREFIX):
        raise serializers.ValidationError(
            "The resource id should be start with %(instance)s(instance) or "
            "%(disk)s(disk)" % {
                "instance": settings.INSTANCE_PREFIX,
                "disk": settings.DISK_PREFIX
            })
    if value.startswith(settings.DISK_PREFIX) and \
            not DisksModel.disk_exists_by_id(disk_id=value):
        raise serializers.ValidationError(
            "The resource id do not exists in the model")
    if value.startswith(settings.INSTANCE_PREFIX) and \
            not InstancesModel.instance_exists_by_id(instance_id=value):
        raise serializers.ValidationError(
            "The resource id do not exists in the model")
Example #12
0
def get_data_disk(ins_list, payload):
    info_dict = {}
    name_dict = {}
    for ins in ins_list:
        ins_uuid = ins.get("id")
        data_list = []
        attached_disks = ins.get("os-extended-volumes:volumes_attached")
        for disk in attached_disks:
            disk = dict(disk)
            disk_uuid = disk.get("id")
            disk_info = DisksModel.get_disk_by_uuid(
                disk_uuid, ZoneModel.get_zone_by_name(payload.get("zone")))
            if disk_info is not None:
                disk_id = disk_info.disk_id
                name_dict.update({disk_uuid: disk_id})
                data_list.append(disk_uuid)
        info_dict[ins_uuid] = data_list
    return info_dict, name_dict
Example #13
0
        def handle_args(*args, **kwargs):

            _payload = kwargs.get("payload", None)
            if _payload is None:
                _payload = args[0]
            payload = copy.deepcopy(_payload)
            owner = payload.get("owner")
            zone = payload.get("zone")
            capacity = 1

            resp = func(*args, **kwargs)
            value = resp.get("ret_set")
            logger.info("%s, %s, %s" % (str(owner), str(zone), str(quota_type)))
            if value is not None:

                # add logic for pre-pay
                pre_pay_num = 0
                if resp.get("ret_code") == 0:
                    records = []
                    if quota_type == 'disk':
                        resource_ids = payload.get("disk_id")
                        records = DisksModel.get_exact_disks_by_ids(resource_ids)
                    elif quota_type == 'instance':
                        resource_ids = payload.get("instances")
                        records = InstancesModel.get_exact_instances_by_ids(
                            resource_ids)
                    elif quota_type == 'backup':
                        resource_ids = payload.get("backup_id_list")
                        records_fir = InstanceBackupModel. \
                            get_exact_backups_by_ids(resource_ids)
                        records_sec = DiskBackupModel. \
                            get_exact_backups_by_ids(resource_ids)
                        for record in records_fir:
                            records.append(record)
                        for record in records_sec:
                            records.append(record)
                    elif quota_type == 'pub_ip':
                        resource_ids = payload.get("ips")
                        records = IpsModel.get_exact_ips_by_ids(resource_ids)
                    if len(records) > 0:
                        for record in records:
                            if getattr(record, 'charge_mode') != "pay_on_time":
                                pre_pay_num += 1

                if isinstance(value, list):
                    dec_resp = append_quota(
                        zone=zone, owner=owner, q_type=quota_type,
                        value=((len(value) - pre_pay_num) * capacity))
                    if dec_resp.get("ret_code") != 0:
                        logger.error(QUOTAS_MSG.get(QuotaErrorCode.
                                                    QUOTA_MODIFICATION_ERROR))
                    else:
                        logger.info("%s quota increased by: %s" %
                                    (str(quota_type), str(len(value) * capacity)))
                else:
                    dec_resp = append_quota(
                        zone=zone, owner=owner, q_type=quota_type,
                        value=(1 - pre_pay_num) * capacity)
                    if dec_resp.get("ret_code") != 0:
                        logger.error(QUOTAS_MSG.get(QuotaErrorCode.
                                                    QUOTA_MODIFICATION_ERROR))
                    else:
                        logger.info("%s quota increased by: %s" %
                                    (str(quota_type), str(capacity)))
            return resp