diff --git a/documentation/examples/custom-sd/adapter/adapter.go b/documentation/examples/custom-sd/adapter/adapter.go index 95bf09163..39cfea289 100644 --- a/documentation/examples/custom-sd/adapter/adapter.go +++ b/documentation/examples/custom-sd/adapter/adapter.go @@ -18,15 +18,14 @@ import ( "context" "encoding/json" "fmt" - "io/ioutil" - "os" - "path/filepath" - "reflect" - "github.com/go-kit/kit/log" "github.com/go-kit/kit/log/level" "github.com/prometheus/prometheus/discovery" "github.com/prometheus/prometheus/discovery/targetgroup" + "io/ioutil" + "os" + "path/filepath" + "reflect" ) type customSD struct { @@ -54,10 +53,8 @@ func mapToArray(m map[string]*customSD) []customSD { return arr } -// Parses incoming target groups updates. If the update contains changes to the target groups -// Adapter already knows about, or new target groups, we Marshal to JSON and write to file. -func (a *Adapter) generateTargetGroups(allTargetGroups map[string][]*targetgroup.Group) { - tempGroups := make(map[string]*customSD) +func generateTargetGroups(allTargetGroups map[string][]*targetgroup.Group) map[string]*customSD { + groups := make(map[string]*customSD) for k, sdTargetGroups := range allTargetGroups { for i, group := range sdTargetGroups { @@ -80,12 +77,21 @@ func (a *Adapter) generateTargetGroups(allTargetGroups map[string][]*targetgroup } // Make a unique key, including the current index, in case the sd_type (map key) and group.Source is not unique. key := fmt.Sprintf("%s:%s:%d", k, group.Source, i) - tempGroups[key] = &customSD{ + groups[key] = &customSD{ Targets: newTargets, Labels: newLabels, } } } + + return groups +} + +// Parses incoming target groups updates. If the update contains changes to the target groups +// Adapter already knows about, or new target groups, we Marshal to JSON and write to file. +func (a *Adapter) refreshTargetGroups(allTargetGroups map[string][]*targetgroup.Group) { + tempGroups := generateTargetGroups(allTargetGroups) + if !reflect.DeepEqual(a.groups, tempGroups) { a.groups = tempGroups err := a.writeOutput() @@ -93,7 +99,6 @@ func (a *Adapter) generateTargetGroups(allTargetGroups map[string][]*targetgroup level.Error(log.With(a.logger, "component", "sd-adapter")).Log("err", err) } } - } // Writes JSON formatted targets to output file. @@ -131,7 +136,7 @@ func (a *Adapter) runCustomSD(ctx context.Context) { if !ok { return } - a.generateTargetGroups(allTargetGroups) + a.refreshTargetGroups(allTargetGroups) } } } diff --git a/documentation/examples/custom-sd/adapter/adapter_test.go b/documentation/examples/custom-sd/adapter/adapter_test.go new file mode 100644 index 000000000..291f2e082 --- /dev/null +++ b/documentation/examples/custom-sd/adapter/adapter_test.go @@ -0,0 +1,151 @@ +// Copyright 2018 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package adapter + +import ( + "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/discovery/targetgroup" + "reflect" + "testing" +) + +// TestGenerateTargetGroups checks that the target is correctly generated. +// It covers the case when the target is empty +func TestGenerateTargetGroups(t *testing.T) { + testCases := []struct { + title string + targetGroup map[string][]*targetgroup.Group + expectedCustomSD map[string]*customSD + }{ + { + title: "Empty targetGroup", + targetGroup: map[string][]*targetgroup.Group{ + "customSD": { + { + Source: "Consul", + }, + { + Source: "Kubernetes", + }, + }, + }, + expectedCustomSD: map[string]*customSD{}, + }, + { + title: "targetGroup filled", + targetGroup: map[string][]*targetgroup.Group{ + "customSD": { + { + Source: "Azure", + Targets: []model.LabelSet{ + { + model.AddressLabel: "host1", + }, + { + model.AddressLabel: "host2", + }, + }, + Labels: model.LabelSet{ + model.LabelName("__meta_test_label"): model.LabelValue("label_test_1"), + }, + }, + { + Source: "Openshift", + Targets: []model.LabelSet{ + { + model.AddressLabel: "host3", + }, + { + model.AddressLabel: "host4", + }, + }, + Labels: model.LabelSet{ + model.LabelName("__meta_test_label"): model.LabelValue("label_test_2"), + }, + }, + }, + }, + expectedCustomSD: map[string]*customSD{ + "customSD:Azure:0": { + Targets: []string{ + "host1", + "host2", + }, + Labels: map[string]string{ + "__meta_test_label": "label_test_1", + }, + }, + "customSD:Openshift:1": { + Targets: []string{ + "host3", + "host4", + }, + Labels: map[string]string{ + "__meta_test_label": "label_test_2", + }, + }, + }, + }, + { + title: "Mixed between empty targetGroup and targetGroup filled", + targetGroup: map[string][]*targetgroup.Group{ + "customSD": { + { + Source: "GCE", + Targets: []model.LabelSet{ + { + model.AddressLabel: "host1", + }, + { + model.AddressLabel: "host2", + }, + }, + Labels: model.LabelSet{ + model.LabelName("__meta_test_label"): model.LabelValue("label_test_1"), + }, + }, + { + Source: "Kubernetes", + Labels: model.LabelSet{ + model.LabelName("__meta_test_label"): model.LabelValue("label_test_2"), + }, + }, + }, + }, + expectedCustomSD: map[string]*customSD{ + "customSD:GCE:0": { + Targets: []string{ + "host1", + "host2", + }, + Labels: map[string]string{ + "__meta_test_label": "label_test_1", + }, + }, + }, + }, + } + + for _, testCase := range testCases { + result := generateTargetGroups(testCase.targetGroup) + + if !reflect.DeepEqual(result, testCase.expectedCustomSD) { + t.Errorf("%v :\nresult produced %v\nmismatch the expected customSD: %v", + testCase.title, + result, + testCase.expectedCustomSD) + } + + } +}