From 3d69312b5bdb7578ef5c2d1b5fcbb8bea50c8f0e Mon Sep 17 00:00:00 2001 From: guillermo Date: Wed, 22 Jun 2022 19:52:48 +0200 Subject: [PATCH] Mejoras en el output y el README --- README.md | 4 +- main copy.js | 277 +++++++++++++++++++++++++++++++++++++++++++++++++++ main.js | 37 ++++--- package.json | 2 +- 4 files changed, 305 insertions(+), 15 deletions(-) create mode 100644 main copy.js diff --git a/README.md b/README.md index 67c6e76..e915734 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ It's recommended to install the package globally. ```text $ npm i -g grafana-find -$ gafana-find +$ grafana-find ``` You can also install locally and use the *npx* command to execute it. @@ -31,7 +31,7 @@ Create a file ".grafana-find.json" with this content to don't put everytime the "password": "" } ``` -We recommend put the file into user folder ( Windows: %HOMEPATH% || Linux: $HOME ) +You need put the file into user folder ( Windows: %HOMEPATH% || Linux: $HOME ), the user and password are optional. ## How to use diff --git a/main copy.js b/main copy.js new file mode 100644 index 0000000..111367c --- /dev/null +++ b/main copy.js @@ -0,0 +1,277 @@ +#!/usr/bin/env node + +const packageJson = require('./package.json'); +const fetch = require('node-fetch'); +const colors = require('colors'); +const os = require('os'); +const fs = require('fs'); +const getopts = require('getopts'); + +const error = `[ERROR]: `.bold; + +console.log( + `Grafana-Find (${packageJson.description})`.yellow.bold, + `v${packageJson.version}`.cyan.bold +); + +const usage = { + description: 'Utility to find strings in dashboards', + params: { + user: 'Grafana username', + version: 'Display the version number and exit', + help: 'Display this help message' + } +}; + +const opts = getopts(process.argv.slice(2), { + alias: { + version: 'v', + help: 'h' + }, + boolean: [ + 'version', + 'help' + ] +}); + +if (opts.version) { + process.exit(); +} +if (opts.help) { + console.log(`Usage:`.gray, `grafana-find`, ``.magenta); + process.exit(); +} + +if (!opts._[0]) { + console.error(`${error}The string to search for is missing`.red); + process.exit(1); +} +if (opts._.length > 1) { + console.error(`${error}This command doesn't allow more parameters`.red); + process.exit(1); +} + +let config; +const configPaths = [ + os.homedir(), + `${__dirname}` +]; +for (const configPath of configPaths) { + const configFile = `${configPath}/.grafana-find.json`; + if (fs.existsSync(configFile)) { + config = require(configFile); + break; + } +} +if (!config) { + console.error(`${error}Configuration file not found, search paths: .grafana-find.json: ${configPaths.join(':')}\n`.red); + process.exit(1); +} + +const findAll = opts._[0]; +const grafanaUrl = config.grafanaUrl; +let user = config.user; +let passw = config.password; + +const grafanaApi = `${grafanaUrl}/api`; +const urlOrganizations = `${grafanaUrl}/api/orgs`; +const urlDashboards = `${grafanaApi}/search?orgId=`; +const urlUID = `${grafanaApi}/dashboards/uid/`; +let numberOfDashboards = 0; +let totalDashboards = 0; +let numberOfPanels = 0; +let numberOfVariables = 0; +let numberOfObjects = 0; +let titlePanels = new Array; +let nameVariables = new Array; + +const regexRawSQL = new RegExp(findAll, 'i'); + +async function main(){ + if (!user) { + const readline = require('readline'); + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + + const answer = await new Promise(resolve => { + rl.question(colors.green('Enter your user: '), resolve); + }); + user = `${answer}`; + if (!answer) { + console.error(`\n${error}You need to put a user\n`.red); + process.exit(0); + } + rl.close(); + } + + if (!passw) { + const readline = require('readline'); + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout + }); + + rl.stdoutMuted = true; + + const answer = await new Promise(resolve => { + rl.question(colors.green('Enter your password: '), resolve); + rl._writeToOutput = function _writeToOutput(stringToWrite) { + if (rl.stdoutMuted) + rl.output.write("*"); + else + rl.output.write(stringToWrite); + }; + }); + passw = `${answer}`; + if (!answer) { + console.error(`\n${error}You need to put a password\n`.red); + process.exit(0); + } + rl.close(); + } + + const credentials = `Basic ` + Buffer.from(`${user}:${passw}`).toString('base64'); + + try { + var response = await fetch(urlOrganizations, { + method: "GET", + headers: { + Authorization: credentials + } + }); + } catch (notfound) { + console.error(`${error}Server '${config.grafanaUrl}' not found`.red); + process.exit(1); + }; + let AllOrganizations = await response.json(); + + if (AllOrganizations.message==='invalid username or password') { + console.error(`\n${error}Invalid username or password\n`.red); + process.exit(1); + } + + console.clear(); + console.log( + `--------- Grafana-Find (${packageJson.description})`.yellow.bold, + `v${packageJson.version}`.cyan.bold, + `--------`.yellow.bold, + ); + console.log(colors.green.bold(`-------------------- Starting process --------------------\n`)); + + for (let x in AllOrganizations) { + + console.log(colors.gray.bold(`(Organization: ${AllOrganizations[x].name})\n`)); + response = await fetch(`${urlDashboards}${AllOrganizations[x].id}`, { + method: "GET", + headers: { + Authorization: credentials + }, + redirect: 'manual' + }); + + if (response.status === 302) { + response = await fetch(`${urlDashboards}${AllOrganizations[x].id}`, { + method: 'GET', + headers: { + Accept: 'application/json' + }, + redirect: 'manual' + }); + } + + let allUID = await response.json(); + + for (let i in allUID) { + let url = `${urlUID}${allUID[i].uid}`; + response = await fetch(url, { + method: "GET", + headers: { + Authorization: credentials, + }, + redirect: 'manual' + }); + + if (response.status === 404) { + response = await fetch(url, { + method: 'GET', + headers: { + Accept: 'application/json' + }, + redirect: 'manual' + }); + } + + let data = await response.json(); + + let isFound = false; + let isFoundSomething = 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(`null`); + numberOfPanels++; + isFoundSomething=true; + } + } + } + + if (dashboard.templating) + for (const list of dashboard.templating.list) { + isFound = regexRawSQL.test(list.query); + if (isFound) { + nameVariables.push(list.name) + numberOfVariables++; + isFoundSomething=true; + } + } + } + + if (isFoundSomething) { + const linkUrl = `${grafanaUrl}/d/${allUID[i].uid}?orgId=${AllOrganizations[x].id}`; + console.log((linkUrl).yellow.underline, dashboard.title); + 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(","))); + } + console.log('') + numberOfDashboards++; + } + + titlePanels = []; + nameVariables= []; + numberOfObjects = numberOfPanels + numberOfVariables + numberOfObjects; + numberOfPanels = 0; + numberOfVariables = 0; + } + totalDashboards = numberOfDashboards + totalDashboards; + if (!numberOfDashboards) + console.log(`No results found\n`.green); + numberOfDashboards = 0; + }; + + console.log(colors.green.bold(`-------- Have been found ${numberOfObjects} results in ${totalDashboards} dashboards -------\n`)); + + if (!response) { + console.log(`${error}The server don't exists`); + process.exit(1); + } + + process.exit(); + +} +main(); \ No newline at end of file diff --git a/main.js b/main.js index 111367c..a2467bb 100644 --- a/main.js +++ b/main.js @@ -154,15 +154,13 @@ async function main(){ console.clear(); console.log( - `--------- Grafana-Find (${packageJson.description})`.yellow.bold, - `v${packageJson.version}`.cyan.bold, - `--------`.yellow.bold, + `───────── Grafana-Find (${packageJson.description}) v${packageJson.version} ────────`.yellow.bold ); - console.log(colors.green.bold(`-------------------- Starting process --------------------\n`)); + console.log(colors.green.bold(`──────────────────── Starting process ────────────────────\n`)); for (let x in AllOrganizations) { - console.log(colors.gray.bold(`(Organization: ${AllOrganizations[x].name})\n`)); + console.log(colors.gray.bold(`-{Organization: ${AllOrganizations[x].name}}-\n`)); response = await fetch(`${urlDashboards}${AllOrganizations[x].id}`, { method: "GET", headers: { @@ -217,9 +215,12 @@ async function main(){ isFound = regexRawSQL.test(target.rawSql); if (isFound) { if (panel.title) - titlePanels.push(panel.title); + if (panel.title==' ') + titlePanels.push(`(null)`.italic); + else + titlePanels.push(panel.title); else - titlePanels.push(`null`); + titlePanels.push(`(undefined)`.italic); numberOfPanels++; isFoundSomething=true; } @@ -241,12 +242,24 @@ async function main(){ const linkUrl = `${grafanaUrl}/d/${allUID[i].uid}?orgId=${AllOrganizations[x].id}`; console.log((linkUrl).yellow.underline, dashboard.title); if (numberOfPanels) { - console.log(colors.cyan.bold(`> ${numberOfPanels} panels`)); - console.log(colors.cyan(titlePanels.toString().split(","))); + console.log(colors.cyan.bold(`[${numberOfPanels}] panels`)); + for (let q in titlePanels) { + if (q==(titlePanels.length-1)) { + console.log(` └─${titlePanels[q]}`.cyan) + break + } + console.log(` ├─${titlePanels[q]}`.cyan) + } } if (numberOfVariables) { - console.log(colors.magenta.bold(`> ${numberOfVariables} variables`)); - console.log(colors.magenta(nameVariables.toString().split(","))); + console.log(colors.magenta.bold(`[${numberOfVariables}] variables`)); + for (let q in nameVariables) { + if (q==(nameVariables.length-1)) { + console.log(` └─${nameVariables[q]}`.magenta) + break + } + console.log(` ├─${nameVariables[q]}`.magenta) + } } console.log('') numberOfDashboards++; @@ -264,7 +277,7 @@ async function main(){ numberOfDashboards = 0; }; - console.log(colors.green.bold(`-------- Have been found ${numberOfObjects} results in ${totalDashboards} dashboards -------\n`)); + console.log(colors.green.bold(`──────── Have been found ${numberOfObjects} results in ${totalDashboards} dashboards ────────\n`)); if (!response) { console.log(`${error}The server don't exists`); diff --git a/package.json b/package.json index bcac78d..3bce800 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "grafana-find", - "version": "1.0.2", + "version": "1.0.3", "author": "Verdnatura Levante SL", "description": "Grafana Find Tool", "license": "GPL-3.0",