Skip to content

Template-Based Backup System

Giới thiệu

Trong bài này, chúng ta sẽ tìm hiểu về hệ thống template-based backup, cho phép tái sử dụng cấu hình backup cho nhiều servers.


Template Model

BackupScheduleTemplate Schema

typescript
interface IBackupScheduleTemplate {
  _id?: string;
  name: string;
  frequency: 'daily' | 'weekly' | 'monthly';
  startHour: number; // 0-23
  startDay?: number; // For monthly: 1-31
  rotate: number; // Number of backups to keep
  vault?: string;
  enabled: boolean;
  customerEmail: string;
  description?: string;
}

Find or Create Pattern

Default Template

typescript
export async function findOrCreateDefaultTemplate(
  customerEmail: string
): Promise<IBackupScheduleTemplate> {
  const defaultTemplateName = 'Default Weekly Backup';

  // Try to find existing default template
  let template = await BackupScheduleTemplate.findOne({
    customerEmail,
    name: defaultTemplateName,
  });

  // If not found, create it
  if (!template) {
    template = new BackupScheduleTemplate({
      name: defaultTemplateName,
      frequency: 'weekly',
      startHour: 2,
      rotate: 1,
      enabled: true,
      customerEmail,
      description: 'Lịch backup mặc định: Hàng tuần vào 2h sáng, giữ 1 bản backup',
    });

    await template.save();
  }

  return template;
}

Custom Template

typescript
export async function findOrCreateTemplate(
  customerEmail: string,
  settings: {
    frequency: TemplateFrequency;
    startHour: number;
    rotate: number;
    startDay?: number;
    vault?: string;
  }
): Promise<IBackupScheduleTemplate> {
  const templateName =
    `${
      settings.frequency.charAt(0).toUpperCase() + settings.frequency.slice(1)
    } ` + `${settings.startHour}h Rotate${settings.rotate}`;

  // Find existing template with same settings
  let template = await BackupScheduleTemplate.findOne({
    customerEmail,
    frequency: settings.frequency,
    startHour: settings.startHour,
    rotate: settings.rotate,
    startDay: settings.startDay || undefined,
  });

  // Create if not found
  if (!template) {
    template = new BackupScheduleTemplate({
      name: templateName,
      ...settings,
      enabled: true,
      customerEmail,
    });
    await template.save();
  }

  return template;
}

Apply Template to Servers

Apply Template

typescript
export async function applyTemplateToServers(
  payload: IBackupScheduleTemplateApplyRequest
) {
  const { templateId, resourceIds, resourceType, customerEmail } = payload;

  // Get template
  const template = await BackupScheduleTemplate.findOne({
    _id: templateId,
    customerEmail,
  });

  if (!template) {
    throw new Error('Template not found');
  }

  const intervalDays = convertFrequencyToIntervalDays(template.frequency);

  // Apply template to each server
  for (const resourceId of resourceIds) {
    await upsertBackupSchedule({
      resourceType,
      resourceId,
      customerEmail,
      startHour: template.startHour,
      intervalDays,
      retain: template.rotate,
      enabled: template.enabled,
      timezone: 'Asia/Ho_Chi_Minh',
      scheduleTemplateId: template._id as string,
    } as any);
  }
}

Benefits

DRY Principle

  • Trước: Mỗi schedule lưu cấu hình riêng
  • Sau: Nhiều schedules share một template

Easy Management

  • Thay đổi template → Áp dụng cho tất cả servers
  • Consistent backup policies
  • Bulk operations

Migration

Xem chi tiết trong file: TEMPLATE_BASED_BACKUP_MIGRATION.md


Summary

Key Points

  1. Template Pattern

    • Reusable configuration
    • Find or create pattern
    • Default templates
  2. Apply Template

    • Link schedule to template
    • Copy template config
    • Bulk operations
  3. Benefits

    • DRY principle
    • Easy management
    • Consistency

Next Steps

Trong bài tiếp theo, chúng ta sẽ tìm hiểu về:


Last Updated: 2025-01-25
Previous: 05. Queue Management
Next: 07. Multi-Location

Internal documentation for iNET Portal