-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
I used cdk8s to import Grafana custom resource definitions from the Grafana operator repository (here: https://github.com/grafana-operator/grafana-operator/tree/v3.10.2/deploy/crds), but some of them had to be manually modified due to typos and/or missing fields. I tested the generated manifests on my local machine using the kubernetes tool "kind" ("minikube" works just as well). The process was: - generate a manifest (by creating a chart and using the API) - create a kind cluster - install the grafana operator on a specific namespace (e.g. "grafana") - apply the manifest in that namespace - `kubectl port-forward service/grafana-service -n <namespace> :3000` - check that Grafana is working in browser TODO: - [x] update based on README - [x] add more tests
- Loading branch information
Showing
13 changed files
with
21,758 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
import { Duration } from 'cdk8s'; | ||
import { Construct } from 'constructs'; | ||
import { GrafanaDashboard } from './imports/grafana-dashboard'; | ||
|
||
export interface DashboardProps { | ||
/** | ||
* Title of the dashboard. | ||
*/ | ||
readonly title: string; | ||
|
||
/** | ||
* Group dashboards into folders. | ||
* @default - default folder | ||
*/ | ||
readonly folder?: string; | ||
|
||
/** | ||
* Specify a mapping from data source variables to data source names. | ||
* This is only needed if you are importing an existing dashboard's JSON | ||
* and it specifies variables within an "__inputs" field. | ||
* | ||
* @example { DS_PROMETHEUS: "my-prometheus-ds" } | ||
* @default - no data source variables | ||
*/ | ||
readonly dataSourceVariables?: { [name: string]: string }; | ||
|
||
/** | ||
* Auto-refresh interval. | ||
* @default - 5 seconds | ||
*/ | ||
readonly refreshRate?: Duration; | ||
|
||
/** | ||
* Time range for the dashboard, e.g. last 6 hours, last 7 days, etc. | ||
* @default - 6 hours | ||
*/ | ||
readonly timeRange?: Duration; | ||
|
||
/** | ||
* Specify plugins required by the dashboard. | ||
*/ | ||
readonly plugins?: GrafanaPlugin[]; | ||
|
||
/** | ||
* Labels to apply to the kubernetes resource. | ||
* | ||
* When adding a dashboard to a Grafana instance using `grafana.addDashboard`, | ||
* labels provided to Grafana will be automatically applied. Otherwise, | ||
* labels must be added manually. | ||
* | ||
* @default - no labels | ||
*/ | ||
readonly labels?: { [name: string]: string }; | ||
|
||
/** | ||
* Namespace to apply to the kubernetes resource. | ||
* | ||
* When adding a dashboard to a Grafana instance using `grafana.addDashboard`, | ||
* the namespace will be automatically inherited. | ||
* | ||
* @default - undefined (will be assigned to the 'default' namespace) | ||
*/ | ||
readonly namespace?: string; | ||
|
||
/** | ||
* All other dashboard customizations. | ||
* @see https://grafana.com/docs/grafana/latest/dashboards/json-model/ | ||
*/ | ||
readonly jsonModel?: { [key: string]: any }; | ||
} | ||
|
||
/** | ||
* A Grafana dashboard. | ||
* @see https://grafana.com/docs/grafana/latest/http_api/dashboard/ | ||
*/ | ||
export class Dashboard extends Construct { | ||
private readonly plugins: GrafanaPlugin[]; | ||
constructor(scope: Construct, id: string, props: DashboardProps) { | ||
super(scope, id); | ||
|
||
this.plugins = []; | ||
|
||
const refreshRate = props.refreshRate ?? Duration.seconds(5); | ||
const timeRange = props.timeRange ?? Duration.hours(6); | ||
const dataSources = Object.entries(props.dataSourceVariables ?? {}).map( | ||
([variable, name]) => ({ datasourceName: name, inputName: variable }), | ||
); | ||
|
||
const defaults = { | ||
title: props.title, | ||
id: null, | ||
tags: [], | ||
style: 'dark', | ||
timezone: 'browser', | ||
editable: true, | ||
hideControls: false, | ||
graphTooltip: 1, | ||
panels: [], | ||
time: { | ||
from: `now-${timeRange.toSeconds()}s`, | ||
to: 'now', | ||
}, | ||
timepicker: { | ||
time_options: [], | ||
refresh_intervals: [], | ||
}, | ||
templating: { | ||
list: [], | ||
}, | ||
annotations: { | ||
list: [], | ||
}, | ||
refresh: `${refreshRate.toSeconds()}s`, | ||
schemaVersion: 17, | ||
version: 0, | ||
links: [], | ||
} as any; | ||
|
||
new GrafanaDashboard(this, 'Resource', { | ||
metadata: { | ||
labels: props.labels, | ||
namespace: props.namespace, | ||
}, | ||
spec: { | ||
customFolderName: props.folder, | ||
datasources: dataSources, | ||
plugins: this.plugins, | ||
json: JSON.stringify({ | ||
...defaults, | ||
...props.jsonModel, | ||
}, null, 2), | ||
name: id, | ||
}, | ||
}); | ||
|
||
if (props.plugins) { | ||
this.addPlugins(...props.plugins); | ||
} | ||
} | ||
|
||
/** | ||
* Adds one or more plugins. | ||
*/ | ||
public addPlugins(...plugins: GrafanaPlugin[]) { | ||
for (const plugin of plugins) { | ||
this.plugins.push(plugin); | ||
} | ||
} | ||
} | ||
|
||
export interface GrafanaPlugin { | ||
/** | ||
* Name of the plugin, e.g. "grafana-piechart-panel" | ||
*/ | ||
readonly name: string; | ||
|
||
/** | ||
* Version of the plugin, e.g. "1.3.6" | ||
*/ | ||
readonly version: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { Construct } from 'constructs'; | ||
import { GrafanaDataSource } from './imports/grafana-datasource'; | ||
|
||
/** | ||
* Mode for accessing a data source. | ||
* @see https://grafana.com/docs/grafana/latest/administration/provisioning/#example-data-source-config-file | ||
*/ | ||
export enum AccessType { | ||
/** | ||
* Access via proxy. | ||
*/ | ||
PROXY = 'proxy', | ||
|
||
/** | ||
* Access directly (via server or browser in UI). | ||
*/ | ||
DIRECT = 'direct', | ||
} | ||
|
||
export interface DataSourceProps { | ||
/** | ||
* Name of the data source. | ||
*/ | ||
readonly name: string; | ||
|
||
/** | ||
* Type of the data source. | ||
*/ | ||
readonly type: string; | ||
|
||
/** | ||
* Access type of the data source. | ||
*/ | ||
readonly access: AccessType; | ||
|
||
/** | ||
* Description of the data source. | ||
* @default - no description | ||
*/ | ||
readonly description?: string; | ||
|
||
/** | ||
* URL of the data source. Most resources besides the 'testdata' data source | ||
* type require this field in order to retrieve data. | ||
* | ||
* @default - default url for data source type | ||
*/ | ||
readonly url?: string; | ||
|
||
/** | ||
* Labels to apply to the kubernetes resource. | ||
* | ||
* When adding a data source to a Grafana instance using `grafana.addDataSource`, | ||
* labels provided to Grafana will be automatically applied. Otherwise, | ||
* labels must be added manually. | ||
* | ||
* @default - no labels | ||
*/ | ||
readonly labels?: { [name: string]: string }; | ||
|
||
/** | ||
* Namespace to apply to the kubernetes resource. | ||
* | ||
* When adding a data source to a Grafana instance using `grafana.addDataSource`, | ||
* the namespace will be automatically inherited. | ||
* | ||
* @default - undefined (will be assigned to the 'default' namespace) | ||
*/ | ||
readonly namespace?: string; | ||
} | ||
|
||
/** | ||
* A Grafana data source. | ||
* @see https://grafana.com/docs/grafana/latest/administration/provisioning/#example-data-source-config-file | ||
*/ | ||
export class DataSource extends Construct { | ||
/** | ||
* Name of the data source. | ||
*/ | ||
public readonly name: string; | ||
|
||
constructor(scope: Construct, id: string, props: DataSourceProps) { | ||
super(scope, id); | ||
|
||
this.name = props.name; | ||
|
||
new GrafanaDataSource(this, 'Resource', { | ||
metadata: { | ||
labels: props.labels, | ||
namespace: props.namespace, | ||
}, | ||
spec: { | ||
name: props.name, | ||
datasources: [{ | ||
name: props.name, | ||
type: props.type, | ||
access: props.access, | ||
url: props.url, | ||
}], | ||
}, | ||
}); | ||
} | ||
} |
Oops, something went wrong.