Extend top-level arguments functions

168 views
Skip to first unread message

Federico Buti

unread,
Mar 11, 2020, 1:09:17 PM3/11/20
to Jsonnet
Hi all.

I'm playing around with Jsonnet because of the Grafonnet library and while the tutorial felt rather clear, I'm finding it difficult to extend the functionality of the library for my usages.


As you can see there is a repeated usage of .addTemplate to add Grafana variables. That part tends to repeat in my case so I'd like to move that boilter-plate code into a function. 

As far as I can tell the Grafana dashboard "new()" function in https://github.com/grafana/grafonnet-lib/blob/master/grafonnet/dashboard.libsonnet is a top-level arguments function - correct me if I'm wrong please. I've tried to extend it and came up, after some play, with the following code:

local grafana = import '../grafonnet-lib/grafonnet/grafana.libsonnet';
local dashboard = grafana.dashboard;
{
new(
title,
tags,
refresh = '5s',
source = 'Prometheus FRA',
variables = {"stack": "mystack", "environment": "pro"}
)::
dashboard.new(
title=title,
tags=tags,
timezone='default',
editable=true,
refresh=refresh,
schemaVersion=18, // Grafana 5.x.x schema
),
}

Now the problem starts. I'd like to use the "variables" parameter as well as the "source" to generate Grafana variables but I can't understand how to do that in the scenario above. I don't want to just call "dashboard.new" but also call "addTemplate", as seen in the first link, on the basis of the values in "variables".

After several tries and out of options I've copy-pasted the whole code of dashboard from https://github.com/grafana/grafonnet-lib/blob/master/grafonnet/dashboard.libsonnet and injected the following code:

    templates:: 
      if source != '' then [
        templatelib.datasource(
          'SOURCE',
          'prometheus',
          source,
          hide='all',
        )
      ] + [     
      templatelib.new(
         key,
         '$SOURCE',
         'label_values(' + key + ')',
         label=key,
         refresh='time',
         current=variables[key]
       )
      for key in std.objectFields(variables) 
    ],

This works fine but I don't really like to have a copy of the original code and instead I'd like to squeeze this stuff - or some variant of that - into my first code snippet.

Is that possible? Is it possible to call "addTemplate" on the object from my first snippet? What's the correct syntax for that?
Thanks in advance. 

Federico Buti

unread,
Mar 12, 2020, 5:00:07 AM3/12/20
to Jsonnet
Hi again.

Answering my own question after realizing how powerful the plus operator really is. I've used that and ended up with the following code:


local grafana = import '../grafonnet-lib/grafonnet/grafana.libsonnet';
local dashboard = grafana.dashboard;
local templatelib = grafana.template;



{
 
new(
    title
,
    tags
,
    refresh
= '5s',
    source
= 'Prometheus FRA',
    variables
= {"stack": "mystack", "environment": "pro"}
 
)::
    dashboard
.new(
      title
=title,
      tags
=tags,
      timezone
='default',
      editable
=true,
      refresh
=refresh,
      schemaVersion
=18, // Grafana 5.x.x schema  
   
)

   
+
   
{
      templates
::
     
if source != '' then ([

        templatelib
.datasource(
         
'SOURCE',
         
'prometheus',
          source
,
          hide
='all',
       
)] + [    
        templatelib
.new(
          key
,
         
'$SOURCE',
         
'label_values(' + key + ')',
          label
=key,
          refresh
='time',
          current
=variables[key]
       
)
       
for key in std.objectFields(variables)

     
]),
   
},
}

Works like a charm and uses the original function, as should have been from the start.
Sorry for the noise guys.

Bests,
F.
Reply all
Reply to author
Forward
0 new messages