From 516579a97eb8f97e8c6743ad871dee1c3a8e7353 Mon Sep 17 00:00:00 2001 From: Robert Fratto Date: Wed, 2 Feb 2022 11:20:18 -0500 Subject: [PATCH] discovery/targetgroup: support marshaling to JSON (#10229) * discovery/targetgroup: support marshaling to JSON targetgroup.Group is able to be marshaled to and from YAML, but not with JSON. JSON is used for the http_sd API representation, so users implementing the API were required to implement their own type which is expected by the JSON unmarshaler. Signed-off-by: Robert Fratto * fix lint error Signed-off-by: Robert Fratto * Update discovery/targetgroup/targetgroup.go Co-authored-by: Julius Volz Signed-off-by: Robert Fratto * s/Json/JSON Signed-off-by: Robert Fratto Co-authored-by: Julius Volz --- discovery/targetgroup/targetgroup.go | 15 ++++++++++ discovery/targetgroup/targetgroup_test.go | 35 ++++++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/discovery/targetgroup/targetgroup.go b/discovery/targetgroup/targetgroup.go index d1dfc7393..e74870f04 100644 --- a/discovery/targetgroup/targetgroup.go +++ b/discovery/targetgroup/targetgroup.go @@ -91,3 +91,18 @@ func (tg *Group) UnmarshalJSON(b []byte) error { tg.Labels = g.Labels return nil } + +// MarshalJSON implements the json.Marshaler interface. +func (tg Group) MarshalJSON() ([]byte, error) { + g := &struct { + Targets []string `json:"targets"` + Labels model.LabelSet `json:"labels,omitempty"` + }{ + Targets: make([]string, 0, len(tg.Targets)), + Labels: tg.Labels, + } + for _, t := range tg.Targets { + g.Targets = append(g.Targets, string(t[model.AddressLabel])) + } + return json.Marshal(g) +} diff --git a/discovery/targetgroup/targetgroup_test.go b/discovery/targetgroup/targetgroup_test.go index fe9587eb8..3843d3156 100644 --- a/discovery/targetgroup/targetgroup_test.go +++ b/discovery/targetgroup/targetgroup_test.go @@ -22,7 +22,7 @@ import ( "gopkg.in/yaml.v2" ) -func TestTargetGroupStrictJsonUnmarshal(t *testing.T) { +func TestTargetGroupStrictJSONUnmarshal(t *testing.T) { tests := []struct { json string expectedReply error @@ -59,6 +59,39 @@ func TestTargetGroupStrictJsonUnmarshal(t *testing.T) { } } +func TestTargetGroupJSONMarshal(t *testing.T) { + tests := []struct { + expectedJSON string + expectedErr error + group Group + }{ + { + // labels should be omitted if empty. + group: Group{}, + expectedJSON: `{"targets": []}`, + expectedErr: nil, + }, + { + // targets only exposes addresses. + group: Group{ + Targets: []model.LabelSet{ + {"__address__": "localhost:9090"}, + {"__address__": "localhost:9091"}, + }, + Labels: model.LabelSet{"foo": "bar", "bar": "baz"}, + }, + expectedJSON: `{"targets": ["localhost:9090", "localhost:9091"], "labels": {"bar": "baz", "foo": "bar"}}`, + expectedErr: nil, + }, + } + + for _, test := range tests { + actual, err := test.group.MarshalJSON() + require.Equal(t, test.expectedErr, err) + require.JSONEq(t, test.expectedJSON, string(actual)) + } +} + func TestTargetGroupYamlMarshal(t *testing.T) { marshal := func(g interface{}) []byte { d, err := yaml.Marshal(g)