diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 000000000..35c95878c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "grafonnet-lib"] + path = grafonnet-lib + url = https://github.com/grafana/grafonnet-lib.git diff --git a/README.md b/README.md index 13f690569..704d1da8d 100644 --- a/README.md +++ b/README.md @@ -35,12 +35,26 @@ Represents a Grafana instance. See [the documentation](./documentation/deploy_gr ## GrafanaDashboard -Represents a Grafana dashboard and allows to specify required plugins. See [the documentation](./documentation/dashboards.md) for a description of properties supported in the spec. +Represents a Grafana dashboard and allows specifying required plugins. See [the documentation](./documentation/dashboards.md) for a description of properties supported in the spec. ## GrafanaDatasource Represents a Grafana datasource. See [the documentation](./documentation/datasources.md) for a description of properties supported in the spec. +# Building the operator image + +Init the submodules first to obtain grafonnet: + +```sh +$ git submodule update --init +``` + +Then build the image using the operatpr-sdk: + +```sh +$ operator-sdk build //grafana-operator: +``` + # Running locally You can run the Operator locally against a remote namespace using the operator-sdk: @@ -52,7 +66,7 @@ Prerequisites: * make sure to deploy the custom resource definition using the command ```kubectl create -f deploy/crds``` ```sh -$ operator-sdk up local --namespace= --operator-flags="" +$ operator-sdk run local --namespace= --operator-flags="" ``` # Grafana features not yet supported in the operator diff --git a/build/Dockerfile b/build/Dockerfile index a73f670ee..d3713e233 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -2,6 +2,10 @@ FROM alpine:3.8 RUN apk upgrade --update --no-cache +RUN mkdir -p /opt/grafonnet-lib + USER nobody +ADD grafonnet-lib /opt/grafonnet-lib + ADD build/_output/bin/grafana-operator /usr/local/bin/grafana-operator diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 7228fc54f..2dea212ab 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -17,7 +17,7 @@ spec: serviceAccountName: grafana-operator containers: - name: grafana-operator - image: quay.io/integreatly/grafana-operator:latest + image: quay.io/pb82/grafana-operator:latest ports: - containerPort: 60000 name: metrics diff --git a/documentation/dashboards.md b/documentation/dashboards.md index 109f65745..099f46a74 100644 --- a/documentation/dashboards.md +++ b/documentation/dashboards.md @@ -10,7 +10,8 @@ The following properties are accepted in the `spec`: * *name*: The filename of the dashboard that gets mounted into a volume in the grafana instance. Not to be confused with `metadata.name`. * *json*: Raw json string with the dashboard contents. Check the [official documentation](https://grafana.com/docs/reference/dashboard/#dashboard-json). -* *url*: Url address to download a json string with the dashboard contents. This will take priority over the json field in case the download is successful +* *jsonnet*: Jsonnet source. The [Grafonnet](https://grafana.github.io/grafonnet-lib/) library is made available automatically and can be imported. +* *url*: Url address to download a json or jsonnet string with the dashboard contents. This will take priority over the json field in case the download is successful. * *plugins*: A list of plugins required by the dashboard. They will be installed by the operator if not already present. * *datasources*: A list of datasources to be used as inputs. See [datasource inputs](#datasource-inputs). diff --git a/documentation/deploy_grafana.md b/documentation/deploy_grafana.md index 016b67f0f..346bef714 100644 --- a/documentation/deploy_grafana.md +++ b/documentation/deploy_grafana.md @@ -94,6 +94,7 @@ The operator accepts a number of flags that can be passed in the `args` section * *--grafana-image-tag*: overrides the Grafana tag. See `controller_config.go` for default. * *--grafana-plugins-init-container-image*: overrides the Grafana Plugins Init Container image, defaults to `quay.io/integreatly/grafana_plugins_init`. * *--grafana-plugins-init-container-tag*: overrides the Grafana Plugins Init Container tag, defaults to `0.0.2`. +* *--grafonnet-location*: overrides the location of the grafonnet library. Defaults to `/opt/grafonnet-lib`. Only useful when running the operator locally. * *--scan-all*: watch for dashboards in all namespaces. This requires the the operator service account to have cluster wide permissions to `get`, `list`, `update` and `watch` dashboards. See `deploy/cluster_roles`. * *--namespaces*: watch for dashboards in a list of namespaces. Mutually exclusive with `--scan-all`. diff --git a/grafonnet-lib b/grafonnet-lib new file mode 160000 index 000000000..8fb95bd89 --- /dev/null +++ b/grafonnet-lib @@ -0,0 +1 @@ +Subproject commit 8fb95bd89990e493a8534205ee636bfcb8db67bd diff --git a/pkg/controller/grafanadashboard/dashboard_pipeline.go b/pkg/controller/grafanadashboard/dashboard_pipeline.go index 62001dc41..2b2066037 100644 --- a/pkg/controller/grafanadashboard/dashboard_pipeline.go +++ b/pkg/controller/grafanadashboard/dashboard_pipeline.go @@ -113,7 +113,11 @@ func (r *DashboardPipelineImpl) validateJson() error { } // Try to get the dashboard json definition either from a provided URL or from the -// raw json in the dashboard resource +// raw json in the dashboard resource. The priority is as follows: +// 1) try to fetch from url if provided +// 2) url fails or not provided: try to fetch from configmap ref +// 3) no configmap specified: try to use embedded json +// 4) no json specified: try to use embedded jsonnet func (r *DashboardPipelineImpl) obtainJson() error { if r.Dashboard.Spec.Url != "" { err := r.loadDashboardFromURL() @@ -148,9 +152,11 @@ func (r *DashboardPipelineImpl) obtainJson() error { } } - return errors.New("dashboard does not contain json") + return errors.New("unable to obtain dashboard contents") } +// Compiles jsonnet to json and makes the grafonnet library available to +// the template func (r *DashboardPipelineImpl) loadJsonnet(source string) (string, error) { cfg := config.GetControllerConfig() grafonnetLocation := cfg.GetConfigString(config.ConfigGrafonnetLocation, config.GrafonnetLocation)