1
0
Fork 0
mirror of https://github.com/prometheus-operator/prometheus-operator.git synced 2025-04-16 09:16:38 +00:00
prometheus-operator/pkg/prometheus/promcfg_test.go

3356 lines
75 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"
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"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"github.com/prometheus-operator/prometheus-operator/pkg/operator"
"github.com/kylelemons/godebug/pretty"
)
func TestConfigGeneration(t *testing.T) {
for _, v := range operator.PrometheusCompatibilityMatrix {
cfg, err := generateTestConfig(v)
if err != nil {
t.Fatal(err)
}
for i := 0; i < 1000; 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 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)
}
}
}