diff --git a/README.md b/README.md index e112f62..1088042 100644 --- a/README.md +++ b/README.md @@ -44,31 +44,22 @@ An example of how to use it could be: local grafana = import 'grafana/grafana.libsonnet'; { - local basic = - (grafana { - _config+:: { - namespace: 'monitoring-grafana', - }, - }).grafana, - - apiVersion: 'v1', - kind: 'List', - items: - basic.dashboardDefinitions + - [ - basic.dashboardSources, - basic.dashboardDatasources, - basic.deployment, - basic.serviceAccount, - basic.service { - spec+: { ports: [ + _config:: { + namespace: 'monitoring-grafana', + }, + + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ port { nodePort: 30910, } for port in super.ports - ] }, + ], }, - ], + }, + }, } ``` @@ -88,71 +79,59 @@ This setup is optimized to work best when Grafana is used declaratively, so when [embedmd]:# (examples/dashboard-definition.jsonnet) ```jsonnet -local grafana = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet'; -local dashboard = grafana.dashboard; -local row = grafana.row; -local prometheus = grafana.prometheus; -local template = grafana.template; -local graphPanel = grafana.graphPanel; +local grafonnet = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet'; +local dashboard = grafonnet.dashboard; +local row = grafonnet.row; +local prometheus = grafonnet.prometheus; +local template = grafonnet.template; +local graphPanel = grafonnet.graphPanel; local grafana = import 'grafana/grafana.libsonnet'; -local grafanaWithDashboards = - (grafana - { - _config+:: { - namespace: 'monitoring-grafana', - grafana+:: { - dashboards+:: { - 'my-dashboard.json': - dashboard.new('My Dashboard') - .addTemplate( - { - current: { - text: 'Prometheus', - value: 'Prometheus', - }, - hide: 0, - label: null, - name: 'datasource', - options: [], - query: 'prometheus', - refresh: 1, - regex: '', - type: 'datasource', - }, - ) - .addRow( - row.new() - .addPanel( - graphPanel.new('My Panel', span=6, datasource='$datasource') - .addTarget(prometheus.target('vector(1)')), - ) - ), - }, - }, - }, - }).grafana; - { - apiVersion: 'v1', - kind: 'List', - items: - grafanaWithDashboards.dashboardDefinitions + - [ - grafanaWithDashboards.dashboardSources, - grafanaWithDashboards.dashboardDatasources, - grafanaWithDashboards.deployment, - grafanaWithDashboards.serviceAccount, - grafanaWithDashboards.service { - spec+: { ports: [ + _config:: { + namespace: 'monitoring-grafana', + dashboards+: { + 'my-dashboard.json': + dashboard.new('My Dashboard') + .addTemplate( + { + current: { + text: 'Prometheus', + value: 'Prometheus', + }, + hide: 0, + label: null, + name: 'datasource', + options: [], + query: 'prometheus', + refresh: 1, + regex: '', + type: 'datasource', + }, + ) + .addRow( + row.new() + .addPanel( + graphPanel.new('My Panel', span=6, datasource='$datasource') + .addTarget(prometheus.target('vector(1)')), + ) + ), + }, + }, + + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ port { nodePort: 30910, } for port in super.ports - ] }, + ], }, - ], + }, + }, } ``` @@ -162,61 +141,49 @@ If you have many dashboards and would like to organize them into folders, you ca [embedmd]:# (examples/dashboard-folder-definition.jsonnet) ```jsonnet -local grafana = import 'grafonnet/grafana.libsonnet'; -local dashboard = grafana.dashboard; -local row = grafana.row; -local prometheus = grafana.prometheus; -local template = grafana.template; -local graphPanel = grafana.graphPanel; +local grafonnet = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet'; +local dashboard = grafonnet.dashboard; +local row = grafonnet.row; +local prometheus = grafonnet.prometheus; +local template = grafonnet.template; +local graphPanel = grafonnet.graphPanel; local grafana = import 'grafana/grafana.libsonnet'; -local grafanaWithDashboards = - (grafana - { - _config+:: { - namespace: 'monitoring-grafana', - grafana+:: { - folderDashboards+:: { - Services: { - 'regional-services-dashboard.json': (import 'dashboards/regional-services-dashboard.json'), - 'global-services-dashboard.json': (import 'dashboards/global-services-dashboard.json'), - }, - AWS: { - 'aws-ec2-dashboard.json': (import 'dashboards/aws-ec2-dashboard.json'), - 'aws-rds-dashboard.json': (import 'dashboards/aws-rds-dashboard.json'), - 'aws-sqs-dashboard.json': (import 'dashboards/aws-sqs-dashboard.json'), - }, - ISTIO: { - 'istio-citadel-dashboard.json': (import 'dashboards/istio-citadel-dashboard.json'), - 'istio-galley-dashboard.json': (import 'dashboards/istio-galley-dashboard.json'), - 'istio-mesh-dashboard.json': (import 'dashboards/istio-mesh-dashboard.json'), - 'istio-pilot-dashboard.json': (import 'dashboards/istio-pilot-dashboard.json'), - }, - }, - }, - }, - }).grafana; - { - apiVersion: 'v1', - kind: 'List', - items: - grafanaWithDashboards.dashboardDefinitions + - [ - grafanaWithDashboards.dashboardSources, - grafanaWithDashboards.dashboardDatasources, - grafanaWithDashboards.deployment, - grafanaWithDashboards.serviceAccount, - grafanaWithDashboards.service { - spec+: { ports: [ + _config:: { + namespace: 'monitoring-grafana', + folderDashboards+: { + Services: { + 'regional-services-dashboard.json': (import 'dashboards/regional-services-dashboard.json'), + 'global-services-dashboard.json': (import 'dashboards/global-services-dashboard.json'), + }, + AWS: { + 'aws-ec2-dashboard.json': (import 'dashboards/aws-ec2-dashboard.json'), + 'aws-rds-dashboard.json': (import 'dashboards/aws-rds-dashboard.json'), + 'aws-sqs-dashboard.json': (import 'dashboards/aws-sqs-dashboard.json'), + }, + ISTIO: { + 'istio-citadel-dashboard.json': (import 'dashboards/istio-citadel-dashboard.json'), + 'istio-galley-dashboard.json': (import 'dashboards/istio-galley-dashboard.json'), + 'istio-mesh-dashboard.json': (import 'dashboards/istio-mesh-dashboard.json'), + 'istio-pilot-dashboard.json': (import 'dashboards/istio-pilot-dashboard.json'), + }, + }, + }, + + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ port { nodePort: 30910, } for port in super.ports - ] }, + ], }, - ], + }, + }, } ``` @@ -236,34 +203,23 @@ local kubernetesMixin = import 'github.com/kubernetes-monitoring/kubernetes-mixi local grafana = import 'grafana/grafana.libsonnet'; { - local basicWithMixin = - (grafana { - _config+:: { - namespace: 'monitoring-grafana', - grafana+:: { - dashboards: kubernetesMixin.grafanaDashboards, - }, - }, - }).grafana, - - apiVersion: 'v1', - kind: 'List', - items: - basicWithMixin.dashboardDefinitions + - [ - basicWithMixin.dashboardSources, - basicWithMixin.dashboardDatasources, - basicWithMixin.deployment, - basicWithMixin.serviceAccount, - basicWithMixin.service { - spec+: { ports: [ + _config:: { + namespace: 'monitoring-grafana', + dashboards: kubernetesMixin.grafanaDashboards, + }, + + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ port { nodePort: 30910, } for port in super.ports - ] }, + ], }, - ], + }, + }, } ``` @@ -287,43 +243,43 @@ local grafana = import 'grafana/grafana.libsonnet'; { local customIni = - (grafana { - _config+:: { - namespace: 'monitoring-grafana', - grafana+:: { - config: { - sections: { - metrics: { enabled: true }, - 'auth.ldap': { - enabled: true, - config_file: '/etc/grafana/ldap.toml', - allow_sign_up: true, - }, - }, - }, - ldap: ||| - [[servers]] - host = "127.0.0.1" - port = 389 - use_ssl = false - start_tls = false - ssl_skip_verify = false - - bind_dn = "cn=admin,dc=grafana,dc=org" - bind_password = 'grafana' - - search_filter = "(cn=%s)" - - search_base_dns = ["dc=grafana,dc=org"] - |||, - }, - }, - }).grafana, + grafana({ + _config+:: { + namespace: 'monitoring-grafana', + grafana+:: { + config: { + sections: { + metrics: { enabled: true }, + 'auth.ldap': { + enabled: true, + config_file: '/etc/grafana/ldap.toml', + allow_sign_up: true, + }, + }, + }, + ldap: ||| + [[servers]] + host = "127.0.0.1" + port = 389 + use_ssl = false + start_tls = false + ssl_skip_verify = false + + bind_dn = "cn=admin,dc=grafana,dc=org" + bind_password = 'grafana' + + search_filter = "(cn=%s)" + + search_base_dns = ["dc=grafana,dc=org"] + |||, + }, + }, + }), apiVersion: 'v1', kind: 'List', items: - customIni.dashboardDefinitions + + customIni.dashboardDefinitions.items + [ customIni.config, customIni.dashboardSources, @@ -351,34 +307,23 @@ The config object allows specifying an array of plugins to install at startup. local grafana = import 'grafana/grafana.libsonnet'; { - local basic = - (grafana { - _config+:: { - namespace: 'monitoring-grafana', - grafana+:: { - plugins: ['camptocamp-prometheus-alertmanager-datasource'], - }, - }, - }).grafana, - - apiVersion: 'v1', - kind: 'List', - items: - basic.dashboardDefinitions + - [ - basic.dashboardSources, - basic.dashboardDatasources, - basic.deployment, - basic.serviceAccount, - basic.service { - spec+: { ports: [ + _config:: { + namespace: 'monitoring-grafana', + plugins: ['camptocamp-prometheus-alertmanager-datasource'], + }, + + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ port { nodePort: 30910, } for port in super.ports - ] }, + ], }, - ], + }, + }, } ``` diff --git a/examples/basic-with-image-renderer.jsonnet b/examples/basic-with-image-renderer.jsonnet index 90b142e..4c1239f 100644 --- a/examples/basic-with-image-renderer.jsonnet +++ b/examples/basic-with-image-renderer.jsonnet @@ -1,59 +1,34 @@ local grafana = import 'grafana/grafana.libsonnet'; -local basicWithImageRenderer = - (grafana { - _config+:: { - namespace: 'monitoring-grafana', - versions+:: { - grafanaImageRenderer: '1.0.9', - }, - - imageRepos+:: { - grafanaImageRenderer: 'grafana/grafana-image-renderer', - }, - - grafana+:: { - imageRendererPort: 8081, - imageRendererContainer: { - requests: { cpu: '100m', memory: '100Mi' }, - limits: { cpu: '200m', memory: '200Mi' }, - }, - - env+: [ - { name: 'GF_RENDERING_SERVER_URL', value: 'http://localhost:' + $._config.grafana.imageRendererPort + '/render' }, - { name: 'GF_RENDERING_CALLBACK_URL', value: 'http://localhost:' + $._config.grafana.port }, - ], - - containers+: [ - { - name: 'grafana-image-renderer', - image: $._config.imageRepos.grafanaImageRenderer + ':' + $._config.versions.grafanaImageRenderer, - ports: [{ name: 'http', containerPort: $._config.grafana.imageRendererPort }], - resources: { - requests: $._config.grafana.imageRendererContainer.requests, - limits: $._config.grafana.imageRendererContainer.limits, - }, - }, - ], - }, - }, - }).grafana; +local imageRenderer = { + name: 'grafana-image-renderer', + image: 'grafana/grafana-image-renderer:1.0.9', + ports: [{ name: 'http', containerPort: 8081 }], + resources: { + requests: { cpu: '100m', memory: '100Mi' }, + limits: { cpu: '200m', memory: '200Mi' }, + }, +}; { - apiVersion: 'v1', - kind: 'List', - items: [ - basicWithImageRenderer.dashboardSources, - basicWithImageRenderer.dashboardDatasources, - basicWithImageRenderer.deployment, - basicWithImageRenderer.serviceAccount, - basicWithImageRenderer.service { - spec+: { ports: [ - port { - nodePort: 30910, - } - for port in super.ports - ] }, + _config:: { + namespace: 'monitoring-grafana', + env: [ + { name: 'GF_RENDERING_SERVER_URL', value: 'http://localhost:' + imageRenderer.ports[0].containerPort + '/render' }, + { name: 'GF_RENDERING_CALLBACK_URL', value: 'http://localhost:' + $.grafana._config.port }, + ], + }, + + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ + port { + nodePort: 30910, + } + for port in super.ports + ], + }, }, - ], + }, } diff --git a/examples/basic-with-mixin.jsonnet b/examples/basic-with-mixin.jsonnet index 3d3a186..da214f3 100644 --- a/examples/basic-with-mixin.jsonnet +++ b/examples/basic-with-mixin.jsonnet @@ -2,32 +2,21 @@ local kubernetesMixin = import 'github.com/kubernetes-monitoring/kubernetes-mixi local grafana = import 'grafana/grafana.libsonnet'; { - local basicWithMixin = - (grafana { - _config+:: { - namespace: 'monitoring-grafana', - grafana+:: { - dashboards: kubernetesMixin.grafanaDashboards, - }, - }, - }).grafana, + _config:: { + namespace: 'monitoring-grafana', + dashboards: kubernetesMixin.grafanaDashboards, + }, - apiVersion: 'v1', - kind: 'List', - items: - basicWithMixin.dashboardDefinitions + - [ - basicWithMixin.dashboardSources, - basicWithMixin.dashboardDatasources, - basicWithMixin.deployment, - basicWithMixin.serviceAccount, - basicWithMixin.service { - spec+: { ports: [ + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ port { nodePort: 30910, } for port in super.ports - ] }, + ], }, - ], + }, + }, } diff --git a/examples/basic.jsonnet b/examples/basic.jsonnet index 32861a5..2c23baa 100644 --- a/examples/basic.jsonnet +++ b/examples/basic.jsonnet @@ -1,29 +1,20 @@ local grafana = import 'grafana/grafana.libsonnet'; { - local basic = - (grafana { - _config+:: { - namespace: 'monitoring-grafana', - }, - }).grafana, + _config:: { + namespace: 'monitoring-grafana', + }, - apiVersion: 'v1', - kind: 'List', - items: - basic.dashboardDefinitions + - [ - basic.dashboardSources, - basic.dashboardDatasources, - basic.deployment, - basic.serviceAccount, - basic.service { - spec+: { ports: [ + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ port { nodePort: 30910, } for port in super.ports - ] }, + ], }, - ], + }, + }, } diff --git a/examples/custom-ini.jsonnet b/examples/custom-ini.jsonnet index dbc1ed4..5abd699 100644 --- a/examples/custom-ini.jsonnet +++ b/examples/custom-ini.jsonnet @@ -2,43 +2,43 @@ local grafana = import 'grafana/grafana.libsonnet'; { local customIni = - (grafana { - _config+:: { - namespace: 'monitoring-grafana', - grafana+:: { - config: { - sections: { - metrics: { enabled: true }, - 'auth.ldap': { - enabled: true, - config_file: '/etc/grafana/ldap.toml', - allow_sign_up: true, - }, - }, - }, - ldap: ||| - [[servers]] - host = "127.0.0.1" - port = 389 - use_ssl = false - start_tls = false - ssl_skip_verify = false + grafana({ + _config+:: { + namespace: 'monitoring-grafana', + grafana+:: { + config: { + sections: { + metrics: { enabled: true }, + 'auth.ldap': { + enabled: true, + config_file: '/etc/grafana/ldap.toml', + allow_sign_up: true, + }, + }, + }, + ldap: ||| + [[servers]] + host = "127.0.0.1" + port = 389 + use_ssl = false + start_tls = false + ssl_skip_verify = false - bind_dn = "cn=admin,dc=grafana,dc=org" - bind_password = 'grafana' + bind_dn = "cn=admin,dc=grafana,dc=org" + bind_password = 'grafana' - search_filter = "(cn=%s)" + search_filter = "(cn=%s)" - search_base_dns = ["dc=grafana,dc=org"] - |||, - }, - }, - }).grafana, + search_base_dns = ["dc=grafana,dc=org"] + |||, + }, + }, + }), apiVersion: 'v1', kind: 'List', items: - customIni.dashboardDefinitions + + customIni.dashboardDefinitions.items + [ customIni.config, customIni.dashboardSources, diff --git a/examples/dashboard-definition.jsonnet b/examples/dashboard-definition.jsonnet index d95bb15..aaa0801 100644 --- a/examples/dashboard-definition.jsonnet +++ b/examples/dashboard-definition.jsonnet @@ -1,66 +1,54 @@ -local grafana = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet'; -local dashboard = grafana.dashboard; -local row = grafana.row; -local prometheus = grafana.prometheus; -local template = grafana.template; -local graphPanel = grafana.graphPanel; +local grafonnet = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet'; +local dashboard = grafonnet.dashboard; +local row = grafonnet.row; +local prometheus = grafonnet.prometheus; +local template = grafonnet.template; +local graphPanel = grafonnet.graphPanel; local grafana = import 'grafana/grafana.libsonnet'; -local grafanaWithDashboards = - (grafana - { - _config+:: { - namespace: 'monitoring-grafana', - grafana+:: { - dashboards+:: { - 'my-dashboard.json': - dashboard.new('My Dashboard') - .addTemplate( - { - current: { - text: 'Prometheus', - value: 'Prometheus', - }, - hide: 0, - label: null, - name: 'datasource', - options: [], - query: 'prometheus', - refresh: 1, - regex: '', - type: 'datasource', - }, - ) - .addRow( - row.new() - .addPanel( - graphPanel.new('My Panel', span=6, datasource='$datasource') - .addTarget(prometheus.target('vector(1)')), - ) - ), - }, - }, - }, - }).grafana; - { - apiVersion: 'v1', - kind: 'List', - items: - grafanaWithDashboards.dashboardDefinitions + - [ - grafanaWithDashboards.dashboardSources, - grafanaWithDashboards.dashboardDatasources, - grafanaWithDashboards.deployment, - grafanaWithDashboards.serviceAccount, - grafanaWithDashboards.service { - spec+: { ports: [ + _config:: { + namespace: 'monitoring-grafana', + dashboards+: { + 'my-dashboard.json': + dashboard.new('My Dashboard') + .addTemplate( + { + current: { + text: 'Prometheus', + value: 'Prometheus', + }, + hide: 0, + label: null, + name: 'datasource', + options: [], + query: 'prometheus', + refresh: 1, + regex: '', + type: 'datasource', + }, + ) + .addRow( + row.new() + .addPanel( + graphPanel.new('My Panel', span=6, datasource='$datasource') + .addTarget(prometheus.target('vector(1)')), + ) + ), + }, + }, + + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ port { nodePort: 30910, } for port in super.ports - ] }, + ], }, - ], + }, + }, } diff --git a/examples/dashboard-folder-definition.jsonnet b/examples/dashboard-folder-definition.jsonnet index 67f6230..52da0f2 100644 --- a/examples/dashboard-folder-definition.jsonnet +++ b/examples/dashboard-folder-definition.jsonnet @@ -1,56 +1,44 @@ -local grafana = import 'grafonnet/grafana.libsonnet'; -local dashboard = grafana.dashboard; -local row = grafana.row; -local prometheus = grafana.prometheus; -local template = grafana.template; -local graphPanel = grafana.graphPanel; +local grafonnet = import 'github.com/grafana/grafonnet-lib/grafonnet/grafana.libsonnet'; +local dashboard = grafonnet.dashboard; +local row = grafonnet.row; +local prometheus = grafonnet.prometheus; +local template = grafonnet.template; +local graphPanel = grafonnet.graphPanel; local grafana = import 'grafana/grafana.libsonnet'; -local grafanaWithDashboards = - (grafana - { - _config+:: { - namespace: 'monitoring-grafana', - grafana+:: { - folderDashboards+:: { - Services: { - 'regional-services-dashboard.json': (import 'dashboards/regional-services-dashboard.json'), - 'global-services-dashboard.json': (import 'dashboards/global-services-dashboard.json'), - }, - AWS: { - 'aws-ec2-dashboard.json': (import 'dashboards/aws-ec2-dashboard.json'), - 'aws-rds-dashboard.json': (import 'dashboards/aws-rds-dashboard.json'), - 'aws-sqs-dashboard.json': (import 'dashboards/aws-sqs-dashboard.json'), - }, - ISTIO: { - 'istio-citadel-dashboard.json': (import 'dashboards/istio-citadel-dashboard.json'), - 'istio-galley-dashboard.json': (import 'dashboards/istio-galley-dashboard.json'), - 'istio-mesh-dashboard.json': (import 'dashboards/istio-mesh-dashboard.json'), - 'istio-pilot-dashboard.json': (import 'dashboards/istio-pilot-dashboard.json'), - }, - }, - }, - }, - }).grafana; - { - apiVersion: 'v1', - kind: 'List', - items: - grafanaWithDashboards.dashboardDefinitions + - [ - grafanaWithDashboards.dashboardSources, - grafanaWithDashboards.dashboardDatasources, - grafanaWithDashboards.deployment, - grafanaWithDashboards.serviceAccount, - grafanaWithDashboards.service { - spec+: { ports: [ + _config:: { + namespace: 'monitoring-grafana', + folderDashboards+: { + Services: { + 'regional-services-dashboard.json': (import 'dashboards/regional-services-dashboard.json'), + 'global-services-dashboard.json': (import 'dashboards/global-services-dashboard.json'), + }, + AWS: { + 'aws-ec2-dashboard.json': (import 'dashboards/aws-ec2-dashboard.json'), + 'aws-rds-dashboard.json': (import 'dashboards/aws-rds-dashboard.json'), + 'aws-sqs-dashboard.json': (import 'dashboards/aws-sqs-dashboard.json'), + }, + ISTIO: { + 'istio-citadel-dashboard.json': (import 'dashboards/istio-citadel-dashboard.json'), + 'istio-galley-dashboard.json': (import 'dashboards/istio-galley-dashboard.json'), + 'istio-mesh-dashboard.json': (import 'dashboards/istio-mesh-dashboard.json'), + 'istio-pilot-dashboard.json': (import 'dashboards/istio-pilot-dashboard.json'), + }, + }, + }, + + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ port { nodePort: 30910, } for port in super.ports - ] }, + ], }, - ], + }, + }, } diff --git a/examples/plugins.jsonnet b/examples/plugins.jsonnet index 5a2e4f7..7ac4a92 100644 --- a/examples/plugins.jsonnet +++ b/examples/plugins.jsonnet @@ -1,32 +1,21 @@ local grafana = import 'grafana/grafana.libsonnet'; { - local basic = - (grafana { - _config+:: { - namespace: 'monitoring-grafana', - grafana+:: { - plugins: ['camptocamp-prometheus-alertmanager-datasource'], - }, - }, - }).grafana, + _config:: { + namespace: 'monitoring-grafana', + plugins: ['camptocamp-prometheus-alertmanager-datasource'], + }, - apiVersion: 'v1', - kind: 'List', - items: - basic.dashboardDefinitions + - [ - basic.dashboardSources, - basic.dashboardDatasources, - basic.deployment, - basic.serviceAccount, - basic.service { - spec+: { ports: [ + grafana: grafana($._config) + { + service+: { + spec+: { + ports: [ port { nodePort: 30910, } for port in super.ports - ] }, + ], }, - ], + }, + }, } diff --git a/grafana/grafana.libsonnet b/grafana/grafana.libsonnet index 2421ee1..166448a 100644 --- a/grafana/grafana.libsonnet +++ b/grafana/grafana.libsonnet @@ -1,357 +1,356 @@ -{ - _config+:: { - namespace: 'default', +local defaults = { + local defaults = self, + namespace: 'default', + version: '7.5.10', + image: 'docker.io/grafana/grafana:' + defaults.version, + commonLabels:: { + 'app.kubernetes.io/name': 'grafana', + 'app.kubernetes.io/version': defaults.version, + 'app.kubernetes.io/component': 'grafana', + }, + selectorLabels:: { + [labelName]: defaults.commonLabels[labelName] + for labelName in std.objectFields(defaults.commonLabels) + if !std.setMember(labelName, ['app.kubernetes.io/version']) + }, + replicas: 1, + port: 3000, + resources: { + requests: { cpu: '100m', memory: '100Mi' }, + limits: { cpu: '200m', memory: '200Mi' }, + }, - versions+:: { - grafana: '7.3.4', + dashboards: {}, + rawDashboards: {}, + folderDashboards: {}, + folderUidGenerator(folder): '', + datasources: [{ + name: 'prometheus', + type: 'prometheus', + access: 'proxy', + orgId: 1, + url: 'http://prometheus-k8s.' + defaults.namespace + '.svc:9090', + version: 1, + editable: false, + }], + // Forces pod restarts when dashboards are changed + dashboardsChecksum: false, + config: { + sections: { + date_formats: { default_timezone: 'UTC' }, }, + }, + ldap: null, + plugins: [], + env: [], + containers: [], +}; - imageRepos+:: { - grafana: 'docker.io/grafana/grafana', - }, +function(params) { + local g = self, + _config:: defaults + params, + _metadata:: { + name: 'grafana', + namespace: g._config.namespace, + labels: g._config.commonLabels, + }, + + serviceAccount: { + apiVersion: 'v1', + kind: 'ServiceAccount', + metadata: g._metadata, + }, - prometheus+:: { - name: 'k8s', - serviceName: 'prometheus-' + $._config.prometheus.name, + service: { + apiVersion: 'v1', + kind: 'Service', + metadata: g._metadata, + spec: { + selector: g.deployment.spec.selector.matchLabels, + ports: [ + { name: 'http', targetPort: 'http', port: 3000 }, + ], }, + }, - grafana+:: { - labels: { - 'app.kubernetes.io/name': 'grafana', - 'app.kubernetes.io/version': $._config.versions.grafana, - 'app.kubernetes.io/component': 'grafana', - }, - dashboards: {}, - rawDashboards: {}, - folderDashboards: {}, - folderUidGenerator(folder): '', - datasources: [{ - name: 'prometheus', - type: 'prometheus', - access: 'proxy', - orgId: 1, - url: 'http://' + $._config.prometheus.serviceName + '.' + $._config.namespace + '.svc:9090', - version: 1, - editable: false, - }], - // Forces pod restarts when dashboards are changed - dashboardsChecksum: false, - config: { - sections: { - date_formats: { default_timezone: 'UTC' }, - }, - }, - ldap: null, - plugins: [], - env: [], - port: 3000, - resources: { - requests: { cpu: '100m', memory: '100Mi' }, - limits: { cpu: '200m', memory: '200Mi' }, - }, - containers: [], + config: { + apiVersion: 'v1', + kind: 'Secret', + metadata: g._metadata { + name: 'grafana-config', }, + type: 'Opaque', + stringData: { + 'grafana.ini': std.manifestIni(g._config.config), + } + if g._config.ldap != null then { 'ldap.toml': g._config.ldap } else {}, }, - grafanaDashboards: {}, - grafana+: { - [if std.length($._config.grafana.config) > 0 then 'config']: + + dashboardDefinitions: { + apiVersion: 'v1', + kind: 'ConfigMapList', + items: [ { + local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), apiVersion: 'v1', - kind: 'Secret', - metadata: { - name: 'grafana-config', - namespace: $._config.namespace, - labels: $._config.grafana.labels, + kind: 'ConfigMap', + metadata: g._metadata { + name: dashboardName, }, - type: 'Opaque', - stringData: { - 'grafana.ini': std.manifestIni($._config.grafana.config), - } + - if $._config.grafana.ldap != null then { 'ldap.toml': $._config.grafana.ldap } else {}, - }, - dashboardDefinitions: - [ - { - local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), - apiVersion: 'v1', - kind: 'ConfigMap', - metadata: { - name: dashboardName, - namespace: $._config.namespace, - labels: $._config.grafana.labels, - }, - data: { [name]: std.manifestJsonEx($._config.grafana.dashboards[name], ' ') }, - } - for name in std.objectFields($._config.grafana.dashboards) - ] + [ - { - local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), - apiVersion: 'v1', - kind: 'ConfigMap', - metadata: { - name: dashboardName, - namespace: $._config.namespace, - labels: $._config.grafana.labels, - }, - data: { [name]: std.manifestJsonEx($._config.grafana.folderDashboards[folder][name], ' ') }, - } - for folder in std.objectFields($._config.grafana.folderDashboards) - for name in std.objectFields($._config.grafana.folderDashboards[folder]) - ] + ( - if std.length($._config.grafana.rawDashboards) > 0 then - [ + data: { [name]: std.manifestJsonEx(g._config.dashboards[name], ' ') }, + } + for name in std.objectFields(g._config.dashboards) + ] + [ + { + local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), + apiVersion: 'v1', + kind: 'ConfigMap', + metadata: g._metadata { + name: dashboardName, + }, + data: { [name]: std.manifestJsonEx(g._config.folderDashboards[folder][name], ' ') }, + } + for folder in std.objectFields(g._config.folderDashboards) + for name in std.objectFields(g._config.folderDashboards[folder]) + ] + ( + if std.length(g._config.rawDashboards) > 0 then + [ + { + local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), + apiVersion: 'v1', + kind: 'ConfigMap', + metadata: g._metadata { + name: dashboardName, + }, + data: { [name]: g._config.rawDashboards[name] }, + } + for name in std.objectFields(g._config.rawDashboards) + ] + else + [] + ), + }, + + dashboardSources: + local dashboardSources = { + apiVersion: 1, + providers: + ( + if std.length(g._config.dashboards) + + std.length(g._config.rawDashboards) > 0 then [ { - local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), - apiVersion: 'v1', - kind: 'ConfigMap', - metadata: { - name: dashboardName, - namespace: $._config.namespace, - labels: $._config.grafana.labels, - }, - data: { [name]: $._config.grafana.rawDashboards[name] }, - } - for name in std.objectFields($._config.grafana.rawDashboards) - ] - else - [] - ), - dashboardSources: - local dashboardSources = { - apiVersion: 1, - providers: - ( - if std.length($._config.grafana.dashboards) + - std.length($._config.grafana.rawDashboards) > 0 then [ - { - name: '0', - orgId: 1, - folder: 'Default', - folderUid: $._config.grafana.folderUidGenerator('Default'), - type: 'file', - options: { - path: '/grafana-dashboard-definitions/0', - }, - }, - ] else [] - ) + - [ - { - name: folder, + name: '0', orgId: 1, - folder: folder, - folderUid: $._config.grafana.folderUidGenerator(folder), + folder: 'Default', + folderUid: g._config.folderUidGenerator('Default'), type: 'file', options: { - path: '/grafana-dashboard-definitions/' + folder, + path: '/grafana-dashboard-definitions/0', }, - } - for folder in std.objectFields($._config.grafana.folderDashboards) - ], - }; + }, + ] else [] + ) + + [ + { + name: folder, + orgId: 1, + folder: folder, + folderUid: g._config.folderUidGenerator(folder), + type: 'file', + options: { + path: '/grafana-dashboard-definitions/' + folder, + }, + } + for folder in std.objectFields(g._config.folderDashboards) + ], + }; - { - kind: 'ConfigMap', - apiVersion: 'v1', - metadata: { - name: 'grafana-dashboards', - namespace: $._config.namespace, - labels: $._config.grafana.labels, - }, - data: { 'dashboards.yaml': std.manifestJsonEx(dashboardSources, ' ') }, - }, - dashboardDatasources: - { - apiVersion: 'v1', - kind: 'Secret', - metadata: { - name: 'grafana-datasources', - namespace: $._config.namespace, - labels: $._config.grafana.labels, - }, - type: 'Opaque', - stringData: { 'datasources.yaml': std.manifestJsonEx({ - apiVersion: 1, - datasources: $._config.grafana.datasources, - }, ' ') }, - }, - service: - { - apiVersion: 'v1', - kind: 'Service', - metadata: { - name: 'grafana', - namespace: $._config.namespace, - labels: $._config.grafana.labels, - }, - spec: { - selector: $.grafana.deployment.spec.selector.matchLabels, - ports: [ - { name: 'http', targetPort: 'http', port: 3000 }, - ], - }, - }, - serviceAccount: - { - apiVersion: 'v1', - kind: 'ServiceAccount', - metadata: { - name: 'grafana', - namespace: $._config.namespace, - }, + { + kind: 'ConfigMap', + apiVersion: 'v1', + metadata: g._metadata { + name: 'grafana-dashboards', }, - deployment: - local targetPort = $._config.grafana.port; - local portName = 'http'; - local podLabels = $._config.grafana.labels; - local podSelectorLabels = { - [labelName]: podLabels[labelName] - for labelName in std.objectFields(podLabels) - if !std.setMember(labelName, ['app.kubernetes.io/version']) - }; + data: { 'dashboards.yaml': std.manifestJsonEx(dashboardSources, ' ') }, + }, - local configVolumeName = 'grafana-config'; - local configSecretName = 'grafana-config'; - local configVolume = { name: configVolumeName, secret: { secretName: configSecretName } }; - local configVolumeMount = { name: configVolumeName, mountPath: '/etc/grafana', readOnly: false }; + dashboardDatasources: { + apiVersion: 'v1', + kind: 'Secret', + metadata: g._metadata { + name: 'grafana-datasources', + }, + type: 'Opaque', + stringData: { + 'datasources.yaml': std.manifestJsonEx( + { + apiVersion: 1, + datasources: g._config.datasources, + }, ' ' + ), + }, + }, - local storageVolumeName = 'grafana-storage'; - local storageVolume = { name: storageVolumeName, emptyDir: {} }; - local storageVolumeMount = { name: storageVolumeName, mountPath: '/var/lib/grafana', readOnly: false }; + deployment: + local configVolume = { + name: 'grafana-config', + secret: { secretName: g.config.metadata.name }, + }; + local configVolumeMount = { + name: configVolume.name, + mountPath: '/etc/grafana', + readOnly: false, + }; - local datasourcesVolumeName = 'grafana-datasources'; - local datasourcesSecretName = 'grafana-datasources'; - local datasourcesVolume = { name: datasourcesVolumeName, secret: { secretName: datasourcesSecretName } }; - local datasourcesVolumeMount = { name: datasourcesVolumeName, mountPath: '/etc/grafana/provisioning/datasources', readOnly: false }; + local storageVolume = { + name: 'grafana-storage', + emptyDir: {}, + }; + local storageVolumeMount = { + name: storageVolume.name, + mountPath: '/var/lib/grafana', + readOnly: false, + }; - local dashboardsVolumeName = 'grafana-dashboards'; - local dashboardsConfigMapName = 'grafana-dashboards'; - local dashboardsVolume = { name: dashboardsVolumeName, configMap: { name: dashboardsConfigMapName } }; - local dashboardsVolumeMount = { name: dashboardsVolumeName, mountPath: '/etc/grafana/provisioning/dashboards', readOnly: false }; + local datasourcesVolume = { + name: 'grafana-datasources', + secret: { secretName: g.dashboardDatasources.metadata.name }, + }; + local datasourcesVolumeMount = { + name: datasourcesVolume.name, + mountPath: '/etc/grafana/provisioning/datasources', + readOnly: false, + }; - local volumeMounts = - [ - storageVolumeMount, - datasourcesVolumeMount, - dashboardsVolumeMount, - ] + - [ - { - local dashboardName = std.strReplace(name, '.json', ''), - name: 'grafana-dashboard-' + dashboardName, - mountPath: '/grafana-dashboard-definitions/0/' + dashboardName, - readOnly: false, - } - for name in std.objectFields($._config.grafana.dashboards) - ] + - [ - { - local dashboardName = std.strReplace(name, '.json', ''), - name: 'grafana-dashboard-' + dashboardName, - mountPath: '/grafana-dashboard-definitions/' + folder + '/' + dashboardName, - readOnly: false, - } - for folder in std.objectFields($._config.grafana.folderDashboards) - for name in std.objectFields($._config.grafana.folderDashboards[folder]) - ] + - [ - { + local dashboardsVolume = { + name: 'grafana-dashboards', + configMap: { name: g.dashboardSources.metadata.name }, + }; + local dashboardsVolumeMount = { + name: dashboardsVolume.name, + mountPath: '/etc/grafana/provisioning/dashboards', + readOnly: false, + }; - local dashboardName = std.strReplace(name, '.json', ''), - name: 'grafana-dashboard-' + dashboardName, - mountPath: '/grafana-dashboard-definitions/0/' + dashboardName, - readOnly: false, - } - for name in std.objectFields($._config.grafana.rawDashboards) - ] + ( - if std.length($._config.grafana.config) > 0 then [configVolumeMount] else [] - ); + local volumeMounts = + [ + storageVolumeMount, + datasourcesVolumeMount, + dashboardsVolumeMount, + ] + + [ + { + local dashboardName = std.strReplace(name, '.json', ''), + name: 'grafana-dashboard-' + dashboardName, + mountPath: '/grafana-dashboard-definitions/0/' + dashboardName, + readOnly: false, + } + for name in std.objectFields(g._config.dashboards + g._config.rawDashboards) + ] + + [ + { + local dashboardName = std.strReplace(name, '.json', ''), + name: 'grafana-dashboard-' + dashboardName, + mountPath: '/grafana-dashboard-definitions/' + folder + '/' + dashboardName, + readOnly: false, + } + for folder in std.objectFields(g._config.folderDashboards) + for name in std.objectFields(g._config.folderDashboards[folder]) + ] + ( + if std.length(g._config.config) > 0 then [configVolumeMount] else [] + ); - local volumes = - [ - storageVolume, - datasourcesVolume, - dashboardsVolume, - ] + - [ - { - local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), - name: dashboardName, - configMap: { name: dashboardName }, - } - for name in std.objectFields($._config.grafana.dashboards) - ] + - [ - { - local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), - name: dashboardName, - configMap: { name: dashboardName }, - } - for folder in std.objectFields($._config.grafana.folderDashboards) - for name in std.objectFields($._config.grafana.folderDashboards[folder]) - ] + - [ - { - local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), - name: dashboardName, - configMap: { name: dashboardName }, - } - for name in std.objectFields($._config.grafana.rawDashboards) - ] + - if std.length($._config.grafana.config) > 0 then [configVolume] else []; + local volumes = + [ + storageVolume, + datasourcesVolume, + dashboardsVolume, + ] + + [ + { + local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), + name: dashboardName, + configMap: { name: dashboardName }, + } + for name in std.objectFields(g._config.dashboards) + ] + + [ + { + local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), + name: dashboardName, + configMap: { name: dashboardName }, + } + for folder in std.objectFields(g._config.folderDashboards) + for name in std.objectFields(g._config.folderDashboards[folder]) + ] + + [ + { + local dashboardName = 'grafana-dashboard-' + std.strReplace(name, '.json', ''), + name: dashboardName, + configMap: { name: dashboardName }, + } + for name in std.objectFields(g._config.rawDashboards) + ] + + if std.length(g._config.config) > 0 then [configVolume] else []; - local plugins = ( - if std.length($._config.grafana.plugins) == 0 then - [] - else - [{ name: 'GF_INSTALL_PLUGINS', value: std.join(',', $._config.grafana.plugins) }] - ); + local plugins = ( + if std.length(g._config.plugins) == 0 then + [] + else + [{ name: 'GF_INSTALL_PLUGINS', value: std.join(',', g._config.plugins) }] + ); - local c = [{ - name: 'grafana', - image: $._config.imageRepos.grafana + ':' + $._config.versions.grafana, - env: $._config.grafana.env + plugins, - volumeMounts: volumeMounts, - ports: [{ name: portName, containerPort: targetPort }], - readinessProbe: { - httpGet: { path: '/api/health', port: portName }, + local grafanaContainer = { + name: 'grafana', + image: g._config.image, + env: g._config.env + plugins, + volumeMounts: volumeMounts, + ports: [{ + name: 'http', + containerPort: g._config.port, + }], + readinessProbe: { + httpGet: { + path: '/api/health', + port: grafanaContainer.ports[0].name, }, - resources: $._config.grafana.resources, - }] + $._config.grafana.containers; + }, + resources: g._config.resources, + }; - { - apiVersion: 'apps/v1', - kind: 'Deployment', - metadata: { - name: 'grafana', - namespace: $._config.namespace, - labels: podLabels, + { + apiVersion: 'apps/v1', + kind: 'Deployment', + metadata: g._metadata, + spec: { + replicas: g._config.replicas, + selector: { + matchLabels: g._config.selectorLabels, }, - spec: { - replicas: 1, - selector: { - matchLabels: podSelectorLabels, + template: { + metadata: { + labels: g._config.commonLabels, + annotations: { + [if std.length(g._config.config) > 0 then 'checksum/grafana-config']: std.md5(std.toString(g.config)), + 'checksum/grafana-datasources': std.md5(std.toString(g.dashboardDatasources)), + [if g._config.dashboardsChecksum then 'checksum/grafana-dashboards']: std.md5(std.toString(g.dashboardDefinitions)), + 'checksum/grafana-dashboardproviders': std.md5(std.toString(g.dashboardSources)), + }, }, - template: { - metadata: { - labels: podLabels, - annotations: { - [if std.length($._config.grafana.config) > 0 then 'checksum/grafana-config']: std.md5(std.toString($.grafana.config)), - 'checksum/grafana-datasources': std.md5(std.toString($.grafana.dashboardDatasources)), - [if $._config.grafana.dashboardsChecksum then 'checksum/grafana-dashboards']: std.md5(std.toString($.grafana.dashboardDefinitions)), - 'checksum/grafana-dashboardproviders': std.md5(std.toString($.grafana.dashboardSources)), - }, + spec: { + containers: [grafanaContainer] + g._config.containers, + volumes: volumes, + serviceAccountName: g.serviceAccount.metadata.name, + nodeSelector: { + 'kubernetes.io/os': 'linux', }, - spec: { - containers: c, - volumes: volumes, - serviceAccountName: $.grafana.serviceAccount.metadata.name, - nodeSelector: { 'kubernetes.io/os': 'linux' }, - securityContext: { fsGroup: 65534, runAsNonRoot: true, runAsUser: 65534 }, + securityContext: { + fsGroup: 65534, + runAsNonRoot: true, + runAsUser: 65534, }, }, }, }, - }, + }, }