ops/monitoring: pull in grafonnet-7.0

Change-Id: Ie036ef767419418876a18255a5ad378f5cfa1535
diff --git a/ops/monitoring/lib/grafonnet/DOCS.md b/ops/monitoring/lib/grafonnet/DOCS.md
new file mode 100644
index 0000000..0c78596
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/DOCS.md
@@ -0,0 +1,846 @@
+# Docs
+
+* [dashboard](#dashboard)
+* [panel](#panel)
+  * [gauge.new](#panelGaugenew)
+  * [graph.new](#panelGraphnew)
+  * [row.new](#panelRownew)
+  * [stat.new](#panelStatnew)
+  * [table.new](#panelTablenew)
+  * [text.new](#panelTextnew)
+* [target](#target)
+  * [prometheus.new](#targetPrometheusnew)
+* [template](#template)
+  * [datasource.new](#templateDatasourcenew)
+  * [query.new](#templateQuerynew)
+
+## dashboard
+
+
+
+### dashboard.new
+
+Instantiate a dashboard.
+
+* **description**: (type: string, default: `null`)
+  
+* **editable**: (type: boolean, default: `true`)
+  
+* **graphTooltip**: (type: integer, default: `0`)
+  
+* **refresh**: (type: string, default: `null`)
+  
+* **schemaVersion**: (type: integer, default: `25`)
+  
+* **style**: (type: string, default: `"dark"`)
+  
+* **tags**: (type: array, default: `[]`)
+  
+* **timezone**: (type: string, default: `null`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **uid**: (type: string, default: `null`)
+  
+
+#### #setTime
+
+* **from**: (type: string, default: `"now-6h"`)
+  
+* **to**: (type: string, default: `"now"`)
+  
+#### #setTimepicker
+
+* **refreshIntervals**: (type: array, default: `["5s","10s","30s","1m","5m","15m","30m","1h","2h","1d"]`)
+  
+
+#### #addAnnotation
+
+* **builtIn**: (type: integer, default: `0`)
+  
+* **datasource**: (type: string, default: `"default"`)
+  
+* **enable**: (type: boolean, default: `true`)
+  
+* **hide**: (type: boolean, default: `false`)
+  
+* **iconColor**: (type: string, default: `null`)
+  
+* **name**: (type: string, default: `null`)
+  
+* **rawQuery**: (type: string, default: `null`)
+  
+* **showIn**: (type: integer, default: `0`)
+  
+#### #addTemplate
+
+* **template**: (type: object)
+  
+
+
+## panel
+
+
+
+### panel.gauge.new
+
+
+
+* **datasource**: (type: string, default: `"default"`)
+  
+* **description**: (type: string, default: `null`)
+  
+* **repeat**: (type: string, default: `null`)
+  
+* **repeatDirection**: (type: string, default: `null`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **transparent**: (type: boolean, default: `false`)
+  
+
+#### #setFieldConfig
+
+* **max**: (type: integer, default: `null`)
+  
+* **min**: (type: integer, default: `null`)
+  
+* **thresholdMode**: (type: string, default: `"absolute"`)
+  
+* **unit**: (type: string, default: `null`)
+  
+#### #setGridPos
+
+* **h**: (type: integer, default: `8`)
+  Panel height.
+* **w**: (type: integer, default: `12`)
+  Panel width.
+* **x**: (type: integer, default: `null`)
+  Panel x position.
+* **y**: (type: integer, default: `null`)
+  Panel y position.
+#### #setOptions
+
+* **calcs**: (type: array, default: `["mean"]`)
+  
+* **fields**: (type: string, default: `null`)
+  
+* **orientation**: (type: string, default: `"auto"`)
+  
+* **showThresholdLabels**: (type: boolean, default: `false`)
+  
+* **showThresholdMarkers**: (type: boolean, default: `true`)
+  
+* **values**: (type: boolean, default: `false`)
+  
+
+#### #addPanelLink
+
+* **targetBlank**: (type: boolean, default: `true`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **url**: (type: string, default: `null`)
+  
+#### #addDataLink
+
+* **targetBlank**: (type: boolean, default: `true`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **url**: (type: string, default: `null`)
+  
+#### #addMapping
+
+* **from**: (type: string, default: `null`)
+  
+* **id**: (type: integer, default: `null`)
+  
+* **operator**: (type: string, default: `null`)
+  
+* **text**: (type: string, default: `null`)
+  
+* **to**: (type: string, default: `null`)
+  
+* **type**: (type: integer, default: `null`)
+  
+* **value**: (type: string, default: `null`)
+  
+#### #addOverride
+
+* **matcher**: (type: oject, default: `null`)
+  
+* **properties**: (type: array, default: `null`)
+  
+#### #addThresholdStep
+
+* **color**: (type: string, default: `null`)
+  
+* **value**: (type: integer, default: `null`)
+  
+#### #addTarget
+
+* **target**: (type: object)
+  
+
+
+### panel.graph.new
+
+
+
+* **bars**: (type: boolean, default: `false`)
+  Display values as a bar chart.
+* **dashLength**: (type: integer, default: `10`)
+  Dashed line length.
+* **dashes**: (type: boolean, default: `false`)
+  Show line with dashes.
+* **datasource**: (type: string, default: `"default"`)
+  
+* **decimals**: (type: integer, default: `null`)
+  Controls how many decimals are displayed for legend values and
+  graph hover tooltips.
+* **description**: (type: string, default: `null`)
+  
+* **fill**: (type: integer, default: `1`)
+  Amount of color fill for a series. Expects a value between 0 and 1.
+* **fillGradient**: (type: integer, default: `0`)
+  Degree of gradient on the area fill. 0 is no gradient, 10 is a
+  steep gradient.
+* **hiddenSeries**: (type: boolean, default: `false`)
+  Hide the series.
+* **lines**: (type: boolean, default: `true`)
+  Display values as a line graph.
+* **linewidth**: (type: integer, default: `1`)
+  The width of the line for a series.
+* **nullPointMode**: (type: string, default: `"null"`)
+  How null values are displayed.
+  * 'null' - If there is a gap in the series, meaning a null value,
+    then the line in the graph will be broken and show the gap.
+  * 'null as zero' - If there is a gap in the series, meaning a null
+    value, then it will be displayed as a zero value in the graph
+    panel.
+  * 'connected' - If there is a gap in the series, meaning a null
+    value or values, then the line will skip the gap and connect to the
+    next non-null value.
+* **percentage**: (type: boolean, default: `false`)
+  Available when `stack` is true. Each series is drawn as a percentage
+  of the total of all series.
+* **pointradius**: (type: integer, default: `null`)
+  Controls how large the points are.
+* **points**: (type: boolean, default: `false`)
+  Display points for values.
+* **repeat**: (type: string, default: `null`)
+  
+* **repeatDirection**: (type: string, default: `null`)
+  
+* **spaceLength**: (type: integer, default: `10`)
+  Dashed line spacing when `dashes` is true.
+* **stack**: (type: boolean, default: `false`)
+  Each series is stacked on top of another.
+* **steppedLine**: (type: boolean, default: `false`)
+  Draws adjacent points as staircase.
+* **timeFrom**: (type: string, default: `null`)
+  
+* **timeShift**: (type: string, default: `null`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **transparent**: (type: boolean, default: `false`)
+  
+
+#### #setGridPos
+
+* **h**: (type: integer, default: `8`)
+  Panel height.
+* **w**: (type: integer, default: `12`)
+  Panel width.
+* **x**: (type: integer, default: `null`)
+  Panel x position.
+* **y**: (type: integer, default: `null`)
+  Panel y position.
+#### #setLegend
+
+* **alignAsTable**: (type: boolean, default: `null`)
+  Whether to display legend in table.
+* **avg**: (type: boolean, default: `false`)
+  Average of all values returned from the metric query.
+* **current**: (type: boolean, default: `false`)
+  Last value returned from the metric query.
+* **max**: (type: boolean, default: `false`)
+  Maximum of all values returned from the metric query.
+* **min**: (type: boolean, default: `false`)
+  Minimum of all values returned from the metric query.
+* **rightSide**: (type: boolean, default: `false`)
+  Display legend to the right.
+* **show**: (type: boolean, default: `true`)
+  Show or hide the legend.
+* **sideWidth**: (type: integer, default: `null`)
+  Available when `rightSide` is true. The minimum width for the legend in
+  pixels.
+* **total**: (type: boolean, default: `false`)
+  Sum of all values returned from the metric query.
+* **values**: (type: boolean, default: `true`)
+  
+#### #setThresholds
+
+* **thresholdMode**: (type: string, default: `"absolute"`)
+  
+#### #setTooltip
+
+* **shared**: (type: boolean, default: `true`)
+  * true - The hover tooltip shows all series in the graph.
+    Grafana highlights the series that you are hovering over in
+    bold in the series list in the tooltip.
+  * false - The hover tooltip shows only a single series, the one
+    that you are hovering over on the graph.
+* **sort**: (type: integer, default: `2`)
+  * 0 (none) - The order of the series in the tooltip is
+    determined by the sort order in your query. For example, they
+    could be alphabetically sorted by series name.
+  * 1 (increasing) - The series in the hover tooltip are sorted
+    by value and in increasing order, with the lowest value at the
+    top of the list.
+  * 2 (decreasing) - The series in the hover tooltip are sorted
+    by value and in decreasing order, with the highest value at the
+    top of the list.
+#### #setXaxis
+
+* **buckets**: (type: string, default: `null`)
+  
+* **mode**: (type: string, default: `"time"`)
+  The display mode completely changes the visualization of the
+  graph panel. It’s like three panels in one. The main mode is
+  the time series mode with time on the X-axis. The other two
+  modes are a basic bar chart mode with series on the X-axis
+  instead of time and a histogram mode.
+  * 'time' - The X-axis represents time and that the data is
+    grouped by time (for example, by hour, or by minute).
+  * 'series' - The data is grouped by series and not by time. The
+    Y-axis still represents the value.
+  * 'histogram' - Converts the graph into a histogram. A histogram
+    is a kind of bar chart that groups numbers into ranges, often
+    called buckets or bins. Taller bars show that more data falls
+    in that range.
+* **name**: (type: string, default: `null`)
+  
+* **show**: (type: boolean, default: `true`)
+  Show or hide the axis.
+#### #setYaxis
+
+* **align**: (type: boolean, default: `false`)
+  Align left and right Y-axes by value.
+* **alignLevel**: (type: integer, default: `0`)
+  Available when align is true. Value to use for alignment of
+  left and right Y-axes, starting from Y=0.
+
+#### #addDataLink
+
+* **targetBlank**: (type: boolean, default: `true`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **url**: (type: string, default: `null`)
+  
+#### #addPanelLink
+
+* **targetBlank**: (type: boolean, default: `true`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **url**: (type: string, default: `null`)
+  
+#### #addOverride
+
+* **matcher**: (type: oject, default: `null`)
+  
+* **properties**: (type: array, default: `null`)
+  
+#### #addSeriesOverride
+
+* **alias**: (type: string, default: `null`)
+  Alias or regex matching the series you'd like to target.
+* **bars**: (type: boolean, default: `null`)
+  
+* **color**: (type: string, default: `null`)
+  
+* **dashLength**: (type: integer, default: `null`)
+  
+* **dashes**: (type: boolean, default: `null`)
+  
+* **fill**: (type: integer, default: `null`)
+  
+* **fillBelowTo**: (type: string, default: `null`)
+  
+* **fillGradient**: (type: integer, default: `null`)
+  
+* **hiddenSeries**: (type: boolean, default: `null`)
+  
+* **hideTooltip**: (type: boolean, default: `null`)
+  
+* **legend**: (type: boolean, default: `null`)
+  
+* **lines**: (type: boolean, default: `null`)
+  
+* **linewidth**: (type: integer, default: `null`)
+  
+* **nullPointMode**: (type: string, default: `null`)
+  
+* **pointradius**: (type: integer, default: `null`)
+  
+* **points**: (type: boolean, default: `null`)
+  
+* **spaceLength**: (type: integer, default: `null`)
+  
+* **stack**: (type: integer, default: `null`)
+  
+* **steppedLine**: (type: boolean, default: `null`)
+  
+* **transform**: (type: string, default: `null`)
+  
+* **yaxis**: (type: integer, default: `null`)
+  
+* **zindex**: (type: integer, default: `null`)
+  
+#### #addThresholdStep
+
+* **color**: (type: string, default: `null`)
+  
+* **value**: (type: integer, default: `null`)
+  
+#### #addTarget
+
+* **target**: (type: object)
+  
+#### #addYaxis
+
+* **decimals**: (type: integer, default: `null`)
+  Defines how many decimals are displayed for Y value.
+* **format**: (type: string, default: `"short"`)
+  The display unit for the Y value.
+* **label**: (type: string, default: `null`)
+  The Y axis label.
+* **logBase**: (type: integer, default: `1`)
+  The scale to use for the Y value - linear, or logarithmic.
+  * 1 - linear
+  * 2 - log (base 2)
+  * 10 - log (base 10)
+  * 32 - log (base 32)
+  * 1024 - log (base 1024)
+* **max**: (type: integer, default: `null`)
+  The maximum Y value.
+* **min**: (type: integer, default: `null`)
+  The minimum Y value.
+* **show**: (type: boolean, default: `true`)
+  Show or hide the axis.
+
+
+### panel.row.new
+
+
+
+* **collapse**: (type: boolean, default: `true`)
+  
+* **collapsed**: (type: boolean, default: `true`)
+  
+* **datasource**: (type: string, default: `null`)
+  
+* **repeat**: (type: string, default: `null`)
+  
+* **repeatIteration**: (type: string, default: `null`)
+  
+* **showTitle**: (type: boolean, default: `true`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **titleSize**: (type: string, default: `"h6"`)
+  
+
+#### #setGridPos
+
+* **h**: (type: integer, default: `8`)
+  Panel height.
+* **w**: (type: integer, default: `12`)
+  Panel width.
+* **x**: (type: integer, default: `null`)
+  Panel x position.
+* **y**: (type: integer, default: `null`)
+  Panel y position.
+
+#### #addPanel
+
+* **panel**: (type: object)
+  
+
+
+### panel.stat.new
+
+
+
+* **datasource**: (type: string, default: `"default"`)
+  
+* **description**: (type: string, default: `null`)
+  
+* **repeat**: (type: string, default: `null`)
+  
+* **repeatDirection**: (type: string, default: `null`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **transparent**: (type: boolean, default: `false`)
+  
+
+#### #setFieldConfig
+
+* **max**: (type: integer, default: `null`)
+  
+* **min**: (type: integer, default: `null`)
+  
+* **thresholdMode**: (type: string, default: `"absolute"`)
+  
+* **unit**: (type: string, default: `null`)
+  
+#### #setGridPos
+
+* **h**: (type: integer, default: `8`)
+  Panel height.
+* **w**: (type: integer, default: `12`)
+  Panel width.
+* **x**: (type: integer, default: `null`)
+  Panel x position.
+* **y**: (type: integer, default: `null`)
+  Panel y position.
+#### #setOptions
+
+* **calcs**: (type: array, default: `["mean"]`)
+  
+* **colorMode**: (type: string, default: `"value"`)
+  
+* **fields**: (type: string, default: `null`)
+  
+* **graphMode**: (type: string, default: `"none"`)
+  
+* **justifyMode**: (type: string, default: `"auto"`)
+  
+* **orientation**: (type: string, default: `"auto"`)
+  
+* **textMode**: (type: string, default: `"auto"`)
+  
+* **values**: (type: boolean, default: `false`)
+  
+
+#### #addDataLink
+
+* **targetBlank**: (type: boolean, default: `true`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **url**: (type: string, default: `null`)
+  
+#### #addPanelLink
+
+* **targetBlank**: (type: boolean, default: `true`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **url**: (type: string, default: `null`)
+  
+#### #addMapping
+
+* **from**: (type: string, default: `null`)
+  
+* **id**: (type: integer, default: `null`)
+  
+* **operator**: (type: string, default: `null`)
+  
+* **text**: (type: string, default: `null`)
+  
+* **to**: (type: string, default: `null`)
+  
+* **type**: (type: integer, default: `null`)
+  
+* **value**: (type: string, default: `null`)
+  
+#### #addOverride
+
+* **matcher**: (type: oject, default: `null`)
+  
+* **properties**: (type: array, default: `null`)
+  
+#### #addThresholdStep
+
+* **color**: (type: string, default: `null`)
+  
+* **value**: (type: integer, default: `null`)
+  
+#### #addTarget
+
+* **target**: (type: object)
+  
+
+
+### panel.table.new
+
+
+
+* **datasource**: (type: string, default: `"default"`)
+  
+* **description**: (type: string, default: `null`)
+  
+* **repeat**: (type: string, default: `null`)
+  
+* **repeatDirection**: (type: string, default: `null`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **transparent**: (type: boolean, default: `false`)
+  
+
+#### #setFieldConfig
+
+* **displayName**: (type: string, default: `null`)
+  
+* **max**: (type: integer, default: `0`)
+  
+* **min**: (type: integer, default: `0`)
+  
+* **thresholdMode**: (type: string, default: `"absolute"`)
+  
+* **noValue**: (type: string, default: `null`)
+  
+* **unit**: (type: string, default: `"short"`)
+  
+* **width**: (type: integer, default: `null`)
+  
+#### #setGridPos
+
+* **h**: (type: integer, default: `8`)
+  Panel height.
+* **w**: (type: integer, default: `12`)
+  Panel width.
+* **x**: (type: integer, default: `null`)
+  Panel x position.
+* **y**: (type: integer, default: `null`)
+  Panel y position.
+#### #setOptions
+
+* **showHeader**: (type: boolean, default: `true`)
+  
+
+#### #addPanelLink
+
+* **targetBlank**: (type: boolean, default: `true`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **url**: (type: string, default: `null`)
+  
+#### #addDataLink
+
+* **targetBlank**: (type: boolean, default: `true`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **url**: (type: string, default: `null`)
+  
+#### #addMapping
+
+* **from**: (type: string, default: `null`)
+  
+* **id**: (type: integer, default: `null`)
+  
+* **operator**: (type: string, default: `null`)
+  
+* **text**: (type: string, default: `null`)
+  
+* **to**: (type: string, default: `null`)
+  
+* **type**: (type: integer, default: `null`)
+  
+* **value**: (type: string, default: `null`)
+  
+#### #addOverride
+
+* **matcher**: (type: oject, default: `null`)
+  
+* **properties**: (type: array, default: `null`)
+  
+#### #addThresholdStep
+
+* **color**: (type: string, default: `null`)
+  
+* **value**: (type: integer, default: `null`)
+  
+#### #addTarget
+
+* **target**: (type: object)
+  
+
+
+### panel.text.new
+
+
+
+* **content**: (type: string, default: `null`)
+  
+* **datasource**: (type: string, default: `"default"`)
+  
+* **description**: (type: string, default: `null`)
+  
+* **mode**: (type: string, default: `"markdown"`)
+  
+* **repeat**: (type: string, default: `null`)
+  
+* **repeatDirection**: (type: string, default: `null`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **transparent**: (type: boolean, default: `false`)
+  
+
+#### #setGridPos
+
+* **h**: (type: integer, default: `8`)
+  Panel height.
+* **w**: (type: integer, default: `12`)
+  Panel width.
+* **x**: (type: integer, default: `null`)
+  Panel x position.
+* **y**: (type: integer, default: `null`)
+  Panel y position.
+
+#### #addPanelLink
+
+* **targetBlank**: (type: boolean, default: `true`)
+  
+* **title**: (type: string, default: `null`)
+  
+* **url**: (type: string, default: `null`)
+  
+#### #addTarget
+
+* **target**: (type: object)
+  
+
+
+
+## target
+
+
+
+### target.prometheus.new
+
+
+
+* **datasource**: (type: string, default: `"default"`)
+  
+* **expr**: (type: string, default: `null`)
+  
+* **format**: (type: string, default: `"time_series"`)
+  
+* **interval**: (type: string, default: `null`)
+  
+* **intervalFactor**: (type: integer, default: `null`)
+  
+* **legendFormat**: (type: string, default: `null`)
+  
+
+
+
+
+
+## template
+
+
+
+### tamplate.datasource.new
+
+
+
+* **hide**: (type: integer, default: `0`)
+  
+* **includeAll**: (type: boolean, default: `false`)
+  
+* **label**: (type: string, default: `null`)
+  
+* **multi**: (type: boolean, default: `false`)
+  
+* **name**: (type: string, default: `null`)
+  
+* **query**: (type: string, default: `null`)
+  
+* **refresh**: (type: integer, default: `1`)
+  
+* **regex**: (type: string, default: `null`)
+  
+* **skipUrlSync**: (type: string, default: `false`)
+  
+
+#### #setCurrent
+
+* **selected**: (type: boolean, default: `false`)
+  
+* **text**: (type: string, default: `null`)
+  
+* **value**: (type: string, default: `null`)
+  
+
+
+
+### tamplate.query.new
+
+
+
+* **allValue**: (type: string, default: `null`)
+  
+* **datasource**: (type: string, default: `null`)
+  
+* **definition**: (type: string, default: `null`)
+  
+* **hide**: (type: integer, default: `0`)
+  
+* **includeAll**: (type: boolean, default: `false`)
+  
+* **label**: (type: string, default: `null`)
+  
+* **multi**: (type: boolean, default: `false`)
+  
+* **name**: (type: string, default: `null`)
+  
+* **query**: (type: string, default: `null`)
+  
+* **refresh**: (type: integer, default: `0`)
+  
+* **regex**: (type: string, default: `null`)
+  
+* **skipUrlSync**: (type: string, default: `false`)
+  
+* **sort**: (type: integer, default: `0`)
+  
+* **tagValuesQuery**: (type: string, default: `null`)
+  
+* **tags**: (type: array, default: `null`)
+  
+* **tagsQuery**: (type: string, default: `null`)
+  
+* **useTags**: (type: boolean, default: `false`)
+  
+
+#### #setCurrent
+
+* **selected**: (type: boolean, default: `null`)
+  
+* **text**: (type: string, default: `null`)
+  
+* **value**: (type: string, default: `null`)
+  
+
+#### #addOption
+
+* **selected**: (type: boolean, default: `true`)
+  
+* **text**: (type: string, default: `null`)
+  
+* **value**: (type: string, default: `null`)
+  
+
+
diff --git a/ops/monitoring/lib/grafonnet/README.hscloud b/ops/monitoring/lib/grafonnet/README.hscloud
new file mode 100644
index 0000000..5b86f96
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/README.hscloud
@@ -0,0 +1,7 @@
+This subpath (//ops/monitoring/lib/grafonnet) comes from the following Git repository:
+
+    repository: https://github.com/grafana/grafonnet-lib.git
+    revision: ff69572caf78c3163980d0d723c85a722eab73d9
+    subpath: grafonnet-7.0
+
+The files contained in this subdirectory are license under the Apache 2.0 License (see //third_party/licenses/Apache-2.0.txt).
diff --git a/ops/monitoring/lib/grafonnet/dashboard.libsonnet b/ops/monitoring/lib/grafonnet/dashboard.libsonnet
new file mode 100644
index 0000000..28dc13a
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/dashboard.libsonnet
@@ -0,0 +1,85 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  new(
+    description=null,
+    editable=true,
+    graphTooltip=0,
+    refresh=null,
+    schemaVersion=25,
+    style='dark',
+    tags=[],
+    timezone=null,
+    title=null,
+    uid=null,
+  ):: {
+    [if description != null then 'description']: description,
+    [if editable != null then 'editable']: editable,
+    [if graphTooltip != null then 'graphTooltip']: graphTooltip,
+    [if refresh != null then 'refresh']: refresh,
+    [if schemaVersion != null then 'schemaVersion']: schemaVersion,
+    [if style != null then 'style']: style,
+    [if tags != null then 'tags']: tags,
+    [if timezone != null then 'timezone']: timezone,
+    [if title != null then 'title']: title,
+    [if uid != null then 'uid']: uid,
+
+    setTime(
+      from='now-6h',
+      to='now',
+    ):: self {}
+        + { time+: { [if from != null then 'from']: from } }
+        + { time+: { [if to != null then 'to']: to } }
+    ,
+
+    setTimepicker(
+      refreshIntervals=['5s', '10s', '30s', '1m', '5m', '15m', '30m', '1h', '2h', '1d'],
+    ):: self {}
+        + { timepicker+: { [if refreshIntervals != null then 'refresh_intervals']: refreshIntervals } }
+    ,
+
+
+    addTemplate(
+      template
+    ):: self {}
+        + { templating+: { list+: [
+          template,
+        ] } },
+
+    addAnnotation(
+      builtIn=0,
+      datasource='default',
+      enable=true,
+      hide=false,
+      iconColor=null,
+      name=null,
+      rawQuery=null,
+      showIn=0,
+    ):: self {}
+        + { annotations+: { list+: [
+          {
+            [if builtIn != null then 'builtIn']: builtIn,
+            [if datasource != null then 'datasource']: datasource,
+            [if enable != null then 'enable']: enable,
+            [if hide != null then 'hide']: hide,
+            [if iconColor != null then 'iconColor']: iconColor,
+            [if name != null then 'name']: name,
+            [if rawQuery != null then 'rawQuery']: rawQuery,
+            [if showIn != null then 'showIn']: showIn,
+          },
+        ] } },
+
+
+    panels: [],
+    _nextPanelID:: 2,
+    addPanel(panel):: self {
+      local nextPanelID = super._nextPanelID,
+      panels+: [
+        panel { id: nextPanelID } +
+        if 'panels' in panel then { panels: std.mapWithIndex(function(i, p) p { id: nextPanelID + i + 1 }, panel.panels) } else {},
+      ],
+      _nextPanelID:: nextPanelID + 1 + (if 'panels' in panel then std.length(panel.panels) else 0),
+    },
+    addPanels(panels):: std.foldl(function(d, p) d.addPanel(p), panels, self),
+  },
+}
diff --git a/ops/monitoring/lib/grafonnet/grafana.libsonnet b/ops/monitoring/lib/grafonnet/grafana.libsonnet
new file mode 100644
index 0000000..738a051
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/grafana.libsonnet
@@ -0,0 +1,20 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  dashboard:: import 'dashboard.libsonnet',
+  panel:: {
+    gauge:: import 'panel/gauge.libsonnet',
+    graph:: import 'panel/graph.libsonnet',
+    row:: import 'panel/row.libsonnet',
+    stat:: import 'panel/stat.libsonnet',
+    table:: import 'panel/table.libsonnet',
+    text:: import 'panel/text.libsonnet',
+  },
+  target:: {
+    prometheus:: import 'target/prometheus.libsonnet',
+  },
+  template:: {
+    datasource:: import 'template/datasource.libsonnet',
+    query:: import 'template/query.libsonnet',
+  },
+}
diff --git a/ops/monitoring/lib/grafonnet/panel/gauge.libsonnet b/ops/monitoring/lib/grafonnet/panel/gauge.libsonnet
new file mode 100644
index 0000000..4520444
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/panel/gauge.libsonnet
@@ -0,0 +1,138 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  new(
+    datasource='default',
+    description=null,
+    repeat=null,
+    repeatDirection=null,
+    title=null,
+    transparent=false,
+  ):: {
+    [if datasource != null then 'datasource']: datasource,
+    [if description != null then 'description']: description,
+    [if repeat != null then 'repeat']: repeat,
+    [if repeatDirection != null then 'repeatDirection']: repeatDirection,
+    [if title != null then 'title']: title,
+    [if transparent != null then 'transparent']: transparent,
+    type: 'gauge',
+
+    setFieldConfig(
+      max=null,
+      min=null,
+      thresholdMode='absolute',
+      unit=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { [if max != null then 'max']: max } } }
+        + { fieldConfig+: { defaults+: { [if min != null then 'min']: min } } }
+        + { fieldConfig+: { defaults+: { thresholds+: { [if thresholdMode != null then 'mode']: thresholdMode } } } }
+        + { fieldConfig+: { defaults+: { [if unit != null then 'unit']: unit } } }
+    ,
+
+    setGridPos(
+      h=8,
+      w=12,
+      x=null,
+      y=null,
+    ):: self {}
+        + { gridPos+: { [if h != null then 'h']: h } }
+        + { gridPos+: { [if w != null then 'w']: w } }
+        + { gridPos+: { [if x != null then 'x']: x } }
+        + { gridPos+: { [if y != null then 'y']: y } }
+    ,
+
+    setOptions(
+      calcs=['mean'],
+      fields=null,
+      orientation='auto',
+      showThresholdLabels=false,
+      showThresholdMarkers=true,
+      values=false,
+    ):: self {}
+        + { options+: { reduceOptions+: { [if calcs != null then 'calcs']: calcs } } }
+        + { options+: { reduceOptions+: { [if fields != null then 'fields']: fields } } }
+        + { options+: { [if orientation != null then 'orientation']: orientation } }
+        + { options+: { [if showThresholdLabels != null then 'showThresholdLabels']: showThresholdLabels } }
+        + { options+: { [if showThresholdMarkers != null then 'showThresholdMarkers']: showThresholdMarkers } }
+        + { options+: { reduceOptions+: { [if values != null then 'values']: values } } }
+    ,
+
+
+    addDataLink(
+      targetBlank=true,
+      title=null,
+      url=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { links+: [
+          {
+            [if targetBlank != null then 'targetBlank']: targetBlank,
+            [if title != null then 'title']: title,
+            [if url != null then 'url']: url,
+          },
+        ] } } },
+
+    addPanelLink(
+      targetBlank=true,
+      title=null,
+      url=null,
+    ):: self {}
+        + { links+: [
+          {
+            [if targetBlank != null then 'targetBlank']: targetBlank,
+            [if title != null then 'title']: title,
+            [if url != null then 'url']: url,
+          },
+        ] },
+
+    addMapping(
+      from=null,
+      id=null,
+      operator=null,
+      text=null,
+      to=null,
+      type=null,
+      value=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { mappings+: [
+          {
+            [if from != null then 'from']: from,
+            [if id != null then 'id']: id,
+            [if operator != null then 'operator']: operator,
+            [if text != null then 'text']: text,
+            [if to != null then 'to']: to,
+            [if type != null then 'type']: type,
+            [if value != null then 'value']: value,
+          },
+        ] } } },
+
+    addOverride(
+      matcher=null,
+      properties=null,
+    ):: self {}
+        + { fieldConfig+: { overrides+: [
+          {
+            [if matcher != null then 'matcher']: matcher,
+            [if properties != null then 'properties']: properties,
+          },
+        ] } },
+
+    addThresholdStep(
+      color=null,
+      value=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { thresholds+: { steps+: [
+          {
+            [if color != null then 'color']: color,
+            [if value != null then 'value']: value,
+          },
+        ] } } } },
+
+    addTarget(
+      target
+    ):: self {}
+        + { targets+: [
+          target,
+        ] },
+
+  },
+}
diff --git a/ops/monitoring/lib/grafonnet/panel/graph.libsonnet b/ops/monitoring/lib/grafonnet/panel/graph.libsonnet
new file mode 100644
index 0000000..34985a1
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/panel/graph.libsonnet
@@ -0,0 +1,257 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  new(
+    bars=false,
+    dashLength=10,
+    dashes=false,
+    datasource='default',
+    decimals=null,
+    description=null,
+    fill=1,
+    fillGradient=0,
+    hiddenSeries=false,
+    lines=true,
+    linewidth=1,
+    nullPointMode='null',
+    percentage=false,
+    pointradius=null,
+    points=false,
+    repeat=null,
+    repeatDirection=null,
+    spaceLength=10,
+    stack=false,
+    steppedLine=false,
+    timeFrom=null,
+    timeShift=null,
+    title=null,
+    transparent=false,
+  ):: {
+    [if bars != null then 'bars']: bars,
+    [if dashLength != null then 'dashLength']: dashLength,
+    [if dashes != null then 'dashes']: dashes,
+    [if datasource != null then 'datasource']: datasource,
+    [if decimals != null then 'decimals']: decimals,
+    [if description != null then 'description']: description,
+    [if fill != null then 'fill']: fill,
+    [if fillGradient != null then 'fillGradient']: fillGradient,
+    [if hiddenSeries != null then 'hiddenSeries']: hiddenSeries,
+    [if lines != null then 'lines']: lines,
+    [if linewidth != null then 'linewidth']: linewidth,
+    [if nullPointMode != null then 'nullPointMode']: nullPointMode,
+    [if percentage != null then 'percentage']: percentage,
+    [if pointradius != null then 'pointradius']: pointradius,
+    [if points != null then 'points']: points,
+    [if repeat != null then 'repeat']: repeat,
+    [if repeatDirection != null then 'repeatDirection']: repeatDirection,
+    [if spaceLength != null then 'spaceLength']: spaceLength,
+    [if stack != null then 'stack']: stack,
+    [if steppedLine != null then 'steppedLine']: steppedLine,
+    [if timeFrom != null then 'timeFrom']: timeFrom,
+    [if timeShift != null then 'timeShift']: timeShift,
+    [if title != null then 'title']: title,
+    [if transparent != null then 'transparent']: transparent,
+    renderer: 'flot',
+    type: 'graph',
+    tooltip+: { value_type: 'individual' },
+
+    setGridPos(
+      h=8,
+      w=12,
+      x=null,
+      y=null,
+    ):: self {}
+        + { gridPos+: { [if h != null then 'h']: h } }
+        + { gridPos+: { [if w != null then 'w']: w } }
+        + { gridPos+: { [if x != null then 'x']: x } }
+        + { gridPos+: { [if y != null then 'y']: y } }
+    ,
+
+    setLegend(
+      alignAsTable=null,
+      avg=false,
+      current=false,
+      max=false,
+      min=false,
+      rightSide=false,
+      show=true,
+      sideWidth=null,
+      total=false,
+      values=true,
+    ):: self {}
+        + { legend+: { [if alignAsTable != null then 'alignAsTable']: alignAsTable } }
+        + { legend+: { [if avg != null then 'avg']: avg } }
+        + { legend+: { [if current != null then 'current']: current } }
+        + { legend+: { [if max != null then 'max']: max } }
+        + { legend+: { [if min != null then 'min']: min } }
+        + { legend+: { [if rightSide != null then 'rightSide']: rightSide } }
+        + { legend+: { [if show != null then 'show']: show } }
+        + { legend+: { [if sideWidth != null then 'sideWidth']: sideWidth } }
+        + { legend+: { [if total != null then 'total']: total } }
+        + { legend+: { [if values != null then 'values']: values } }
+    ,
+
+    setThresholds(
+      thresholdMode='absolute',
+    ):: self {}
+        + { thresholds+: { [if thresholdMode != null then 'mode']: thresholdMode } }
+    ,
+
+    setTooltip(
+      shared=true,
+      sort=2,
+    ):: self {}
+        + { tooltip+: { [if shared != null then 'shared']: shared } }
+        + { tooltip+: { [if sort != null then 'sort']: sort } }
+    ,
+
+    setXaxis(
+      buckets=null,
+      mode='time',
+      name=null,
+      show=true,
+    ):: self {}
+        + { xaxis+: { [if buckets != null then 'buckets']: buckets } }
+        + { xaxis+: { [if mode != null then 'mode']: mode } }
+        + { xaxis+: { [if name != null then 'name']: name } }
+        + { xaxis+: { [if show != null then 'show']: show } }
+    ,
+
+    setYaxis(
+      align=false,
+      alignLevel=0,
+    ):: self {}
+        + { yaxis+: { [if align != null then 'align']: align } }
+        + { yaxis+: { [if alignLevel != null then 'alignLevel']: alignLevel } }
+    ,
+
+
+    addDataLink(
+      targetBlank=true,
+      title=null,
+      url=null,
+    ):: self {}
+        + { options+: { dataLinks+: [
+          {
+            [if targetBlank != null then 'targetBlank']: targetBlank,
+            [if title != null then 'title']: title,
+            [if url != null then 'url']: url,
+          },
+        ] } },
+
+    addPanelLink(
+      targetBlank=true,
+      title=null,
+      url=null,
+    ):: self {}
+        + { links+: [
+          {
+            [if targetBlank != null then 'targetBlank']: targetBlank,
+            [if title != null then 'title']: title,
+            [if url != null then 'url']: url,
+          },
+        ] },
+
+    addOverride(
+      matcher=null,
+      properties=null,
+    ):: self {}
+        + { fieldConfig+: { overrides+: [
+          {
+            [if matcher != null then 'matcher']: matcher,
+            [if properties != null then 'properties']: properties,
+          },
+        ] } },
+
+    addSeriesOverride(
+      alias=null,
+      bars=null,
+      color=null,
+      dashLength=null,
+      dashes=null,
+      fill=null,
+      fillBelowTo=null,
+      fillGradient=null,
+      hiddenSeries=null,
+      hideTooltip=null,
+      legend=null,
+      lines=null,
+      linewidth=null,
+      nullPointMode=null,
+      pointradius=null,
+      points=null,
+      spaceLength=null,
+      stack=null,
+      steppedLine=null,
+      transform=null,
+      yaxis=null,
+      zindex=null,
+    ):: self {}
+        + { seriesOverrides+: [
+          {
+            [if alias != null then 'alias']: alias,
+            [if bars != null then 'bars']: bars,
+            [if color != null then 'color']: color,
+            [if dashLength != null then 'dashLength']: dashLength,
+            [if dashes != null then 'dashes']: dashes,
+            [if fill != null then 'fill']: fill,
+            [if fillBelowTo != null then 'fillBelowTo']: fillBelowTo,
+            [if fillGradient != null then 'fillGradient']: fillGradient,
+            [if hiddenSeries != null then 'hiddenSeries']: hiddenSeries,
+            [if hideTooltip != null then 'hideTooltip']: hideTooltip,
+            [if legend != null then 'legend']: legend,
+            [if lines != null then 'lines']: lines,
+            [if linewidth != null then 'linewidth']: linewidth,
+            [if nullPointMode != null then 'nullPointMode']: nullPointMode,
+            [if pointradius != null then 'pointradius']: pointradius,
+            [if points != null then 'points']: points,
+            [if spaceLength != null then 'spaceLength']: spaceLength,
+            [if stack != null then 'stack']: stack,
+            [if steppedLine != null then 'steppedLine']: steppedLine,
+            [if transform != null then 'transform']: transform,
+            [if yaxis != null then 'yaxis']: yaxis,
+            [if zindex != null then 'zindex']: zindex,
+          },
+        ] },
+
+    addThresholdStep(
+      color=null,
+      value=null,
+    ):: self {}
+        + { thresholds+: { steps+: [
+          {
+            [if color != null then 'color']: color,
+            [if value != null then 'value']: value,
+          },
+        ] } },
+
+    addTarget(
+      target
+    ):: self {}
+        + { targets+: [
+          target,
+        ] },
+
+    addYaxis(
+      decimals=null,
+      format='short',
+      label=null,
+      logBase=1,
+      max=null,
+      min=null,
+      show=true,
+    ):: self {}
+        + { yaxes+: [
+          {
+            [if decimals != null then 'decimals']: decimals,
+            [if format != null then 'format']: format,
+            [if label != null then 'label']: label,
+            [if logBase != null then 'logBase']: logBase,
+            [if max != null then 'max']: max,
+            [if min != null then 'min']: min,
+            [if show != null then 'show']: show,
+          },
+        ] },
+
+  },
+}
diff --git a/ops/monitoring/lib/grafonnet/panel/row.libsonnet b/ops/monitoring/lib/grafonnet/panel/row.libsonnet
new file mode 100644
index 0000000..e8a21d3
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/panel/row.libsonnet
@@ -0,0 +1,45 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  new(
+    collapse=true,
+    collapsed=true,
+    datasource=null,
+    repeat=null,
+    repeatIteration=null,
+    showTitle=true,
+    title=null,
+    titleSize='h6',
+  ):: {
+    [if collapse != null then 'collapse']: collapse,
+    [if collapsed != null then 'collapsed']: collapsed,
+    [if datasource != null then 'datasource']: datasource,
+    [if repeat != null then 'repeat']: repeat,
+    [if repeatIteration != null then 'repeatIteration']: repeatIteration,
+    [if showTitle != null then 'showTitle']: showTitle,
+    [if title != null then 'title']: title,
+    [if titleSize != null then 'titleSize']: titleSize,
+    type: 'row',
+
+    setGridPos(
+      h=8,
+      w=12,
+      x=null,
+      y=null,
+    ):: self {}
+        + { gridPos+: { [if h != null then 'h']: h } }
+        + { gridPos+: { [if w != null then 'w']: w } }
+        + { gridPos+: { [if x != null then 'x']: x } }
+        + { gridPos+: { [if y != null then 'y']: y } }
+    ,
+
+
+    addPanel(
+      panel
+    ):: self {}
+        + { panels+: [
+          panel,
+        ] },
+
+  },
+}
diff --git a/ops/monitoring/lib/grafonnet/panel/stat.libsonnet b/ops/monitoring/lib/grafonnet/panel/stat.libsonnet
new file mode 100644
index 0000000..a14c938
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/panel/stat.libsonnet
@@ -0,0 +1,142 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  new(
+    datasource='default',
+    description=null,
+    repeat=null,
+    repeatDirection=null,
+    title=null,
+    transparent=false,
+  ):: {
+    [if datasource != null then 'datasource']: datasource,
+    [if description != null then 'description']: description,
+    [if repeat != null then 'repeat']: repeat,
+    [if repeatDirection != null then 'repeatDirection']: repeatDirection,
+    [if title != null then 'title']: title,
+    [if transparent != null then 'transparent']: transparent,
+    type: 'stat',
+
+    setFieldConfig(
+      max=null,
+      min=null,
+      thresholdMode='absolute',
+      unit=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { [if max != null then 'max']: max } } }
+        + { fieldConfig+: { defaults+: { [if min != null then 'min']: min } } }
+        + { fieldConfig+: { defaults+: { thresholds+: { [if thresholdMode != null then 'mode']: thresholdMode } } } }
+        + { fieldConfig+: { defaults+: { [if unit != null then 'unit']: unit } } }
+    ,
+
+    setGridPos(
+      h=8,
+      w=12,
+      x=null,
+      y=null,
+    ):: self {}
+        + { gridPos+: { [if h != null then 'h']: h } }
+        + { gridPos+: { [if w != null then 'w']: w } }
+        + { gridPos+: { [if x != null then 'x']: x } }
+        + { gridPos+: { [if y != null then 'y']: y } }
+    ,
+
+    setOptions(
+      calcs=['mean'],
+      colorMode='value',
+      fields=null,
+      graphMode='none',
+      justifyMode='auto',
+      orientation='auto',
+      textMode='auto',
+      values=false,
+    ):: self {}
+        + { options+: { reduceOptions+: { [if calcs != null then 'calcs']: calcs } } }
+        + { options+: { [if colorMode != null then 'colorMode']: colorMode } }
+        + { options+: { reduceOptions+: { [if fields != null then 'fields']: fields } } }
+        + { options+: { [if graphMode != null then 'graphMode']: graphMode } }
+        + { options+: { [if justifyMode != null then 'justifyMode']: justifyMode } }
+        + { options+: { [if orientation != null then 'orientation']: orientation } }
+        + { options+: { [if textMode != null then 'textMode']: textMode } }
+        + { options+: { reduceOptions+: { [if values != null then 'values']: values } } }
+    ,
+
+
+    addPanelLink(
+      targetBlank=true,
+      title=null,
+      url=null,
+    ):: self {}
+        + { links+: [
+          {
+            [if targetBlank != null then 'targetBlank']: targetBlank,
+            [if title != null then 'title']: title,
+            [if url != null then 'url']: url,
+          },
+        ] },
+
+    addDataLink(
+      targetBlank=true,
+      title=null,
+      url=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { links+: [
+          {
+            [if targetBlank != null then 'targetBlank']: targetBlank,
+            [if title != null then 'title']: title,
+            [if url != null then 'url']: url,
+          },
+        ] } } },
+
+    addMapping(
+      from=null,
+      id=null,
+      operator=null,
+      text=null,
+      to=null,
+      type=null,
+      value=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { mappings+: [
+          {
+            [if from != null then 'from']: from,
+            [if id != null then 'id']: id,
+            [if operator != null then 'operator']: operator,
+            [if text != null then 'text']: text,
+            [if to != null then 'to']: to,
+            [if type != null then 'type']: type,
+            [if value != null then 'value']: value,
+          },
+        ] } } },
+
+    addOverride(
+      matcher=null,
+      properties=null,
+    ):: self {}
+        + { fieldConfig+: { overrides+: [
+          {
+            [if matcher != null then 'matcher']: matcher,
+            [if properties != null then 'properties']: properties,
+          },
+        ] } },
+
+    addThresholdStep(
+      color=null,
+      value=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { thresholds+: { steps+: [
+          {
+            [if color != null then 'color']: color,
+            [if value != null then 'value']: value,
+          },
+        ] } } } },
+
+    addTarget(
+      target
+    ):: self {}
+        + { targets+: [
+          target,
+        ] },
+
+  },
+}
diff --git a/ops/monitoring/lib/grafonnet/panel/table.libsonnet b/ops/monitoring/lib/grafonnet/panel/table.libsonnet
new file mode 100644
index 0000000..1bd2152
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/panel/table.libsonnet
@@ -0,0 +1,134 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  new(
+    datasource='default',
+    description=null,
+    repeat=null,
+    repeatDirection=null,
+    title=null,
+    transparent=false,
+  ):: {
+    [if datasource != null then 'datasource']: datasource,
+    [if description != null then 'description']: description,
+    [if repeat != null then 'repeat']: repeat,
+    [if repeatDirection != null then 'repeatDirection']: repeatDirection,
+    [if title != null then 'title']: title,
+    [if transparent != null then 'transparent']: transparent,
+    type: 'table',
+
+    setFieldConfig(
+      displayName=null,
+      max=0,
+      min=0,
+      thresholdMode='absolute',
+      noValue=null,
+      unit='short',
+      width=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { [if displayName != null then 'displayName']: displayName } } }
+        + { fieldConfig+: { defaults+: { [if max != null then 'max']: max } } }
+        + { fieldConfig+: { defaults+: { [if min != null then 'min']: min } } }
+        + { fieldConfig+: { defaults+: { thresholds+: { [if thresholdMode != null then 'mode']: thresholdMode } } } }
+        + { fieldConfig+: { defaults+: { [if noValue != null then 'noValue']: noValue } } }
+        + { fieldConfig+: { defaults+: { [if unit != null then 'unit']: unit } } }
+        + { fieldConfig+: { defaults+: { custom+: { [if width != null then 'width']: width } } } }
+    ,
+
+    setGridPos(
+      h=8,
+      w=12,
+      x=null,
+      y=null,
+    ):: self {}
+        + { gridPos+: { [if h != null then 'h']: h } }
+        + { gridPos+: { [if w != null then 'w']: w } }
+        + { gridPos+: { [if x != null then 'x']: x } }
+        + { gridPos+: { [if y != null then 'y']: y } }
+    ,
+
+    setOptions(
+      showHeader=true,
+    ):: self {}
+        + { options+: { [if showHeader != null then 'showHeader']: showHeader } }
+    ,
+
+
+    addDataLink(
+      targetBlank=true,
+      title=null,
+      url=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { links+: [
+          {
+            [if targetBlank != null then 'targetBlank']: targetBlank,
+            [if title != null then 'title']: title,
+            [if url != null then 'url']: url,
+          },
+        ] } } },
+
+    addPanelLink(
+      targetBlank=true,
+      title=null,
+      url=null,
+    ):: self {}
+        + { links+: [
+          {
+            [if targetBlank != null then 'targetBlank']: targetBlank,
+            [if title != null then 'title']: title,
+            [if url != null then 'url']: url,
+          },
+        ] },
+
+    addMapping(
+      from=null,
+      id=null,
+      operator=null,
+      text=null,
+      to=null,
+      type=null,
+      value=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { mappings+: [
+          {
+            [if from != null then 'from']: from,
+            [if id != null then 'id']: id,
+            [if operator != null then 'operator']: operator,
+            [if text != null then 'text']: text,
+            [if to != null then 'to']: to,
+            [if type != null then 'type']: type,
+            [if value != null then 'value']: value,
+          },
+        ] } } },
+
+    addOverride(
+      matcher=null,
+      properties=null,
+    ):: self {}
+        + { fieldConfig+: { overrides+: [
+          {
+            [if matcher != null then 'matcher']: matcher,
+            [if properties != null then 'properties']: properties,
+          },
+        ] } },
+
+    addThresholdStep(
+      color=null,
+      value=null,
+    ):: self {}
+        + { fieldConfig+: { defaults+: { thresholds+: { steps+: [
+          {
+            [if color != null then 'color']: color,
+            [if value != null then 'value']: value,
+          },
+        ] } } } },
+
+    addTarget(
+      target
+    ):: self {}
+        + { targets+: [
+          target,
+        ] },
+
+  },
+}
diff --git a/ops/monitoring/lib/grafonnet/panel/text.libsonnet b/ops/monitoring/lib/grafonnet/panel/text.libsonnet
new file mode 100644
index 0000000..1c4c682
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/panel/text.libsonnet
@@ -0,0 +1,58 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  new(
+    content=null,
+    datasource='default',
+    description=null,
+    mode='markdown',
+    repeat=null,
+    repeatDirection=null,
+    title=null,
+    transparent=false,
+  ):: {
+    [if content != null then 'content']: content,
+    [if datasource != null then 'datasource']: datasource,
+    [if description != null then 'description']: description,
+    [if mode != null then 'mode']: mode,
+    [if repeat != null then 'repeat']: repeat,
+    [if repeatDirection != null then 'repeatDirection']: repeatDirection,
+    [if title != null then 'title']: title,
+    [if transparent != null then 'transparent']: transparent,
+    type: 'text',
+
+    setGridPos(
+      h=8,
+      w=12,
+      x=null,
+      y=null,
+    ):: self {}
+        + { gridPos+: { [if h != null then 'h']: h } }
+        + { gridPos+: { [if w != null then 'w']: w } }
+        + { gridPos+: { [if x != null then 'x']: x } }
+        + { gridPos+: { [if y != null then 'y']: y } }
+    ,
+
+
+    addPanelLink(
+      targetBlank=true,
+      title=null,
+      url=null,
+    ):: self {}
+        + { links+: [
+          {
+            [if targetBlank != null then 'targetBlank']: targetBlank,
+            [if title != null then 'title']: title,
+            [if url != null then 'url']: url,
+          },
+        ] },
+
+    addTarget(
+      target
+    ):: self {}
+        + { targets+: [
+          target,
+        ] },
+
+  },
+}
diff --git a/ops/monitoring/lib/grafonnet/target/prometheus.libsonnet b/ops/monitoring/lib/grafonnet/target/prometheus.libsonnet
new file mode 100644
index 0000000..5bfe65d
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/target/prometheus.libsonnet
@@ -0,0 +1,19 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  new(
+    datasource='default',
+    expr=null,
+    format='time_series',
+    interval=null,
+    intervalFactor=null,
+    legendFormat=null,
+  ):: {
+    [if datasource != null then 'datasource']: datasource,
+    [if expr != null then 'expr']: expr,
+    [if format != null then 'format']: format,
+    [if interval != null then 'interval']: interval,
+    [if intervalFactor != null then 'intervalFactor']: intervalFactor,
+    [if legendFormat != null then 'legendFormat']: legendFormat,
+  },
+}
diff --git a/ops/monitoring/lib/grafonnet/template/datasource.libsonnet b/ops/monitoring/lib/grafonnet/template/datasource.libsonnet
new file mode 100644
index 0000000..0bdaf83
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/template/datasource.libsonnet
@@ -0,0 +1,36 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  new(
+    hide=0,
+    includeAll=false,
+    label=null,
+    multi=false,
+    name=null,
+    query=null,
+    refresh=1,
+    regex=null,
+    skipUrlSync=false,
+  ):: {
+    [if hide != null then 'hide']: hide,
+    [if includeAll != null then 'includeAll']: includeAll,
+    [if label != null then 'label']: label,
+    [if multi != null then 'multi']: multi,
+    [if name != null then 'name']: name,
+    [if query != null then 'query']: query,
+    [if refresh != null then 'refresh']: refresh,
+    [if regex != null then 'regex']: regex,
+    [if skipUrlSync != null then 'skipUrlSync']: skipUrlSync,
+    type: 'datasource',
+
+    setCurrent(
+      selected=false,
+      text=null,
+      value=null,
+    ):: self {}
+        + { current+: { [if selected != null then 'selected']: selected } }
+        + { current+: { [if text != null then 'text']: text } }
+        + { current+: { [if value != null then 'value']: value } },
+
+  },
+}
diff --git a/ops/monitoring/lib/grafonnet/template/query.libsonnet b/ops/monitoring/lib/grafonnet/template/query.libsonnet
new file mode 100644
index 0000000..951cef7
--- /dev/null
+++ b/ops/monitoring/lib/grafonnet/template/query.libsonnet
@@ -0,0 +1,52 @@
+// This file was generated by https://github.com/grafana/dashboard-spec
+
+{
+  new(
+    allValue=null,
+    datasource=null,
+    definition=null,
+    hide=0,
+    includeAll=false,
+    label=null,
+    multi=false,
+    name=null,
+    query=null,
+    refresh=0,
+    regex=null,
+    skipUrlSync=false,
+    sort=0,
+    tagValuesQuery=null,
+    tags=null,
+    tagsQuery=null,
+    useTags=false,
+  ):: {
+    [if allValue != null then 'allValue']: allValue,
+    [if datasource != null then 'datasource']: datasource,
+    [if definition != null then 'definition']: definition,
+    [if hide != null then 'hide']: hide,
+    [if includeAll != null then 'includeAll']: includeAll,
+    [if label != null then 'label']: label,
+    [if multi != null then 'multi']: multi,
+    [if name != null then 'name']: name,
+    [if query != null then 'query']: query,
+    [if refresh != null then 'refresh']: refresh,
+    [if regex != null then 'regex']: regex,
+    [if skipUrlSync != null then 'skipUrlSync']: skipUrlSync,
+    [if sort != null then 'sort']: sort,
+    [if tagValuesQuery != null then 'tagValuesQuery']: tagValuesQuery,
+    [if tags != null then 'tags']: tags,
+    [if tagsQuery != null then 'tagsQuery']: tagsQuery,
+    [if useTags != null then 'useTags']: useTags,
+    type: 'query',
+
+    setCurrent(
+      selected=null,
+      text=null,
+      value=null,
+    ):: self {}
+        + { current+: { [if selected != null then 'selected']: selected } }
+        + { current+: { [if text != null then 'text']: text } }
+        + { current+: { [if value != null then 'value']: value } },
+
+  },
+}