mirror of
https://github.com/prometheus/prometheus.git
synced 2024-12-23 12:44:05 -08:00
Expose TargetsFromGroup/AlertmanagerFromGroup func and reuse this for (#9343)
static/file sd config check in promtool Signed-off-by: DrAuYueng <ouyang1204@gmail.com>
This commit is contained in:
parent
8207b132fd
commit
69e309d202
|
@ -44,13 +44,16 @@ import (
|
|||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/prometheus/prometheus/config"
|
||||
"github.com/prometheus/prometheus/discovery"
|
||||
"github.com/prometheus/prometheus/discovery/file"
|
||||
_ "github.com/prometheus/prometheus/discovery/install" // Register service discovery implementations.
|
||||
"github.com/prometheus/prometheus/discovery/kubernetes"
|
||||
"github.com/prometheus/prometheus/discovery/targetgroup"
|
||||
"github.com/prometheus/prometheus/notifier"
|
||||
"github.com/prometheus/prometheus/pkg/labels"
|
||||
"github.com/prometheus/prometheus/pkg/rulefmt"
|
||||
"github.com/prometheus/prometheus/promql"
|
||||
"github.com/prometheus/prometheus/scrape"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
@ -363,19 +366,60 @@ func checkConfig(filename string) ([]string, error) {
|
|||
}
|
||||
if len(files) != 0 {
|
||||
for _, f := range files {
|
||||
err = checkSDFile(f)
|
||||
var targetGroups []*targetgroup.Group
|
||||
targetGroups, err = checkSDFile(f)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("checking SD file %q: %v", file, err)
|
||||
}
|
||||
if err := checkTargetGroupsForScrapeConfig(targetGroups, scfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
fmt.Printf(" WARNING: file %q for file_sd in scrape job %q does not exist\n", file, scfg.JobName)
|
||||
}
|
||||
case discovery.StaticConfig:
|
||||
if err := checkTargetGroupsForScrapeConfig(c, scfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alertConfig := cfg.AlertingConfig
|
||||
for _, amcfg := range alertConfig.AlertmanagerConfigs {
|
||||
for _, c := range amcfg.ServiceDiscoveryConfigs {
|
||||
switch c := c.(type) {
|
||||
case *file.SDConfig:
|
||||
for _, file := range c.Files {
|
||||
files, err := filepath.Glob(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(files) != 0 {
|
||||
for _, f := range files {
|
||||
var targetGroups []*targetgroup.Group
|
||||
targetGroups, err = checkSDFile(f)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("checking SD file %q: %v", file, err)
|
||||
}
|
||||
|
||||
if err := checkTargetGroupsForAlertmanager(targetGroups, amcfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
fmt.Printf(" WARNING: file %q for file_sd in alertmanager config does not exist\n", file)
|
||||
}
|
||||
case discovery.StaticConfig:
|
||||
if err := checkTargetGroupsForAlertmanager(c, amcfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ruleFiles, nil
|
||||
}
|
||||
|
||||
|
@ -397,16 +441,16 @@ func checkTLSConfig(tlsConfig config_util.TLSConfig) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func checkSDFile(filename string) error {
|
||||
func checkSDFile(filename string) ([]*targetgroup.Group, error) {
|
||||
fd, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
content, err := ioutil.ReadAll(fd)
|
||||
if err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var targetGroups []*targetgroup.Group
|
||||
|
@ -414,23 +458,23 @@ func checkSDFile(filename string) error {
|
|||
switch ext := filepath.Ext(filename); strings.ToLower(ext) {
|
||||
case ".json":
|
||||
if err := json.Unmarshal(content, &targetGroups); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
case ".yml", ".yaml":
|
||||
if err := yaml.UnmarshalStrict(content, &targetGroups); err != nil {
|
||||
return err
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
return errors.Errorf("invalid file extension: %q", ext)
|
||||
return nil, 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, errors.Errorf("nil target group item found (index %d)", i)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return targetGroups, nil
|
||||
}
|
||||
|
||||
// CheckRules validates rule files.
|
||||
|
@ -981,3 +1025,25 @@ func importRules(url *url.URL, start, end, outputDir string, evalInterval time.D
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkTargetGroupsForAlertmanager(targetGroups []*targetgroup.Group, amcfg *config.AlertmanagerConfig) error {
|
||||
for _, tg := range targetGroups {
|
||||
if _, _, err := notifier.AlertmanagerFromGroup(tg, amcfg); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkTargetGroupsForScrapeConfig(targetGroups []*targetgroup.Group, scfg *config.ScrapeConfig) error {
|
||||
for _, tg := range targetGroups {
|
||||
_, failures := scrape.TargetsFromGroup(tg, scfg)
|
||||
if len(failures) > 0 {
|
||||
first := failures[0]
|
||||
return first
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ func TestCheckSDFile(t *testing.T) {
|
|||
}
|
||||
for _, test := range cases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := checkSDFile(test.file)
|
||||
_, err := checkSDFile(test.file)
|
||||
if test.err != "" {
|
||||
require.Equalf(t, test.err, err.Error(), "Expected error %q, got %q", test.err, err.Error())
|
||||
return
|
||||
|
@ -163,3 +163,42 @@ func BenchmarkCheckDuplicates(b *testing.B) {
|
|||
checkDuplicates(rgs.Groups)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckTargetConfig(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
file string
|
||||
err string
|
||||
}{
|
||||
{
|
||||
name: "url_in_scrape_targetgroup_with_relabel_config.good",
|
||||
file: "url_in_scrape_targetgroup_with_relabel_config.good.yml",
|
||||
err: "",
|
||||
},
|
||||
{
|
||||
name: "url_in_alert_targetgroup_with_relabel_config.good",
|
||||
file: "url_in_alert_targetgroup_with_relabel_config.good.yml",
|
||||
err: "",
|
||||
},
|
||||
{
|
||||
name: "url_in_scrape_targetgroup_with_relabel_config.bad",
|
||||
file: "url_in_scrape_targetgroup_with_relabel_config.bad.yml",
|
||||
err: "instance 0 in group 0: \"http://bad\" is not a valid hostname",
|
||||
},
|
||||
{
|
||||
name: "url_in_alert_targetgroup_with_relabel_config.bad",
|
||||
file: "url_in_alert_targetgroup_with_relabel_config.bad.yml",
|
||||
err: "\"http://bad\" is not a valid hostname",
|
||||
},
|
||||
}
|
||||
for _, test := range cases {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
_, err := checkConfig("testdata/" + 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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
8
cmd/promtool/testdata/url_in_alert_targetgroup_with_relabel_config.bad.yml
vendored
Normal file
8
cmd/promtool/testdata/url_in_alert_targetgroup_with_relabel_config.bad.yml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
alerting:
|
||||
alertmanagers:
|
||||
- relabel_configs:
|
||||
- source_labels: [__address__]
|
||||
target_label: __param_target
|
||||
static_configs:
|
||||
- targets:
|
||||
- http://bad
|
10
cmd/promtool/testdata/url_in_alert_targetgroup_with_relabel_config.good.yml
vendored
Normal file
10
cmd/promtool/testdata/url_in_alert_targetgroup_with_relabel_config.good.yml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
alerting:
|
||||
alertmanagers:
|
||||
- relabel_configs:
|
||||
- source_labels: [__address__]
|
||||
target_label: __param_target
|
||||
- target_label: __address__
|
||||
replacement: good
|
||||
static_configs:
|
||||
- targets:
|
||||
- http://bad
|
8
cmd/promtool/testdata/url_in_scrape_targetgroup_with_relabel_config.bad.yml
vendored
Normal file
8
cmd/promtool/testdata/url_in_scrape_targetgroup_with_relabel_config.bad.yml
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
relabel_configs:
|
||||
- source_labels: [__address__]
|
||||
target_label: __param_target
|
||||
static_configs:
|
||||
- targets:
|
||||
- http://bad
|
10
cmd/promtool/testdata/url_in_scrape_targetgroup_with_relabel_config.good.yml
vendored
Normal file
10
cmd/promtool/testdata/url_in_scrape_targetgroup_with_relabel_config.good.yml
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
scrape_configs:
|
||||
- job_name: prometheus
|
||||
relabel_configs:
|
||||
- source_labels: [__address__]
|
||||
target_label: __param_target
|
||||
- target_label: __address__
|
||||
replacement: good
|
||||
static_configs:
|
||||
- targets:
|
||||
- http://good
|
|
@ -602,7 +602,7 @@ func (n *Manager) Stop() {
|
|||
n.cancel()
|
||||
}
|
||||
|
||||
// alertmanager holds Alertmanager endpoint information.
|
||||
// Alertmanager holds Alertmanager endpoint information.
|
||||
type alertmanager interface {
|
||||
url() *url.URL
|
||||
}
|
||||
|
@ -654,7 +654,7 @@ func (s *alertmanagerSet) sync(tgs []*targetgroup.Group) {
|
|||
allDroppedAms := []alertmanager{}
|
||||
|
||||
for _, tg := range tgs {
|
||||
ams, droppedAms, err := alertmanagerFromGroup(tg, s.cfg)
|
||||
ams, droppedAms, err := AlertmanagerFromGroup(tg, s.cfg)
|
||||
if err != nil {
|
||||
level.Error(s.logger).Log("msg", "Creating discovered Alertmanagers failed", "err", err)
|
||||
continue
|
||||
|
@ -691,9 +691,9 @@ func postPath(pre string, v config.AlertmanagerAPIVersion) string {
|
|||
return path.Join("/", pre, alertPushEndpoint)
|
||||
}
|
||||
|
||||
// alertmanagerFromGroup extracts a list of alertmanagers from a target group
|
||||
// AlertmanagerFromGroup extracts a list of alertmanagers from a target group
|
||||
// and an associated AlertmanagerConfig.
|
||||
func alertmanagerFromGroup(tg *targetgroup.Group, cfg *config.AlertmanagerConfig) ([]alertmanager, []alertmanager, error) {
|
||||
func AlertmanagerFromGroup(tg *targetgroup.Group, cfg *config.AlertmanagerConfig) ([]alertmanager, []alertmanager, error) {
|
||||
var res []alertmanager
|
||||
var droppedAlertManagers []alertmanager
|
||||
|
||||
|
|
|
@ -447,7 +447,7 @@ func (a alertmanagerMock) url() *url.URL {
|
|||
|
||||
func TestLabelSetNotReused(t *testing.T) {
|
||||
tg := makeInputTargetGroup()
|
||||
_, _, err := alertmanagerFromGroup(tg, &config.AlertmanagerConfig{})
|
||||
_, _, err := AlertmanagerFromGroup(tg, &config.AlertmanagerConfig{})
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
|
@ -472,7 +472,7 @@ func (sp *scrapePool) Sync(tgs []*targetgroup.Group) {
|
|||
var all []*Target
|
||||
sp.droppedTargets = []*Target{}
|
||||
for _, tg := range tgs {
|
||||
targets, failures := targetsFromGroup(tg, sp.config)
|
||||
targets, failures := TargetsFromGroup(tg, sp.config)
|
||||
for _, err := range failures {
|
||||
level.Error(sp.logger).Log("msg", "Creating target failed", "err", err)
|
||||
}
|
||||
|
|
|
@ -469,8 +469,8 @@ func populateLabels(lset labels.Labels, cfg *config.ScrapeConfig) (res, orig lab
|
|||
return res, preRelabelLabels, nil
|
||||
}
|
||||
|
||||
// targetsFromGroup builds targets based on the given TargetGroup and config.
|
||||
func targetsFromGroup(tg *targetgroup.Group, cfg *config.ScrapeConfig) ([]*Target, []error) {
|
||||
// TargetsFromGroup builds targets based on the given TargetGroup and config.
|
||||
func TargetsFromGroup(tg *targetgroup.Group, cfg *config.ScrapeConfig) ([]*Target, []error) {
|
||||
targets := make([]*Target, 0, len(tg.Targets))
|
||||
failures := []error{}
|
||||
|
||||
|
|
|
@ -371,7 +371,7 @@ func TestNewClientWithBadTLSConfig(t *testing.T) {
|
|||
func TestTargetsFromGroup(t *testing.T) {
|
||||
expectedError := "instance 0 in group : no address"
|
||||
|
||||
targets, failures := targetsFromGroup(&targetgroup.Group{Targets: []model.LabelSet{{}, {model.AddressLabel: "localhost:9090"}}}, &config.ScrapeConfig{})
|
||||
targets, failures := TargetsFromGroup(&targetgroup.Group{Targets: []model.LabelSet{{}, {model.AddressLabel: "localhost:9090"}}}, &config.ScrapeConfig{})
|
||||
if len(targets) != 1 {
|
||||
t.Fatalf("Expected 1 target, got %v", len(targets))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue