first version
This commit is contained in:
commit
a5d307f435
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
config.json
|
||||
node_modules
|
107
app.js
Normal file
107
app.js
Normal file
@ -0,0 +1,107 @@
|
||||
const request = require('request');
|
||||
const config = require('./config.json');
|
||||
const so = require('./libs/storeObject');
|
||||
|
||||
/**
|
||||
* @param {string} uri
|
||||
* @param {string} method
|
||||
* @param {object} data
|
||||
*/
|
||||
async function urlRequest(uri, method = 'GET', data = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let token = so.get('token');
|
||||
|
||||
let headers = {
|
||||
'X-Auth-Token': token && token.id ? token.id : '',
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
let json = {
|
||||
method,
|
||||
uri,
|
||||
headers,
|
||||
json: data
|
||||
};
|
||||
request(json, (err, res, body) => {
|
||||
if (err) return reject(err);
|
||||
if (res.statusCode != 200) return reject(`HTTP Request Fail , URL: ${uri} , StatusCode: ${res.statusCode} , Reponse: ${JSON.stringify(body)}`);
|
||||
return resolve(body);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
const runUpdateDNS = async() => {
|
||||
try {
|
||||
let ip = await urlRequest('http://ip.trj.tw/getip.php');
|
||||
console.log(`${Date.now()} // get public ip: ${ip}`);
|
||||
|
||||
let t = so.get('token');
|
||||
if (t == null || ('etime' in t && t.etime < Date.now() + 30000)) {
|
||||
|
||||
let tokenData = await urlRequest(`${config.api.url.identity}/tokens`, 'POST', {
|
||||
'auth': {
|
||||
'passwordCredentials': {
|
||||
'username': config.api.username,
|
||||
'password': config.api.password
|
||||
},
|
||||
'tenantId': config.api.tenantid
|
||||
}
|
||||
});
|
||||
let { token } = tokenData.access;
|
||||
token.etime = new Date(token.expires).getTime();
|
||||
so.set('token', token);
|
||||
console.log(`${Date.now()} - get api token: ${token.id}, expire: ${token.expires}`);
|
||||
}
|
||||
|
||||
let domainsData = await urlRequest(`${config.api.url.dns}/v1/domains`);
|
||||
for (let i in domainsData.domains) {
|
||||
let tmp = domainsData.domains[i];
|
||||
for (let j in config.domain) {
|
||||
if (config.domain[j].name == tmp.name) {
|
||||
config.domain[j].id = tmp.id;
|
||||
console.log(`${Date.now()} - get domain ${config.domain[i].name} id: ${tmp.id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i in config.domain) {
|
||||
if (!('id' in config.domain[i])) continue;
|
||||
let data = await urlRequest(`${config.api.url.dns}/v1/domains/${config.domain[i].id}/records`);
|
||||
for (let j in data.records) {
|
||||
let tmp = data.records[j];
|
||||
if (!/^a$/i.test(tmp.type)) continue;
|
||||
for (let k in config.domain[i].sub) {
|
||||
let ctmp = config.domain[i].sub[k];
|
||||
if (tmp.name == `${ctmp.name}.${config.domain[i].name}`) {
|
||||
ctmp.id = tmp.id;
|
||||
ctmp.changed = ip == tmp.data ? false : true;
|
||||
console.log(`${Date.now()} - get record ${ctmp.name}.${config.domain[i].name} id: ${tmp.id}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i in config.domain) {
|
||||
if (!('id' in config.domain[i])) continue;
|
||||
let id = config.domain[i].id;
|
||||
for (let j in config.domain[i].sub) {
|
||||
let tmp = config.domain[i].sub[j];
|
||||
if (!('id' in tmp) || !('changed' in tmp)) continue;
|
||||
if (!tmp.changed) {
|
||||
console.log(`${Date.now()} - dns record ${tmp.name}.${config.domain[i].name} ip not change`);
|
||||
continue;
|
||||
}
|
||||
await urlRequest(`${config.api.url.dns}/v1/domains/${id}/records/${tmp.id}`, 'PUT', { data: ip });
|
||||
console.log(`${Date.now()} - dns record ${tmp.name}.${config.domain[i].name} update finish`);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.log(`${Date.now()} - ${e}`);
|
||||
return;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
runUpdateDNS();
|
||||
setInterval(() => runUpdateDNS(), 300000);
|
17
config.sample.json
Normal file
17
config.sample.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"api": {
|
||||
"username": "",
|
||||
"password": "",
|
||||
"tenantid": "",
|
||||
"url": {
|
||||
"identity": "https://identity.tyo1.conoha.io/v2.0",
|
||||
"dns": "https://dns-service.tyo1.conoha.io"
|
||||
}
|
||||
},
|
||||
"domain": [{
|
||||
"name": "example.com",
|
||||
"sub": [
|
||||
"sub1"
|
||||
]
|
||||
}]
|
||||
}
|
68
libs/storeObject.js
Normal file
68
libs/storeObject.js
Normal file
@ -0,0 +1,68 @@
|
||||
const StoreObj = (() => {
|
||||
|
||||
let memStore = {};
|
||||
let maxAge = 3600000;
|
||||
|
||||
/**
|
||||
* @param {string} uuid
|
||||
* @param {object} obj
|
||||
*/
|
||||
const set = (uuid, obj) => {
|
||||
memStore[uuid] = {
|
||||
obj,
|
||||
age: Date.now() + maxAge
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} uuid
|
||||
*/
|
||||
const get = (uuid) => {
|
||||
if (uuid in memStore) {
|
||||
let s = memStore[uuid];
|
||||
if (Date.now() < s.age) {
|
||||
s.age = Date.now() + maxAge;
|
||||
return s.obj;
|
||||
} else {
|
||||
delete memStore[uuid];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} uuid
|
||||
*/
|
||||
const chkKey = (uuid) => {
|
||||
if (uuid in memStore) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} uuid
|
||||
*/
|
||||
const del = (uuid) => {
|
||||
if (uuid in memStore) delete memStore[uuid];
|
||||
}
|
||||
|
||||
const clear = () => {
|
||||
let t = Date.now();
|
||||
for (var i in memStore) {
|
||||
let s = memStore[i];
|
||||
if (s.age < t) delete memStore[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} uuid if not input return all
|
||||
*/
|
||||
const show = (uuid) => {
|
||||
if (uuid && uuid in memStore) return memStore[uuid];
|
||||
|
||||
return memStore;
|
||||
}
|
||||
|
||||
return {set, get, chkKey, clear, del, show };
|
||||
})()
|
||||
|
||||
module.exports = StoreObj;
|
19
package.json
Normal file
19
package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "node-conoha-ddns",
|
||||
"version": "1.0.0",
|
||||
"description": "ConoHa DNS API DDNS腳本",
|
||||
"main": "app.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://git.trj.tw/nodejs/conoha-ddns.git"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "UrWind",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"request": "^2.81.0"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user