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 <robertfratto@gmail.com>

* fix lint error

Signed-off-by: Robert Fratto <robertfratto@gmail.com>

* Update discovery/targetgroup/targetgroup.go

Co-authored-by: Julius Volz <julius.volz@gmail.com>
Signed-off-by: Robert Fratto <robertfratto@gmail.com>

* s/Json/JSON

Signed-off-by: Robert Fratto <robertfratto@gmail.com>

Co-authored-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Robert Fratto 2022-02-02 11:20:18 -05:00 committed by GitHub
parent 0cd4e0a8dd
commit 516579a97e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 1 deletions

View file

@ -91,3 +91,18 @@ func (tg *Group) UnmarshalJSON(b []byte) error {
tg.Labels = g.Labels tg.Labels = g.Labels
return nil 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)
}

View file

@ -22,7 +22,7 @@ import (
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
) )
func TestTargetGroupStrictJsonUnmarshal(t *testing.T) { func TestTargetGroupStrictJSONUnmarshal(t *testing.T) {
tests := []struct { tests := []struct {
json string json string
expectedReply error 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) { func TestTargetGroupYamlMarshal(t *testing.T) {
marshal := func(g interface{}) []byte { marshal := func(g interface{}) []byte {
d, err := yaml.Marshal(g) d, err := yaml.Marshal(g)