Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Harvest should add grafana import rewrite svm filtering for multi-tenant support #2092

Merged
merged 1 commit into from
May 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions cmd/tools/grafana/grafana.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type options struct {
labels []string
dirGrafanaFolderMap map[string]*Folder
addMultiSelect bool
svmRegex string
}

type Folder struct {
Expand Down Expand Up @@ -182,6 +183,28 @@ func exportFiles(dir string, folder *Folder) error {
return nil
}

func addSvmRegex(content []byte, fileName string, val string) []byte {
var err error
newContent := content
var svmExpression []string
if fileName == "snapmirror.json" {
svmExpression = []string{"templating.list.#(name=\"DestinationSVM\")", "templating.list.#(name=\"SourceSVM\")"}
} else {
svmExpression = []string{"templating.list.#(name=\"SVM\")"}
}
for _, s := range svmExpression {
svm := gjson.GetBytes(content, s)
if svm.Exists() {
newContent, err = sjson.SetBytes(newContent, s+".regex", []byte(val))
if err != nil {
fmt.Printf("error while setting svm regex")
continue
}
}
}
return newContent
}

func addLabel(content []byte, label string, labelMap map[string]string) []byte {
// extract the list of variables
templateList := gjson.GetBytes(content, "templating.list")
Expand Down Expand Up @@ -469,6 +492,11 @@ func importFiles(dir string, folder *Folder) {
}
}

// add svm regex
if opts.svmRegex != "" {
data = addSvmRegex(data, file.Name(), opts.svmRegex)
}

// labelMap is used to ensure we don't modify the query of one of the new labels we're adding
labelMap := make(map[string]string)
caser := cases.Title(language.Und)
Expand Down Expand Up @@ -1015,6 +1043,7 @@ func addFlags(commands ...*cobra.Command) {
cmd.PersistentFlags().StringVar(&opts.config, "config", "./harvest.yml", "harvest config file path")
cmd.PersistentFlags().StringVarP(&opts.addr, "addr", "a", "http://127.0.0.1:3000", "Address of Grafana server (IP, FQDN or hostname)")
cmd.PersistentFlags().StringVarP(&opts.token, "token", "t", "", "API token issued by Grafana server for authentication")
cmd.PersistentFlags().StringVar(&opts.svmRegex, "svm-variable-regex", "", "SVM variable regex to filter SVM query results")
cmd.PersistentFlags().StringVarP(&opts.prefix, "prefix", "p", "", "Use global metric prefix in queries")
cmd.PersistentFlags().StringVarP(&opts.datasource, "datasource", "s", grafanaDataSource, "Grafana datasource for the dashboards")
cmd.PersistentFlags().BoolVarP(&opts.variable, "variable", "v", false, "Use datasource as variable, overrides: --datasource")
Expand All @@ -1023,6 +1052,7 @@ func addFlags(commands ...*cobra.Command) {
cmd.PersistentFlags().BoolVarP(&opts.useInsecureTLS, "insecure", "k", false, "Allow insecure server connections when using SSL")
cmd.PersistentFlags().StringVarP(&opts.serverfolder.name, "serverfolder", "f", "", "Grafana folder name for dashboards")
cmd.PersistentFlags().StringVarP(&opts.dir, "directory", "d", "", "When importing, import dashboards from this local directory.\nWhen exporting, local directory to write dashboards to")
_ = cmd.PersistentFlags().MarkHidden("svm-variable-regex")
_ = cmd.MarkPersistentFlagRequired("serverfolder")
_ = cmd.MarkPersistentFlagRequired("directory")
}
Expand Down
27 changes: 27 additions & 0 deletions cmd/tools/grafana/grafana_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"github.com/tidwall/gjson"
"path/filepath"
"regexp"
"strings"
"testing"
Expand Down Expand Up @@ -102,6 +103,32 @@ func TestAddPrefixToMetricNames(t *testing.T) {
})
}

func TestAddSvmRegex(t *testing.T) {

regex := ".*ABC.*"
visitDashboards(
[]string{"../../../grafana/dashboards/cmode/svm.json", "../../../grafana/dashboards/cmode/snapmirror.json"},
func(path string, data []byte) {
file := filepath.Base(path)
out := addSvmRegex(data, file, regex)
if file == "svm.json" {
r := gjson.GetBytes(out, "templating.list.#(name=\"SVM\").regex")
if r.String() != regex {
t.Errorf("path: %s \nExpected: [%s]\n Got: [%s]", path, regex, r.String())
}
} else if file == "snapmirror.json" {
r := gjson.GetBytes(out, "templating.list.#(name=\"DestinationSVM\").regex")
if r.String() != regex {
t.Errorf("path: %s \nExpected: [%s]\n Got: [%s]", path, regex, r.String())
}
r = gjson.GetBytes(out, "templating.list.#(name=\"SourceSVM\").regex")
if r.String() != regex {
t.Errorf("path: %s \nExpected: [%s]\n Got: [%s]", path, regex, r.String())
}
}
})
}

func getExp(expr string, expressions *[]string) {
regex := regexp.MustCompile(`([a-zA-Z0-9_+-]+)\s?{.+?}`)
match := regex.FindAllStringSubmatch(expr, -1)
Expand Down