Auto API-key configuration #7
Merged
rozetko
merged 6 commits from auto-api-key-configuration
into master
2 years ago
13 changed files with 154 additions and 53 deletions
@ -1,5 +1,6 @@
|
||||
node_modules/ |
||||
dist/ |
||||
exported/ |
||||
data/ |
||||
config.json |
||||
package-lock.json |
||||
api-keys.json |
||||
|
@ -1,6 +1,3 @@
|
||||
{ |
||||
"apiKeys" : { |
||||
"http://localhost:3000": "eyJrIjoiTjlUcmtLSFRNcTdqeXBaQjB5REk2TFkyUDBDM0Z1bWciLCJuIjoiZXhwb3J0LW1hbmFnZXIiLCJpZCI6MX0=" |
||||
}, |
||||
"port": "8000" |
||||
} |
||||
|
@ -0,0 +1,13 @@
|
||||
version: '2' |
||||
|
||||
services: |
||||
exporter: |
||||
image: corpglory/grafana-data-exporter:latest |
||||
restart: always |
||||
ports: |
||||
- 8000: 8000 |
||||
volumes: |
||||
- data:/var/www/data |
||||
|
||||
volumes: |
||||
data |
@ -0,0 +1,53 @@
|
||||
import { upsertApiKey, validateGrafanaUrl } from '../services/api_keys'; |
||||
|
||||
import * as express from 'express' |
||||
|
||||
import * as _ from 'lodash'; |
||||
|
||||
|
||||
async function checkConnection(req, res) { |
||||
const query = req.query; |
||||
|
||||
const clientUrl = query.url; |
||||
if (_.isEmpty(clientUrl)) { |
||||
res.status(400).send('"url" field is required'); |
||||
return; |
||||
} |
||||
|
||||
try { |
||||
validateGrafanaUrl(clientUrl); |
||||
} catch (e) { |
||||
res.status(500).send(e.message); |
||||
return; |
||||
} |
||||
|
||||
res.status(200).send({ version: process.env.npm_package_version }); |
||||
} |
||||
|
||||
async function connectPlugin(req, res) { |
||||
const body = req.body; |
||||
|
||||
const clientUrl = body.url; |
||||
if (_.isEmpty(clientUrl)) { |
||||
res.status(400).send('"url" field is required'); |
||||
return; |
||||
} |
||||
const apiToken = body.apiToken; |
||||
if (_.isEmpty(apiToken)) { |
||||
res.status(400).send('"apiToken" field is required'); |
||||
return; |
||||
} |
||||
|
||||
const grafanaUrl = new URL(clientUrl).origin; |
||||
|
||||
upsertApiKey(grafanaUrl, apiToken); |
||||
|
||||
console.log(`Grafana at ${grafanaUrl} is connected`); |
||||
|
||||
res.status(200).send({ version: process.env.npm_package_version }); |
||||
} |
||||
|
||||
export const router = express.Router(); |
||||
|
||||
router.get('/', checkConnection); |
||||
router.post('/', connectPlugin); |
@ -1,10 +1,10 @@
|
||||
import * as express from 'express' |
||||
|
||||
|
||||
async function deleteTask(req, res) { |
||||
res.status(200).send({ version: 123 }); |
||||
async function getStatus(req, res) { |
||||
res.status(200).send({ version: process.env.npm_package_version }); |
||||
} |
||||
|
||||
export const router = express.Router(); |
||||
|
||||
router.get('/', deleteTask); |
||||
router.get('/', getStatus); |
||||
|
@ -0,0 +1,41 @@
|
||||
import { DATA_PATH } from '../config'; |
||||
|
||||
import * as path from 'path'; |
||||
import * as fs from 'fs'; |
||||
import * as _ from 'lodash'; |
||||
|
||||
|
||||
const API_KEYS_FILE = path.join(DATA_PATH, 'api-keys.json'); |
||||
if(!fs.existsSync(API_KEYS_FILE)) { |
||||
console.log(`${API_KEYS_FILE} doesn't exist, creating`); |
||||
fs.writeFileSync(API_KEYS_FILE, JSON.stringify({}), 'utf8'); |
||||
} |
||||
|
||||
export function getApiKey(grafanaUrl: string): string | null { |
||||
const data = fs.readFileSync(API_KEYS_FILE, 'utf8'); |
||||
const apiKey = JSON.parse(data)[grafanaUrl]; |
||||
if(_.isNil(apiKey)) { |
||||
return null; |
||||
} |
||||
|
||||
return apiKey; |
||||
} |
||||
|
||||
export function upsertApiKey(grafanaUrl: string, apiKey: string): void { |
||||
const data = fs.readFileSync(API_KEYS_FILE, 'utf8'); |
||||
const apiKeys = JSON.parse(data); |
||||
|
||||
apiKeys[grafanaUrl] = apiKey; |
||||
|
||||
fs.writeFileSync(API_KEYS_FILE, JSON.stringify(apiKeys), 'utf8'); |
||||
} |
||||
|
||||
// TODO: query Grafana API if a key exists && remove the key if it doesn't work for specified grafanaUrl
|
||||
export function validateGrafanaUrl(grafanaUrl: string) { |
||||
const host = new URL(grafanaUrl).origin; |
||||
const apiKey = getApiKey(host); |
||||
|
||||
if (_.isNil(apiKey) || apiKey === '') { |
||||
throw new Error(`Please configure API key for ${host}`); |
||||
} |
||||
} |
@ -1,17 +1,5 @@
|
||||
import * as moment from 'moment-timezone'; |
||||
|
||||
export async function promisify(method: (...params: any[]) => Promise<any> | void, ...params: any[]) { |
||||
return new Promise((resolve, reject) => { |
||||
method(...params, (err, result) => { |
||||
if(err) { |
||||
reject(err); |
||||
} else { |
||||
resolve(result); |
||||
} |
||||
}) |
||||
}); |
||||
} |
||||
|
||||
export function toIsoString(msTimestamp: number, timeZone: string): string { |
||||
return moment.tz(msTimestamp, timeZone).format('YYYY-MM-DD HH:mm:ssZ').replace(/:00$/, ''); |
||||
} |
||||
|
Loading…
Reference in new issue