-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcPanel.js
91 lines (79 loc) · 3.4 KB
/
cPanel.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
"use strict";
const log = require ('./logger');
const fs = require ('fs');
const dns = require ('node:dns').promises;
const axios = require ('axios');
const parseDomain = require ('tld-extract');
const apiToken = fs.readFileSync (process.env.AGASSI_CPANEL_API_TOKEN_FILE).toString ().trim ();
const cPanelServer = process.env.AGASSI_CPANEL_SERVER.trim ();
const username = process.env.AGASSI_CPANEL_USERNAME.trim ();
const ttl = Math.round(process.env.AGASSI_DNS_TTL);
const auth = {
headers: {'Authorization': `cpanel ${username}:${apiToken}`}
};
module.exports = {
putCnameRecord,
putTxtRecord
};
// string, string, int, string
// '_record' is the argument, 'record' is one of many records
async function putRecord (_fqdn, _type, _record) {
// make arguments consistent and fit with domain parser
let fqdn = parseDomain (`https://${_fqdn}`);
let type = _type.toUpperCase();
let records = (await axios.get (`https://${cPanelServer}/execute/DNS/parse_zone?zone=${fqdn.domain}`, auth)).data.data;
let serial = Buffer.from (records.find (record => record.record_type=='SOA').data_b64[2], 'base64').toString ();
let dname = fqdn.sub; // for consistency with the cPanel API
let b64Subdomain = Buffer.from (dname).toString ('base64');
let recordB64Array = [Buffer.from (_record).toString ('base64')];
let existingRecord = records.find (function findRecord (record) {
if (record.type == 'record' &&
record.record_type == type &&
b64Subdomain == record.dname_b64 &&
recordB64Array.toString () == record.data_b64.toString ()) {
return record;
}
});
if (existingRecord) {
log.debug (`${type} already set`);
log.debug ('checking ttl');
// if ttl doesn't match, update record
if (existingRecord.ttl != ttl) {
log.debug ('ttl does not match');
log.debug ('updating record');
let edit = await axios.get (`https://${cPanelServer}/execute/DNS/mass_edit_zone?zone=${fqdn.domain}&serial=${serial}&edit={"line_index":"${existingRecord.line_index}","dname":"${dname}","ttl":"${ttl}","record_type":"${type}","data":["${_record}"]}`, auth);
edit = edit.data;
if (edit.errors) {
throw new Error (edit.errors.toString ());
} else {
if (edit.warnings) {
log.warn ('warning:', edit.warnings.toString ());
} else {
log.debug (`${type} ttl updated`);
}
}
} else {
log.debug ('nothing to do');
}
} else {
log.debug (`setting ${type} record`);
let addition = await axios.get (`https://${cPanelServer}/execute/DNS/mass_edit_zone?zone=${fqdn.domain}&serial=${serial}&add={"dname":"${dname}","ttl":"${ttl}","record_type":"${type}","data":["${_record}"]}`, auth);
addition = addition.data;
if (addition.errors) {
throw new Error (addition.errors.toString ());
} else {
if (addition.warnings) {
log.warn ('warning:', addition.warnings.toString ());
} else {
log.debug (`${type} record set`);
}
}
}
return 0;
}
async function putCnameRecord (fqdn, record) {
return putRecord (fqdn, 'CNAME', record);
}
async function putTxtRecord (fqdn, record) {
return putRecord (fqdn, 'TXT', record);
}