2025-01-20 02:11:12 +01:00
|
|
|
import { SecretBundle } from 'ts/manager.secret/classes.secretbundle.js';
|
2024-06-13 09:36:02 +02:00
|
|
|
import * as plugins from '../plugins.js';
|
2024-08-25 14:29:26 +02:00
|
|
|
import { ServiceManager } from './classes.servicemanager.js';
|
2024-06-13 09:36:02 +02:00
|
|
|
|
feat: Implement Cloudly Task Manager with predefined tasks and execution tracking
- Added CloudlyTaskManager class for managing tasks, including registration, execution, scheduling, and cancellation.
- Created predefined tasks: DNS Sync, Certificate Renewal, Cleanup, Health Check, Resource Report, Database Maintenance, Security Scan, and Docker Cleanup.
- Introduced ITaskExecution interface for tracking task execution details and outcomes.
- Developed API request interfaces for task management operations (getTasks, getTaskExecutions, triggerTask, cancelTask).
- Implemented CloudlyViewTasks web component for displaying tasks and their execution history, including filtering and detailed views.
2025-09-10 16:37:03 +00:00
|
|
|
@plugins.smartdata.managed()
|
2024-10-27 19:50:39 +01:00
|
|
|
export class Service extends plugins.smartdata.SmartDataDbDoc<
|
|
|
|
Service,
|
|
|
|
plugins.servezoneInterfaces.data.IService,
|
|
|
|
ServiceManager
|
|
|
|
> {
|
2025-01-20 02:11:12 +01:00
|
|
|
// STATIC
|
|
|
|
public static async getServiceById(serviceIdArg: string) {
|
|
|
|
const service = await this.getInstance({
|
|
|
|
id: serviceIdArg,
|
|
|
|
});
|
|
|
|
return service;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async getServices() {
|
|
|
|
const services = await this.getInstances({});
|
|
|
|
return services;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static async createService(serviceDataArg: Partial<plugins.servezoneInterfaces.data.IService['data']>) {
|
|
|
|
const service = new Service();
|
|
|
|
service.id = await Service.getNewId();
|
|
|
|
Object.assign(service, serviceDataArg);
|
|
|
|
await service.save();
|
2025-09-10 15:38:42 +00:00
|
|
|
|
|
|
|
// Create DNS entries if service has web port and domains configured
|
|
|
|
if (service.data.ports?.web && service.data.domains?.length > 0) {
|
|
|
|
await service.createDnsEntries();
|
|
|
|
}
|
|
|
|
|
2025-01-20 02:11:12 +01:00
|
|
|
return service;
|
|
|
|
}
|
|
|
|
|
|
|
|
// INSTANCE
|
2024-06-13 09:36:02 +02:00
|
|
|
@plugins.smartdata.svDb()
|
|
|
|
public id: string;
|
|
|
|
|
|
|
|
@plugins.smartdata.svDb()
|
|
|
|
public data: plugins.servezoneInterfaces.data.IService['data'];
|
2025-01-20 02:11:12 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* a service runs in a specific environment
|
|
|
|
* so -> this method returns the secret bundles as a flat object accordingly.
|
|
|
|
* in other words, it resolves secret groups for the relevant environment
|
|
|
|
* @param environmentArg
|
|
|
|
*/
|
|
|
|
public async getSecretBundlesAsFlatObject(environmentArg: string = 'production') {
|
|
|
|
const secreBundleIds = this.data.additionalSecretBundleIds || [];
|
|
|
|
secreBundleIds.push(this.data.secretBundleId); // put this last, so it overwrites any other secret bundles.
|
|
|
|
let finalFlatObject = {};
|
|
|
|
for (const secretBundleId of secreBundleIds) {
|
|
|
|
const secretBundle = await SecretBundle.getInstance({
|
|
|
|
id: secretBundleId,
|
|
|
|
});
|
|
|
|
const flatObject = await secretBundle.getFlatKeyValueObject(environmentArg);
|
|
|
|
Object.assign(finalFlatObject, flatObject);
|
|
|
|
}
|
|
|
|
return finalFlatObject;
|
|
|
|
}
|
2025-09-10 15:38:42 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates DNS entries for this service (in inactive state)
|
|
|
|
* These will be activated when the service is deployed
|
|
|
|
*/
|
|
|
|
public async createDnsEntries() {
|
|
|
|
const dnsManager = this.manager.cloudlyRef.dnsManager;
|
|
|
|
|
|
|
|
for (const domain of this.data.domains) {
|
|
|
|
const dnsEntryData: plugins.servezoneInterfaces.data.IDnsEntry['data'] = {
|
|
|
|
type: 'A', // Default to A record, could be made configurable
|
|
|
|
name: domain.name,
|
|
|
|
value: '0.0.0.0', // Placeholder, will be updated on deployment
|
|
|
|
ttl: 3600,
|
|
|
|
zone: '', // Will be set based on domainId
|
|
|
|
domainId: domain.domainId,
|
|
|
|
active: false, // Created as inactive
|
|
|
|
description: `Auto-generated DNS entry for service ${this.data.name}`,
|
|
|
|
createdAt: Date.now(),
|
|
|
|
isAutoGenerated: true,
|
|
|
|
sourceServiceId: this.id,
|
|
|
|
sourceType: 'service',
|
|
|
|
};
|
|
|
|
|
|
|
|
// Create the DNS entry
|
|
|
|
await dnsManager.createServiceDnsEntry(dnsEntryData);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Removes DNS entries for this service
|
|
|
|
*/
|
|
|
|
public async removeDnsEntries() {
|
|
|
|
const dnsManager = this.manager.cloudlyRef.dnsManager;
|
|
|
|
await dnsManager.removeServiceDnsEntries(this.id);
|
|
|
|
}
|
2024-10-27 19:50:39 +01:00
|
|
|
}
|