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