From addf748158ab77831124dc26b93742470d9ec6cc Mon Sep 17 00:00:00 2001 From: Akshay Nair Date: Sun, 11 Oct 2020 14:41:07 +0530 Subject: [PATCH] Adds cpanel util --- tests/cpanel.test.js | 88 ++++++++++++++++++++++++++++++++++++++++++++ utils/lib/cpanel.js | 59 +++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 tests/cpanel.test.js create mode 100644 utils/lib/cpanel.js diff --git a/tests/cpanel.test.js b/tests/cpanel.test.js new file mode 100644 index 0000000000..29d4606fb6 --- /dev/null +++ b/tests/cpanel.test.js @@ -0,0 +1,88 @@ +const R = require('ramda'); +const { CpanelClient } = require('../utils/lib/cpanel'); + +const mockFetch = (expectRequest, decorate = R.identity) => (reqUrl, request) => { + expectRequest(reqUrl, request); + return Promise.resolve({ + json: async () => decorate(request), + }); +}; + +describe('Cpanel client', () => { + describe('fetchzonerecords', () => { + it('should make the correct request', async () => { + const fetch = mockFetch((url, request) => { + expect(url).toBe('https://example.com:2000//json-api/cpanel?customonly=1&domain=is-a.dev&cpanel_jsonapi_user=boy&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&cpanel_jsonapi_apiversion=2'); + expect(request).toEqual({ + headers: { + Authorization: 'cpanel boy:boybyebye', + }, + rejectUnauthorized: false, + }); + }); + + const cpanel = CpanelClient({ + host: 'example.com', + port: 2000, + username: 'boy', + apiKey: 'boybyebye', + dependencies: { fetch }, + }); + + await cpanel.fetchZoneRecords(); + }); + + it('should make the correct request with query', async () => { + const fetch = mockFetch((url, request) => { + expect(url).toBe('https://example.com:2000//json-api/cpanel?customonly=1&domain=foobar.boeey&cpanel_jsonapi_user=boy&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=fetchzone_records&cpanel_jsonapi_apiversion=2'); + expect(request).toEqual({ + headers: { + Authorization: 'cpanel boy:boybyebye', + }, + rejectUnauthorized: false, + }); + }); + + const cpanel = CpanelClient({ + host: 'example.com', + port: 2000, + username: 'boy', + apiKey: 'boybyebye', + dependencies: { fetch }, + }); + + await cpanel.fetchZoneRecords({ domain: 'foobar.boeey' }); + }); + }); + + describe('addzonerecord', () => { + it('should make the correct request', async () => { + const fetch = mockFetch((url, request) => { + expect(url).toBe('https://example.com:2000//json-api/cpanel?domain=is-a.dev&name=googo&type=CNAME&cname=beey&ttl=2020&cpanel_jsonapi_user=boy&cpanel_jsonapi_module=ZoneEdit&cpanel_jsonapi_func=add_zone_record&cpanel_jsonapi_apiversion=2'); + expect(request).toEqual({ + headers: { + Authorization: 'cpanel boy:boybyebye', + }, + rejectUnauthorized: false, + }); + }); + + const cpanel = CpanelClient({ + host: 'example.com', + port: 2000, + username: 'boy', + apiKey: 'boybyebye', + dependencies: { fetch }, + }); + + await cpanel.addZoneRecord({ + name: 'googo', + type: 'boyee', + cname: 'beey', + type: 'CNAME', + ttl: 2020, + }); + }); + }); +}); + diff --git a/utils/lib/cpanel.js b/utils/lib/cpanel.js new file mode 100644 index 0000000000..cadca4d4ba --- /dev/null +++ b/utils/lib/cpanel.js @@ -0,0 +1,59 @@ +const R = require('ramda'); +const fetch = require('node-fetch'); +const qs = require('qs'); +const { DOMAIN_API_HOST, DOMAIN_API_PORT, DOMAIN_USER, DOMAIN_API_KEY, DOMAIN_DOMAIN } = require('../constants'); + +const CpanelClient = (options) => { + const api = (module, func, defaultQuery = {}) => (q = {}) => { + const query = { + ...defaultQuery, + ...q, + cpanel_jsonapi_user: options.username, + cpanel_jsonapi_module: module, + cpanel_jsonapi_func: func, + cpanel_jsonapi_apiversion: 2, + }; + + const request = { + headers: { + Authorization: `cpanel ${options.username}:${options.apiKey}`, + }, + rejectUnauthorized: false, + }; + + const path = `${options.path || '/json-api'}/cpanel?${qs.stringify(query)}`; + const reqUrl = `https://${options.host}:${options.port}/${path}`; + + const { fetch } = options.dependencies; + return fetch(reqUrl, request).then(res => res.json()); + }; + + return { + // { customonly, domain } + // -> { cpanelresult: { data[{ class, ttl, name, line, Line, cname, type, record }] } } + fetchZoneRecords: api('ZoneEdit', 'fetchzone_records', { customonly: 1, domain: options.domain }), + // { domain, name, type, cname, address, ttl } + // -> { result: { status } } + addZoneRecord: api('ZoneEdit', 'add_zone_record', { domain: options.domain }), + }; +}; + +if (!DOMAIN_API_KEY) { + console.error('Api key cannot be empty'); + process.exit(1); +} + +const cpanel = CpanelClient({ + host: DOMAIN_API_HOST, + port: DOMAIN_API_PORT, + username: DOMAIN_USER, + apiKey: DOMAIN_API_KEY, + domain: DOMAIN_DOMAIN, + dependencies: { fetch }, +}); + +module.exports = { + cpanel, + CpanelClient, +}; +