mirror of
https://github.com/prometheus-operator/prometheus-operator.git
synced 2025-04-16 09:16:38 +00:00
This test generates the same configuration many times, for each Prometheus version, to see if it is deterministic. As the compatibility matrix grows, test times increase. Now, this sometimes fails in CI because Travis kills jobs after 10 minutes of no output. Run each version as a subtest, and run tests with `-v`, so that output is produced after each version. This avoids the no-output timeout. Parallelize testing for each Prometheus version. When the tests are run with `-short` (as in `make test-unit`), only try one hundred iterations. With the race detector on, as in that target, this takes around 5 seconds. Without the race detector, short tests on this package now run quick enough for fast iteration in an IDE. Add an additional target and Travis job for running the long tests, but without the race detector. This brings the run time for the full 1000 iterations per version to under a minute. Signed-off-by: Matthias Rampke <matthias@rampke.de>
3444 lines
77 KiB
Go
3444 lines
77 KiB
Go
// Copyright 2017 The prometheus-operator Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package prometheus
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/go-openapi/swag"
|
|
"github.com/kylelemons/godebug/pretty"
|
|
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
|
|
"github.com/prometheus-operator/prometheus-operator/pkg/operator"
|
|
yaml "gopkg.in/yaml.v2"
|
|
v1 "k8s.io/api/core/v1"
|
|
"k8s.io/apimachinery/pkg/api/resource"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"k8s.io/apimachinery/pkg/util/intstr"
|
|
"k8s.io/utils/pointer"
|
|
)
|
|
|
|
func TestConfigGeneration(t *testing.T) {
|
|
for _, v := range operator.PrometheusCompatibilityMatrix {
|
|
t.Run(v, func(t *testing.T) {
|
|
t.Parallel()
|
|
cfg, err := generateTestConfig(v)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
reps := 1000
|
|
if testing.Short() {
|
|
reps = 100
|
|
}
|
|
|
|
for i := 0; i < reps; i++ {
|
|
testcfg, err := generateTestConfig(v)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if !bytes.Equal(cfg, testcfg) {
|
|
t.Fatalf("Config generation is not deterministic.\n\n\nFirst generation: \n\n%s\n\nDifferent generation: \n\n%s\n\n", string(cfg), string(testcfg))
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGlobalSettings(t *testing.T) {
|
|
type testCase struct {
|
|
EvaluationInterval string
|
|
ScrapeInterval string
|
|
ScrapeTimeout string
|
|
ExternalLabels map[string]string
|
|
QueryLogFile string
|
|
Version string
|
|
Expected string
|
|
}
|
|
|
|
testcases := []testCase{
|
|
{
|
|
Version: "v2.15.2",
|
|
Expected: `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: /
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`,
|
|
},
|
|
{
|
|
Version: "v2.15.2",
|
|
EvaluationInterval: "60s",
|
|
Expected: `global:
|
|
evaluation_interval: 60s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: /
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`,
|
|
},
|
|
{
|
|
Version: "v2.15.2",
|
|
ScrapeInterval: "60s",
|
|
Expected: `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 60s
|
|
external_labels:
|
|
prometheus: /
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`,
|
|
},
|
|
{
|
|
Version: "v2.15.2",
|
|
ScrapeTimeout: "30s",
|
|
Expected: `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: /
|
|
prometheus_replica: $(POD_NAME)
|
|
scrape_timeout: 30s
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`,
|
|
},
|
|
{
|
|
Version: "v2.15.2",
|
|
ExternalLabels: map[string]string{
|
|
"key1": "value1",
|
|
"key2": "value2",
|
|
},
|
|
Expected: `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
key1: value1
|
|
key2: value2
|
|
prometheus: /
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`,
|
|
},
|
|
{
|
|
Version: "v2.16.0",
|
|
QueryLogFile: "test.log",
|
|
Expected: `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: /
|
|
prometheus_replica: $(POD_NAME)
|
|
query_log_file: test.log
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
EvaluationInterval: tc.EvaluationInterval,
|
|
ScrapeInterval: tc.ScrapeInterval,
|
|
ScrapeTimeout: tc.ScrapeTimeout,
|
|
ExternalLabels: tc.ExternalLabels,
|
|
QueryLogFile: tc.QueryLogFile,
|
|
Version: tc.Version,
|
|
},
|
|
},
|
|
map[string]*monitoringv1.ServiceMonitor{},
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
result := string(cfg)
|
|
if tc.Expected != string(cfg) {
|
|
fmt.Println(pretty.Compare(tc.Expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNamespaceSetCorrectly(t *testing.T) {
|
|
type testCase struct {
|
|
ServiceMonitor *monitoringv1.ServiceMonitor
|
|
IgnoreNamespaceSelectors bool
|
|
Expected string
|
|
}
|
|
|
|
testcases := []testCase{
|
|
// Test that namespaces from 'MatchNames' are returned instead of the current namespace
|
|
{
|
|
ServiceMonitor: &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
NamespaceSelector: monitoringv1.NamespaceSelector{
|
|
MatchNames: []string{"test1", "test2"},
|
|
},
|
|
},
|
|
},
|
|
IgnoreNamespaceSelectors: false,
|
|
Expected: `kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- test1
|
|
- test2
|
|
`,
|
|
},
|
|
// Test that 'Any' returns an empty list instead of the current namespace
|
|
{
|
|
ServiceMonitor: &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor2",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
NamespaceSelector: monitoringv1.NamespaceSelector{
|
|
Any: true,
|
|
},
|
|
},
|
|
},
|
|
IgnoreNamespaceSelectors: false,
|
|
Expected: `kubernetes_sd_configs:
|
|
- role: endpoints
|
|
`,
|
|
},
|
|
// Test that Any takes precedence over MatchNames
|
|
{
|
|
ServiceMonitor: &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor2",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
NamespaceSelector: monitoringv1.NamespaceSelector{
|
|
Any: true,
|
|
MatchNames: []string{"foo", "bar"},
|
|
},
|
|
},
|
|
},
|
|
IgnoreNamespaceSelectors: false,
|
|
Expected: `kubernetes_sd_configs:
|
|
- role: endpoints
|
|
`,
|
|
},
|
|
// Test that IgnoreNamespaceSelectors overrides Any and MatchNames
|
|
{
|
|
ServiceMonitor: &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor2",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
NamespaceSelector: monitoringv1.NamespaceSelector{
|
|
Any: true,
|
|
MatchNames: []string{"foo", "bar"},
|
|
},
|
|
},
|
|
},
|
|
IgnoreNamespaceSelectors: true,
|
|
Expected: `kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
`,
|
|
},
|
|
}
|
|
cg := &configGenerator{}
|
|
|
|
for _, tc := range testcases {
|
|
selectedNamespaces := getNamespacesFromNamespaceSelector(&tc.ServiceMonitor.Spec.NamespaceSelector, tc.ServiceMonitor.Namespace, tc.IgnoreNamespaceSelectors)
|
|
c := cg.generateK8SSDConfig(selectedNamespaces, nil, nil, kubernetesSDRoleEndpoint)
|
|
s, err := yaml.Marshal(yaml.MapSlice{c})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if tc.Expected != string(s) {
|
|
t.Fatalf("Unexpected result.\n\nGot:\n\n%s\n\nExpected:\n\n%s\n\n", string(s), tc.Expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNamespaceSetCorrectlyForPodMonitor(t *testing.T) {
|
|
pm := &monitoringv1.PodMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testpodmonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.PodMonitorSpec{
|
|
NamespaceSelector: monitoringv1.NamespaceSelector{
|
|
MatchNames: []string{"test"},
|
|
},
|
|
},
|
|
}
|
|
|
|
cg := &configGenerator{}
|
|
selectedNamespaces := getNamespacesFromNamespaceSelector(&pm.Spec.NamespaceSelector, pm.Namespace, false)
|
|
c := cg.generateK8SSDConfig(selectedNamespaces, nil, nil, kubernetesSDRolePod)
|
|
s, err := yaml.Marshal(yaml.MapSlice{c})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `kubernetes_sd_configs:
|
|
- role: pod
|
|
namespaces:
|
|
names:
|
|
- test
|
|
`
|
|
|
|
result := string(s)
|
|
if expected != result {
|
|
t.Fatalf("Unexpected result.\n\nGot:\n\n%s\n\nExpected:\n\n%s\n\n", result, expected)
|
|
}
|
|
}
|
|
|
|
func TestProbeStaticTargetsConfigGeneration(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
ProbeSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]*monitoringv1.Probe{
|
|
"probe1": &monitoringv1.Probe{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testprobe1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ProbeSpec{
|
|
ProberSpec: monitoringv1.ProberSpec{
|
|
Scheme: "http",
|
|
URL: "blackbox.exporter.io",
|
|
Path: "/probe",
|
|
},
|
|
Module: "http_2xx",
|
|
Targets: monitoringv1.ProbeTargets{
|
|
StaticConfig: &monitoringv1.ProbeTargetStaticConfig{
|
|
Targets: []string{
|
|
"prometheus.io",
|
|
"promcon.io",
|
|
},
|
|
Labels: map[string]string{
|
|
"static": "label",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]BasicAuthCredentials{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testprobe1
|
|
honor_timestamps: true
|
|
metrics_path: /probe
|
|
scheme: http
|
|
params:
|
|
module:
|
|
- http_2xx
|
|
static_configs:
|
|
- targets:
|
|
- prometheus.io
|
|
- promcon.io
|
|
labels:
|
|
static: label
|
|
relabel_configs:
|
|
- source_labels:
|
|
- __address__
|
|
target_label: __param_target
|
|
- source_labels:
|
|
- __param_target
|
|
target_label: instance
|
|
- target_label: __address__
|
|
replacement: blackbox.exporter.io
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
if expected != result {
|
|
t.Fatalf("Unexpected result.\n\nGot:\n\n%s\n\nExpected:\n\n%s\n\n", result, expected)
|
|
}
|
|
}
|
|
|
|
func TestProbeStaticTargetsConfigGenerationWithLabelEnforce(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
EnforcedNamespaceLabel: "namespace",
|
|
ProbeSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]*monitoringv1.Probe{
|
|
"probe1": &monitoringv1.Probe{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testprobe1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ProbeSpec{
|
|
ProberSpec: monitoringv1.ProberSpec{
|
|
Scheme: "http",
|
|
URL: "blackbox.exporter.io",
|
|
Path: "/probe",
|
|
},
|
|
Module: "http_2xx",
|
|
Targets: monitoringv1.ProbeTargets{
|
|
StaticConfig: &monitoringv1.ProbeTargetStaticConfig{
|
|
Targets: []string{
|
|
"prometheus.io",
|
|
"promcon.io",
|
|
},
|
|
Labels: map[string]string{
|
|
"static": "label",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]BasicAuthCredentials{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testprobe1
|
|
honor_timestamps: true
|
|
metrics_path: /probe
|
|
scheme: http
|
|
params:
|
|
module:
|
|
- http_2xx
|
|
static_configs:
|
|
- targets:
|
|
- prometheus.io
|
|
- promcon.io
|
|
labels:
|
|
static: label
|
|
relabel_configs:
|
|
- source_labels:
|
|
- __address__
|
|
target_label: __param_target
|
|
- source_labels:
|
|
- __param_target
|
|
target_label: instance
|
|
- target_label: __address__
|
|
replacement: blackbox.exporter.io
|
|
- target_label: namespace
|
|
replacement: default
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
if expected != result {
|
|
t.Fatalf("Unexpected result.\n\nGot:\n\n%s\n\nExpected:\n\n%s\n\n", result, expected)
|
|
}
|
|
}
|
|
|
|
func TestProbeStaticTargetsConfigGenerationWithJobName(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
ProbeSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]*monitoringv1.Probe{
|
|
"probe1": &monitoringv1.Probe{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testprobe1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ProbeSpec{
|
|
JobName: "blackbox",
|
|
ProberSpec: monitoringv1.ProberSpec{
|
|
Scheme: "http",
|
|
URL: "blackbox.exporter.io",
|
|
Path: "/probe",
|
|
},
|
|
Module: "http_2xx",
|
|
Targets: monitoringv1.ProbeTargets{
|
|
StaticConfig: &monitoringv1.ProbeTargetStaticConfig{
|
|
Targets: []string{
|
|
"prometheus.io",
|
|
"promcon.io",
|
|
},
|
|
Labels: map[string]string{
|
|
"static": "label",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]BasicAuthCredentials{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: blackbox
|
|
honor_timestamps: true
|
|
metrics_path: /probe
|
|
scheme: http
|
|
params:
|
|
module:
|
|
- http_2xx
|
|
static_configs:
|
|
- targets:
|
|
- prometheus.io
|
|
- promcon.io
|
|
labels:
|
|
static: label
|
|
relabel_configs:
|
|
- source_labels:
|
|
- __address__
|
|
target_label: __param_target
|
|
- source_labels:
|
|
- __param_target
|
|
target_label: instance
|
|
- target_label: __address__
|
|
replacement: blackbox.exporter.io
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
if expected != result {
|
|
t.Fatalf("Unexpected result.\n\nGot:\n\n%s\n\nExpected:\n\n%s\n\n", result, expected)
|
|
}
|
|
}
|
|
|
|
func TestProbeIngressSDConfigGeneration(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
ProbeSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]*monitoringv1.Probe{
|
|
"probe1": &monitoringv1.Probe{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testprobe1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ProbeSpec{
|
|
ProberSpec: monitoringv1.ProberSpec{
|
|
Scheme: "http",
|
|
URL: "blackbox.exporter.io",
|
|
Path: "/probe",
|
|
},
|
|
Module: "http_2xx",
|
|
Targets: monitoringv1.ProbeTargets{
|
|
Ingress: &monitoringv1.ProbeTargetIngress{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"prometheus.io/probe": "true",
|
|
},
|
|
},
|
|
NamespaceSelector: monitoringv1.NamespaceSelector{
|
|
Any: true,
|
|
},
|
|
RelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
TargetLabel: "foo",
|
|
Replacement: "bar",
|
|
Action: "replace",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]BasicAuthCredentials{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testprobe1
|
|
honor_timestamps: true
|
|
metrics_path: /probe
|
|
scheme: http
|
|
params:
|
|
module:
|
|
- http_2xx
|
|
kubernetes_sd_configs:
|
|
- role: ingress
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_ingress_label_prometheus_io_probe
|
|
regex: "true"
|
|
- source_labels:
|
|
- __meta_kubernetes_ingress_scheme
|
|
- __address__
|
|
- __meta_kubernetes_ingress_path
|
|
separator: ;
|
|
regex: (.+);(.+);(.+)
|
|
target_label: __param_target
|
|
replacement: ${1}://${2}${3}
|
|
action: replace
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_ingress_name
|
|
target_label: ingress
|
|
- source_labels:
|
|
- __param_target
|
|
target_label: instance
|
|
- target_label: __address__
|
|
replacement: blackbox.exporter.io
|
|
- target_label: foo
|
|
replacement: bar
|
|
action: replace
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
if expected != result {
|
|
t.Fatalf("Unexpected result.\n\nGot:\n\n%s\n\nExpected:\n\n%s\n\n", result, expected)
|
|
}
|
|
}
|
|
|
|
func TestProbeIngressSDConfigGenerationWithLabelEnforce(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
EnforcedNamespaceLabel: "namespace",
|
|
ProbeSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]*monitoringv1.Probe{
|
|
"probe1": &monitoringv1.Probe{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testprobe1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ProbeSpec{
|
|
ProberSpec: monitoringv1.ProberSpec{
|
|
Scheme: "http",
|
|
URL: "blackbox.exporter.io",
|
|
Path: "/probe",
|
|
},
|
|
Module: "http_2xx",
|
|
Targets: monitoringv1.ProbeTargets{
|
|
Ingress: &monitoringv1.ProbeTargetIngress{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"prometheus.io/probe": "true",
|
|
},
|
|
},
|
|
NamespaceSelector: monitoringv1.NamespaceSelector{
|
|
Any: true,
|
|
},
|
|
RelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
TargetLabel: "foo",
|
|
Replacement: "bar",
|
|
Action: "replace",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]BasicAuthCredentials{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testprobe1
|
|
honor_timestamps: true
|
|
metrics_path: /probe
|
|
scheme: http
|
|
params:
|
|
module:
|
|
- http_2xx
|
|
kubernetes_sd_configs:
|
|
- role: ingress
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_ingress_label_prometheus_io_probe
|
|
regex: "true"
|
|
- source_labels:
|
|
- __meta_kubernetes_ingress_scheme
|
|
- __address__
|
|
- __meta_kubernetes_ingress_path
|
|
separator: ;
|
|
regex: (.+);(.+);(.+)
|
|
target_label: __param_target
|
|
replacement: ${1}://${2}${3}
|
|
action: replace
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_ingress_name
|
|
target_label: ingress
|
|
- source_labels:
|
|
- __param_target
|
|
target_label: instance
|
|
- target_label: __address__
|
|
replacement: blackbox.exporter.io
|
|
- target_label: foo
|
|
replacement: bar
|
|
action: replace
|
|
- target_label: namespace
|
|
replacement: default
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
if expected != result {
|
|
t.Fatalf("Unexpected result.\n\nGot:\n\n%s\n\nExpected:\n\n%s\n\n", result, expected)
|
|
}
|
|
}
|
|
|
|
func TestK8SSDConfigGeneration(t *testing.T) {
|
|
sm := &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
NamespaceSelector: monitoringv1.NamespaceSelector{
|
|
MatchNames: []string{"test"},
|
|
},
|
|
},
|
|
}
|
|
|
|
cg := &configGenerator{}
|
|
|
|
testcases := []struct {
|
|
apiserverConfig *monitoringv1.APIServerConfig
|
|
basicAuthSecrets map[string]BasicAuthCredentials
|
|
expected string
|
|
}{
|
|
{
|
|
nil,
|
|
nil,
|
|
`kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- test
|
|
`,
|
|
},
|
|
{
|
|
&monitoringv1.APIServerConfig{
|
|
Host: "example.com",
|
|
BasicAuth: &monitoringv1.BasicAuth{},
|
|
BearerToken: "bearer_token",
|
|
BearerTokenFile: "bearer_token_file",
|
|
TLSConfig: nil,
|
|
},
|
|
map[string]BasicAuthCredentials{
|
|
"apiserver": {
|
|
"foo",
|
|
"bar",
|
|
},
|
|
},
|
|
`kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- test
|
|
api_server: example.com
|
|
basic_auth:
|
|
username: foo
|
|
password: bar
|
|
bearer_token: bearer_token
|
|
bearer_token_file: bearer_token_file
|
|
`,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
c := cg.generateK8SSDConfig(
|
|
getNamespacesFromNamespaceSelector(&sm.Spec.NamespaceSelector, sm.Namespace, false),
|
|
tc.apiserverConfig,
|
|
tc.basicAuthSecrets,
|
|
kubernetesSDRoleEndpoint,
|
|
)
|
|
s, err := yaml.Marshal(yaml.MapSlice{c})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
result := string(s)
|
|
|
|
if result != tc.expected {
|
|
t.Fatalf("Unexpected result.\n\nGot:\n\n%s\n\nExpected:\n\n%s\n\n", result, tc.expected)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAlertmanagerBearerToken(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
Alerting: &monitoringv1.AlertingSpec{
|
|
Alertmanagers: []monitoringv1.AlertmanagerEndpoints{
|
|
{
|
|
Name: "alertmanager-main",
|
|
Namespace: "default",
|
|
Port: intstr.FromString("web"),
|
|
BearerTokenFile: "/some/file/on/disk",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// If this becomes an endless sink of maintenance, then we should just
|
|
// change this to check that just the `bearer_token_file` is set with
|
|
// something like json-path.
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers:
|
|
- path_prefix: /
|
|
scheme: http
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
bearer_token_file: /some/file/on/disk
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_service_name
|
|
regex: alertmanager-main
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestAlertmanagerAPIVersion(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
Version: "v2.11.0",
|
|
Alerting: &monitoringv1.AlertingSpec{
|
|
Alertmanagers: []monitoringv1.AlertmanagerEndpoints{
|
|
{
|
|
Name: "alertmanager-main",
|
|
Namespace: "default",
|
|
Port: intstr.FromString("web"),
|
|
APIVersion: "v2",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// If this becomes an endless sink of maintenance, then we should just
|
|
// change this to check that just the `api_version` is set with
|
|
// something like json-path.
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers:
|
|
- path_prefix: /
|
|
scheme: http
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
api_version: v2
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_service_name
|
|
regex: alertmanager-main
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestAlertmanagerTimeoutConfig(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
Version: "v2.11.0",
|
|
Alerting: &monitoringv1.AlertingSpec{
|
|
Alertmanagers: []monitoringv1.AlertmanagerEndpoints{
|
|
{
|
|
Name: "alertmanager-main",
|
|
Namespace: "default",
|
|
Port: intstr.FromString("web"),
|
|
APIVersion: "v2",
|
|
Timeout: pointer.StringPtr("60s"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// If this becomes an endless sink of maintenance, then we should just
|
|
// change this to check that just the `api_version` is set with
|
|
// something like json-path.
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers:
|
|
- path_prefix: /
|
|
scheme: http
|
|
timeout: 60s
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
api_version: v2
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_service_name
|
|
regex: alertmanager-main
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestAdditionalAlertRelabelConfigs(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
Alerting: &monitoringv1.AlertingSpec{
|
|
Alertmanagers: []monitoringv1.AlertmanagerEndpoints{
|
|
{
|
|
Name: "alertmanager-main",
|
|
Namespace: "default",
|
|
Port: intstr.FromString("web"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
[]byte(`- action: drop
|
|
source_labels: [__meta_kubernetes_node_name]
|
|
regex: spot-(.+)
|
|
|
|
`),
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
- action: drop
|
|
source_labels:
|
|
- __meta_kubernetes_node_name
|
|
regex: spot-(.+)
|
|
alertmanagers:
|
|
- path_prefix: /
|
|
scheme: http
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_service_name
|
|
regex: alertmanager-main
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestNoEnforcedNamespaceLabelServiceMonitor(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "ns-value",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{},
|
|
},
|
|
map[string]*monitoringv1.ServiceMonitor{
|
|
"test": &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
Port: "https-metrics",
|
|
HonorLabels: true,
|
|
Interval: "30s",
|
|
MetricRelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
Action: "drop",
|
|
Regex: "container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s)",
|
|
SourceLabels: []string{"__name__"},
|
|
},
|
|
},
|
|
RelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
Action: "replace",
|
|
Regex: "(.+)(?::d+)",
|
|
Replacement: "$1:9537",
|
|
SourceLabels: []string{"__address__"},
|
|
TargetLabel: "__address__",
|
|
},
|
|
{
|
|
Action: "replace",
|
|
Replacement: "crio",
|
|
TargetLabel: "job",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: ns-value/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/test/0
|
|
honor_labels: true
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_service_label_foo
|
|
regex: bar
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: https-metrics
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Node;(.*)
|
|
replacement: ${1}
|
|
target_label: node
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Pod;(.*)
|
|
replacement: ${1}
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: service
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: job
|
|
replacement: ${1}
|
|
- target_label: endpoint
|
|
replacement: https-metrics
|
|
- source_labels:
|
|
- __address__
|
|
target_label: __address__
|
|
regex: (.+)(?::d+)
|
|
replacement: $1:9537
|
|
action: replace
|
|
- target_label: job
|
|
replacement: crio
|
|
action: replace
|
|
metric_relabel_configs:
|
|
- source_labels:
|
|
- __name__
|
|
regex: container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s)
|
|
action: drop
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
func TestEnforcedNamespaceLabelPodMonitor(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "ns-value",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
EnforcedNamespaceLabel: "ns-key",
|
|
},
|
|
},
|
|
nil,
|
|
map[string]*monitoringv1.PodMonitor{
|
|
"testpodmonitor1": {
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testpodmonitor1",
|
|
Namespace: "pod-monitor-ns",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.PodMonitorSpec{
|
|
PodTargetLabels: []string{"example", "env"},
|
|
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
MetricRelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
Action: "drop",
|
|
Regex: "my-job-pod-.+",
|
|
SourceLabels: []string{"pod_name"},
|
|
TargetLabel: "my-ns",
|
|
},
|
|
},
|
|
RelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
Action: "replace",
|
|
Regex: "(.*)",
|
|
Replacement: "$1",
|
|
SourceLabels: []string{"__meta_kubernetes_pod_ready"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: ns-value/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: pod-monitor-ns/testpodmonitor1/0
|
|
honor_labels: false
|
|
kubernetes_sd_configs:
|
|
- role: pod
|
|
namespaces:
|
|
names:
|
|
- pod-monitor-ns
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_pod_container_port_name
|
|
regex: web
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_label_example
|
|
target_label: example
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_label_env
|
|
target_label: env
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- target_label: job
|
|
replacement: pod-monitor-ns/testpodmonitor1
|
|
- target_label: endpoint
|
|
replacement: web
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_ready
|
|
regex: (.*)
|
|
replacement: $1
|
|
action: replace
|
|
- target_label: ns-key
|
|
replacement: pod-monitor-ns
|
|
metric_relabel_configs:
|
|
- source_labels:
|
|
- pod_name
|
|
target_label: my-ns
|
|
regex: my-job-pod-.+
|
|
action: drop
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestEnforcedNamespaceLabelServiceMonitor(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "ns-value",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
EnforcedNamespaceLabel: "ns-key",
|
|
},
|
|
},
|
|
map[string]*monitoringv1.ServiceMonitor{
|
|
"test": &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
MetricRelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
Action: "drop",
|
|
Regex: "my-job-pod-.+",
|
|
SourceLabels: []string{"pod_name"},
|
|
TargetLabel: "ns-key",
|
|
},
|
|
},
|
|
RelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
Action: "replace",
|
|
Regex: "(.*)",
|
|
Replacement: "$1",
|
|
SourceLabels: []string{"__meta_kubernetes_pod_ready"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: ns-value/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/test/0
|
|
honor_labels: false
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_service_label_foo
|
|
regex: bar
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Node;(.*)
|
|
replacement: ${1}
|
|
target_label: node
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Pod;(.*)
|
|
replacement: ${1}
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: service
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: job
|
|
replacement: ${1}
|
|
- target_label: endpoint
|
|
replacement: web
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_ready
|
|
regex: (.*)
|
|
replacement: $1
|
|
action: replace
|
|
- target_label: ns-key
|
|
replacement: default
|
|
metric_relabel_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match for enforced namespace label test")
|
|
}
|
|
}
|
|
|
|
func TestAdditionalAlertmanagers(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
Alerting: &monitoringv1.AlertingSpec{
|
|
Alertmanagers: []monitoringv1.AlertmanagerEndpoints{
|
|
{
|
|
Name: "alertmanager-main",
|
|
Namespace: "default",
|
|
Port: intstr.FromString("web"),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
[]byte(`- static_configs:
|
|
- targets:
|
|
- localhost
|
|
`),
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs: []
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers:
|
|
- path_prefix: /
|
|
scheme: http
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_service_name
|
|
regex: alertmanager-main
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
- static_configs:
|
|
- targets:
|
|
- localhost
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestSettingHonorTimestampsInServiceMonitor(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
Version: "v2.9.0",
|
|
ServiceMonitorSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]*monitoringv1.ServiceMonitor{
|
|
"testservicemonitor1": &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
TargetLabels: []string{"example", "env"},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
HonorTimestamps: swag.Bool(false),
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testservicemonitor1/0
|
|
honor_labels: false
|
|
honor_timestamps: false
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Node;(.*)
|
|
replacement: ${1}
|
|
target_label: node
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Pod;(.*)
|
|
replacement: ${1}
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: service
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_service_label_example
|
|
target_label: example
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_label_env
|
|
target_label: env
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: job
|
|
replacement: ${1}
|
|
- target_label: endpoint
|
|
replacement: web
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestSettingHonorTimestampsInPodMonitor(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
Version: "v2.9.0",
|
|
ServiceMonitorSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
map[string]*monitoringv1.PodMonitor{
|
|
"testpodmonitor1": {
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testpodmonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.PodMonitorSpec{
|
|
PodTargetLabels: []string{"example", "env"},
|
|
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
|
|
{
|
|
HonorTimestamps: swag.Bool(false),
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testpodmonitor1/0
|
|
honor_labels: false
|
|
honor_timestamps: false
|
|
kubernetes_sd_configs:
|
|
- role: pod
|
|
namespaces:
|
|
names:
|
|
- default
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_pod_container_port_name
|
|
regex: web
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_label_example
|
|
target_label: example
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_label_env
|
|
target_label: env
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- target_label: job
|
|
replacement: default/testpodmonitor1
|
|
- target_label: endpoint
|
|
replacement: web
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestHonorTimestampsOverriding(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
Version: "v2.9.0",
|
|
OverrideHonorTimestamps: true,
|
|
ServiceMonitorSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]*monitoringv1.ServiceMonitor{
|
|
"testservicemonitor1": &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
TargetLabels: []string{"example", "env"},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
HonorTimestamps: swag.Bool(true),
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testservicemonitor1/0
|
|
honor_labels: false
|
|
honor_timestamps: false
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Node;(.*)
|
|
replacement: ${1}
|
|
target_label: node
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Pod;(.*)
|
|
replacement: ${1}
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: service
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_service_label_example
|
|
target_label: example
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_label_env
|
|
target_label: env
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: job
|
|
replacement: ${1}
|
|
- target_label: endpoint
|
|
replacement: web
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestSettingHonorLabels(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
ServiceMonitorSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]*monitoringv1.ServiceMonitor{
|
|
"testservicemonitor1": &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
TargetLabels: []string{"example", "env"},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
HonorLabels: true,
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testservicemonitor1/0
|
|
honor_labels: true
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Node;(.*)
|
|
replacement: ${1}
|
|
target_label: node
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Pod;(.*)
|
|
replacement: ${1}
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: service
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_service_label_example
|
|
target_label: example
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_label_env
|
|
target_label: env
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: job
|
|
replacement: ${1}
|
|
- target_label: endpoint
|
|
replacement: web
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
func TestHonorLabelsOverriding(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
OverrideHonorLabels: true,
|
|
ServiceMonitorSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]*monitoringv1.ServiceMonitor{
|
|
"testservicemonitor1": &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
TargetLabels: []string{"example", "env"},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
HonorLabels: true,
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testservicemonitor1/0
|
|
honor_labels: false
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Node;(.*)
|
|
replacement: ${1}
|
|
target_label: node
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Pod;(.*)
|
|
replacement: ${1}
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: service
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_service_label_example
|
|
target_label: example
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_label_env
|
|
target_label: env
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: job
|
|
replacement: ${1}
|
|
- target_label: endpoint
|
|
replacement: web
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
func TestTargetLabels(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
OverrideHonorLabels: false,
|
|
ServiceMonitorSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]*monitoringv1.ServiceMonitor{
|
|
"testservicemonitor1": &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
TargetLabels: []string{"example", "env"},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testservicemonitor1/0
|
|
honor_labels: false
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Node;(.*)
|
|
replacement: ${1}
|
|
target_label: node
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Pod;(.*)
|
|
replacement: ${1}
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: service
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_service_label_example
|
|
target_label: example
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_label_env
|
|
target_label: env
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: job
|
|
replacement: ${1}
|
|
- target_label: endpoint
|
|
replacement: web
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestPodTargetLabels(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
ServiceMonitorSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
map[string]*monitoringv1.ServiceMonitor{
|
|
"testservicemonitor1": &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
PodTargetLabels: []string{"example", "env"},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testservicemonitor1/0
|
|
honor_labels: false
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_endpoint_port_name
|
|
regex: web
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Node;(.*)
|
|
replacement: ${1}
|
|
target_label: node
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Pod;(.*)
|
|
replacement: ${1}
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: service
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_label_example
|
|
target_label: example
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_label_env
|
|
target_label: env
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: job
|
|
replacement: ${1}
|
|
- target_label: endpoint
|
|
replacement: web
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestPodTargetLabelsFromPodMonitor(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
ServiceMonitorSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
map[string]*monitoringv1.PodMonitor{
|
|
"testpodmonitor1": {
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testpodmonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.PodMonitorSpec{
|
|
PodTargetLabels: []string{"example", "env"},
|
|
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/testpodmonitor1/0
|
|
honor_labels: false
|
|
kubernetes_sd_configs:
|
|
- role: pod
|
|
namespaces:
|
|
names:
|
|
- default
|
|
scrape_interval: 30s
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_pod_container_port_name
|
|
regex: web
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_label_example
|
|
target_label: example
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_label_env
|
|
target_label: env
|
|
regex: (.+)
|
|
replacement: ${1}
|
|
- target_label: job
|
|
replacement: default/testpodmonitor1
|
|
- target_label: endpoint
|
|
replacement: web
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func TestEmptyEndointPorts(t *testing.T) {
|
|
cg := &configGenerator{}
|
|
cfg, err := cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
},
|
|
map[string]*monitoringv1.ServiceMonitor{
|
|
"test": &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"foo": "bar",
|
|
},
|
|
},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
// Add a single endpoint with empty configuration.
|
|
{},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
nil,
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// If this becomes an endless sink of maintenance, then we should just
|
|
// change this to check that just the `bearer_token_file` is set with
|
|
// something like json-path.
|
|
expected := `global:
|
|
evaluation_interval: 30s
|
|
scrape_interval: 30s
|
|
external_labels:
|
|
prometheus: default/test
|
|
prometheus_replica: $(POD_NAME)
|
|
rule_files: []
|
|
scrape_configs:
|
|
- job_name: default/test/0
|
|
honor_labels: false
|
|
kubernetes_sd_configs:
|
|
- role: endpoints
|
|
namespaces:
|
|
names:
|
|
- default
|
|
relabel_configs:
|
|
- action: keep
|
|
source_labels:
|
|
- __meta_kubernetes_service_label_foo
|
|
regex: bar
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Node;(.*)
|
|
replacement: ${1}
|
|
target_label: node
|
|
- source_labels:
|
|
- __meta_kubernetes_endpoint_address_target_kind
|
|
- __meta_kubernetes_endpoint_address_target_name
|
|
separator: ;
|
|
regex: Pod;(.*)
|
|
replacement: ${1}
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_namespace
|
|
target_label: namespace
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: service
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_name
|
|
target_label: pod
|
|
- source_labels:
|
|
- __meta_kubernetes_pod_container_name
|
|
target_label: container
|
|
- source_labels:
|
|
- __meta_kubernetes_service_name
|
|
target_label: job
|
|
replacement: ${1}
|
|
alerting:
|
|
alert_relabel_configs:
|
|
- action: labeldrop
|
|
regex: prometheus_replica
|
|
alertmanagers: []
|
|
`
|
|
|
|
result := string(cfg)
|
|
if expected != result {
|
|
fmt.Println(pretty.Compare(expected, result))
|
|
t.Fatal("expected Prometheus configuration and actual configuration do not match")
|
|
}
|
|
}
|
|
|
|
func generateTestConfig(version string) ([]byte, error) {
|
|
cg := &configGenerator{}
|
|
replicas := int32(1)
|
|
return cg.generateConfig(
|
|
&monitoringv1.Prometheus{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test",
|
|
Namespace: "default",
|
|
},
|
|
Spec: monitoringv1.PrometheusSpec{
|
|
Alerting: &monitoringv1.AlertingSpec{
|
|
Alertmanagers: []monitoringv1.AlertmanagerEndpoints{
|
|
{
|
|
Name: "alertmanager-main",
|
|
Namespace: "default",
|
|
Port: intstr.FromString("web"),
|
|
},
|
|
},
|
|
},
|
|
ExternalLabels: map[string]string{
|
|
"label1": "value1",
|
|
"label2": "value2",
|
|
},
|
|
Version: version,
|
|
Replicas: &replicas,
|
|
ServiceMonitorSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
PodMonitorSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
RuleSelector: &metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"role": "rulefile",
|
|
},
|
|
},
|
|
Resources: v1.ResourceRequirements{
|
|
Requests: v1.ResourceList{
|
|
v1.ResourceMemory: resource.MustParse("400Mi"),
|
|
},
|
|
},
|
|
RemoteRead: []monitoringv1.RemoteReadSpec{{
|
|
URL: "https://example.com/remote_read",
|
|
}},
|
|
RemoteWrite: []monitoringv1.RemoteWriteSpec{{
|
|
URL: "https://example.com/remote_write",
|
|
}},
|
|
},
|
|
},
|
|
makeServiceMonitors(),
|
|
makePodMonitors(),
|
|
nil,
|
|
map[string]BasicAuthCredentials{},
|
|
map[string]BearerToken{},
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
)
|
|
}
|
|
|
|
func makeServiceMonitors() map[string]*monitoringv1.ServiceMonitor {
|
|
res := map[string]*monitoringv1.ServiceMonitor{}
|
|
|
|
res["servicemonitor1"] = &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
res["servicemonitor2"] = &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor2",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group2",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group2",
|
|
"group3": "group3",
|
|
},
|
|
},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
res["servicemonitor3"] = &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor3",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group4",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group4",
|
|
"group3": "group5",
|
|
},
|
|
},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
Path: "/federate",
|
|
Params: map[string][]string{"metrics[]": {"{__name__=~\"job:.*\"}"}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
res["servicemonitor4"] = &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor4",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group6",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group6",
|
|
"group3": "group7",
|
|
},
|
|
},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
MetricRelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
Action: "drop",
|
|
Regex: "my-job-pod-.+",
|
|
SourceLabels: []string{"pod_name"},
|
|
},
|
|
{
|
|
Action: "drop",
|
|
Regex: "test",
|
|
SourceLabels: []string{"namespace"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
res["servicemonitor5"] = &monitoringv1.ServiceMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testservicemonitor4",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group8",
|
|
},
|
|
},
|
|
Spec: monitoringv1.ServiceMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group8",
|
|
"group3": "group9",
|
|
},
|
|
},
|
|
Endpoints: []monitoringv1.Endpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
RelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
Action: "replace",
|
|
Regex: "(.*)",
|
|
Replacement: "$1",
|
|
SourceLabels: []string{"__meta_kubernetes_pod_ready"},
|
|
TargetLabel: "pod_ready",
|
|
},
|
|
{
|
|
Action: "replace",
|
|
Regex: "(.*)",
|
|
Replacement: "$1",
|
|
SourceLabels: []string{"__meta_kubernetes_pod_node_name"},
|
|
TargetLabel: "nodename",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func makePodMonitors() map[string]*monitoringv1.PodMonitor {
|
|
res := map[string]*monitoringv1.PodMonitor{}
|
|
|
|
res["podmonitor1"] = &monitoringv1.PodMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testpodmonitor1",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
Spec: monitoringv1.PodMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group1",
|
|
},
|
|
},
|
|
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
res["podmonitor2"] = &monitoringv1.PodMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testpodmonitor2",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group2",
|
|
},
|
|
},
|
|
Spec: monitoringv1.PodMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group2",
|
|
"group3": "group3",
|
|
},
|
|
},
|
|
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
res["podmonitor3"] = &monitoringv1.PodMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testpodmonitor3",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group4",
|
|
},
|
|
},
|
|
Spec: monitoringv1.PodMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group4",
|
|
"group3": "group5",
|
|
},
|
|
},
|
|
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
Path: "/federate",
|
|
Params: map[string][]string{"metrics[]": {"{__name__=~\"job:.*\"}"}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
res["podmonitor4"] = &monitoringv1.PodMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testpodmonitor4",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group6",
|
|
},
|
|
},
|
|
Spec: monitoringv1.PodMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group6",
|
|
"group3": "group7",
|
|
},
|
|
},
|
|
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
MetricRelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
Action: "drop",
|
|
Regex: "my-job-pod-.+",
|
|
SourceLabels: []string{"pod_name"},
|
|
},
|
|
{
|
|
Action: "drop",
|
|
Regex: "test",
|
|
SourceLabels: []string{"namespace"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
res["podmonitor5"] = &monitoringv1.PodMonitor{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "testpodmonitor4",
|
|
Namespace: "default",
|
|
Labels: map[string]string{
|
|
"group": "group8",
|
|
},
|
|
},
|
|
Spec: monitoringv1.PodMonitorSpec{
|
|
Selector: metav1.LabelSelector{
|
|
MatchLabels: map[string]string{
|
|
"group": "group8",
|
|
"group3": "group9",
|
|
},
|
|
},
|
|
PodMetricsEndpoints: []monitoringv1.PodMetricsEndpoint{
|
|
{
|
|
Port: "web",
|
|
Interval: "30s",
|
|
RelabelConfigs: []*monitoringv1.RelabelConfig{
|
|
{
|
|
Action: "replace",
|
|
Regex: "(.*)",
|
|
Replacement: "$1",
|
|
SourceLabels: []string{"__meta_kubernetes_pod_ready"},
|
|
TargetLabel: "pod_ready",
|
|
},
|
|
{
|
|
Action: "replace",
|
|
Regex: "(.*)",
|
|
Replacement: "$1",
|
|
SourceLabels: []string{"__meta_kubernetes_pod_node_name"},
|
|
TargetLabel: "nodename",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
return res
|
|
}
|
|
|
|
func TestHonorLabels(t *testing.T) {
|
|
type testCase struct {
|
|
UserHonorLabels bool
|
|
OverrideHonorLabels bool
|
|
Expected bool
|
|
}
|
|
|
|
testCases := []testCase{
|
|
{
|
|
UserHonorLabels: false,
|
|
OverrideHonorLabels: true,
|
|
Expected: false,
|
|
},
|
|
{
|
|
UserHonorLabels: true,
|
|
OverrideHonorLabels: false,
|
|
Expected: true,
|
|
},
|
|
{
|
|
UserHonorLabels: true,
|
|
OverrideHonorLabels: true,
|
|
Expected: false,
|
|
},
|
|
{
|
|
UserHonorLabels: false,
|
|
OverrideHonorLabels: false,
|
|
Expected: false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
hl := honorLabels(tc.UserHonorLabels, tc.OverrideHonorLabels)
|
|
if tc.Expected != hl {
|
|
t.Fatalf("\nGot: %t, \nExpected: %t\nFor values UserHonorLabels %t, OverrideHonorLabels %t\n", hl, tc.Expected, tc.UserHonorLabels, tc.OverrideHonorLabels)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestHonorTimestamps(t *testing.T) {
|
|
type testCase struct {
|
|
UserHonorTimestamps *bool
|
|
OverrideHonorTimestamps bool
|
|
Expected string
|
|
}
|
|
|
|
testCases := []testCase{
|
|
{
|
|
UserHonorTimestamps: nil,
|
|
OverrideHonorTimestamps: true,
|
|
Expected: "honor_timestamps: false\n",
|
|
},
|
|
{
|
|
UserHonorTimestamps: nil,
|
|
OverrideHonorTimestamps: false,
|
|
Expected: "{}\n",
|
|
},
|
|
{
|
|
UserHonorTimestamps: swag.Bool(false),
|
|
OverrideHonorTimestamps: true,
|
|
Expected: "honor_timestamps: false\n",
|
|
},
|
|
{
|
|
UserHonorTimestamps: swag.Bool(false),
|
|
OverrideHonorTimestamps: false,
|
|
Expected: "honor_timestamps: false\n",
|
|
},
|
|
{
|
|
UserHonorTimestamps: swag.Bool(true),
|
|
OverrideHonorTimestamps: true,
|
|
Expected: "honor_timestamps: false\n",
|
|
},
|
|
{
|
|
UserHonorTimestamps: swag.Bool(true),
|
|
OverrideHonorTimestamps: false,
|
|
Expected: "honor_timestamps: true\n",
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
hl, _ := yaml.Marshal(honorTimestamps(yaml.MapSlice{}, tc.UserHonorTimestamps, tc.OverrideHonorTimestamps))
|
|
cfg := string(hl)
|
|
if tc.Expected != cfg {
|
|
t.Fatalf("\nGot: %s, \nExpected: %s\nFor values UserHonorTimestamps %+v, OverrideHonorTimestamps %t\n", cfg, tc.Expected, tc.UserHonorTimestamps, tc.OverrideHonorTimestamps)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetSampleLimit(t *testing.T) {
|
|
tcs := []struct {
|
|
Enforced uint64
|
|
Expected uint64
|
|
User uint64
|
|
}{
|
|
{
|
|
Enforced: 100,
|
|
User: 1000,
|
|
Expected: 100,
|
|
},
|
|
{
|
|
Enforced: 99,
|
|
User: 88,
|
|
Expected: 88,
|
|
},
|
|
{
|
|
Enforced: 0,
|
|
User: 888,
|
|
Expected: 888,
|
|
},
|
|
{
|
|
Enforced: 1,
|
|
User: 0,
|
|
Expected: 1,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tcs {
|
|
actual := getSampleLimit(tc.User, &tc.Enforced)
|
|
if actual != tc.Expected {
|
|
t.Fatalf("Got %d, Expected: %d, Enforced: %d, User: %d", actual, tc.Expected, tc.Enforced, tc.User)
|
|
}
|
|
}
|
|
|
|
}
|