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})
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")
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))
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"])
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"))
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
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
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
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
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
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")
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
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