Skip to content

Multi-Location Support (HCM/HNI)

Giới thiệu

Trong bài này, chúng ta sẽ tìm hiểu cách xử lý multi-location support, cho phép hệ thống hoạt động với cả OpenStack HCM và Hà Nội.


Location Normalization

Normalize Function

typescript
function normalizeLocation(location?: string): string {
  if (!location || location === '') {
    return 'HCM';
  }
  if (location === 'HNI') {
    return 'HNI';
  }
  return 'HCM'; // Default to HCM
}

Rules:

  • Empty/null → 'HCM'
  • 'HNI' → 'HNI'
  • Any other value → 'HCM'

Location-Based Configuration

Environment Variables

bash
# HCM Configuration
OPENSTACK_ENDPOINT_HCM=https://keystone-hcm.inet.vn:5000
OPENSTACK_USERNAME_HCM=portal-user-hcm
OPENSTACK_PASSWORD_HCM=password-hcm
OPENSTACK_PROJECT_ID_HCM=project-id-hcm

# HNI Configuration
OPENSTACK_ENDPOINT_HN=https://keystone-hni.inet.vn:5000
OPENSTACK_USERNAME_HN=portal-user-hni
OPENSTACK_PASSWORD_HN=password-hni
OPENSTACK_PROJECT_ID_HN=project-id-hni

Get OpenStack Environment

typescript
export function getOpenStackEnv(location?: string): OpenStackEnv {
  const normalizedLocation = normalizeLocation(location);
  const isHanoi = normalizedLocation === 'HNI';
  
  const baseEndpoint = isHanoi 
    ? process.env.OPENSTACK_ENDPOINT_HN
    : process.env.OPENSTACK_ENDPOINT_HCM;
  
  const username = isHanoi
    ? process.env.OPENSTACK_USERNAME_HN
    : process.env.OPENSTACK_USERNAME_HCM;
  
  // ... other configs
  
  return {
    authUrl: `${baseEndpoint}/identity/v3`,
    baseEndpoint,
    username,
    // ...
  };
}

Location trong BackupSchedule

Schedule Model

typescript
interface IBackupSchedule {
  location?: string; // 'HCM' or 'HNI'
  // ...
}

Usage

typescript
// Create schedule với location
await upsertBackupSchedule({
  resourceId: 'server-123',
  location: 'HNI', // Specify location
  // ...
});

// Normalize trong service
if (!data.location || data.location === '') {
  data.location = 'HCM';
} else if (data.location === 'HNI') {
  data.location = 'HNI';
} else {
  data.location = 'HCM';
}

Endpoint Routing

Build Endpoint

typescript
function buildEndpoint(
  service: 'compute' | 'image' | 'cloudformation',
  location?: string
): string {
  const env = getOpenStackEnv(location);
  const baseEndpoint = env.baseEndpoint;
  
  switch (service) {
    case 'compute':
      return `${baseEndpoint}/compute/v2.1`;
    case 'image':
      return `${baseEndpoint}/image`;
    case 'cloudformation':
      return `${baseEndpoint}/cloudformation/v1`;
    default:
      throw new Error(`Unknown service: ${service}`);
  }
}

Best Practices

Always Normalize Location

typescript
// ✅ DO
const normalizedLocation = normalizeLocation(location);
const { token } = await getScopedToken(normalizedLocation);

// ❌ DON'T
const { token } = await getScopedToken(location); // May be undefined

Pass Location Through Chain

typescript
// ✅ DO: Pass location through all functions
async function createBackup(serverId: string, location: string) {
  const { token } = await getScopedToken(location);
  const endpoint = buildEndpoint('compute', location);
  // ...
}

Summary

Key Points

  1. Location Normalization

    • Always normalize before use
    • Default to HCM
  2. Environment Variables

    • Separate configs per location
    • Use location-specific env vars
  3. Endpoint Routing

    • Build endpoints based on location
    • Pass location through chain

Next Steps

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


Last Updated: 2025-01-25
Previous: 06. Template System
Next: 08. Snapshot Limits

Internal documentation for iNET Portal