#!/usr/bin/env node const fetch = require('node-fetch'); const colors = require('colors'); const os = require('os'); const fs = require('fs'); const getopts = require('getopts'); const homeDir = os.homedir(); const configFile = `${homeDir}/.grafana-find.json`; if (!fs.existsSync(configFile)) { console.error(`Configuration file not found: ${configFile}`.red); process.exit(1); } const findAll = `Client`; const config = require(configFile); const grafanaUrl = config.grafanaUrl; const grafanaApi = `${grafanaUrl}/api`; const urlDashboards = `${grafanaApi}/search`; const urlUID = `${grafanaApi}/dashboards/uid/`; let numberOfDashboards = 0; let numberOfPanels = 0; let numberOfVariables = 0; let numberOfObjects = 0; let titlePanels = new Array; let nameVariables = new Array; const regexRawSQL = new RegExp(findAll, 'i'); const user = `guillermo`; async function main(){ const readline = require('readline'); const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); const answer = await new Promise(resolve => { rl.question(colors.yellow('Enter your password: '), resolve); }); if (!answer) { console.error(`You need to put a password`.red); process.exit(0); } const passw = `${answer}`; const credentials = `Basic ` + Buffer.from(`${user}:${passw}`).toString('base64'); rl.close(); console.clear(); console.log(colors.green.bold(`-------------------- Starting process --------------------`)); let responseAllUID = await fetch(urlDashboards, { method: "GET", headers: { "Authorization": credentials, "Content-Type" : "application/json" } }); let allUID = await responseAllUID.json(); for (let i=0; i < allUID.length; i++) { let url = urlUID + allUID[i].uid; let response = await fetch(url, { method: "GET", headers: { "Authorization": credentials, } }); let data = await response.json(); let isFound = false; const dashboard = data.dashboard; if (dashboard) { if (dashboard.panels) for (const panel of dashboard.panels) { if (panel.targets) for (const target of panel.targets) { isFound = regexRawSQL.test(target.rawSql); if (isFound) { if (panel.title) titlePanels.push(panel.title); else titlePanels.push("?"); numberOfPanels++; } } } if (dashboard.templating) for (const list of dashboard.templating.list) { isFound = regexRawSQL.test(list.query); if (isFound) { nameVariables.push(list.name) numberOfVariables++; } } } if (isFound) { const linkUrl = `${grafanaUrl}/d/${allUID[i].uid}`; console.log(colors.yellow(linkUrl)); if (numberOfPanels) { console.log(colors.cyan.bold(`> ${numberOfPanels} panels`)); console.log(colors.cyan(titlePanels.toString().split(","))); } if (numberOfVariables) { console.log(colors.magenta.bold(`> ${numberOfVariables} variables`)); console.log(colors.magenta(nameVariables.toString().split(","))); } numberOfDashboards++; } titlePanels = []; nameVariables= []; numberOfObjects = numberOfPanels + numberOfVariables + numberOfObjects numberOfPanels=0; numberOfVariables=0; } if (numberOfDashboards==0) console.log(`No results found`.red); else console.log(colors.green.bold(`-------- Have been found ${numberOfObjects} results in ${numberOfDashboards} dashboards -------`)); process.exit(0); } main();