f40ef6b7c0
Align Cloudly with the current typedserver, smartconfig, smartstate, and Docker tooling releases so builds and Docker output stay compatible with the upgraded stack.
101 lines
3.3 KiB
TypeScript
101 lines
3.3 KiB
TypeScript
import { SecretBundle } from '../manager.secret/classes.secretbundle.js';
|
|
import * as plugins from '../plugins.js';
|
|
import { ServiceManager } from './classes.servicemanager.js';
|
|
|
|
@plugins.smartdata.managed()
|
|
export class Service extends plugins.smartdata.SmartDataDbDoc<
|
|
Service,
|
|
plugins.servezoneInterfaces.data.IService,
|
|
ServiceManager
|
|
> {
|
|
// 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();
|
|
service.data = serviceDataArg as plugins.servezoneInterfaces.data.IService['data'];
|
|
await service.save();
|
|
|
|
// Create DNS entries if service has web port and domains configured
|
|
if (service.data.ports?.web && service.data.domains?.length > 0) {
|
|
await service.createDnsEntries();
|
|
}
|
|
|
|
return service;
|
|
}
|
|
|
|
// INSTANCE
|
|
@plugins.smartdata.unI()
|
|
public id!: string;
|
|
|
|
@plugins.smartdata.svDb()
|
|
public data!: plugins.servezoneInterfaces.data.IService['data'];
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
}
|