Skip to content

Commit c8e5814

Browse files
authored
Merge pull request #3302 from emerbe/MakePrometheusSecretCreationIdempotent
Make Prometheus secret creation idempotent
2 parents c6ad58d + 54173d6 commit c8e5814

File tree

1 file changed

+64
-16
lines changed

1 file changed

+64
-16
lines changed

clusterloader2/pkg/prometheus/prometheus.go

Lines changed: 64 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ const (
5050
storageClass = "ssd"
5151
checkPrometheusReadyInterval = 30 * time.Second
5252
numK8sClients = 1
53+
monitoringServiceAccount = "monitoringserviceaccount"
54+
secretName = "prometheus-token"
5355

5456
// All paths here are relative to manifests dir.
5557
coreManifests = "*.yaml"
@@ -60,7 +62,6 @@ const (
6062
nodeExporterPod = "exporters/node_exporter/node-exporter.yaml"
6163
windowsNodeExporterManifests = "exporters/windows_node_exporter/*.yaml"
6264
pushgatewayManifests = "pushgateway/*.yaml"
63-
monitoringServiceAccount = "monitoringserviceaccount"
6465
)
6566

6667
//go:embed manifests
@@ -393,10 +394,6 @@ func (pc *Controller) createToken(k8sClient kubernetes.Interface, testClusterCli
393394
Name: monitoringServiceAccount,
394395
},
395396
}
396-
serviceAccount := func() error {
397-
_, err := testClusterClientSet.CoreV1().ServiceAccounts(corev1.NamespaceDefault).Create(context.TODO(), saObj, metav1.CreateOptions{})
398-
return err
399-
}
400397

401398
token := func() (string, error) {
402399
expirationSeconds := int64(86400) // 24h
@@ -415,30 +412,81 @@ func (pc *Controller) createToken(k8sClient kubernetes.Interface, testClusterCli
415412
return tokenResp.Status.Token, nil
416413
}
417414

415+
secret := func(token string) *corev1.Secret {
416+
return &corev1.Secret{
417+
ObjectMeta: metav1.ObjectMeta{
418+
Name: secretName,
419+
Namespace: namespace,
420+
},
421+
Data: map[string][]byte{
422+
"token": []byte(token),
423+
},
424+
Type: corev1.SecretTypeOpaque,
425+
}
426+
}
427+
428+
serviceAccount := func() error {
429+
_, err := testClusterClientSet.CoreV1().ServiceAccounts(corev1.NamespaceDefault).Create(context.TODO(), saObj, metav1.CreateOptions{})
430+
return err
431+
}
432+
433+
// Check if the service account already exists
434+
_, err := testClusterClientSet.CoreV1().ServiceAccounts(corev1.NamespaceDefault).Get(context.TODO(), saObj.Name, metav1.GetOptions{})
435+
if err == nil {
436+
// Service account exists already. This mean the test is run again in cluster created previously
437+
// Secret should be created OR should be updated if exists
438+
tokenResponse, err := retryCreateFunctionWithResponse(token)
439+
if err != nil {
440+
return err
441+
}
442+
secret := secret(tokenResponse)
443+
err = createPrometheusSecretForExistingServiceAccount(k8sClient, secret)
444+
if err != nil {
445+
return err
446+
}
447+
return nil
448+
}
449+
// If ServiceAccount could not be retrieved but the error is not "not found", return it
450+
if !apierrs.IsNotFound(err) {
451+
return err
452+
}
418453
if err := retryCreateFunction(serviceAccount); err != nil {
419454
return err
420455
}
421456
tokenResponse, err := retryCreateFunctionWithResponse(token)
422457
if err != nil {
423458
return err
424459
}
425-
secret := &corev1.Secret{
426-
ObjectMeta: metav1.ObjectMeta{
427-
Name: "prometheus-token",
428-
Namespace: namespace,
429-
},
430-
Data: map[string][]byte{
431-
"token": []byte(tokenResponse),
432-
},
433-
Type: corev1.SecretTypeOpaque,
434-
}
435-
_, err = k8sClient.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
460+
_, err = k8sClient.CoreV1().Secrets(namespace).Create(context.TODO(), secret(tokenResponse), metav1.CreateOptions{})
436461
if err != nil {
437462
return err
438463
}
439464
return nil
440465
}
441466

467+
func createPrometheusSecretForExistingServiceAccount(k8sClient kubernetes.Interface, secret *corev1.Secret) error {
468+
// Check if the secret already exists
469+
_, inErr := k8sClient.CoreV1().Secrets(namespace).Get(context.TODO(), secretName, metav1.GetOptions{})
470+
if inErr == nil {
471+
// Secret already exists, update it
472+
_, inErr = k8sClient.CoreV1().Secrets(namespace).Update(context.TODO(), secret, metav1.UpdateOptions{})
473+
if inErr != nil {
474+
return fmt.Errorf("failed to update secret %s in namespace %s: %w", secretName, namespace, inErr)
475+
}
476+
return nil
477+
}
478+
if apierrs.IsNotFound(inErr) {
479+
// Secret doesn't exist, create it
480+
_, inErr = k8sClient.CoreV1().Secrets(namespace).Create(context.TODO(), secret, metav1.CreateOptions{})
481+
if inErr != nil {
482+
return fmt.Errorf("failed to create secret %s in namespace %s: %w", secretName, namespace, inErr)
483+
}
484+
return nil
485+
}
486+
// Error occurred while trying to get the secret
487+
return inErr
488+
}
489+
442490
// configureRBACForMetrics creates a ClusterRole and ClusterRoleBinding
443491
// to allow the monitoringServiceAccount (used by Prometheus) to scrape metrics.
444492
func (pc *Controller) configureRBACForMetrics(testClusterClientSet kubernetes.Interface) error {

0 commit comments

Comments
 (0)