From 02c3e00e3d6795a7a44571cf33097bcf9e97ffc4 Mon Sep 17 00:00:00 2001 From: potchin Date: Fri, 9 Jun 2017 15:31:18 +0100 Subject: [PATCH 1/3] Add support for custom image sizes The default image width of 1000px is sometimes not enough but was originally hardcoded. This PR adds the ability to specify the width/height of the image when calling the dashboard --- src/grafana.coffee | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/grafana.coffee b/src/grafana.coffee index 05751a2..4cdc5de 100644 --- a/src/grafana.coffee +++ b/src/grafana.coffee @@ -4,6 +4,8 @@ # Examples: # - `hubot graf db graphite-carbon-metrics` - Get all panels in the dashboard # - `hubot graf db graphite-carbon-metrics:3` - Get only the third panel, from left to right, of a particular dashboard +# - `hubot graf db graphite-carbon-metrics:3 width=1000` - Get only the third panel, from left to right, of a particular dashboard. Set the image width to 1000px +# - `hubot graf db graphite-carbon-metrics:3 height=2000` - Get only the third panel, from left to right, of a particular dashboard. Set the image height to 2000px # - `hubot graf db graphite-carbon-metrics:panel-8` - Get only the panel of a particular dashboard with the ID of 8 # - `hubot graf db graphite-carbon-metrics:cpu` - Get only the panels containing "cpu" (case insensitive) in the title # - `hubot graf db graphite-carbon-metrics now-12hr` - Get a dashboard with a window of 12 hours ago to now @@ -67,6 +69,7 @@ module.exports = (robot) -> visualPanelId = false apiPanelId = false pname = false + imagesize = { "width": 1000, "height": 500 } # Parse out a specific panel if /\:/.test slug @@ -89,6 +92,10 @@ module.exports = (robot) -> for part in remainder.trim().split ' ' # Check if it's a variable or part of the timespan if part.indexOf('=') >= 0 + #put imagesize stuff into its own dict + if part.split('=')[0] of imagesize + imagesize[part.split('=')[0]] = part.split('=')[1] + variables = "#{variables}&var-#{part}" template_params.push { "name": part.split('=')[0], "value": part.split('=')[1] } @@ -161,7 +168,7 @@ module.exports = (robot) -> # Build links for message sending title = formatTitleWithTemplate(panel.title, template_map) - imageUrl = "#{grafana_host}/render/#{apiEndpoint}/db/#{slug}/?panelId=#{panel.id}&width=1000&height=500&from=#{timespan.from}&to=#{timespan.to}#{variables}" + imageUrl = "#{grafana_host}/render/#{apiEndpoint}/db/#{slug}/?panelId=#{panel.id}&width=#{imagesize.width}&height=#{imagesize.height}&from=#{timespan.from}&to=#{timespan.to}#{variables}" link = "#{grafana_host}/dashboard/db/#{slug}/?panelId=#{panel.id}&fullscreen&from=#{timespan.from}&to=#{timespan.to}#{variables}" # Fork here for S3-based upload and non-S3 From 4d555e5db6b80af01411b667f853c058a2899355 Mon Sep 17 00:00:00 2001 From: potchin Date: Fri, 9 Jun 2017 15:41:51 +0100 Subject: [PATCH 2/3] Add missing continue --- src/grafana.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/grafana.coffee b/src/grafana.coffee index 4cdc5de..0b7ffa6 100644 --- a/src/grafana.coffee +++ b/src/grafana.coffee @@ -95,6 +95,7 @@ module.exports = (robot) -> #put imagesize stuff into its own dict if part.split('=')[0] of imagesize imagesize[part.split('=')[0]] = part.split('=')[1] + continue variables = "#{variables}&var-#{part}" template_params.push { "name": part.split('=')[0], "value": part.split('=')[1] } From d9f596176dbec79c97b039d3a16309ded73a5c23 Mon Sep 17 00:00:00 2001 From: Stephen Yeargin Date: Thu, 8 Feb 2018 10:34:16 -0600 Subject: [PATCH 3/3] Allow default image sizes to be set in environment - Updates README - Updates tests --- README.md | 3 ++- src/grafana.coffee | 17 +++++++++------ test/grafana-test.coffee | 46 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b2b1bea..8a730cb 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,8 @@ Then add **hubot-grafana** to your `external-scripts.json`: | `HUBOT_GRAFANA_HOST` | **Yes** | Host for your Grafana 2.x install, e.g. `http://play.grafana.org` | | `HUBOT_GRAFANA_API_KEY` | _Yes^_ | Grafana API key (This can be "Viewer" role.) | | `HUBOT_GRAFANA_QUERY_TIME_RANGE` | No | Default time range for queries (defaults to 6h) | - +| `HUBOT_GRAFANA_DEFAULT_WIDTH` | No | Default width for rendered images (defaults to 1000) | +| `HUBOT_GRAFANA_DEFAULT_HEIGHT` | No | Default height for rendered images (defaults to 500) | ^ _Not required for `auth.anonymous` Grafana configurations. All other authentication models will require a user-specific API key._ ### Amazon S3 Image Hosting diff --git a/src/grafana.coffee b/src/grafana.coffee index 2975846..28bab53 100644 --- a/src/grafana.coffee +++ b/src/grafana.coffee @@ -16,6 +16,8 @@ # HUBOT_GRAFANA_HOST - Host for your Grafana 2.0 install, e.g. 'http://play.grafana.org' # HUBOT_GRAFANA_API_KEY - API key for a particular user (leave unset if unauthenticated) # HUBOT_GRAFANA_QUERY_TIME_RANGE - Optional; Default time range for queries (defaults to 6h) +# HUBOT_GRAFANA_DEFAULT_WIDTH - Optional; Default width for rendered images (defaults to 1000) +# HUBOT_GRAFANA_DEFAULT_HEIGHT - Optional; Default height for rendered images (defaults to 500) # HUBOT_GRAFANA_S3_ENDPOINT - Optional; Endpoint of the S3 API (useful for S3 compatible API, defaults to s3.amazonaws.com) # HUBOT_GRAFANA_S3_BUCKET - Optional; Name of the S3 bucket to copy the graph into # HUBOT_GRAFANA_S3_ACCESS_KEY_ID - Optional; Access key ID for S3 @@ -56,11 +58,12 @@ module.exports = (robot) -> s3_region = process.env.HUBOT_GRAFANA_S3_REGION or 'us-standard' s3_port = process.env.HUBOT_GRAFANA_S3_PORT if process.env.HUBOT_GRAFANA_S3_PORT slack_token = process.env.HUBOT_SLACK_TOKEN + site = () -> # prioritize S3 no matter if adpater is slack if (s3_bucket && s3_access_key && s3_secret_key) 's3' - else if (robot.adapterName == 'slack') + else if (robot.adapterName == 'slack') 'slack' else '' @@ -79,7 +82,9 @@ module.exports = (robot) -> visualPanelId = false apiPanelId = false pname = false - imagesize = { "width": 1000, "height": 500 } + imagesize = + width: process.env.HUBOT_GRAFANA_DEFAULT_WIDTH or 1000 + height: process.env.HUBOT_GRAFANA_DEFAULT_HEIGHT or 500 # Parse out a specific panel if /\:/.test slug @@ -106,7 +111,7 @@ module.exports = (robot) -> if part.split('=')[0] of imagesize imagesize[part.split('=')[0]] = part.split('=')[1] continue - + variables = "#{variables}&var-#{part}" template_params.push { "name": part.split('=')[0], "value": part.split('=')[1] } @@ -297,7 +302,7 @@ module.exports = (robot) -> uploadPath = () -> prefix = s3_prefix || 'grafana' "#{prefix}/#{crypto.randomBytes(20).toString('hex')}.png" - + uploadTo = 's3': (msg, title, grafanaDashboardRequest, link) -> grafanaDashboardRequest (err, res, body) -> @@ -339,7 +344,7 @@ module.exports = (robot) -> req.end body 'slack': (msg, title, grafanaDashboardRequest, link) -> - testAuthData = + testAuthData = url: 'https://slack.com/api/auth.test' formData: token: slack_token @@ -395,4 +400,4 @@ module.exports = (robot) -> if callback callback(err, res, body) - uploadTo[site()](msg, title, grafanaDashboardRequest, link) \ No newline at end of file + uploadTo[site()](msg, title, grafanaDashboardRequest, link) diff --git a/test/grafana-test.coffee b/test/grafana-test.coffee index 42d5c08..bd515ba 100644 --- a/test/grafana-test.coffee +++ b/test/grafana-test.coffee @@ -113,6 +113,52 @@ describe 'grafana', -> [ 'hubot', "Graphite examples: http://play.grafana.org/render/dashboard-solo/db/grafana-play-home/?panelId=8&width=1000&height=500&from=now-6h&to=now - http://play.grafana.org/dashboard/db/grafana-play-home/?panelId=8&fullscreen&from=now-6h&to=now"] ] + context 'ask hubot to return different default image sizes', -> + beforeEach (done) -> + process.env.HUBOT_GRAFANA_DEFAULT_WIDTH = 1024 + process.env.HUBOT_GRAFANA_DEFAULT_HEIGHT = 768 + nock('http://play.grafana.org') + .get('/api/dashboards/db/grafana-play-home') + .replyWithFile(200, __dirname + '/fixtures/dashboard-grafana-play-home.json') + room.user.say 'alice', 'hubot graf db grafana-play-home:3' + setTimeout done, 100 + afterEach -> + delete process.env.HUBOT_GRAFANA_DEFAULT_WIDTH + delete process.env.HUBOT_GRAFANA_DEFAULT_HEIGHT + + it 'hubot should respond with the custom image size set in environment', -> + expect(room.messages).to.eql [ + [ 'alice', 'hubot graf db grafana-play-home:3' ] + [ 'hubot', "Graphite examples: http://play.grafana.org/render/dashboard-solo/db/grafana-play-home/?panelId=8&width=1024&height=768&from=now-6h&to=now - http://play.grafana.org/dashboard/db/grafana-play-home/?panelId=8&fullscreen&from=now-6h&to=now"] + ] + + context 'ask hubot to return a specific panel with a custom size', -> + beforeEach (done) -> + nock('http://play.grafana.org') + .get('/api/dashboards/db/grafana-play-home') + .replyWithFile(200, __dirname + '/fixtures/dashboard-grafana-play-home.json') + room.user.say 'alice', 'hubot graf db grafana-play-home:3 width=2500 height=700' + setTimeout done, 100 + + it 'hubot should respond with a resized image specified in request', -> + expect(room.messages).to.eql [ + [ 'alice', 'hubot graf db grafana-play-home:3 width=2500 height=700' ] + [ 'hubot', "Graphite examples: http://play.grafana.org/render/dashboard-solo/db/grafana-play-home/?panelId=8&width=2500&height=700&from=now-6h&to=now - http://play.grafana.org/dashboard/db/grafana-play-home/?panelId=8&fullscreen&from=now-6h&to=now"] + ] + context 'ask hubot to return a specific panel with a custom size in any order', -> + beforeEach (done) -> + nock('http://play.grafana.org') + .get('/api/dashboards/db/grafana-play-home') + .replyWithFile(200, __dirname + '/fixtures/dashboard-grafana-play-home.json') + room.user.say 'alice', 'hubot graf db grafana-play-home:3 height=700 width=2500' + setTimeout done, 100 + + it 'hubot should respond with a resized image specified in request', -> + expect(room.messages).to.eql [ + [ 'alice', 'hubot graf db grafana-play-home:3 height=700 width=2500' ] + [ 'hubot', "Graphite examples: http://play.grafana.org/render/dashboard-solo/db/grafana-play-home/?panelId=8&width=2500&height=700&from=now-6h&to=now - http://play.grafana.org/dashboard/db/grafana-play-home/?panelId=8&fullscreen&from=now-6h&to=now"] + ] + context 'ask hubot for templated dashboard', -> beforeEach (done) -> nock('http://play.grafana.org')