- Added DnsManager and DnsEntry classes to handle DNS entries. - Introduced new interfaces for DNS entry requests and data structures. - Updated Cloudly class to include DnsManager instance. - Enhanced app state to manage DNS entries and actions for creating, updating, and deleting DNS records. - Created UI components for DNS management, including forms for adding and editing DNS entries. - Updated overview and services views to reflect DNS entries. - Added validation and formatting methods for DNS entries.
148 lines
4.0 KiB
TypeScript
148 lines
4.0 KiB
TypeScript
import * as plugins from '../plugins.js';
|
|
import { DnsManager } from './classes.dnsmanager.js';
|
|
|
|
export class DnsEntry extends plugins.smartdata.SmartDataDbDoc<
|
|
DnsEntry,
|
|
plugins.servezoneInterfaces.data.IDnsEntry,
|
|
DnsManager
|
|
> {
|
|
// STATIC
|
|
public static async getDnsEntryById(dnsEntryIdArg: string) {
|
|
const dnsEntry = await this.getInstance({
|
|
id: dnsEntryIdArg,
|
|
});
|
|
return dnsEntry;
|
|
}
|
|
|
|
public static async getDnsEntries(filterArg?: { zone?: string }) {
|
|
const filter: any = {};
|
|
if (filterArg?.zone) {
|
|
filter['data.zone'] = filterArg.zone;
|
|
}
|
|
const dnsEntries = await this.getInstances(filter);
|
|
return dnsEntries;
|
|
}
|
|
|
|
public static async getDnsZones() {
|
|
const dnsEntries = await this.getInstances({});
|
|
const zones = new Set<string>();
|
|
for (const entry of dnsEntries) {
|
|
if (entry.data.zone) {
|
|
zones.add(entry.data.zone);
|
|
}
|
|
}
|
|
return Array.from(zones).sort();
|
|
}
|
|
|
|
public static async createDnsEntry(dnsEntryDataArg: plugins.servezoneInterfaces.data.IDnsEntry['data']) {
|
|
const dnsEntry = new DnsEntry();
|
|
dnsEntry.id = await DnsEntry.getNewId();
|
|
dnsEntry.data = {
|
|
...dnsEntryDataArg,
|
|
ttl: dnsEntryDataArg.ttl || 3600, // Default TTL: 1 hour
|
|
active: dnsEntryDataArg.active !== false, // Default to active
|
|
createdAt: Date.now(),
|
|
updatedAt: Date.now(),
|
|
};
|
|
await dnsEntry.save();
|
|
return dnsEntry;
|
|
}
|
|
|
|
public static async updateDnsEntry(
|
|
dnsEntryIdArg: string,
|
|
dnsEntryDataArg: Partial<plugins.servezoneInterfaces.data.IDnsEntry['data']>
|
|
) {
|
|
const dnsEntry = await this.getInstance({
|
|
id: dnsEntryIdArg,
|
|
});
|
|
if (!dnsEntry) {
|
|
throw new Error(`DNS entry with id ${dnsEntryIdArg} not found`);
|
|
}
|
|
Object.assign(dnsEntry.data, dnsEntryDataArg, {
|
|
updatedAt: Date.now(),
|
|
});
|
|
await dnsEntry.save();
|
|
return dnsEntry;
|
|
}
|
|
|
|
public static async deleteDnsEntry(dnsEntryIdArg: string) {
|
|
const dnsEntry = await this.getInstance({
|
|
id: dnsEntryIdArg,
|
|
});
|
|
if (!dnsEntry) {
|
|
throw new Error(`DNS entry with id ${dnsEntryIdArg} not found`);
|
|
}
|
|
await dnsEntry.delete();
|
|
return true;
|
|
}
|
|
|
|
// INSTANCE
|
|
@plugins.smartdata.svDb()
|
|
public id: string;
|
|
|
|
@plugins.smartdata.svDb()
|
|
public data: plugins.servezoneInterfaces.data.IDnsEntry['data'];
|
|
|
|
/**
|
|
* Validates the DNS entry data
|
|
*/
|
|
public validateData(): boolean {
|
|
const { type, name, value, zone } = this.data;
|
|
|
|
// Basic validation
|
|
if (!type || !name || !value || !zone) {
|
|
return false;
|
|
}
|
|
|
|
// Type-specific validation
|
|
switch (type) {
|
|
case 'A':
|
|
// Validate IPv4 address
|
|
return /^(\d{1,3}\.){3}\d{1,3}$/.test(value);
|
|
case 'AAAA':
|
|
// Validate IPv6 address (simplified)
|
|
return /^([0-9a-fA-F]{0,4}:){7}[0-9a-fA-F]{0,4}$/.test(value);
|
|
case 'MX':
|
|
// MX records must have priority
|
|
return this.data.priority !== undefined && this.data.priority >= 0;
|
|
case 'SRV':
|
|
// SRV records must have priority, weight, and port
|
|
return (
|
|
this.data.priority !== undefined &&
|
|
this.data.weight !== undefined &&
|
|
this.data.port !== undefined
|
|
);
|
|
case 'CNAME':
|
|
case 'NS':
|
|
case 'PTR':
|
|
// These should point to valid domain names
|
|
return /^[a-zA-Z0-9.-]+$/.test(value);
|
|
case 'TXT':
|
|
case 'CAA':
|
|
case 'SOA':
|
|
// These can contain any text
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get a formatted string representation of the DNS entry
|
|
*/
|
|
public toFormattedString(): string {
|
|
const { type, name, value, ttl, priority } = this.data;
|
|
let result = `${name} ${ttl} IN ${type}`;
|
|
|
|
if (priority !== undefined) {
|
|
result += ` ${priority}`;
|
|
}
|
|
|
|
if (type === 'SRV' && this.data.weight !== undefined && this.data.port !== undefined) {
|
|
result += ` ${this.data.weight} ${this.data.port}`;
|
|
}
|
|
|
|
result += ` ${value}`;
|
|
return result;
|
|
}
|
|
} |