@@ -22,7 +22,10 @@ import (
22
22
"github.com/go-logr/logr"
23
23
"github.com/google/go-cmp/cmp"
24
24
"github.com/prometheus/prometheus/config"
25
+ "github.com/stretchr/testify/require"
25
26
"gopkg.in/yaml.v3"
27
+ corev1 "k8s.io/api/core/v1"
28
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26
29
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27
30
"k8s.io/apimachinery/pkg/types"
28
31
"k8s.io/utils/ptr"
@@ -257,3 +260,162 @@ func TestEnsureOperatorConfig(t *testing.T) {
257
260
})
258
261
}
259
262
}
263
+
264
+ // Regression against https://github.com/GoogleCloudPlatform/prometheus-engine/issues/1550
265
+ func TestEnsureAlertmanagerConfigSecret (t * testing.T ) {
266
+ operatorOpts := Options {
267
+ ProjectID : "test-project" ,
268
+ Location : "us-central1-c" ,
269
+ Cluster : "test-cluster" ,
270
+ PublicNamespace : DefaultPublicNamespace ,
271
+ OperatorNamespace : DefaultOperatorNamespace ,
272
+ }
273
+ for _ , tcase := range []struct {
274
+ name string
275
+ operatorConfigManagedAMExtURL string
276
+ amConfig string
277
+
278
+ expectedAmConfig string
279
+ }{
280
+ {
281
+ name : "with secret; no external url" ,
282
+ amConfig : `
283
+ route:
284
+ receiver: "slack"
285
+ receivers:
286
+ - name: "slack"
287
+ slack_configs:
288
+ - channel: '#some_channel'
289
+ api_url: https://slack.com/api/chat.postMessage
290
+ http_config:
291
+ authorization:
292
+ type: 'Bearer'
293
+ credentials: 'SUPER IMPORTANT SECRET'
294
+ ` ,
295
+ expectedAmConfig : `
296
+ route:
297
+ receiver: "slack"
298
+ receivers:
299
+ - name: "slack"
300
+ slack_configs:
301
+ - channel: '#some_channel'
302
+ api_url: https://slack.com/api/chat.postMessage
303
+ http_config:
304
+ authorization:
305
+ type: 'Bearer'
306
+ credentials: 'SUPER IMPORTANT SECRET'
307
+ ` ,
308
+ },
309
+ {
310
+ name : "with secret; set external url with the same values" ,
311
+ operatorConfigManagedAMExtURL : "https://alertmanager.mycompany.com/" ,
312
+ amConfig : `
313
+ google_cloud:
314
+ # Must be exactly the same value as in OperatorConfig.managedAlertmanager.externalURL,
315
+ # so buggy re-encoding is skipped until the 0.14.3 bugfix is rolled.
316
+ external_url: "https://alertmanager.mycompany.com/"
317
+ route:
318
+ receiver: "slack"
319
+ receivers:
320
+ - name: "slack"
321
+ slack_configs:
322
+ - channel: '#some_channel'
323
+ api_url: https://slack.com/api/chat.postMessage
324
+ http_config:
325
+ authorization:
326
+ type: 'Bearer'
327
+ credentials: 'SUPER IMPORTANT SECRET'
328
+ ` ,
329
+ expectedAmConfig : `
330
+ google_cloud:
331
+ # Must be exactly the same value as in OperatorConfig.managedAlertmanager.externalURL,
332
+ # so buggy re-encoding is skipped until the 0.14.3 bugfix is rolled.
333
+ external_url: "https://alertmanager.mycompany.com/"
334
+ route:
335
+ receiver: "slack"
336
+ receivers:
337
+ - name: "slack"
338
+ slack_configs:
339
+ - channel: '#some_channel'
340
+ api_url: https://slack.com/api/chat.postMessage
341
+ http_config:
342
+ authorization:
343
+ type: 'Bearer'
344
+ credentials: 'SUPER IMPORTANT SECRET'
345
+ ` ,
346
+ },
347
+ // This is expected to fail until https://github.com/GoogleCloudPlatform/prometheus-engine/issues/1550 is fixed.
348
+ {
349
+ name : "with secret; external url set in operator config, but not in am yaml" ,
350
+ operatorConfigManagedAMExtURL : "https://alertmanager.mycompany.com/" ,
351
+ amConfig : `
352
+ route:
353
+ receiver: "slack"
354
+ receivers:
355
+ - name: "slack"
356
+ slack_configs:
357
+ - channel: '#some_channel'
358
+ api_url: https://slack.com/api/chat.postMessage
359
+ http_config:
360
+ authorization:
361
+ type: 'Bearer'
362
+ credentials: 'SUPER IMPORTANT SECRET'
363
+ ` ,
364
+ expectedAmConfig : `
365
+ route:
366
+ receiver: "slack"
367
+ receivers:
368
+ - name: "slack"
369
+ slack_configs:
370
+ - channel: '#some_channel'
371
+ api_url: https://slack.com/api/chat.postMessage
372
+ http_config:
373
+ authorization:
374
+ type: 'Bearer'
375
+ credentials: 'SUPER IMPORTANT SECRET'
376
+ ` ,
377
+ },
378
+ } {
379
+ t .Run (tcase .name , func (t * testing.T ) {
380
+ operatorConfig := & monitoringv1.OperatorConfig {
381
+ ObjectMeta : v1.ObjectMeta {
382
+ Namespace : DefaultPublicNamespace ,
383
+ Name : NameOperatorConfig ,
384
+ },
385
+ ManagedAlertmanager : & monitoringv1.ManagedAlertmanagerSpec {
386
+ ConfigSecret : & corev1.SecretKeySelector {
387
+ LocalObjectReference : corev1.LocalObjectReference {
388
+ Name : AlertmanagerSecretName ,
389
+ },
390
+ Key : AlertmanagerConfigKey ,
391
+ },
392
+ ExternalURL : tcase .operatorConfigManagedAMExtURL ,
393
+ },
394
+ }
395
+ amSecret := & corev1.Secret {
396
+ ObjectMeta : metav1.ObjectMeta {
397
+ Name : AlertmanagerSecretName ,
398
+ Namespace : DefaultPublicNamespace ,
399
+ Annotations : componentAnnotations (),
400
+ Labels : alertmanagerLabels (),
401
+ },
402
+ Data : map [string ][]byte {AlertmanagerConfigKey : []byte (tcase .amConfig )},
403
+ }
404
+
405
+ ctx := context .Background ()
406
+ fakeClient := newFakeClientBuilder ().WithObjects (
407
+ operatorConfig .DeepCopy (),
408
+ amSecret .DeepCopy (),
409
+ )
410
+ kubeClient := fakeClient .Build ()
411
+ reconciler := newOperatorConfigReconciler (kubeClient , operatorOpts )
412
+ require .NoError (t , reconciler .ensureAlertmanagerConfigSecret (ctx , operatorConfig .ManagedAlertmanager ))
413
+
414
+ // Get output secret from gmp-system.
415
+ b , err := getSecretKeyBytes (ctx , kubeClient , DefaultOperatorNamespace , operatorConfig .ManagedAlertmanager .ConfigSecret )
416
+ require .NoError (t , err )
417
+
418
+ require .Equal (t , tcase .expectedAmConfig , string (b ))
419
+ })
420
+ }
421
+ }
0 commit comments