2025-11-18 00:03:24 +00:00
|
|
|
import { Injectable, inject } from '@angular/core';
|
|
|
|
|
import { HttpClient } from '@angular/common/http';
|
|
|
|
|
import { Observable } from 'rxjs';
|
|
|
|
|
|
|
|
|
|
export interface ApiResponse<T = any> {
|
|
|
|
|
success: boolean;
|
|
|
|
|
data?: T;
|
|
|
|
|
error?: string;
|
|
|
|
|
message?: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface Service {
|
|
|
|
|
id: number;
|
|
|
|
|
name: string;
|
|
|
|
|
image: string;
|
|
|
|
|
registry?: string;
|
|
|
|
|
envVars: Record<string, string>;
|
|
|
|
|
port: number;
|
|
|
|
|
domain?: string;
|
|
|
|
|
containerID?: string;
|
|
|
|
|
status: 'stopped' | 'starting' | 'running' | 'stopping' | 'failed';
|
|
|
|
|
createdAt: number;
|
|
|
|
|
updatedAt: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface Registry {
|
|
|
|
|
id: number;
|
|
|
|
|
url: string;
|
|
|
|
|
username: string;
|
|
|
|
|
createdAt: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export interface SystemStatus {
|
|
|
|
|
docker: {
|
|
|
|
|
running: boolean;
|
|
|
|
|
version: any;
|
|
|
|
|
};
|
2025-11-18 19:34:26 +00:00
|
|
|
reverseProxy: {
|
|
|
|
|
http: {
|
|
|
|
|
running: boolean;
|
|
|
|
|
port: number;
|
|
|
|
|
};
|
|
|
|
|
https: {
|
|
|
|
|
running: boolean;
|
|
|
|
|
port: number;
|
|
|
|
|
certificates: number;
|
|
|
|
|
};
|
|
|
|
|
routes: number;
|
2025-11-18 00:03:24 +00:00
|
|
|
};
|
|
|
|
|
dns: {
|
|
|
|
|
configured: boolean;
|
|
|
|
|
};
|
|
|
|
|
ssl: {
|
|
|
|
|
configured: boolean;
|
|
|
|
|
certbotInstalled: boolean;
|
|
|
|
|
};
|
|
|
|
|
services: {
|
|
|
|
|
total: number;
|
|
|
|
|
running: number;
|
|
|
|
|
stopped: number;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Injectable({
|
|
|
|
|
providedIn: 'root',
|
|
|
|
|
})
|
|
|
|
|
export class ApiService {
|
|
|
|
|
private http = inject(HttpClient);
|
|
|
|
|
private baseUrl = '/api';
|
|
|
|
|
|
|
|
|
|
// System
|
|
|
|
|
getStatus(): Observable<ApiResponse<SystemStatus>> {
|
|
|
|
|
return this.http.get<ApiResponse<SystemStatus>>(`${this.baseUrl}/status`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Services
|
|
|
|
|
getServices(): Observable<ApiResponse<Service[]>> {
|
|
|
|
|
return this.http.get<ApiResponse<Service[]>>(`${this.baseUrl}/services`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getService(name: string): Observable<ApiResponse<Service>> {
|
|
|
|
|
return this.http.get<ApiResponse<Service>>(`${this.baseUrl}/services/${name}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
createService(data: any): Observable<ApiResponse<Service>> {
|
|
|
|
|
return this.http.post<ApiResponse<Service>>(`${this.baseUrl}/services`, data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deleteService(name: string): Observable<ApiResponse> {
|
|
|
|
|
return this.http.delete<ApiResponse>(`${this.baseUrl}/services/${name}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
startService(name: string): Observable<ApiResponse> {
|
|
|
|
|
return this.http.post<ApiResponse>(`${this.baseUrl}/services/${name}/start`, {});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
stopService(name: string): Observable<ApiResponse> {
|
|
|
|
|
return this.http.post<ApiResponse>(`${this.baseUrl}/services/${name}/stop`, {});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
restartService(name: string): Observable<ApiResponse> {
|
|
|
|
|
return this.http.post<ApiResponse>(`${this.baseUrl}/services/${name}/restart`, {});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getServiceLogs(name: string): Observable<ApiResponse<string>> {
|
|
|
|
|
return this.http.get<ApiResponse<string>>(`${this.baseUrl}/services/${name}/logs`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Registries
|
|
|
|
|
getRegistries(): Observable<ApiResponse<Registry[]>> {
|
|
|
|
|
return this.http.get<ApiResponse<Registry[]>>(`${this.baseUrl}/registries`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
createRegistry(data: any): Observable<ApiResponse<Registry>> {
|
|
|
|
|
return this.http.post<ApiResponse<Registry>>(`${this.baseUrl}/registries`, data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deleteRegistry(url: string): Observable<ApiResponse> {
|
|
|
|
|
return this.http.delete<ApiResponse>(`${this.baseUrl}/registries/${encodeURIComponent(url)}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DNS
|
|
|
|
|
getDnsRecords(): Observable<ApiResponse<any[]>> {
|
|
|
|
|
return this.http.get<ApiResponse<any[]>>(`${this.baseUrl}/dns`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
createDnsRecord(data: any): Observable<ApiResponse> {
|
|
|
|
|
return this.http.post<ApiResponse>(`${this.baseUrl}/dns`, data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deleteDnsRecord(domain: string): Observable<ApiResponse> {
|
|
|
|
|
return this.http.delete<ApiResponse>(`${this.baseUrl}/dns/${domain}`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// SSL
|
|
|
|
|
getSslCertificates(): Observable<ApiResponse<any[]>> {
|
|
|
|
|
return this.http.get<ApiResponse<any[]>>(`${this.baseUrl}/ssl`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
renewSslCertificate(domain: string): Observable<ApiResponse> {
|
|
|
|
|
return this.http.post<ApiResponse>(`${this.baseUrl}/ssl/${domain}/renew`, {});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Settings
|
|
|
|
|
getSettings(): Observable<ApiResponse<Record<string, string>>> {
|
|
|
|
|
return this.http.get<ApiResponse<Record<string, string>>>(`${this.baseUrl}/settings`);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
updateSetting(key: string, value: string): Observable<ApiResponse> {
|
|
|
|
|
return this.http.post<ApiResponse>(`${this.baseUrl}/settings`, { key, value });
|
|
|
|
|
}
|
|
|
|
|
}
|