Path: blob/main/pkg/operator/config/metrics_templates_test.go
4095 views
package config12import (3"fmt"4"os"5"strings"6"testing"78jsonnet "github.com/google/go-jsonnet"9gragent "github.com/grafana/agent/pkg/operator/apis/monitoring/v1alpha1"10"github.com/grafana/agent/pkg/operator/assets"11"github.com/grafana/agent/pkg/util"12prom_v1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"13"github.com/stretchr/testify/assert"14"github.com/stretchr/testify/require"15v1 "k8s.io/api/core/v1"16meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"17"k8s.io/utils/pointer"18)1920func TestExternalLabels(t *testing.T) {21tt := []struct {22name string23input interface{}24addReplica bool25expect string26}{27{28name: "no replica",29addReplica: false,30input: gragent.Deployment{31Agent: &gragent.GrafanaAgent{32ObjectMeta: meta_v1.ObjectMeta{33Namespace: "operator",34Name: "agent",35},36},37},38expect: util.Untab(`39cluster: operator/agent40`),41},42{43name: "defaults",44addReplica: true,45input: gragent.Deployment{46Agent: &gragent.GrafanaAgent{47ObjectMeta: meta_v1.ObjectMeta{48Namespace: "operator",49Name: "agent",50},51},52},53expect: util.Untab(`54cluster: operator/agent55__replica__: replica-$(STATEFULSET_ORDINAL_NUMBER)56`),57},58{59name: "external_labels",60addReplica: true,61input: gragent.Deployment{62Agent: &gragent.GrafanaAgent{63ObjectMeta: meta_v1.ObjectMeta{64Namespace: "operator",65Name: "agent",66},67Spec: gragent.GrafanaAgentSpec{68Metrics: gragent.MetricsSubsystemSpec{69ExternalLabels: map[string]string{"foo": "bar"},70},71},72},73},74expect: util.Untab(`75cluster: operator/agent76foo: bar77__replica__: replica-$(STATEFULSET_ORDINAL_NUMBER)78`),79},80{81name: "custom labels",82addReplica: true,83input: gragent.Deployment{84Agent: &gragent.GrafanaAgent{85ObjectMeta: meta_v1.ObjectMeta{86Namespace: "operator",87Name: "agent",88},89Spec: gragent.GrafanaAgentSpec{90Metrics: gragent.MetricsSubsystemSpec{91MetricsExternalLabelName: pointer.String("deployment"),92ReplicaExternalLabelName: pointer.String("replica"),93ExternalLabels: map[string]string{"foo": "bar"},94},95},96},97},98expect: util.Untab(`99deployment: operator/agent100foo: bar101replica: replica-$(STATEFULSET_ORDINAL_NUMBER)102`),103},104}105106for _, tc := range tt {107t.Run(tc.name, func(t *testing.T) {108vm, err := createVM(nil)109require.NoError(t, err)110bb, err := jsonnetMarshal(tc.input)111require.NoError(t, err)112113vm.TLACode("ctx", string(bb))114vm.TLACode("addReplica", fmt.Sprintf("%v", tc.addReplica))115actual, err := runSnippet(vm, "./component/metrics/external_labels.libsonnet", "ctx", "addReplica")116require.NoError(t, err)117require.YAMLEq(t, tc.expect, actual)118})119}120}121122func TestKubeSDConfig(t *testing.T) {123tt := []struct {124name string125input map[string]interface{}126expect string127}{128{129name: "defaults",130input: map[string]interface{}{131"namespace": "operator",132"role": "pod",133},134expect: util.Untab(`135role: pod136`),137},138{139name: "defaults",140input: map[string]interface{}{141"namespace": "operator",142"namespaces": []string{"operator"},143"role": "pod",144},145expect: util.Untab(`146role: pod147namespaces:148names: [operator]149`),150},151{152name: "host",153input: map[string]interface{}{154"namespace": "operator",155"apiServer": &prom_v1.APIServerConfig{Host: "host"},156"role": "pod",157},158expect: util.Untab(`159role: pod160api_server: host161`),162},163{164name: "basic auth",165input: map[string]interface{}{166"namespace": "operator",167"apiServer": &prom_v1.APIServerConfig{168BasicAuth: &prom_v1.BasicAuth{169Username: v1.SecretKeySelector{170LocalObjectReference: v1.LocalObjectReference{Name: "obj"},171Key: "key",172},173Password: v1.SecretKeySelector{174LocalObjectReference: v1.LocalObjectReference{Name: "obj"},175Key: "key",176},177},178},179"role": "pod",180},181expect: util.Untab(`182role: pod183basic_auth:184username: secretkey185password: secretkey186`),187},188{189name: "bearer auth",190input: map[string]interface{}{191"namespace": "operator",192"apiServer": &prom_v1.APIServerConfig{193BearerToken: "bearer",194BearerTokenFile: "file",195},196"role": "pod",197},198expect: util.Untab(`199role: pod200authorization:201type: Bearer202credentials: bearer203credentials_file: file204`),205},206{207name: "tls_config",208input: map[string]interface{}{209"namespace": "operator",210"apiServer": &prom_v1.APIServerConfig{211TLSConfig: &prom_v1.TLSConfig{212CAFile: "ca",213},214},215"role": "pod",216},217expect: util.Untab(`218role: pod219tls_config:220ca_file: ca221`),222},223}224225for _, tc := range tt {226t.Run(tc.name, func(t *testing.T) {227vm, err := createVM(testStore())228require.NoError(t, err)229230args := []string{"namespace", "namespaces", "apiServer", "role"}231for _, arg := range args {232bb, err := jsonnetMarshal(tc.input[arg])233require.NoError(t, err)234vm.TLACode(arg, string(bb))235}236237actual, err := runSnippet(vm, "./component/metrics/kube_sd_config.libsonnet", args...)238require.NoError(t, err)239require.YAMLEq(t, tc.expect, actual)240})241}242}243244func TestPodMonitor(t *testing.T) {245var falseVal = false246var trueVal = true247tt := []struct {248name string249input map[string]interface{}250expect string251}{252{253name: "default",254input: map[string]interface{}{255"agentNamespace": "operator",256"monitor": prom_v1.PodMonitor{257ObjectMeta: meta_v1.ObjectMeta{258Namespace: "operator",259Name: "podmonitor",260},261},262"endpoint": prom_v1.PodMetricsEndpoint{263Port: "metrics",264EnableHttp2: &falseVal,265FilterRunning: &trueVal,266},267"index": 0,268"apiServer": prom_v1.APIServerConfig{},269"overrideHonorLabels": false,270"overrideHonorTimestamps": false,271"ignoreNamespaceSelectors": false,272"enforcedNamespaceLabel": "",273"enforcedSampleLimit": nil,274"enforcedTargetLimit": nil,275"shards": 1,276},277expect: util.Untab(`278job_name: podMonitor/operator/podmonitor/0279enable_http2: false280honor_labels: false281kubernetes_sd_configs:282- role: pod283namespaces:284names: [operator]285relabel_configs:286- source_labels: [job]287target_label: __tmp_prometheus_job_name288- source_labels: [__meta_kubernetes_pod_phase]289regex: (Failed|Succeeded)290action: drop291- source_labels: [__meta_kubernetes_pod_container_port_name]292regex: metrics293action: keep294- source_labels: [__meta_kubernetes_namespace]295target_label: namespace296- source_labels: [__meta_kubernetes_service_name]297target_label: service298- source_labels: [__meta_kubernetes_pod_name]299target_label: pod300- source_labels: [__meta_kubernetes_pod_container_name]301target_label: container302- target_label: job303replacement: operator/podmonitor304- target_label: endpoint305replacement: metrics306- source_labels: [__address__]307target_label: __tmp_hash308action: hashmod309modulus: 1310- source_labels: [__tmp_hash]311action: keep312regex: $(SHARD)313`),314},315}316317for _, tc := range tt {318t.Run(tc.name, func(t *testing.T) {319vm, err := createVM(testStore())320require.NoError(t, err)321322args := []string{323"agentNamespace", "monitor", "endpoint", "index", "apiServer", "overrideHonorLabels",324"overrideHonorTimestamps", "ignoreNamespaceSelectors", "enforcedNamespaceLabel",325"enforcedSampleLimit", "enforcedTargetLimit", "shards",326}327for _, arg := range args {328bb, err := jsonnetMarshal(tc.input[arg])329require.NoError(t, err)330vm.TLACode(arg, string(bb))331}332333actual, err := runSnippet(vm, "./component/metrics/pod_monitor.libsonnet", args...)334require.NoError(t, err)335if !assert.YAMLEq(t, tc.expect, actual) {336fmt.Fprintln(os.Stderr, actual)337}338})339}340}341342func TestProbe(t *testing.T) {343tt := []struct {344name string345input map[string]interface{}346expect string347}{348{349name: "default",350input: map[string]interface{}{351"agentNamespace": "operator",352"probe": prom_v1.Probe{353ObjectMeta: meta_v1.ObjectMeta{354Namespace: "operator",355Name: "probe",356},357Spec: prom_v1.ProbeSpec{358Module: "mod",359Targets: prom_v1.ProbeTargets{360Ingress: &prom_v1.ProbeTargetIngress{361Selector: meta_v1.LabelSelector{362MatchLabels: map[string]string{"foo": "bar"},363},364},365},366TLSConfig: &prom_v1.ProbeTLSConfig{367SafeTLSConfig: prom_v1.SafeTLSConfig{368InsecureSkipVerify: true,369},370},371},372},373"apiServer": prom_v1.APIServerConfig{},374"overrideHonorTimestamps": false,375"ignoreNamespaceSelectors": false,376"enforcedNamespaceLabel": "",377"enforcedSampleLimit": nil,378"enforcedTargetLimit": nil,379"shards": 1,380},381expect: util.Untab(`382job_name: probe/operator/probe383honor_timestamps: true384kubernetes_sd_configs:385- role: ingress386namespaces:387names: [operator]388metrics_path: /probe389params:390module: ["mod"]391relabel_configs:392- source_labels: [job]393target_label: __tmp_prometheus_job_name394- action: keep395regex: bar396source_labels: [__meta_kubernetes_ingress_label_foo]397- action: replace398regex: (.+);(.+);(.+)399replacement: $1://$2$3400separator: ;401source_labels:402- __meta_kubernetes_ingress_scheme403- __address__404- __meta_kubernetes_ingress_path405target_label: __param_target406- source_labels: [__meta_kubernetes_namespace]407target_label: namespace408- source_labels: [__meta_kubernetes_ingress_name]409target_label: ingress410- source_labels: [__param_target]411target_label: instance412- replacement: ""413target_label: __address__414tls_config:415insecure_skip_verify: true416`),417},418}419420for _, tc := range tt {421t.Run(tc.name, func(t *testing.T) {422vm, err := createVM(testStore())423require.NoError(t, err)424425args := []string{426"agentNamespace", "probe", "apiServer", "overrideHonorTimestamps",427"ignoreNamespaceSelectors", "enforcedNamespaceLabel",428"enforcedSampleLimit", "enforcedTargetLimit", "shards",429}430for _, arg := range args {431bb, err := jsonnetMarshal(tc.input[arg])432require.NoError(t, err)433vm.TLACode(arg, string(bb))434}435436actual, err := runSnippet(vm, "./component/metrics/probe.libsonnet", args...)437require.NoError(t, err)438if !assert.YAMLEq(t, tc.expect, actual) {439fmt.Fprintln(os.Stderr, actual)440}441})442}443}444445func TestRelabelConfig(t *testing.T) {446tt := []struct {447name string448input interface{}449expect string450}{451{452name: "full",453input: prom_v1.RelabelConfig{454SourceLabels: []prom_v1.LabelName{"input_a", "input_b"},455Separator: ";",456TargetLabel: "target_a",457Regex: "regex",458Modulus: 1234,459Replacement: "foobar",460Action: "replace",461},462expect: util.Untab(`463source_labels: ["input_a", "input_b"]464separator: ";"465target_label: "target_a"466regex: regex467modulus: 1234468replacement: foobar469action: replace470`),471},472}473474for _, tc := range tt {475t.Run(tc.name, func(t *testing.T) {476vm, err := createVM(nil)477require.NoError(t, err)478bb, err := jsonnetMarshal(tc.input)479require.NoError(t, err)480481vm.TLACode("cfg", string(bb))482actual, err := runSnippet(vm, "./component/metrics/relabel_config.libsonnet", "cfg")483require.NoError(t, err)484require.YAMLEq(t, tc.expect, actual)485})486}487}488489func TestRemoteWrite(t *testing.T) {490tt := []struct {491name string492input map[string]interface{}493expect string494}{495{496name: "bare",497input: map[string]interface{}{498"namespace": "operator",499"rw": gragent.RemoteWriteSpec{500URL: "http://cortex/api/prom/push",501},502},503expect: util.Untab(`504url: http://cortex/api/prom/push505`),506},507{508name: "base configs",509input: map[string]interface{}{510"namespace": "operator",511"rw": gragent.RemoteWriteSpec{512Name: "cortex",513URL: "http://cortex/api/prom/push",514RemoteTimeout: "5m",515Headers: map[string]string{"foo": "bar"},516},517},518expect: util.Untab(`519name: cortex520url: http://cortex/api/prom/push521remote_timeout: 5m522headers:523foo: bar524`),525},526{527name: "write_relabel_configs",528input: map[string]interface{}{529"namespace": "operator",530"rw": gragent.RemoteWriteSpec{531URL: "http://cortex/api/prom/push",532WriteRelabelConfigs: []prom_v1.RelabelConfig{{533SourceLabels: []prom_v1.LabelName{"__name__"},534Action: "drop",535}},536},537},538expect: util.Untab(`539url: http://cortex/api/prom/push540write_relabel_configs:541- source_labels: [__name__]542action: drop543`),544},545{546name: "tls_config",547input: map[string]interface{}{548"namespace": "operator",549"rw": gragent.RemoteWriteSpec{550URL: "http://cortex/api/prom/push",551TLSConfig: &prom_v1.TLSConfig{552CAFile: "ca",553CertFile: "cert",554},555},556},557expect: util.Untab(`558url: http://cortex/api/prom/push559tls_config:560ca_file: ca561cert_file: cert562`),563},564{565name: "basic_auth",566input: map[string]interface{}{567"namespace": "operator",568"rw": gragent.RemoteWriteSpec{569URL: "http://cortex/api/prom/push",570BasicAuth: &prom_v1.BasicAuth{571Username: v1.SecretKeySelector{572LocalObjectReference: v1.LocalObjectReference{Name: "obj"},573Key: "key",574},575Password: v1.SecretKeySelector{576LocalObjectReference: v1.LocalObjectReference{Name: "obj"},577Key: "key",578},579},580},581},582expect: util.Untab(`583url: http://cortex/api/prom/push584basic_auth:585username: secretkey586password_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key587`),588},589{590name: "bearer_token",591input: map[string]interface{}{592"namespace": "operator",593"rw": gragent.RemoteWriteSpec{594URL: "http://cortex/api/prom/push",595BearerToken: "my-token",596},597},598expect: util.Untab(`599url: http://cortex/api/prom/push600authorization:601type: Bearer602credentials: my-token603`),604},605{606name: "bearer_token_file",607input: map[string]interface{}{608"namespace": "operator",609"rw": gragent.RemoteWriteSpec{610URL: "http://cortex/api/prom/push",611BearerTokenFile: "/path/to/file",612},613},614expect: util.Untab(`615url: http://cortex/api/prom/push616authorization:617type: Bearer618credentials_file: /path/to/file619`),620},621{622name: "sigv4",623input: map[string]interface{}{624"namespace": "operator",625"rw": gragent.RemoteWriteSpec{626URL: "http://cortex/api/prom/push",627SigV4: &gragent.SigV4Config{628Region: "region",629AccessKey: &v1.SecretKeySelector{630LocalObjectReference: v1.LocalObjectReference{Name: "obj"},631Key: "key",632},633SecretKey: &v1.SecretKeySelector{634LocalObjectReference: v1.LocalObjectReference{Name: "obj"},635Key: "key",636},637Profile: "profile",638RoleARN: "arn",639},640},641},642expect: util.Untab(`643url: http://cortex/api/prom/push644sigv4:645region: region646access_key: secretkey647secret_key: secretkey648profile: profile649role_arn: arn650`),651},652{653name: "queue_config",654input: map[string]interface{}{655"namespace": "operator",656"rw": gragent.RemoteWriteSpec{657URL: "http://cortex/api/prom/push",658QueueConfig: &gragent.QueueConfig{659Capacity: 1000,660MinShards: 1,661MaxShards: 100,662MaxSamplesPerSend: 500,663BatchSendDeadline: "5m",664MinBackoff: "1m",665MaxBackoff: "5m",666},667},668},669expect: util.Untab(`670url: http://cortex/api/prom/push671queue_config:672capacity: 1000673min_shards: 1674max_shards: 100675max_samples_per_send: 500676batch_send_deadline: 5m677min_backoff: 1m678max_backoff: 5m679`),680},681{682name: "metadata_config",683input: map[string]interface{}{684"namespace": "operator",685"rw": gragent.RemoteWriteSpec{686URL: "http://cortex/api/prom/push",687MetadataConfig: &gragent.MetadataConfig{688Send: true,689SendInterval: "5m",690},691},692},693expect: util.Untab(`694url: http://cortex/api/prom/push695metadata_config:696send: true697send_interval: 5m698`),699},700{701name: "proxy_url",702input: map[string]interface{}{703"namespace": "operator",704"rw": gragent.RemoteWriteSpec{705URL: "http://cortex/api/prom/push",706ProxyURL: "http://proxy",707},708},709expect: util.Untab(`710url: http://cortex/api/prom/push711proxy_url: http://proxy712`),713},714}715716for _, tc := range tt {717t.Run(tc.name, func(t *testing.T) {718vm, err := createVM(testStore())719require.NoError(t, err)720721args := []string{"namespace", "rw"}722for _, arg := range args {723bb, err := jsonnetMarshal(tc.input[arg])724require.NoError(t, err)725vm.TLACode(arg, string(bb))726}727728actual, err := runSnippet(vm, "./component/metrics/remote_write.libsonnet", args...)729require.NoError(t, err)730require.YAMLEq(t, tc.expect, actual)731})732}733}734735func TestSafeTLSConfig(t *testing.T) {736tt := []struct {737name string738input map[string]interface{}739expect string740}{741{742name: "configmap",743input: map[string]interface{}{744"namespace": "operator",745"config": prom_v1.SafeTLSConfig{746ServerName: "server",747InsecureSkipVerify: true,748CA: prom_v1.SecretOrConfigMap{749ConfigMap: &v1.ConfigMapKeySelector{750LocalObjectReference: v1.LocalObjectReference{Name: "obj"},751Key: "key",752},753},754Cert: prom_v1.SecretOrConfigMap{755ConfigMap: &v1.ConfigMapKeySelector{756LocalObjectReference: v1.LocalObjectReference{Name: "obj"},757Key: "key",758},759},760KeySecret: &v1.SecretKeySelector{761LocalObjectReference: v1.LocalObjectReference{Name: "obj"},762Key: "key",763},764},765},766expect: util.Untab(`767ca_file: /var/lib/grafana-agent/secrets/_configMaps_operator_obj_key768cert_file: /var/lib/grafana-agent/secrets/_configMaps_operator_obj_key769key_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key770server_name: server771insecure_skip_verify: true772`),773},774{775name: "secrets",776input: map[string]interface{}{777"namespace": "operator",778"config": prom_v1.SafeTLSConfig{779ServerName: "server",780InsecureSkipVerify: true,781CA: prom_v1.SecretOrConfigMap{782Secret: &v1.SecretKeySelector{783LocalObjectReference: v1.LocalObjectReference{Name: "obj"},784Key: "key",785},786},787Cert: prom_v1.SecretOrConfigMap{788Secret: &v1.SecretKeySelector{789LocalObjectReference: v1.LocalObjectReference{Name: "obj"},790Key: "key",791},792},793KeySecret: &v1.SecretKeySelector{794LocalObjectReference: v1.LocalObjectReference{Name: "obj"},795Key: "key",796},797},798},799expect: util.Untab(`800ca_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key801cert_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key802key_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key803server_name: server804insecure_skip_verify: true805`),806},807}808809for _, tc := range tt {810t.Run(tc.name, func(t *testing.T) {811vm, err := createVM(testStore())812require.NoError(t, err)813814args := []string{"namespace", "config"}815for _, arg := range args {816bb, err := jsonnetMarshal(tc.input[arg])817require.NoError(t, err)818vm.TLACode(arg, string(bb))819}820821actual, err := runSnippet(vm, "./component/metrics/safe_tls_config.libsonnet", args...)822require.NoError(t, err)823require.YAMLEq(t, tc.expect, actual)824})825}826}827828func TestServiceMonitor(t *testing.T) {829trueVal := true830tt := []struct {831name string832input map[string]interface{}833expect string834}{835{836name: "default",837input: map[string]interface{}{838"agentNamespace": "operator",839"monitor": prom_v1.ServiceMonitor{840ObjectMeta: meta_v1.ObjectMeta{841Namespace: "operator",842Name: "servicemonitor",843},844},845"endpoint": prom_v1.Endpoint{846Port: "metrics",847FilterRunning: &trueVal,848},849"index": 0,850"apiServer": prom_v1.APIServerConfig{},851"overrideHonorLabels": false,852"overrideHonorTimestamps": false,853"ignoreNamespaceSelectors": false,854"enforcedNamespaceLabel": "",855"enforcedSampleLimit": nil,856"enforcedTargetLimit": nil,857"shards": 1,858},859expect: util.Untab(`860job_name: serviceMonitor/operator/servicemonitor/0861honor_labels: false862kubernetes_sd_configs:863- role: endpoints864namespaces:865names: [operator]866relabel_configs:867- source_labels:868- job869target_label: __tmp_prometheus_job_name870- action: keep871regex: metrics872source_labels:873- __meta_kubernetes_endpoint_port_name874- regex: Node;(.*)875replacement: $1876separator: ;877source_labels:878- __meta_kubernetes_endpoint_address_target_kind879- __meta_kubernetes_endpoint_address_target_name880target_label: node881- regex: Pod;(.*)882replacement: $1883separator: ;884source_labels:885- __meta_kubernetes_endpoint_address_target_kind886- __meta_kubernetes_endpoint_address_target_name887target_label: pod888- source_labels:889- __meta_kubernetes_namespace890target_label: namespace891- source_labels:892- __meta_kubernetes_service_name893target_label: service894- source_labels:895- __meta_kubernetes_pod_name896target_label: pod897- source_labels:898- __meta_kubernetes_pod_container_name899target_label: container900- source_labels: [__meta_kubernetes_pod_phase]901regex: (Failed|Succeeded)902action: drop903- replacement: $1904source_labels:905- __meta_kubernetes_service_name906target_label: job907- replacement: metrics908target_label: endpoint909- action: hashmod910modulus: 1911source_labels:912- __address__913target_label: __tmp_hash914- action: keep915regex: $(SHARD)916source_labels:917- __tmp_hash918`),919},920{921name: "no_filter_running",922input: map[string]interface{}{923"agentNamespace": "operator",924"monitor": prom_v1.ServiceMonitor{925ObjectMeta: meta_v1.ObjectMeta{926Namespace: "operator",927Name: "servicemonitor",928},929},930"endpoint": prom_v1.Endpoint{931Port: "metrics",932},933"index": 0,934"apiServer": prom_v1.APIServerConfig{},935"overrideHonorLabels": false,936"overrideHonorTimestamps": false,937"ignoreNamespaceSelectors": false,938"enforcedNamespaceLabel": "",939"enforcedSampleLimit": nil,940"enforcedTargetLimit": nil,941"shards": 1,942},943expect: util.Untab(`944job_name: serviceMonitor/operator/servicemonitor/0945honor_labels: false946kubernetes_sd_configs:947- role: endpoints948namespaces:949names: [operator]950relabel_configs:951- source_labels:952- job953target_label: __tmp_prometheus_job_name954- action: keep955regex: metrics956source_labels:957- __meta_kubernetes_endpoint_port_name958- regex: Node;(.*)959replacement: $1960separator: ;961source_labels:962- __meta_kubernetes_endpoint_address_target_kind963- __meta_kubernetes_endpoint_address_target_name964target_label: node965- regex: Pod;(.*)966replacement: $1967separator: ;968source_labels:969- __meta_kubernetes_endpoint_address_target_kind970- __meta_kubernetes_endpoint_address_target_name971target_label: pod972- source_labels:973- __meta_kubernetes_namespace974target_label: namespace975- source_labels:976- __meta_kubernetes_service_name977target_label: service978- source_labels:979- __meta_kubernetes_pod_name980target_label: pod981- source_labels:982- __meta_kubernetes_pod_container_name983target_label: container984- replacement: $1985source_labels:986- __meta_kubernetes_service_name987target_label: job988- replacement: metrics989target_label: endpoint990- action: hashmod991modulus: 1992source_labels:993- __address__994target_label: __tmp_hash995- action: keep996regex: $(SHARD)997source_labels:998- __tmp_hash999`),1000},1001}10021003for _, tc := range tt {1004t.Run(tc.name, func(t *testing.T) {1005vm, err := createVM(testStore())1006require.NoError(t, err)10071008args := []string{1009"agentNamespace", "monitor", "endpoint", "index", "apiServer", "overrideHonorLabels",1010"overrideHonorTimestamps", "ignoreNamespaceSelectors", "enforcedNamespaceLabel",1011"enforcedSampleLimit", "enforcedTargetLimit", "shards",1012}1013for _, arg := range args {1014bb, err := jsonnetMarshal(tc.input[arg])1015require.NoError(t, err)1016vm.TLACode(arg, string(bb))1017}10181019actual, err := runSnippet(vm, "./component/metrics/service_monitor.libsonnet", args...)1020require.NoError(t, err)1021if !assert.YAMLEq(t, tc.expect, actual) {1022fmt.Fprintln(os.Stderr, actual)1023}1024})1025}1026}10271028func TestTLSConfig(t *testing.T) {1029tt := []struct {1030name string1031input map[string]interface{}1032expect string1033}{1034{1035name: "passthrough",1036input: map[string]interface{}{1037"namespace": "operator",1038"config": prom_v1.TLSConfig{1039SafeTLSConfig: prom_v1.SafeTLSConfig{1040ServerName: "server",1041InsecureSkipVerify: true,1042CA: prom_v1.SecretOrConfigMap{1043Secret: &v1.SecretKeySelector{1044LocalObjectReference: v1.LocalObjectReference{Name: "obj"},1045Key: "key",1046},1047},1048Cert: prom_v1.SecretOrConfigMap{1049Secret: &v1.SecretKeySelector{1050LocalObjectReference: v1.LocalObjectReference{Name: "obj"},1051Key: "key",1052},1053},1054KeySecret: &v1.SecretKeySelector{1055LocalObjectReference: v1.LocalObjectReference{Name: "obj"},1056Key: "key",1057},1058},1059},1060},1061expect: util.Untab(`1062ca_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key1063cert_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key1064key_file: /var/lib/grafana-agent/secrets/_secrets_operator_obj_key1065server_name: server1066insecure_skip_verify: true1067`),1068},1069{1070name: "overrides",1071input: map[string]interface{}{1072"namespace": "operator",1073"config": prom_v1.TLSConfig{1074SafeTLSConfig: prom_v1.SafeTLSConfig{1075ServerName: "server",1076InsecureSkipVerify: true,1077CA: prom_v1.SecretOrConfigMap{1078Secret: &v1.SecretKeySelector{1079LocalObjectReference: v1.LocalObjectReference{Name: "obj"},1080Key: "key",1081},1082},1083Cert: prom_v1.SecretOrConfigMap{1084Secret: &v1.SecretKeySelector{1085LocalObjectReference: v1.LocalObjectReference{Name: "obj"},1086Key: "key",1087},1088},1089KeySecret: &v1.SecretKeySelector{1090LocalObjectReference: v1.LocalObjectReference{Name: "obj"},1091Key: "key",1092},1093},1094CAFile: "ca",1095CertFile: "cert",1096KeyFile: "key",1097},1098},1099expect: util.Untab(`1100ca_file: ca1101cert_file: cert1102key_file: key1103server_name: server1104insecure_skip_verify: true1105`),1106},1107}11081109for _, tc := range tt {1110t.Run(tc.name, func(t *testing.T) {1111vm, err := createVM(testStore())1112require.NoError(t, err)11131114args := []string{"namespace", "config"}1115for _, arg := range args {1116bb, err := jsonnetMarshal(tc.input[arg])1117require.NoError(t, err)1118vm.TLACode(arg, string(bb))1119}11201121actual, err := runSnippet(vm, "./component/metrics/tls_config.libsonnet", args...)1122require.NoError(t, err)1123require.YAMLEq(t, tc.expect, actual)1124})1125}1126}11271128func runSnippet(vm *jsonnet.VM, filename string, args ...string) (string, error) {1129boundArgs := make([]string, len(args))1130for i := range args {1131boundArgs[i] = fmt.Sprintf("%[1]s=%[1]s", args[i])1132}11331134return vm.EvaluateAnonymousSnippet(1135filename,1136fmt.Sprintf(`1137local marshal = import './ext/marshal.libsonnet';1138local optionals = import './ext/optionals.libsonnet';1139local eval = import '%s';1140function(%s) marshal.YAML(optionals.trim(eval(%s)))1141`, filename, strings.Join(args, ","), strings.Join(boundArgs, ",")),1142)1143}11441145func testStore() assets.SecretStore {1146store := make(assets.SecretStore)11471148store[assets.KeyForConfigMap("operator", &v1.ConfigMapKeySelector{1149LocalObjectReference: v1.LocalObjectReference{Name: "obj"},1150Key: "key",1151})] = "secretcm"11521153store[assets.KeyForSecret("operator", &v1.SecretKeySelector{1154LocalObjectReference: v1.LocalObjectReference{Name: "obj"},1155Key: "key",1156})] = "secretkey"11571158return store1159}116011611162