Skip to content

Commit

Permalink
Make Grizzly support multiple providers/endpoints (grafana#44)
Browse files Browse the repository at this point in the history
* Major rewrite to add 'provider' support

* Remove redundant code

* Add Grafana synthetic-monitoring support

* Updated testing data

* Add preview, separate add/update

* Add providers cmd, s/board/source/

* Fix error handling on not found

* Handle data source updates

* Remove unnecessary field

* Add prepare/unprepare, switch to probe names from ids

* Switch test data to probe names

* Providers provide Handlers for Resource Types

* Use Resource not MSI

* Remove Plugins, no HTTP API

* Dashboard folders

* Remove folderName and add docs

* Set defaults on datasources to quieten diffs

* Switch to interface{}

* Move APIErr to grizzly pkg

* Fix diff on apply

* (re-)fix dashboard folders

* Remove extraneous file

* De-java the code

* handle errors

* s/dashboard/something else/

* fix lint, simplify

* Split handlers into two files
  • Loading branch information
malcolmholmes authored Oct 12, 2020
1 parent f338173 commit cfe8301
Show file tree
Hide file tree
Showing 24 changed files with 1,747 additions and 738 deletions.
34 changes: 26 additions & 8 deletions cmd/grr/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"log"

"github.com/go-clix/cli"
"github.com/grafana/grizzly/pkg/grafana"
"github.com/grafana/grizzly/pkg/grizzly"
)

// Version is the current version of the grr command.
Expand All @@ -19,20 +21,36 @@ func main() {
Version: Version,
}

registry, err := GetProviderRegistry()
if err != nil {
log.Fatalln(err)
}

config := grizzly.Config{
Registry: registry,
}
// workflow commands
rootCmd.AddCommand(
getCmd(),
listCmd(),
showCmd(),
diffCmd(),
applyCmd(),
watchCmd(),
exportCmd(),
previewCmd(),
getCmd(config),
listCmd(config),
showCmd(config),
diffCmd(config),
applyCmd(config),
watchCmd(config),
exportCmd(config),
previewCmd(config),
providersCmd(config),
)

// Run!
if err := rootCmd.Execute(); err != nil {
log.Fatalln(err)
}
}

// GetProviderRegistry registers all known providers
func GetProviderRegistry() (grizzly.Registry, error) {
registry := grizzly.NewProviderRegistry()
registry.RegisterProvider(&grafana.Provider{})
return registry, nil
}
85 changes: 41 additions & 44 deletions cmd/grr/workflow.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
package main

import (
"fmt"
"os"
"text/tabwriter"

"github.com/go-clix/cli"
"github.com/grafana/grizzly/pkg/grizzly"
)

