Merge pull request #778 from prometheus/fabxc/lname-re

config: ensure correct labelname in JSON target group.
This commit is contained in:
Fabian Reinartz 2015-06-08 11:59:25 +02:00
commit ea8099a1d2
5 changed files with 60 additions and 0 deletions

View file

@ -14,6 +14,7 @@
package model
import (
"encoding/json"
"fmt"
"regexp"
"strings"
@ -81,6 +82,19 @@ func (ln *LabelName) UnmarshalYAML(unmarshal func(interface{}) error) error {
return nil
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (ln *LabelName) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
if !LabelNameRE.MatchString(s) {
return fmt.Errorf("%q is not a valid label name", s)
}
*ln = LabelName(s)
return nil
}
// LabelNames is a sortable LabelName slice. In implements sort.Interface.
type LabelNames []LabelName

View file

@ -14,6 +14,7 @@
package model
import (
"encoding/json"
"fmt"
"sort"
"strings"
@ -62,3 +63,21 @@ func (l LabelSet) MergeFromMetric(m Metric) {
l[k] = v
}
}
// UnmarshalJSON implements the json.Unmarshaler interface.
func (l *LabelSet) UnmarshalJSON(b []byte) error {
var m map[LabelName]LabelValue
if err := json.Unmarshal(b, &m); err != nil {
return err
}
// encoding/json only unmarshals maps of the form map[string]T. It does not
// detect that LabelName is a string and does not call its UnmarshalJSON method.
// Thus we have to replicate the behavior here.
for ln := range m {
if !LabelNameRE.MatchString(string(ln)) {
return fmt.Errorf("%q is not a valid label name", ln)
}
}
*l = LabelSet(m)
return nil
}

View file

@ -1,6 +1,8 @@
package config
import (
"encoding/json"
"io/ioutil"
"reflect"
"regexp"
"strings"
@ -149,6 +151,9 @@ var expectedErrors = []struct {
}, {
filename: "labelname.bad.yml",
errMsg: `"not$allowed" is not a valid label name`,
}, {
filename: "labelname2.bad.yml",
errMsg: `"not:allowed" is not a valid label name`,
}, {
filename: "regex.bad.yml",
errMsg: "error parsing regexp",
@ -170,3 +175,15 @@ func TestBadConfigs(t *testing.T) {
}
}
}
func TestBadTargetGroup(t *testing.T) {
content, err := ioutil.ReadFile("testdata/tgroup.bad.json")
if err != nil {
t.Fatal(err)
}
var tg TargetGroup
err = json.Unmarshal(content, &tg)
if err == nil {
t.Errorf("Expected unmarshal error but got none.")
}
}

3
config/testdata/labelname2.bad.yml vendored Normal file
View file

@ -0,0 +1,3 @@
global:
labels:
'not:allowed': value

7
config/testdata/tgroup.bad.json vendored Normal file
View file

@ -0,0 +1,7 @@
{
"targets": ["1.2.3.4:9100"],
"labels": {
"some_valid_label": "foo",
"oops:this-label-is-invalid": "bar"
}
}