Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
aos
GitHub Repository: aos/grafana-agent
Path: blob/main/pkg/operator/config/metrics_templates_test.go
4095 views
1
package config
2
3
import (
4
"fmt"
5
"os"
6
"strings"
7
"testing"
8
9
jsonnet "github.com/google/go-jsonnet"
10
gragent "github.com/grafana/agent/pkg/operator/apis/monitoring/v1alpha1"
11
"github.com/grafana/agent/pkg/operator/assets"
12
"github.com/grafana/agent/pkg/util"
13
prom_v1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
14
"github.com/stretchr/testify/assert"
15
"github.com/stretchr/testify/require"
16
v1 "k8s.io/api/core/v1"
17
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
18
"k8s.io/utils/pointer"
19
)
20
21
func TestExternalLabels(t *testing.T) {
22
tt := []struct {
23
name string
24
input interface{}
25
addReplica bool
26
expect string
27
}{
28
{
29
name: "no replica",
30
addReplica: false,
31
input: gragent.Deployment{
32
Agent: &gragent.GrafanaAgent{
33
ObjectMeta: meta_v1.ObjectMeta{
34
Namespace: "operator",
35
Name: "agent",
36
},
37
},
38
},
39
expect: util.Untab(`
40
cluster: operator/agent
41
`),
42
},
43
{
44
name: "defaults",
45
addReplica: true,
46
input: gragent.Deployment{
47
Agent: &gragent.GrafanaAgent{
48
ObjectMeta: meta_v1.ObjectMeta{
49
Namespace: "operator",
50
Name: "agent",
51
},
52
},
53
},
54
expect: util.Untab(`
55
cluster: operator/agent
56
__replica__: replica-$(STATEFULSET_ORDINAL_NUMBER)
57
`),
58
},
59
{
60
name: "external_labels",
61
addReplica: true,
62
input: gragent.Deployment{
63
Agent: &gragent.GrafanaAgent{
64
ObjectMeta: meta_v1.ObjectMeta{
65
Namespace: "operator",
66
Name: "agent",
67
},
68
Spec: gragent.GrafanaAgentSpec{
69
Metrics: gragent.MetricsSubsystemSpec{
70
ExternalLabels: map[string]string{"foo": "bar"},
71
},
72
},
73
},
74
},
75
expect: util.Untab(`
76
cluster: operator/agent
77
foo: bar
78
__replica__: replica-$(STATEFULSET_ORDINAL_NUMBER)
79
`),
80
},
81
{
82
name: "custom labels",
83
addReplica: true,
84
input: gragent.Deployment{
85
Agent: &gragent.GrafanaAgent{
86
ObjectMeta: meta_v1.ObjectMeta{
87
Namespace: "operator",
88
Name: "agent",
89
},
90
Spec: gragent.GrafanaAgentSpec{
91
Metrics: gragent.MetricsSubsystemSpec{
92
MetricsExternalLabelName: pointer.String("deployment"),
93
ReplicaExternalLabelName: pointer.String("replica"),
94
ExternalLabels: map[string]string{"foo": "bar"},
95
},
96
},
97
},
98
},
99
expect: util.Untab(`
100
deployment: operator/agent
101
foo: bar
102
replica: replica-$(STATEFULSET_ORDINAL_NUMBER)
103
`),
104
},
105
}
106
107
for _, tc := range tt {
108
t.Run(tc.name, func(t *testing.T) {
109
vm, err := createVM(nil)
110
require.NoError(t, err)
111
bb, err := jsonnetMarshal(tc.input)
112
require.NoError(t, err)
113
114
vm.TLACode("ctx", string(bb))
115
vm.TLACode("addReplica", fmt.Sprintf("%v", tc.addReplica))
116
actual, err := runSnippet(vm, "./component/metrics/external_labels.libsonnet", "ctx", "addReplica")
117
require.NoError(t, err)
118
require.YAMLEq(t, tc.expect, actual)
119
})
120
}
121
}
122
123
func TestKubeSDConfig(t *testing.T) {
124
tt := []struct {
125
name string
126
input map[string]interface{}
127
expect string
128
}{
129
{
130
name: "defaults",
131
input: map[string]interface{}{
132
"namespace": "operator",
133
"role": "pod",
134
},
135
expect: util.Untab(`
136
role: pod
137
`),
138
},
139
{
140
name: "defaults",
141
input: map[string]interface{}{
142
"namespace": "operator",
143
"namespaces": []string{"operator"},
144
"role": "pod",
145
},
146
expect: util.Untab(`
147
role: pod
148
namespaces:
149
names: [operator]
150
`),
151
},
152
{
153
name: "host",
154
input: map[string]interface{}{
155
"namespace": "operator",
156
"apiServer": &prom_v1.APIServerConfig{Host: "host"},
157
"role": "pod",
158
},
159
expect: util.Untab(`
160
role: pod
161
api_server: host
162
`),
163
},
164
{
165
name: "basic auth",
166
input: map[string]interface{}{
167
"namespace": "operator",
168
"apiServer": &prom_v1.APIServerConfig{
169
BasicAuth: &prom_v1.BasicAuth{
170
Username: v1.SecretKeySelector{
171
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
172
Key: "key",
173
},
174
Password: v1.SecretKeySelector{
175
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
176
Key: "key",
177
},
178
},
179
},
180
"role": "pod",
181
},
182
expect: util.Untab(`
183
role: pod
184
basic_auth:
185
username: secretkey
186
password: secretkey
187
`),
188
},
189
{
190
name: "bearer auth",
191
input: map[string]interface{}{
192
"namespace": "operator",
193
"apiServer": &prom_v1.APIServerConfig{
194
BearerToken: "bearer",
195
BearerTokenFile: "file",
196
},
197
"role": "pod",
198
},
199
expect: util.Untab(`
200
role: pod
201
authorization:
202
type: Bearer
203
credentials: bearer
204
credentials_file: file
205
`),
206
},
207
{
208
name: "tls_config",
209
input: map[string]interface{}{
210
"namespace": "operator",
211
"apiServer": &prom_v1.APIServerConfig{
212
TLSConfig: &prom_v1.TLSConfig{
213
CAFile: "ca",
214
},
215
},
216
"role": "pod",
217
},
218
expect: util.Untab(`
219
role: pod
220
tls_config:
221
ca_file: ca
222
`),
223
},
224
}
225
226
for _, tc := range tt {
227
t.Run(tc.name, func(t *testing.T) {
228
vm, err := createVM(testStore())
229
require.NoError(t, err)
230
231
args := []string{"namespace", "namespaces", "apiServer", "role"}
232
for _, arg := range args {
233
bb, err := jsonnetMarshal(tc.input[arg])
234
require.NoError(t, err)
235
vm.TLACode(arg, string(bb))
236
}
237
238
actual, err := runSnippet(vm, "./component/metrics/kube_sd_config.libsonnet", args...)
239
require.NoError(t, err)
240
require.YAMLEq(t, tc.expect, actual)
241
})
242
}
243
}
244
245
func TestPodMonitor(t *testing.T) {
246
var falseVal = false
247
var trueVal = true
248
tt := []struct {
249
name string
250
input map[string]interface{}
251
expect string
252
}{
253
{
254
name: "default",
255
input: map[string]interface{}{
256
"agentNamespace": "operator",
257
"monitor": prom_v1.PodMonitor{
258
ObjectMeta: meta_v1.ObjectMeta{
259
Namespace: "operator",
260
Name: "podmonitor",
261
},
262
},
263
"endpoint": prom_v1.PodMetricsEndpoint{
264
Port: "metrics",
265
EnableHttp2: &falseVal,
266
FilterRunning: &trueVal,
267
},
268
"index": 0,
269
"apiServer": prom_v1.APIServerConfig{},
270
"overrideHonorLabels": false,
271
"overrideHonorTimestamps": false,
272
"ignoreNamespaceSelectors": false,
273
"enforcedNamespaceLabel": "",
274
"enforcedSampleLimit": nil,
275
"enforcedTargetLimit": nil,
276
"shards": 1,
277
},
278
expect: util.Untab(`
279
job_name: podMonitor/operator/podmonitor/0
280
enable_http2: false
281
honor_labels: false
282
kubernetes_sd_configs:
283
- role: pod
284
namespaces:
285
names: [operator]
286
relabel_configs:
287
- source_labels: [job]
288
target_label: __tmp_prometheus_job_name
289
- source_labels: [__meta_kubernetes_pod_phase]
290
regex: (Failed|Succeeded)
291
action: drop
292
- source_labels: [__meta_kubernetes_pod_container_port_name]
293
regex: metrics
294
action: keep
295
- source_labels: [__meta_kubernetes_namespace]
296
target_label: namespace
297
- source_labels: [__meta_kubernetes_service_name]
298
target_label: service
299
- source_labels: [__meta_kubernetes_pod_name]
300
target_label: pod
301
- source_labels: [__meta_kubernetes_pod_container_name]
302
target_label: container
303
- target_label: job
304
replacement: operator/podmonitor
305
- target_label: endpoint
306
replacement: metrics
307
- source_labels: [__address__]
308
target_label: __tmp_hash
309
action: hashmod
310
modulus: 1
311
- source_labels: [__tmp_hash]
312
action: keep
313
regex: $(SHARD)
314
`),
315
},
316
}
317
318
for _, tc := range tt {
319
t.Run(tc.name, func(t *testing.T) {
320
vm, err := createVM(testStore())
321
require.NoError(t, err)
322
323
args := []string{
324
"agentNamespace", "monitor", "endpoint", "index", "apiServer", "overrideHonorLabels",
325
"overrideHonorTimestamps", "ignoreNamespaceSelectors", "enforcedNamespaceLabel",
326
"enforcedSampleLimit", "enforcedTargetLimit", "shards",
327
}
328
for _, arg := range args {
329
bb, err := jsonnetMarshal(tc.input[arg])
330
require.NoError(t, err)
331
vm.TLACode(arg, string(bb))
332
}
333
334
actual, err := runSnippet(vm, "./component/metrics/pod_monitor.libsonnet", args...)
335
require.NoError(t, err)
336
if !assert.YAMLEq(t, tc.expect, actual) {
337
fmt.Fprintln(os.Stderr, actual)
338
}
339
})
340
}
341
}
342
343
func TestProbe(t *testing.T) {
344
tt := []struct {
345
name string
346
input map[string]interface{}
347
expect string
348
}{
349
{
350
name: "default",
351
input: map[string]interface{}{
352
"agentNamespace": "operator",
353
"probe": prom_v1.Probe{
354
ObjectMeta: meta_v1.ObjectMeta{
355
Namespace: "operator",
356
Name: "probe",
357
},
358
Spec: prom_v1.ProbeSpec{
359
Module: "mod",
360
Targets: prom_v1.ProbeTargets{
361
Ingress: &prom_v1.ProbeTargetIngress{
362
Selector: meta_v1.LabelSelector{
363
MatchLabels: map[string]string{"foo": "bar"},
364
},
365
},
366
},
367
TLSConfig: &prom_v1.ProbeTLSConfig{
368
SafeTLSConfig: prom_v1.SafeTLSConfig{
369
InsecureSkipVerify: true,
370
},
371
},
372
},
373
},
374
"apiServer": prom_v1.APIServerConfig{},
375
"overrideHonorTimestamps": false,
376
"ignoreNamespaceSelectors": false,
377
"enforcedNamespaceLabel": "",
378
"enforcedSampleLimit": nil,
379
"enforcedTargetLimit": nil,
380
"shards": 1,
381
},
382
expect: util.Untab(`
383
job_name: probe/operator/probe
384
honor_timestamps: true
385
kubernetes_sd_configs:
386
- role: ingress
387
namespaces:
388
names: [operator]
389
metrics_path: /probe
390
params:
391
module: ["mod"]
392
relabel_configs:
393
- source_labels: [job]
394
target_label: __tmp_prometheus_job_name
395
- action: keep
396
regex: bar
397
source_labels: [__meta_kubernetes_ingress_label_foo]
398
- action: replace
399
regex: (.+);(.+);(.+)
400
replacement: $1://$2$3
401
separator: ;
402
source_labels:
403
- __meta_kubernetes_ingress_scheme
404
- __address__
405
- __meta_kubernetes_ingress_path
406
target_label: __param_target
407
- source_labels: [__meta_kubernetes_namespace]
408
target_label: namespace
409
- source_labels: [__meta_kubernetes_ingress_name]
410
target_label: ingress
411
- source_labels: [__param_target]
412
target_label: instance
413
- replacement: ""
414
target_label: __address__
415
tls_config:
416
insecure_skip_verify: true
417
`),
418
},
419
}
420
421
for _, tc := range tt {
422
t.Run(tc.name, func(t *testing.T) {
423
vm, err := createVM(testStore())
424
require.NoError(t, err)
425
426
args := []string{
427
"agentNamespace", "probe", "apiServer", "overrideHonorTimestamps",
428
"ignoreNamespaceSelectors", "enforcedNamespaceLabel",
429
"enforcedSampleLimit", "enforcedTargetLimit", "shards",
430
}
431
for _, arg := range args {
432
bb, err := jsonnetMarshal(tc.input[arg])
433
require.NoError(t, err)
434
vm.TLACode(arg, string(bb))
435
}
436
437
actual, err := runSnippet(vm, "./component/metrics/probe.libsonnet", args...)
438
require.NoError(t, err)
439
if !assert.YAMLEq(t, tc.expect, actual) {
440
fmt.Fprintln(os.Stderr, actual)
441
}
442
})
443
}
444
}
445
446
func TestRelabelConfig(t *testing.T) {
447
tt := []struct {
448
name string
449
input interface{}
450
expect string
451
}{
452
{
453
name: "full",
454
input: prom_v1.RelabelConfig{
455
SourceLabels: []prom_v1.LabelName{"input_a", "input_b"},
456
Separator: ";",
457
TargetLabel: "target_a",
458
Regex: "regex",
459
Modulus: 1234,
460
Replacement: "foobar",
461
Action: "replace",
462
},
463
expect: util.Untab(`
464
source_labels: ["input_a", "input_b"]
465
separator: ";"
466
target_label: "target_a"
467
regex: regex
468
modulus: 1234
469
replacement: foobar
470
action: replace
471
`),
472
},
473
}
474
475
for _, tc := range tt {
476
t.Run(tc.name, func(t *testing.T) {
477
vm, err := createVM(nil)
478
require.NoError(t, err)
479
bb, err := jsonnetMarshal(tc.input)
480
require.NoError(t, err)
481
482
vm.TLACode("cfg", string(bb))
483
actual, err := runSnippet(vm, "./component/metrics/relabel_config.libsonnet", "cfg")
484
require.NoError(t, err)
485
require.YAMLEq(t, tc.expect, actual)
486
})
487
}
488
}
489
490
func TestRemoteWrite(t *testing.T) {
491
tt := []struct {
492
name string
493
input map[string]interface{}
494
expect string
495
}{
496
{
497
name: "bare",
498
input: map[string]interface{}{
499
"namespace": "operator",
500
"rw": gragent.RemoteWriteSpec{
501
URL: "http://cortex/api/prom/push",
502
},
503
},
504
expect: util.Untab(`
505
url: http://cortex/api/prom/push
506
`),
507
},
508
{
509
name: "base configs",
510
input: map[string]interface{}{
511
"namespace": "operator",
512
"rw": gragent.RemoteWriteSpec{
513
Name: "cortex",
514
URL: "http://cortex/api/prom/push",
515
RemoteTimeout: "5m",
516
Headers: map[string]string{"foo": "bar"},
517
},
518
},
519
expect: util.Untab(`
520
name: cortex
521
url: http://cortex/api/prom/push
522
remote_timeout: 5m
523
headers:
524
foo: bar
525
`),
526
},
527
{
528
name: "write_relabel_configs",
529
input: map[string]interface{}{
530
"namespace": "operator",
531
"rw": gragent.RemoteWriteSpec{
532
URL: "http://cortex/api/prom/push",
533
WriteRelabelConfigs: []prom_v1.RelabelConfig{{
534
SourceLabels: []prom_v1.LabelName{"__name__"},
535
Action: "drop",
536
}},
537
},
538
},
539
expect: util.Untab(`
540
url: http://cortex/api/prom/push
541
write_relabel_configs:
542
- source_labels: [__name__]
543
action: drop
544
`),
545
},
546
{
547
name: "tls_config",
548
input: map[string]interface{}{
549
"namespace": "operator",
550
"rw": gragent.RemoteWriteSpec{
551
URL: "http://cortex/api/prom/push",
552
TLSConfig: &prom_v1.TLSConfig{
553
CAFile: "ca",
554
CertFile: "cert",
555
},
556
},
557
},
558
expect: util.Untab(`
559
url: http://cortex/api/prom/push
560
tls_config:
561
ca_file: ca
562
cert_file: cert
563
`),
564
},
565
{
566
name: "basic_auth",
567
input: map[string]interface{}{
568
"namespace": "operator",
569
"rw": gragent.RemoteWriteSpec{
570
URL: "http://cortex/api/prom/push",
571
BasicAuth: &prom_v1.BasicAuth{
572
Username: v1.SecretKeySelector{
573
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
574
Key: "key",
575
},
576
Password: v1.SecretKeySelector{
577
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
578
Key: "key",
579
},
580
},
581
},
582
},
583
expect: util.Untab(`
584
url: http://cortex/api/prom/push
585
basic_auth:
586
username: secretkey
587
password_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key
588
`),
589
},
590
{
591
name: "bearer_token",
592
input: map[string]interface{}{
593
"namespace": "operator",
594
"rw": gragent.RemoteWriteSpec{
595
URL: "http://cortex/api/prom/push",
596
BearerToken: "my-token",
597
},
598
},
599
expect: util.Untab(`
600
url: http://cortex/api/prom/push
601
authorization:
602
type: Bearer
603
credentials: my-token
604
`),
605
},
606
{
607
name: "bearer_token_file",
608
input: map[string]interface{}{
609
"namespace": "operator",
610
"rw": gragent.RemoteWriteSpec{
611
URL: "http://cortex/api/prom/push",
612
BearerTokenFile: "/path/to/file",
613
},
614
},
615
expect: util.Untab(`
616
url: http://cortex/api/prom/push
617
authorization:
618
type: Bearer
619
credentials_file: /path/to/file
620
`),
621
},
622
{
623
name: "sigv4",
624
input: map[string]interface{}{
625
"namespace": "operator",
626
"rw": gragent.RemoteWriteSpec{
627
URL: "http://cortex/api/prom/push",
628
SigV4: &gragent.SigV4Config{
629
Region: "region",
630
AccessKey: &v1.SecretKeySelector{
631
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
632
Key: "key",
633
},
634
SecretKey: &v1.SecretKeySelector{
635
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
636
Key: "key",
637
},
638
Profile: "profile",
639
RoleARN: "arn",
640
},
641
},
642
},
643
expect: util.Untab(`
644
url: http://cortex/api/prom/push
645
sigv4:
646
region: region
647
access_key: secretkey
648
secret_key: secretkey
649
profile: profile
650
role_arn: arn
651
`),
652
},
653
{
654
name: "queue_config",
655
input: map[string]interface{}{
656
"namespace": "operator",
657
"rw": gragent.RemoteWriteSpec{
658
URL: "http://cortex/api/prom/push",
659
QueueConfig: &gragent.QueueConfig{
660
Capacity: 1000,
661
MinShards: 1,
662
MaxShards: 100,
663
MaxSamplesPerSend: 500,
664
BatchSendDeadline: "5m",
665
MinBackoff: "1m",
666
MaxBackoff: "5m",
667
},
668
},
669
},
670
expect: util.Untab(`
671
url: http://cortex/api/prom/push
672
queue_config:
673
capacity: 1000
674
min_shards: 1
675
max_shards: 100
676
max_samples_per_send: 500
677
batch_send_deadline: 5m
678
min_backoff: 1m
679
max_backoff: 5m
680
`),
681
},
682
{
683
name: "metadata_config",
684
input: map[string]interface{}{
685
"namespace": "operator",
686
"rw": gragent.RemoteWriteSpec{
687
URL: "http://cortex/api/prom/push",
688
MetadataConfig: &gragent.MetadataConfig{
689
Send: true,
690
SendInterval: "5m",
691
},
692
},
693
},
694
expect: util.Untab(`
695
url: http://cortex/api/prom/push
696
metadata_config:
697
send: true
698
send_interval: 5m
699
`),
700
},
701
{
702
name: "proxy_url",
703
input: map[string]interface{}{
704
"namespace": "operator",
705
"rw": gragent.RemoteWriteSpec{
706
URL: "http://cortex/api/prom/push",
707
ProxyURL: "http://proxy",
708
},
709
},
710
expect: util.Untab(`
711
url: http://cortex/api/prom/push
712
proxy_url: http://proxy
713
`),
714
},
715
}
716
717
for _, tc := range tt {
718
t.Run(tc.name, func(t *testing.T) {
719
vm, err := createVM(testStore())
720
require.NoError(t, err)
721
722
args := []string{"namespace", "rw"}
723
for _, arg := range args {
724
bb, err := jsonnetMarshal(tc.input[arg])
725
require.NoError(t, err)
726
vm.TLACode(arg, string(bb))
727
}
728
729
actual, err := runSnippet(vm, "./component/metrics/remote_write.libsonnet", args...)
730
require.NoError(t, err)
731
require.YAMLEq(t, tc.expect, actual)
732
})
733
}
734
}
735
736
func TestSafeTLSConfig(t *testing.T) {
737
tt := []struct {
738
name string
739
input map[string]interface{}
740
expect string
741
}{
742
{
743
name: "configmap",
744
input: map[string]interface{}{
745
"namespace": "operator",
746
"config": prom_v1.SafeTLSConfig{
747
ServerName: "server",
748
InsecureSkipVerify: true,
749
CA: prom_v1.SecretOrConfigMap{
750
ConfigMap: &v1.ConfigMapKeySelector{
751
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
752
Key: "key",
753
},
754
},
755
Cert: prom_v1.SecretOrConfigMap{
756
ConfigMap: &v1.ConfigMapKeySelector{
757
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
758
Key: "key",
759
},
760
},
761
KeySecret: &v1.SecretKeySelector{
762
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
763
Key: "key",
764
},
765
},
766
},
767
expect: util.Untab(`
768
ca_file: /var/lib/grafana-agent/secrets/_configMaps_operator_obj_key
769
cert_file: /var/lib/grafana-agent/secrets/_configMaps_operator_obj_key
770
key_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key
771
server_name: server
772
insecure_skip_verify: true
773
`),
774
},
775
{
776
name: "secrets",
777
input: map[string]interface{}{
778
"namespace": "operator",
779
"config": prom_v1.SafeTLSConfig{
780
ServerName: "server",
781
InsecureSkipVerify: true,
782
CA: prom_v1.SecretOrConfigMap{
783
Secret: &v1.SecretKeySelector{
784
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
785
Key: "key",
786
},
787
},
788
Cert: prom_v1.SecretOrConfigMap{
789
Secret: &v1.SecretKeySelector{
790
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
791
Key: "key",
792
},
793
},
794
KeySecret: &v1.SecretKeySelector{
795
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
796
Key: "key",
797
},
798
},
799
},
800
expect: util.Untab(`
801
ca_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key
802
cert_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key
803
key_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key
804
server_name: server
805
insecure_skip_verify: true
806
`),
807
},
808
}
809
810
for _, tc := range tt {
811
t.Run(tc.name, func(t *testing.T) {
812
vm, err := createVM(testStore())
813
require.NoError(t, err)
814
815
args := []string{"namespace", "config"}
816
for _, arg := range args {
817
bb, err := jsonnetMarshal(tc.input[arg])
818
require.NoError(t, err)
819
vm.TLACode(arg, string(bb))
820
}
821
822
actual, err := runSnippet(vm, "./component/metrics/safe_tls_config.libsonnet", args...)
823
require.NoError(t, err)
824
require.YAMLEq(t, tc.expect, actual)
825
})
826
}
827
}
828
829
func TestServiceMonitor(t *testing.T) {
830
trueVal := true
831
tt := []struct {
832
name string
833
input map[string]interface{}
834
expect string
835
}{
836
{
837
name: "default",
838
input: map[string]interface{}{
839
"agentNamespace": "operator",
840
"monitor": prom_v1.ServiceMonitor{
841
ObjectMeta: meta_v1.ObjectMeta{
842
Namespace: "operator",
843
Name: "servicemonitor",
844
},
845
},
846
"endpoint": prom_v1.Endpoint{
847
Port: "metrics",
848
FilterRunning: &trueVal,
849
},
850
"index": 0,
851
"apiServer": prom_v1.APIServerConfig{},
852
"overrideHonorLabels": false,
853
"overrideHonorTimestamps": false,
854
"ignoreNamespaceSelectors": false,
855
"enforcedNamespaceLabel": "",
856
"enforcedSampleLimit": nil,
857
"enforcedTargetLimit": nil,
858
"shards": 1,
859
},
860
expect: util.Untab(`
861
job_name: serviceMonitor/operator/servicemonitor/0
862
honor_labels: false
863
kubernetes_sd_configs:
864
- role: endpoints
865
namespaces:
866
names: [operator]
867
relabel_configs:
868
- source_labels:
869
- job
870
target_label: __tmp_prometheus_job_name
871
- action: keep
872
regex: metrics
873
source_labels:
874
- __meta_kubernetes_endpoint_port_name
875
- regex: Node;(.*)
876
replacement: $1
877
separator: ;
878
source_labels:
879
- __meta_kubernetes_endpoint_address_target_kind
880
- __meta_kubernetes_endpoint_address_target_name
881
target_label: node
882
- regex: Pod;(.*)
883
replacement: $1
884
separator: ;
885
source_labels:
886
- __meta_kubernetes_endpoint_address_target_kind
887
- __meta_kubernetes_endpoint_address_target_name
888
target_label: pod
889
- source_labels:
890
- __meta_kubernetes_namespace
891
target_label: namespace
892
- source_labels:
893
- __meta_kubernetes_service_name
894
target_label: service
895
- source_labels:
896
- __meta_kubernetes_pod_name
897
target_label: pod
898
- source_labels:
899
- __meta_kubernetes_pod_container_name
900
target_label: container
901
- source_labels: [__meta_kubernetes_pod_phase]
902
regex: (Failed|Succeeded)
903
action: drop
904
- replacement: $1
905
source_labels:
906
- __meta_kubernetes_service_name
907
target_label: job
908
- replacement: metrics
909
target_label: endpoint
910
- action: hashmod
911
modulus: 1
912
source_labels:
913
- __address__
914
target_label: __tmp_hash
915
- action: keep
916
regex: $(SHARD)
917
source_labels:
918
- __tmp_hash
919
`),
920
},
921
{
922
name: "no_filter_running",
923
input: map[string]interface{}{
924
"agentNamespace": "operator",
925
"monitor": prom_v1.ServiceMonitor{
926
ObjectMeta: meta_v1.ObjectMeta{
927
Namespace: "operator",
928
Name: "servicemonitor",
929
},
930
},
931
"endpoint": prom_v1.Endpoint{
932
Port: "metrics",
933
},
934
"index": 0,
935
"apiServer": prom_v1.APIServerConfig{},
936
"overrideHonorLabels": false,
937
"overrideHonorTimestamps": false,
938
"ignoreNamespaceSelectors": false,
939
"enforcedNamespaceLabel": "",
940
"enforcedSampleLimit": nil,
941
"enforcedTargetLimit": nil,
942
"shards": 1,
943
},
944
expect: util.Untab(`
945
job_name: serviceMonitor/operator/servicemonitor/0
946
honor_labels: false
947
kubernetes_sd_configs:
948
- role: endpoints
949
namespaces:
950
names: [operator]
951
relabel_configs:
952
- source_labels:
953
- job
954
target_label: __tmp_prometheus_job_name
955
- action: keep
956
regex: metrics
957
source_labels:
958
- __meta_kubernetes_endpoint_port_name
959
- regex: Node;(.*)
960
replacement: $1
961
separator: ;
962
source_labels:
963
- __meta_kubernetes_endpoint_address_target_kind
964
- __meta_kubernetes_endpoint_address_target_name
965
target_label: node
966
- regex: Pod;(.*)
967
replacement: $1
968
separator: ;
969
source_labels:
970
- __meta_kubernetes_endpoint_address_target_kind
971
- __meta_kubernetes_endpoint_address_target_name
972
target_label: pod
973
- source_labels:
974
- __meta_kubernetes_namespace
975
target_label: namespace
976
- source_labels:
977
- __meta_kubernetes_service_name
978
target_label: service
979
- source_labels:
980
- __meta_kubernetes_pod_name
981
target_label: pod
982
- source_labels:
983
- __meta_kubernetes_pod_container_name
984
target_label: container
985
- replacement: $1
986
source_labels:
987
- __meta_kubernetes_service_name
988
target_label: job
989
- replacement: metrics
990
target_label: endpoint
991
- action: hashmod
992
modulus: 1
993
source_labels:
994
- __address__
995
target_label: __tmp_hash
996
- action: keep
997
regex: $(SHARD)
998
source_labels:
999
- __tmp_hash
1000
`),
1001
},
1002
}
1003
1004
for _, tc := range tt {
1005
t.Run(tc.name, func(t *testing.T) {
1006
vm, err := createVM(testStore())
1007
require.NoError(t, err)
1008
1009
args := []string{
1010
"agentNamespace", "monitor", "endpoint", "index", "apiServer", "overrideHonorLabels",
1011
"overrideHonorTimestamps", "ignoreNamespaceSelectors", "enforcedNamespaceLabel",
1012
"enforcedSampleLimit", "enforcedTargetLimit", "shards",
1013
}
1014
for _, arg := range args {
1015
bb, err := jsonnetMarshal(tc.input[arg])
1016
require.NoError(t, err)
1017
vm.TLACode(arg, string(bb))
1018
}
1019
1020
actual, err := runSnippet(vm, "./component/metrics/service_monitor.libsonnet", args...)
1021
require.NoError(t, err)
1022
if !assert.YAMLEq(t, tc.expect, actual) {
1023
fmt.Fprintln(os.Stderr, actual)
1024
}
1025
})
1026
}
1027
}
1028
1029
func TestTLSConfig(t *testing.T) {
1030
tt := []struct {
1031
name string
1032
input map[string]interface{}
1033
expect string
1034
}{
1035
{
1036
name: "passthrough",
1037
input: map[string]interface{}{
1038
"namespace": "operator",
1039
"config": prom_v1.TLSConfig{
1040
SafeTLSConfig: prom_v1.SafeTLSConfig{
1041
ServerName: "server",
1042
InsecureSkipVerify: true,
1043
CA: prom_v1.SecretOrConfigMap{
1044
Secret: &v1.SecretKeySelector{
1045
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
1046
Key: "key",
1047
},
1048
},
1049
Cert: prom_v1.SecretOrConfigMap{
1050
Secret: &v1.SecretKeySelector{
1051
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
1052
Key: "key",
1053
},
1054
},
1055
KeySecret: &v1.SecretKeySelector{
1056
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
1057
Key: "key",
1058
},
1059
},
1060
},
1061
},
1062
expect: util.Untab(`
1063
ca_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key
1064
cert_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key
1065
key_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key
1066
server_name: server
1067
insecure_skip_verify: true
1068
`),
1069
},
1070
{
1071
name: "overrides",
1072
input: map[string]interface{}{
1073
"namespace": "operator",
1074
"config": prom_v1.TLSConfig{
1075
SafeTLSConfig: prom_v1.SafeTLSConfig{
1076
ServerName: "server",
1077
InsecureSkipVerify: true,
1078
CA: prom_v1.SecretOrConfigMap{
1079
Secret: &v1.SecretKeySelector{
1080
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
1081
Key: "key",
1082
},
1083
},
1084
Cert: prom_v1.SecretOrConfigMap{
1085
Secret: &v1.SecretKeySelector{
1086
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
1087
Key: "key",
1088
},
1089
},
1090
KeySecret: &v1.SecretKeySelector{
1091
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
1092
Key: "key",
1093
},
1094
},
1095
CAFile: "ca",
1096
CertFile: "cert",
1097
KeyFile: "key",
1098
},
1099
},
1100
expect: util.Untab(`
1101
ca_file: ca
1102
cert_file: cert
1103
key_file: key
1104
server_name: server
1105
insecure_skip_verify: true
1106
`),
1107
},
1108
}
1109
1110
for _, tc := range tt {
1111
t.Run(tc.name, func(t *testing.T) {
1112
vm, err := createVM(testStore())
1113
require.NoError(t, err)
1114
1115
args := []string{"namespace", "config"}
1116
for _, arg := range args {
1117
bb, err := jsonnetMarshal(tc.input[arg])
1118
require.NoError(t, err)
1119
vm.TLACode(arg, string(bb))
1120
}
1121
1122
actual, err := runSnippet(vm, "./component/metrics/tls_config.libsonnet", args...)
1123
require.NoError(t, err)
1124
require.YAMLEq(t, tc.expect, actual)
1125
})
1126
}
1127
}
1128
1129
func runSnippet(vm *jsonnet.VM, filename string, args ...string) (string, error) {
1130
boundArgs := make([]string, len(args))
1131
for i := range args {
1132
boundArgs[i] = fmt.Sprintf("%[1]s=%[1]s", args[i])
1133
}
1134
1135
return vm.EvaluateAnonymousSnippet(
1136
filename,
1137
fmt.Sprintf(`
1138
local marshal = import './ext/marshal.libsonnet';
1139
local optionals = import './ext/optionals.libsonnet';
1140
local eval = import '%s';
1141
function(%s) marshal.YAML(optionals.trim(eval(%s)))
1142
`, filename, strings.Join(args, ","), strings.Join(boundArgs, ",")),
1143
)
1144
}
1145
1146
func testStore() assets.SecretStore {
1147
store := make(assets.SecretStore)
1148
1149
store[assets.KeyForConfigMap("operator", &v1.ConfigMapKeySelector{
1150
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
1151
Key: "key",
1152
})] = "secretcm"
1153
1154
store[assets.KeyForSecret("operator", &v1.SecretKeySelector{
1155
LocalObjectReference: v1.LocalObjectReference{Name: "obj"},
1156
Key: "key",
1157
})] = "secretkey"
1158
1159
return store
1160
}
1161
1162