func getCmd() *cli.Command {
func getCmd(config grizzly.Config) *cli.Command {
cmd := &cli.Command{
Use: "get <dashboard-uid>",
Short: "retrieve dashboard json",
Args: cli.ArgsExact(1),
}
cmd.Run = func(cmd *cli.Command, args []string) error {
uid := args[0]
config, err := grizzly.ParseEnvironment()
if err != nil {
return err
}
return grizzly.Get(*config, uid)
return grizzly.Get(config, uid)
}
return cmd
}

func listCmd() *cli.Command {
func listCmd(config grizzly.Config) *cli.Command {
cmd := &cli.Command{
Use: "list <jsonnet-file>",
Short: "list dashboard keys from file",
Expand All @@ -31,12 +31,12 @@ func listCmd() *cli.Command {
cmd.Run = func(cmd *cli.Command, args []string) error {
jsonnetFile := args[0]

return grizzly.List(jsonnetFile)
return grizzly.List(config, jsonnetFile)
}
return cmd
}

func showCmd() *cli.Command {
func showCmd(config grizzly.Config) *cli.Command {
cmd := &cli.Command{
Use: "show <jsonnet-file>",
Short: "render Jsonnet dashboard as json",
Expand All @@ -45,16 +45,12 @@ func showCmd() *cli.Command {
targets := cmd.Flags().StringSliceP("target", "t", nil, "dashboards to target")
cmd.Run = func(cmd *cli.Command, args []string) error {
jsonnetFile := args[0]
config, err := grizzly.ParseEnvironment()
if err != nil {
return err
}
return grizzly.Show(*config, jsonnetFile, *targets)
return grizzly.Show(config, jsonnetFile, *targets)
}
return cmd
}

func diffCmd() *cli.Command {
func diffCmd(config grizzly.Config) *cli.Command {
cmd := &cli.Command{
Use: "diff <jsonnet-file>",
Short: "compare Jsonnet with dashboard(s) in Grafana",
Expand All @@ -63,16 +59,12 @@ func diffCmd() *cli.Command {
targets := cmd.Flags().StringSliceP("target", "t", nil, "dashboards to target")
cmd.Run = func(cmd *cli.Command, args []string) error {
jsonnetFile := args[0]
config, err := grizzly.ParseEnvironment()
if err != nil {
return err
}
return grizzly.Diff(*config, jsonnetFile, *targets)
return grizzly.Diff(config, jsonnetFile, *targets)
}
return cmd
}

func applyCmd() *cli.Command {
func applyCmd(config grizzly.Config) *cli.Command {
cmd := &cli.Command{
Use: "apply <jsonnet-file>",
Short: "render Jsonnet and push dashboard(s) to Grafana",
Expand All @@ -81,16 +73,12 @@ func applyCmd() *cli.Command {
targets := cmd.Flags().StringSliceP("target", "t", nil, "dashboards to target")
cmd.Run = func(cmd *cli.Command, args []string) error {
jsonnetFile := args[0]
config, err := grizzly.ParseEnvironment()
if err != nil {
return err
}
return grizzly.Apply(*config, jsonnetFile, *targets)
return grizzly.Apply(config, jsonnetFile, *targets)
}
return cmd
}

func watchCmd() *cli.Command {
func watchCmd(config grizzly.Config) *cli.Command {
cmd := &cli.Command{
Use: "watch <dir-to-watch> <jsonnet-file>",
Short: "watch for file changes and apply",
Expand All @@ -100,18 +88,13 @@ func watchCmd() *cli.Command {
cmd.Run = func(cmd *cli.Command, args []string) error {
watchDir := args[0]
jsonnetFile := args[1]
config, err := grizzly.ParseEnvironment()
if err != nil {
return err
}

return grizzly.Watch(*config, watchDir, jsonnetFile, *targets)
return grizzly.Watch(config, watchDir, jsonnetFile, *targets)

}
return cmd
}

func previewCmd() *cli.Command {
func previewCmd(config grizzly.Config) *cli.Command {
cmd := &cli.Command{
Use: "preview <jsonnet-file>",
Short: "upload a snapshot to preview the rendered file",
Expand All @@ -129,16 +112,12 @@ func previewCmd() *cli.Command {
ExpiresSeconds: e,
}

config, err := grizzly.ParseEnvironment()
if err != nil {
return err
}
return grizzly.Preview(*config, jsonnetFile, *targets, opts)
return grizzly.Preview(config, jsonnetFile, *targets, opts)
}
return cmd
}

func exportCmd() *cli.Command {
func exportCmd(config grizzly.Config) *cli.Command {
cmd := &cli.Command{
Use: "export <jsonnet-file> <dashboard-dir>",
Short: "render Jsonnet and save to a directory",
Expand All @@ -148,11 +127,29 @@ func exportCmd() *cli.Command {
cmd.Run = func(cmd *cli.Command, args []string) error {
jsonnetFile := args[0]
dashboardDir := args[1]
config, err := grizzly.ParseEnvironment()
if err != nil {
return err
return grizzly.Export(config, jsonnetFile, dashboardDir, *targets)
}
return cmd
}

func providersCmd(config grizzly.Config) *cli.Command {
cmd := &cli.Command{
Use: "providers",
Short: "Lists all providers registered with Grizzly",
Args: cli.ArgsExact(0),
}
cmd.Run = func(cmd *cli.Command, args []string) error {
f := "%s\t%s\t%s\n"
w := tabwriter.NewWriter(os.Stdout, 0, 0, 4, ' ', 0)

fmt.Fprintf(w, f, "PROVIDER", "HANDLER", "JSON PATH")
for _, provider := range config.Registry.Providers {
for _, handler := range provider.GetHandlers() {
path := handler.GetJSONPath()
fmt.Fprintf(w, f, provider.GetName(), handler.GetName(), "/"+path)
}
}
return grizzly.Export(*config, jsonnetFile, dashboardDir, *targets)
return w.Flush()
}
return cmd
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ require (
github.com/google/go-jsonnet v0.15.1-0.20200331184325-4f4aa80dd785
github.com/kr/pretty v0.2.0
github.com/kylelemons/godebug v1.1.0
github.com/malcolmholmes/grizzly v0.0.1
github.com/mitchellh/mapstructure v1.3.3
github.com/prometheus/prometheus v1.8.2-0.20200622142935-153f859b7499
github.com/rivo/tview v0.0.0-20200818120338-53d50e499bf9
golang.org/x/crypto v0.0.0-20200422194213-44a606286825
gopkg.in/fsnotify.v1 v1.4.7
Expand Down
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,9 @@ github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjG
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-version v1.0.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
Expand Down Expand Up @@ -606,6 +608,8 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mailru/easyjson v0.7.1/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/malcolmholmes/grizzly v0.0.1 h1:MW+Vf9TPS8ElPsNKp5Y91jwEPz/Jm61heeC4IVzHNtk=
github.com/malcolmholmes/grizzly v0.0.1/go.mod h1:NUqvP1ze/DS9oMiKlC/LpD8b8l5ghPYM+3ENbL+jPaw=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
Expand Down Expand Up @@ -656,10 +660,13 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/gox v1.0.1/go.mod h1:ED6BioOGXMswlXa2zxfh/xdd5QhwYliBFn9V18Ap4z4=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
Expand Down Expand Up @@ -1316,6 +1323,7 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200603094226-e3079894b1e8 h1:jL/vaozO53FMfZLySWM+4nulF3gQEC6q5jH90LPomDo=
gopkg.in/yaml.v3 v3.0.0-20200603094226-e3079894b1e8/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
28 changes: 28 additions & 0 deletions pkg/grafana/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package grafana

import (
"fmt"
"net/url"
"os"
"path"
)

func getGrafanaURL(urlPath string) (string, error) {
if grafanaURL, exists := os.LookupEnv("GRAFANA_URL"); exists {
u, err := url.Parse(grafanaURL)
if err != nil {
return "", err
}
u.Path = path.Join(u.Path, urlPath)
grafanaURL = u.String()
if token, exists := os.LookupEnv("GRAFANA_TOKEN"); exists {
user, exists := os.LookupEnv("GRAFANA_USER")
if !exists {
user = "api_key"
}
u.User = url.UserPassword(user, token)
}
return u.String(), nil
}
return "", fmt.Errorf("Require GRAFANA_URL (optionally GRAFANA_TOKEN & GRAFANA_USER")
}
19 changes: 12 additions & 7 deletions pkg/grizzly/config_test.go → pkg/grafana/config_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package grizzly
package grafana

import (
"os"
Expand All @@ -8,37 +8,42 @@ import (
func TestParseEnvironment(t *testing.T) {
tests := map[string]struct {
url string
path string
user string
token string
expect string
err bool
}{
"GRAFANA_URL only": {
"https://my.grafana.net",
"/this",
"",
"",
"https://my.grafana.net",
"https://my.grafana.net/this",
false,
},
"w/ token": {
"https://my.grafana.net",
"/that",
"",
"token",
"https://api_key:[email protected]",
"https://api_key:[email protected]/that",
false,
},
"Basic auth": {
"https://my.grafana.net",
"/secure",
"user",
"pass",
"https://user:[email protected]",
"https://user:[email protected]/secure",
false,
},
"GRAFANA_URL blank": {
"",
"",
"",
"",
"",
true,
},
}
Expand All @@ -59,12 +64,12 @@ func TestParseEnvironment(t *testing.T) {
os.Unsetenv("GRAFANA_TOKEN")
}
t.Logf("Running test case, %q...", testName)
cfg, err := ParseEnvironment()
url, err := getGrafanaURL(test.path)
if err != nil && !test.err {
t.Errorf("Unexpected error getting Jsonnet files: %s", err)
}
if cfg != nil && cfg.GrafanaURL != test.expect {
t.Errorf("Expected GrafanaURL %s, got: %s", test.expect, cfg.GrafanaURL)
if url != test.expect {
t.Errorf("Expected GrafanaURL %s, got: %s", test.expect, url)
}
}
}
Loading

0 comments on commit cfe8301

Please sign in to comment.