feat: add server lifecycle management and D1 logging
- Add start/stop/reboot endpoints for server power management - Add D1-based logging system (logs table + db-logger utility) - Add idempotency_key validation for order deduplication - Extend VPS provider interface with lifecycle methods Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -134,9 +134,96 @@ export class VultrProvider extends VPSProviderBase {
|
||||
}
|
||||
}
|
||||
|
||||
async startServer(instanceId: string): Promise<{ success: boolean; error?: string }> {
|
||||
const url = `${this.config.baseUrl}/instances/${instanceId}/start`;
|
||||
|
||||
try {
|
||||
const response = await this.fetchWithRetry(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.config.apiKey}`,
|
||||
},
|
||||
});
|
||||
|
||||
// Vultr returns 204 No Content on success
|
||||
if (response.status === 204 || response.ok) {
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
const error = (await response.json()) as VultrError;
|
||||
return {
|
||||
success: false,
|
||||
error: error.error || 'Failed to start instance',
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Network error',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async stopServer(instanceId: string): Promise<{ success: boolean; error?: string }> {
|
||||
const url = `${this.config.baseUrl}/instances/${instanceId}/halt`;
|
||||
|
||||
try {
|
||||
const response = await this.fetchWithRetry(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.config.apiKey}`,
|
||||
},
|
||||
});
|
||||
|
||||
// Vultr returns 204 No Content on success
|
||||
if (response.status === 204 || response.ok) {
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
const error = (await response.json()) as VultrError;
|
||||
return {
|
||||
success: false,
|
||||
error: error.error || 'Failed to stop instance',
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Network error',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async rebootServer(instanceId: string): Promise<{ success: boolean; error?: string }> {
|
||||
const url = `${this.config.baseUrl}/instances/${instanceId}/reboot`;
|
||||
|
||||
try {
|
||||
const response = await this.fetchWithRetry(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.config.apiKey}`,
|
||||
},
|
||||
});
|
||||
|
||||
// Vultr returns 204 No Content on success
|
||||
if (response.status === 204 || response.ok) {
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
const error = (await response.json()) as VultrError;
|
||||
return {
|
||||
success: false,
|
||||
error: error.error || 'Failed to reboot instance',
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
success: false,
|
||||
error: error instanceof Error ? error.message : 'Network error',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async getServerStatus(
|
||||
instanceId: string
|
||||
): Promise<{ status: string; ipv4?: string; ipv6?: string }> {
|
||||
): Promise<{ status: string; power_status?: string; ipv4?: string; ipv6?: string }> {
|
||||
const url = `${this.config.baseUrl}/instances/${instanceId}`;
|
||||
|
||||
try {
|
||||
@@ -154,6 +241,7 @@ export class VultrProvider extends VPSProviderBase {
|
||||
const data = (await response.json()) as { instance: VultrInstance };
|
||||
return {
|
||||
status: data.instance.status,
|
||||
power_status: data.instance.power_status,
|
||||
ipv4: data.instance.main_ip !== '0.0.0.0' ? data.instance.main_ip : undefined,
|
||||
ipv6: data.instance.v6_main_ip || undefined,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user