grafana / grizzly

A utility for managing Jsonnet dashboards against the Grafana API
https://grafana.github.io/grizzly/
Apache License 2.0
514 stars 66 forks source link

[Bug]: Watch command doesn't make use of resource path argument #456

Closed vincent-ehl closed 3 months ago

vincent-ehl commented 3 months ago

Grizzly Version

v0.4.2

Expected Behavior

Running the watch command, I expect the directory in to be watched and on any change of a file in this directory, the file should be executed and applied.

I hope I didn't misunderstand the resource-path argument, but this is how I interpret https://grafana.github.io/grizzly/workflows/#grr-watch.

Actual Behavior

Changing a file in the directory causes this file to be executed and applied, instead of the file given in .

Steps to Reproduce

  1. Create a basic grr.jsonnet and my-lib.libsonnet file:
// grr.jsonnet
local grr = import 'grizzly/grizzly.libsonnet';
local myLib = import './my-lib.libsonnet';

{
  folders: [],
  dashboards: [
    grr.dashboard.new('my-dashboard', myLib)
  ]
}
// my-lib.libsonnet
local g = import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet';

g.dashboard.new('My Dashboard')
+ g.dashboard.withUid('my-dashboard')
  1. Run the watch command: grr watch . grr.jsonnet
  2. Resave the my-lib.libsonnet file to trigger the watcher

The following output should be visible:

INFO[0002] Changes detected. Parsing                    
INFO[0002] Changes detected. Applying my-lib.libsonnet  
ERRO[0002] Error: parse error in 'my-lib.libsonnet': found invalid object (at .): errors parsing resource: kind missing, metadata missing, spec missing
thampiotr commented 3 months ago

I have the same issue on the latest 0.4.3, which appears to be a regression since the previous 2.x version we have used.

The watch command takes two positional arguments. The first one is the path to set up the watcher for and the second is the grizzly config file that should be reloaded when changes are detected by the watcher.

What happens instead is that the path of the file that has been modified is attempted to be reloaded, instead of the path provided in the second positional argument (the grizzly config file).

This can be reproduced with:

dash.libsonnet:

{
    folderName: "test",
}

grizzly.jsonnet:

local mixin = import "./dash.libsonnet";

{
  folder: {
    apiVersion: 'grizzly.grafana.com/v1alpha1',
    kind: 'DashboardFolder',
    metadata: {
      name: 'test-folder',
    },
    spec: {
      title: mixin.folderName,
    },
  },
}

Then run: GRAFANA_URL=http://localhost:3000 grr watch -l debug ./ ./grizzly.jsonnet and go to modify the dash.libsonnet. You will get the following:

➜  repro git:(main) ✗ GRAFANA_URL=http://localhost:3000 grr watch -l debug ./ ./grizzly.jsonnet
Providers: Grafana - active, Mimir - inactive (mimir address is not set), Synthetic Monitoring - inactive (stack id is not set)
INFO[0000] Watching for changes
INFO[0006] Changes detected. Parsing
INFO[0006] Changes detected. Applying dash.libsonnet
DEBU[0006] recursion ended on key "folderName" of type string which does not belong to a valid resource
ERRO[0006] Error: parse error in 'dash.libsonnet': found invalid object (at .): errors parsing resource: kind missing, metadata missing, spec missing

folderName: test
grafana:
    dashboards: {}
    datasources: {}
    folders: null
prometheus: []
syntheticMonitoringChecks: {}

This is identical error to what you get if you run GRAFANA_URL=http://localhost:3000 grr apply -l debug ./dash.libsonnet, so that's why I believe that the wrong path is being provided to apply to the remote.