oggui/ogWebconsole/src/app/components/global-status/global-status.component.ts

624 lines
19 KiB
TypeScript

import { HttpClient } from '@angular/common/http';
import { Component, OnInit } from '@angular/core';
import { ConfigService } from '@services/config.service';
import { ToastrService } from "ngx-toastr";
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
@Component({
selector: 'app-global-status',
templateUrl: './global-status.component.html',
styleUrl: './global-status.component.css'
})
export class GlobalStatusComponent implements OnInit {
baseUrl: string;
loading: boolean = false;
loadingOgBoot: boolean = false;
loadingDhcps: boolean = false;
loadingRepositories: boolean = false;
errorOgBoot: boolean = false;
errorDhcps: { [key: string]: boolean } = {};
errorRepositories: { [key: string]: boolean } = {};
installedOgLives: any[] = [];
subnets: any[] = [];
showLabels: boolean = true;
isDoughnut: boolean = true;
colorScheme: any = {
domain: ['#df200d', '#26a700']
};
view: [number, number] = [400, 220];
repositoriesUrl: string;
repositories: any[] = [];
repositoryStatuses: { [key: string]: any } = {};
lastUpdateTime: string = '';
selectedRepositoryUuid: string = '';
selectedSection: 'repositories' | 'ogboot' | 'dhcp' | 'ogcore' = 'repositories';
ogBootApiUrl: string;
ogBootDiskUsage: any = {};
ogBootServicesStatus: any = {};
ogBootDiskUsageChartData: any[] = [];
dhcpsApiUrl: string;
dhcps: any[] = [];
dhcpDiskUsage: any = {};
dhcpStatuses: { [key: string]: any } = {};
dhcpDiskUsageChartData: any[] = [];
selectedDhcpUuid: string = '';
isDhcp: boolean = false;
isRepository: boolean = false;
ogCoreApiUrl: string;
loadingOgBootOgLives: boolean = false;
loadingOgBootServices: boolean = false;
loadingOgBootDisk: boolean = false;
loadingDhcpSubnets: boolean = false;
loadingDhcpServices: boolean = false;
loadingDhcpDisk: boolean = false;
constructor(
private configService: ConfigService,
private toastService: ToastrService,
private http: HttpClient,
private sanitizer: DomSanitizer
) {
this.baseUrl = this.configService.apiUrl;
this.ogBootApiUrl = `${this.baseUrl}/og-boot/status`;
this.dhcpsApiUrl = `${this.baseUrl}/dhcp-servers`;
this.ogCoreApiUrl = `${this.baseUrl}`;
this.repositoriesUrl = `${this.baseUrl}/image-repositories`;
this.ogBootDiskUsageChartData = [];
this.dhcpDiskUsageChartData = [];
}
ngOnInit(): void {
this.updateLastUpdateTime();
this.loadOgBootStatus();
this.loadDhcps(false);
this.loadRepositories(false);
this.syncSubnets();
this.syncTemplates();
this.syncOgLives();
}
syncSubnets() {
this.http.get<any>(`${this.dhcpsApiUrl}?page=1&itemsPerPage=10`).subscribe(data => {
const dhcps = data['hydra:member'] || [];
if (dhcps.length === 0) return;
let pending = dhcps.length;
let hasError = false;
const timeoutId = setTimeout(() => {
if (!hasError) {
this.toastService.error('Error al sincronizar las subredes: tiempo de espera agotado');
hasError = true;
}
}, 5000);
dhcps.forEach((dhcp: any) => {
this.http.post(`${this.baseUrl}/dhcp-servers/${dhcp.uuid}/sync`, {}).subscribe({
next: () => {
pending--;
if (pending === 0 && !hasError) {
clearTimeout(timeoutId);
this.toastService.success('Sincronización de subredes de servidores DHCP exitosa');
}
},
error: (error) => {
pending--;
if (!hasError) {
hasError = true;
clearTimeout(timeoutId);
this.toastService.error(error.error['hydra:description'] || `Error al sincronizar subredes del DHCP ${dhcp.name || dhcp.uuid}`);
}
}
});
});
}, error => {
console.error('Error fetching DHCP servers for subnet sync', error);
});
}
syncTemplates() {
const timeoutId = setTimeout(() => {
this.toastService.error('Error al sincronizar las plantillas Pxe: tiempo de espera agotado');
}, 3500);
this.http.post(`${this.baseUrl}/pxe-templates/sync`, {})
.subscribe(response => {
clearTimeout(timeoutId);
this.toastService.success('Sincronización de las plantillas Pxe completada');
}, error => {
clearTimeout(timeoutId);
this.toastService.error(error.error['hydra:description'] || 'Error al sincronizar las plantillas Pxe');
});
}
syncOgLives(): void {
const timeoutId = setTimeout(() => {
this.toastService.error('Error al sincronizar las imagenes ogLive : tiempo de espera agotado');
}, 3500);
this.http.post(`${this.baseUrl}/og-lives/sync`, {})
.subscribe(response => {
clearTimeout(timeoutId);
this.toastService.success('Sincronización con los ogLives completada');
}, error => {
clearTimeout(timeoutId);
this.toastService.error(error.error['hydra:description'] || 'Error al sincronizar las imagenes ogLive');
});
}
[key: string]: any;
loadStatus(apiUrl: string, diskUsage: any, servicesStatus: any, diskUsageChartData: any[], installedOgLives: any[], isDhcp: boolean, errorState: string, showLoading: boolean = true): void {
if (isDhcp) {
this.loadingDhcps = true;
} else {
this.loadingOgBoot = true;
}
if (showLoading) {
this.loading = true;
}
this[errorState] = false;
const timeoutId = setTimeout(() => {
if (showLoading) {
this.loading = false;
}
if (isDhcp) {
this.loadingDhcps = false;
} else {
this.loadingOgBoot = false;
}
this[errorState] = true;
}, 3500);
this.http.get<any>(apiUrl).subscribe({
next: data => {
diskUsage.used = data.message.disk_usage.used;
diskUsage.available = data.message.disk_usage.available;
diskUsage.total = data.message.disk_usage.total;
diskUsage.percentage = data.message.disk_usage.percentage;
Object.assign(servicesStatus, data.message.services_status);
if (isDhcp) {
this.subnets.length = 0;
if (data.message.subnets) {
this.subnets.push(...data.message.subnets);
}
} else {
installedOgLives.length = 0;
if (data.message.installed_oglives) {
installedOgLives.push(...data.message.installed_oglives);
}
this.loadingOgBootOgLives = false;
}
diskUsageChartData.length = 0;
diskUsageChartData.push(
{ name: 'Usado', value: parseFloat(diskUsage.used) },
{ name: 'Disponible', value: parseFloat(diskUsage.available) }
);
if (showLoading) {
this.loading = false;
}
if (isDhcp) {
this.loadingDhcps = false;
} else {
this.loadingOgBoot = false;
}
clearTimeout(timeoutId);
},
error: error => {
this.toastService.error(error.error['hydra:description'] || 'Error al cargar el estado de ogBoot');
if (showLoading) {
this.loading = false;
}
if (isDhcp) {
this.loadingDhcps = false;
} else {
this.loadingOgBoot = false;
}
this[errorState] = true;
clearTimeout(timeoutId);
}
});
}
loadRepositories(showLoading: boolean = true): void {
if (showLoading) {
this.loading = true;
}
this.errorRepositories = {};
this.http.get<any>(`${this.repositoriesUrl}?page=1&itemsPerPage=10`).subscribe(
data => {
this.repositories = data['hydra:member'] || [];
if (this.repositories.length === 0) {
if (showLoading) {
this.loading = false;
}
return;
}
let remainingRepositories = this.repositories.length;
const timeoutId = setTimeout(() => {
if (showLoading) {
this.loading = false;
}
this.repositories.forEach(repository => {
if (!(repository.uuid in this.errorRepositories)) {
this.errorRepositories[repository.uuid] = true;
}
});
}, 5000);
this.repositories.forEach(repository => {
this.loadRepositoryStatus(repository.uuid, (errorOccurred: boolean) => {
remainingRepositories--;
this.errorRepositories[repository.uuid] = errorOccurred;
if (remainingRepositories === 0) {
if (showLoading) {
this.loading = false;
}
clearTimeout(timeoutId);
}
});
});
},
error => {
this.loading = false;
this.repositories = [];
this.toastService.error('Error al cargar la lista de repositorios');
}
);
}
loadRepositoryStatus(repositoryUuid: string, callback: (errorOccurred: boolean) => void): void {
console.log(`Cargando estado del repositorio: ${repositoryUuid}`);
const timeoutId = setTimeout(() => {
callback(true);
}, 5000);
this.http.get<any>(`${this.baseUrl}/image-repositories/server/${repositoryUuid}/status`).subscribe(
data => {
if (!data.success) {
clearTimeout(timeoutId);
callback(true);
return;
}
const details = data.details;
const { disk, services, ram, cpu, processes } = details;
this.repositoryStatuses[repositoryUuid] = {
disk: {
...disk,
used: parseFloat(disk.used.replace('GB', '')),
available: parseFloat(disk.available.replace('GB', '')),
total: parseFloat(disk.total.replace('GB', '')),
percentage: disk.used_percentage
},
ram: {
...ram,
used: parseFloat(ram.used.replace('GB', '')),
available: parseFloat(ram.available.replace('GB', '')),
total: parseFloat(ram.total.replace('GB', '')),
percentage: ram.used_percentage
},
cpu: {
used_percentage: cpu.used_percentage
},
services: services,
processes: processes
};
clearTimeout(timeoutId);
callback(false);
},
error => {
this.toastService.error(error.error['hydra:description'] || 'Error al cargar el estado del repositorio');
clearTimeout(timeoutId);
callback(true);
}
);
}
loadOgBootStatus(): void {
this.isDhcp = false;
this.loadStatus(this.ogBootApiUrl, this.ogBootDiskUsage, this.ogBootServicesStatus, this.ogBootDiskUsageChartData, this.installedOgLives, this.isDhcp, 'errorOgBoot', false);
}
loadDhcps(showLoading: boolean = true): void {
if (showLoading) {
this.loading = true;
}
this.errorDhcps = {};
this.http.get<any>(`${this.dhcpsApiUrl}?page=1&itemsPerPage=10`).subscribe(
data => {
this.dhcps = data['hydra:member'] || [];
if (this.dhcps.length === 0) {
if (showLoading) {
this.loading = false;
}
return;
}
let remainingDhcps = this.dhcps.length;
const timeoutId = setTimeout(() => {
if (showLoading) {
this.loading = false;
}
this.dhcps.forEach(dhcp => {
if (!(dhcp.uuid in this.errorDhcps)) {
this.errorDhcps[dhcp.uuid] = true;
}
});
}, 5000);
this.dhcps.forEach(dhcp => {
this.loadDhcpStatus(dhcp.uuid, (errorOccurred: boolean) => {
remainingDhcps--;
this.errorDhcps[dhcp.uuid] = errorOccurred;
if (remainingDhcps === 0) {
if (showLoading) {
this.loading = false;
}
clearTimeout(timeoutId);
}
});
});
},
error => {
this.loading = false;
this.dhcps = [];
this.toastService.error('Error al cargar la lista de Dhcps');
}
);
}
loadDhcpStatus(dhcpUuid: string, callback: (errorOccurred: boolean) => void): void {
console.log(`Cargando estado del Dhcp: ${dhcpUuid}`);
const timeoutId = setTimeout(() => {
callback(true);
}, 5000);
this.http.get<any>(`${this.baseUrl}/dhcp-servers/server/${dhcpUuid}/status`).subscribe(
data => {
if (!data.success) {
clearTimeout(timeoutId);
callback(true);
return;
}
const disk = data.message.disk_usage;
const services = data.message.services_status;
let diskUsageChartData: any[] = [];
diskUsageChartData.length = 0;
diskUsageChartData.push(
{ name: 'Usado', value: parseFloat(disk.used) },
{ name: 'Disponible', value: parseFloat(disk.available) }
);
this.subnets.length = 0;
if (data.message.subnets) {
this.subnets.push(...data.message.subnets);
}
this.dhcpStatuses[dhcpUuid] = {
disk: {
...disk,
used: parseFloat(disk.used.replace('GB', '')),
available: parseFloat(disk.available.replace('GB', '')),
total: parseFloat(disk.total.replace('GB', '')),
percentage: disk.used_percentage
},
services: services,
diskUsageChartData: diskUsageChartData
};
clearTimeout(timeoutId);
callback(false);
},
error => {
this.toastService.error(error.error['hydra:description'] || 'Error al cargar el estado del dhcp');
clearTimeout(timeoutId);
callback(true);
}
);
}
onDhcpChange(dhcpUuid: string): void {
this.selectedDhcpUuid = dhcpUuid;
if (dhcpUuid && !this.dhcpStatuses[dhcpUuid]) {
this.loadDhcpStatus(dhcpUuid, (errorOccurred: boolean) => {
if (errorOccurred) {
this.errorDhcps[dhcpUuid] = true;
}
});
}
}
getSelectedDhcpName(): string {
const selectedDhcp = this.dhcps.find(dhcp => dhcp.uuid === this.selectedDhcpUuid);
return selectedDhcp ? selectedDhcp.name : '';
}
onRepositoryChange(repositoryUuid: string): void {
this.selectedRepositoryUuid = repositoryUuid;
if (repositoryUuid && !this.repositoryStatuses[repositoryUuid]) {
this.loadRepositoryStatus(repositoryUuid, (errorOccurred: boolean) => {
if (errorOccurred) {
this.errorRepositories[repositoryUuid] = true;
}
});
}
}
getSelectedRepositoryName(): string {
const selectedRepo = this.repositories.find(repo => repo.uuid === this.selectedRepositoryUuid);
return selectedRepo ? selectedRepo.name : '';
}
getRepositoryIframeUrl(): SafeResourceUrl {
const repositoryName = this.getSelectedRepositoryName();
if (repositoryName) {
const encodedName = encodeURIComponent(repositoryName);
const url = `${this.configService.logUrl}/d-solo/ogrepo-logs/ogrepo-logs?orgId=1&timezone=browser&refresh=5s&var-query0=&editIndex=0&var-hostname=${encodedName}&theme=dark&panelId=1&__feature.dashboardSceneSolo`;
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
return this.sanitizer.bypassSecurityTrustResourceUrl('');
}
getOgBootIframeUrl(): SafeResourceUrl {
const url = `${this.configService.logUrl}/d-solo/ogboot-logs/ogboot-logs?orgId=1&timezone=browser&refresh=5s&theme=dark&panelId=1&__feature.dashboardSceneSolo`;
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
getDhcpIframeUrl(): SafeResourceUrl {
const dhcpName = this.getSelectedDhcpName();
if (dhcpName) {
const encodedName = encodeURIComponent(dhcpName);
const url = `${this.configService.logUrl}/d-solo/ogdhcp-logs/ogdhcp-logs?orgId=1&timezone=browser&refresh=5s&var-query0=&editIndex=0&var-hostname=${encodedName}&theme=dark&panelId=1&__feature.dashboardSceneSolo`;
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
return this.sanitizer.bypassSecurityTrustResourceUrl('');
}
getOgCoreIframeUrl(): SafeResourceUrl {
const url = `${this.configService.logUrl}/d-solo/ogcore-logs/ogcore-logs?orgId=1&tab=transformations&theme=dark&panelId=1&__feature.dashboardSceneSolo&now-5m&to=now&timezone=browser`;
return this.sanitizer.bypassSecurityTrustResourceUrl(url);
}
refreshAll(): void {
this.loading = true;
this.updateLastUpdateTime();
this.loadStatus(this.ogBootApiUrl, this.ogBootDiskUsage, this.ogBootServicesStatus, this.ogBootDiskUsageChartData, this.installedOgLives, false, 'errorOgBoot', true);
this.loadDhcps(true);
this.loadRepositories(true);
this.syncSubnets();
this.syncTemplates();
this.syncOgLives();
this.toastService.success('Datos actualizados correctamente');
}
updateLastUpdateTime(): void {
const now = new Date();
this.lastUpdateTime = now.toLocaleTimeString('es-ES', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
}
getCurrentTime(): string {
const now = new Date();
return now.toLocaleTimeString('es-ES', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
}
retryRepositoryStatus(repositoryUuid: string): void {
this.loadRepositoryStatus(repositoryUuid, (errorOccurred: boolean) => {
this.errorRepositories[repositoryUuid] = errorOccurred;
if (!errorOccurred) {
this.toastService.success('Estado del repositorio actualizado correctamente');
} else {
this.toastService.error('Error al cargar el estado del repositorio');
}
});
}
retryDhcpStatus(dhcpUuid: string): void {
this.loadDhcpStatus(dhcpUuid, (errorOccurred: boolean) => {
this.errorDhcps[dhcpUuid] = errorOccurred;
if (!errorOccurred) {
this.toastService.success('Estado del dhcp actualizado correctamente');
} else {
this.toastService.error('Error al cargar el estado del dhcp');
}
});
}
selectSection(section: 'repositories' | 'ogboot' | 'dhcp' | 'ogcore'): void {
this.selectedSection = section;
switch (section) {
case 'repositories':
break;
case 'ogboot':
if (!this.ogBootDiskUsage) {
this.loadOgBootStatus();
}
break;
case 'dhcp':
break;
case 'ogcore':
break;
}
}
scrollToLogs(): void {
let logsSectionId: string;
switch (this.selectedSection) {
case 'repositories':
logsSectionId = 'repository-logs-section';
break;
case 'ogboot':
logsSectionId = 'ogboot-logs-section';
break;
case 'dhcp':
logsSectionId = 'dhcp-logs-section';
break;
case 'ogcore':
logsSectionId = 'ogcore-logs-section';
break;
default:
return;
}
const checkAndScroll = () => {
const logsSection = document.getElementById(logsSectionId);
if (logsSection) {
logsSection.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
return true;
}
return false;
};
const interval = setInterval(() => {
if (checkAndScroll()) {
clearInterval(interval);
}
}, 100);
setTimeout(() => {
clearInterval(interval);
}, 3000);
}
}