Act

defensivedepth/grafana-generate-snapshots

  • Builds
  • latest 0.0.3 / 2018-03-06
  • Created 2018-03-02
  • Last modified 2018-03-06
  • grade 3

Description

Generates a Grafana Dashboard Snapshot. To use, edit the Grafana login URL in the source and re-build the act. Then call the API with valid Grafana credentials and target report URL in the body. The output will be the snapshot URL. This act must use image with Puppeteer (Node.js 8 + Puppeteer on Debian).


API

To run the act, send a HTTP POST request to:

https://api.apify.com/v2/acts/defensivedepth~grafana-generate-snapshots/runs?token=<YOUR_API_TOKEN>

The POST payload will be passed as input for the act. For more information, read the docs.


Example input

Content type: application/json; charset=utf-8

{"userName":"GrafanaUsername","password":"GrafanaPassword","url":"ReportURL"}

Source code

Based on the apify/actor-node-chrome Docker image (see docs).

const Apify = require('apify');
const utils = require('apify/build/utils');
const ApifyClient = require('apify-client');
require('puppeteer');
const path = require('path')
require('jquery');
const cheerio = require('cheerio')

const humanDelay = ms => (Math.random() + 1) * ms;

const sleepPromised = ms => new Promise(resolve => setTimeout(resolve, ms));

const saveScreen = async (page, key) => {
    const screenshotBuffer = await page.screenshot();
    await Apify.setValue(key, screenshotBuffer, { contentType: 'image/png' });
    const html = await page.evaluate('document.documentElement.outerHTML');
    await Apify.setValue(key+'txt', html, { contentType: 'text/html' });
};

const opts = {
    args: [
        '--disable-web-security',
    ],
    //proxyUrl : ''
};

var browser = {};

const setCookies = async (page) => {
      
}

const pageGoto = async (page, url, timeout, retryCount)  => {
    //if !(page) await page = await browser.newPage();
    let done = '';
    let counter = 0;
    await setCookies(page);
    do {
        try {
            //console.log('BEFORE REQ')
            //console.log(url);
            var response = await page.goto(url,{ waitUntil: 'networkidle2',timeout: timeout });
            //console.log('AFTER REQ')
            done = '';
        }
        catch (error){
            console.log(error)
            counter += 1;
            done = error;
            await page.close();
            if (counter>1){
                browser = await Apify.launchPuppeteer(opts);
                console.log('new browser');
            }
            page = await browser.newPage();
            await new Promise((resolve) => setTimeout(resolve, 3000));
            console.log('RETRY Error')
        }
        if (response) {
            if (response.status()!==200){
                await page.close();
                if (counter>1){
                    browser = await Apify.launchPuppeteer(opts);
                    console.log('new browser');
                }
                page = await browser.newPage();
                counter += 1;
                done = '403';
                await new Promise((resolve) => setTimeout(resolve, 3000));
                console.log('RETRY '+response.status())
            }
        }
    } while (done!=='' && counter < retryCount)

    if (done!==''){
        console.log('RETURN NULL')
        return null;
    }
    else
    {
        return page;
    }
}

Apify.main(async () => {
    var results = [];
    
    const input = await Apify.getValue('INPUT')
    
    var userName = input.userName;
    var password = input.password;
    var url = input.url;
    
    console.log('Launching Puppeteer...');
    browser = await Apify.launchPuppeteer(opts);
    var page = await browser.newPage();
        
    await page.setUserAgent('Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; .NET4.0E; .NET4.0C; .NET CLR 3.5.30729; .NET CLR 2.0.50727; .NET CLR 3.0.30729; InfoPath.3; MALCJS; rv:11.0) like Gecko');
    page = await pageGoto(page,"https://YourGrafanaDomain.com/login", 100000, 10);
    if (page!==null){
        console.log('logIn');
        await page.type('[name="username"]', userName, { delay: 100 });
        await page.type('[id="inputPassword"]', password, { delay: 100 });
        page.click('[type="submit"]');
        await page.waitForNavigation({ waitUntil: 'networkidle2' });
        console.log('after logIn submit');
    }   

    page = await pageGoto(page,url, 100000, 10);
   
    page.click('[bs-tooltip="\'Share dashboard\'"]');
    try {
        await page.waitForSelector('a[class="gf-tabs-link"]');
    }
    catch (error) {
        await saveScreen(page,'errr');
        throw error;
    }
   
    page.click('a[class="gf-tabs-link"]');

    try {
        await page.waitForSelector('[ng-click="createSnapshot()"]');
    }
    catch (error) {
        await saveScreen(page,'errr');
        throw error;
    } 
   
    page.click('[ng-click="createSnapshot()"]');
    
    try {
        await page.waitForSelector('a[class="large share-modal-link"]');
    }
    catch (error) {
        await saveScreen(page,'errr');
        throw error;
    } 
   
   let href = await page.$eval('a[class="large share-modal-link"]', a => a.href)
   
    await Apify.setValue('OUTPUT', href);

    console.log('Done.');
});