mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-24 13:14:05 -08:00
Promtool: Validate service discovery files (#8950)
* Check SD files in promtool Signed-off-by: Levi Harrison <git@leviharrison.dev>
This commit is contained in:
parent
fd6c852567
commit
ca1896c15b
|
@ -18,6 +18,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"math"
|
"math"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -40,11 +41,13 @@ import (
|
||||||
"github.com/prometheus/common/version"
|
"github.com/prometheus/common/version"
|
||||||
"github.com/prometheus/exporter-toolkit/web"
|
"github.com/prometheus/exporter-toolkit/web"
|
||||||
"gopkg.in/alecthomas/kingpin.v2"
|
"gopkg.in/alecthomas/kingpin.v2"
|
||||||
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/config"
|
"github.com/prometheus/prometheus/config"
|
||||||
"github.com/prometheus/prometheus/discovery/file"
|
"github.com/prometheus/prometheus/discovery/file"
|
||||||
_ "github.com/prometheus/prometheus/discovery/install" // Register service discovery implementations.
|
_ "github.com/prometheus/prometheus/discovery/install" // Register service discovery implementations.
|
||||||
"github.com/prometheus/prometheus/discovery/kubernetes"
|
"github.com/prometheus/prometheus/discovery/kubernetes"
|
||||||
|
"github.com/prometheus/prometheus/discovery/targetgroup"
|
||||||
"github.com/prometheus/prometheus/pkg/rulefmt"
|
"github.com/prometheus/prometheus/pkg/rulefmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -337,8 +340,12 @@ func checkConfig(filename string) ([]string, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(files) != 0 {
|
if len(files) != 0 {
|
||||||
// There was at least one match for the glob and we can assume checkFileExists
|
for _, f := range files {
|
||||||
// for all matches would pass, we can continue the loop.
|
err = checkSDFile(f)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Errorf("checking SD file %q: %v", file, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
fmt.Printf(" WARNING: file %q for file_sd in scrape job %q does not exist\n", file, scfg.JobName)
|
fmt.Printf(" WARNING: file %q for file_sd in scrape job %q does not exist\n", file, scfg.JobName)
|
||||||
|
@ -368,6 +375,42 @@ func checkTLSConfig(tlsConfig config_util.TLSConfig) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkSDFile(filename string) error {
|
||||||
|
fd, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fd.Close()
|
||||||
|
|
||||||
|
content, err := ioutil.ReadAll(fd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var targetGroups []*targetgroup.Group
|
||||||
|
|
||||||
|
switch ext := filepath.Ext(filename); strings.ToLower(ext) {
|
||||||
|
case ".json":
|
||||||
|
if err := json.Unmarshal(content, &targetGroups); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
case ".yml", ".yaml":
|
||||||
|
if err := yaml.UnmarshalStrict(content, &targetGroups); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return errors.Errorf("invalid file extension: %q", ext)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, tg := range targetGroups {
|
||||||
|
if tg == nil {
|
||||||
|
return errors.Errorf("nil target group item found (index %d)", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// CheckRules validates rule files.
|
// CheckRules validates rule files.
|
||||||
func CheckRules(files ...string) int {
|
func CheckRules(files ...string) int {
|
||||||
failed := false
|
failed := false
|
||||||
|
|
|
@ -77,3 +77,44 @@ func mockServer(code int, body string) (*httptest.Server, func() *http.Request)
|
||||||
}
|
}
|
||||||
return server, f
|
return server, f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCheckSDFile(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
name string
|
||||||
|
file string
|
||||||
|
err string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "good .yml",
|
||||||
|
file: "./testdata/good-sd-file.yml",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "good .yaml",
|
||||||
|
file: "./testdata/good-sd-file.yaml",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "good .json",
|
||||||
|
file: "./testdata/good-sd-file.json",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bad file extension",
|
||||||
|
file: "./testdata/bad-sd-file-extension.nonexistant",
|
||||||
|
err: "invalid file extension: \".nonexistant\"",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bad format",
|
||||||
|
file: "./testdata/bad-sd-file-format.yml",
|
||||||
|
err: "yaml: unmarshal errors:\n line 1: field targats not found in type struct { Targets []string \"yaml:\\\"targets\\\"\"; Labels model.LabelSet \"yaml:\\\"labels\\\"\" }",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, test := range cases {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
err := checkSDFile(test.file)
|
||||||
|
if test.err != "" {
|
||||||
|
require.Equalf(t, test.err, err.Error(), "Expected error %q, got %q", test.err, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
require.NoError(t, err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
0
cmd/promtool/testdata/bad-sd-file-extension.nonexistant
vendored
Normal file
0
cmd/promtool/testdata/bad-sd-file-extension.nonexistant
vendored
Normal file
2
cmd/promtool/testdata/bad-sd-file-format.yml
vendored
Normal file
2
cmd/promtool/testdata/bad-sd-file-format.yml
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
- targats:
|
||||||
|
- localhost:9100
|
8
cmd/promtool/testdata/good-sd-file.json
vendored
Normal file
8
cmd/promtool/testdata/good-sd-file.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"labels": {
|
||||||
|
"job": "node"
|
||||||
|
},
|
||||||
|
"targets": ["localhost:9100"]
|
||||||
|
}
|
||||||
|
]
|
4
cmd/promtool/testdata/good-sd-file.yaml
vendored
Normal file
4
cmd/promtool/testdata/good-sd-file.yaml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
- labels:
|
||||||
|
job: node
|
||||||
|
- targets:
|
||||||
|
- localhost:9100
|
4
cmd/promtool/testdata/good-sd-file.yml
vendored
Normal file
4
cmd/promtool/testdata/good-sd-file.yml
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
- labels:
|
||||||
|
job: node
|
||||||
|
- targets:
|
||||||
|
- localhost:9100
|
Loading…
Reference in a new issue