Skip to content

Commit ca0c27a

Browse files
Retry when getting the pod_environment_secret (zalando#1777)
* Retry when getting the pod_environment_secret
1 parent da83982 commit ca0c27a

File tree

3 files changed

+66
-12
lines changed

3 files changed

+66
-12
lines changed

docs/developer.md

+7
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,13 @@ dlv connect 127.0.0.1:DLV_PORT
218218

219219
## Unit tests
220220

221+
Prerequisites:
222+
223+
```bash
224+
make deps
225+
make mocks
226+
```
227+
221228
To run all unit tests, you can simply do:
222229

223230
```bash

pkg/cluster/k8sres.go

+26-5
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import (
88
"sort"
99
"strings"
1010

11+
"github.com/pkg/errors"
1112
"github.com/sirupsen/logrus"
1213

1314
appsv1 "k8s.io/api/apps/v1"
1415
v1 "k8s.io/api/core/v1"
1516
policybeta1 "k8s.io/api/policy/v1beta1"
17+
apierrors "k8s.io/apimachinery/pkg/api/errors"
1618
"k8s.io/apimachinery/pkg/api/resource"
1719
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1820
"k8s.io/apimachinery/pkg/types"
@@ -24,6 +26,7 @@ import (
2426
"github.com/zalando/postgres-operator/pkg/util/config"
2527
"github.com/zalando/postgres-operator/pkg/util/constants"
2628
"github.com/zalando/postgres-operator/pkg/util/k8sutil"
29+
"github.com/zalando/postgres-operator/pkg/util/retryutil"
2730
batchv1 "k8s.io/api/batch/v1"
2831
batchv1beta1 "k8s.io/api/batch/v1beta1"
2932
"k8s.io/apimachinery/pkg/labels"
@@ -897,12 +900,30 @@ func (c *Cluster) getPodEnvironmentSecretVariables() ([]v1.EnvVar, error) {
897900
return secretPodEnvVarsList, nil
898901
}
899902

900-
secret, err := c.KubeClient.Secrets(c.Namespace).Get(
901-
context.TODO(),
902-
c.OpConfig.PodEnvironmentSecret,
903-
metav1.GetOptions{})
903+
secret := &v1.Secret{}
904+
var notFoundErr error
905+
err := retryutil.Retry(c.OpConfig.ResourceCheckInterval, c.OpConfig.ResourceCheckTimeout,
906+
func() (bool, error) {
907+
var err error
908+
secret, err = c.KubeClient.Secrets(c.Namespace).Get(
909+
context.TODO(),
910+
c.OpConfig.PodEnvironmentSecret,
911+
metav1.GetOptions{})
912+
if err != nil {
913+
if apierrors.IsNotFound(err) {
914+
notFoundErr = err
915+
return false, nil
916+
}
917+
return false, err
918+
}
919+
return true, nil
920+
},
921+
)
922+
if notFoundErr != nil && err != nil {
923+
err = errors.Wrap(notFoundErr, err.Error())
924+
}
904925
if err != nil {
905-
return nil, fmt.Errorf("could not read Secret PodEnvironmentSecretName: %v", err)
926+
return nil, errors.Wrap(err, "could not read Secret PodEnvironmentSecretName")
906927
}
907928

908929
for k := range secret.Data {

pkg/cluster/k8sres_test.go

+33-7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"reflect"
77
"sort"
8+
"time"
89

910
"testing"
1011

@@ -21,8 +22,10 @@ import (
2122
appsv1 "k8s.io/api/apps/v1"
2223
v1 "k8s.io/api/core/v1"
2324
policyv1beta1 "k8s.io/api/policy/v1beta1"
25+
k8serrors "k8s.io/apimachinery/pkg/api/errors"
2426
"k8s.io/apimachinery/pkg/api/resource"
2527
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
"k8s.io/apimachinery/pkg/runtime/schema"
2629
"k8s.io/apimachinery/pkg/types"
2730
"k8s.io/client-go/kubernetes/fake"
2831
v1core "k8s.io/client-go/kubernetes/typed/core/v1"
@@ -640,8 +643,12 @@ func TestSecretVolume(t *testing.T) {
640643
}
641644

642645
const (
643-
testPodEnvironmentConfigMapName = "pod_env_cm"
644-
testPodEnvironmentSecretName = "pod_env_sc"
646+
testPodEnvironmentConfigMapName = "pod_env_cm"
647+
testPodEnvironmentSecretName = "pod_env_sc"
648+
testPodEnvironmentObjectNotExists = "idonotexist"
649+
testPodEnvironmentSecretNameAPIError = "pod_env_sc_apierror"
650+
testResourceCheckInterval = 3
651+
testResourceCheckTimeout = 10
645652
)
646653

647654
type mockSecret struct {
@@ -653,8 +660,11 @@ type mockConfigMap struct {
653660
}
654661

655662
func (c *mockSecret) Get(ctx context.Context, name string, options metav1.GetOptions) (*v1.Secret, error) {
663+
if name == testPodEnvironmentSecretNameAPIError {
664+
return nil, fmt.Errorf("Secret PodEnvironmentSecret API error")
665+
}
656666
if name != testPodEnvironmentSecretName {
657-
return nil, fmt.Errorf("Secret PodEnvironmentSecret not found")
667+
return nil, k8serrors.NewNotFound(schema.GroupResource{Group: "core", Resource: "secret"}, name)
658668
}
659669
secret := &v1.Secret{}
660670
secret.Name = testPodEnvironmentSecretName
@@ -723,7 +733,7 @@ func TestPodEnvironmentConfigMapVariables(t *testing.T) {
723733
opConfig: config.Config{
724734
Resources: config.Resources{
725735
PodEnvironmentConfigMap: spec.NamespacedName{
726-
Name: "idonotexist",
736+
Name: testPodEnvironmentObjectNotExists,
727737
},
728738
},
729739
},
@@ -774,6 +784,7 @@ func TestPodEnvironmentConfigMapVariables(t *testing.T) {
774784

775785
// Test if the keys of an existing secret are properly referenced
776786
func TestPodEnvironmentSecretVariables(t *testing.T) {
787+
maxRetries := int(testResourceCheckTimeout / testResourceCheckInterval)
777788
testName := "TestPodEnvironmentSecretVariables"
778789
tests := []struct {
779790
subTest string
@@ -789,16 +800,31 @@ func TestPodEnvironmentSecretVariables(t *testing.T) {
789800
subTest: "Secret referenced by PodEnvironmentSecret does not exist",
790801
opConfig: config.Config{
791802
Resources: config.Resources{
792-
PodEnvironmentSecret: "idonotexist",
803+
PodEnvironmentSecret: testPodEnvironmentObjectNotExists,
804+
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
805+
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
806+
},
807+
},
808+
err: fmt.Errorf("could not read Secret PodEnvironmentSecretName: still failing after %d retries: secret.core %q not found", maxRetries, testPodEnvironmentObjectNotExists),
809+
},
810+
{
811+
subTest: "API error during PodEnvironmentSecret retrieval",
812+
opConfig: config.Config{
813+
Resources: config.Resources{
814+
PodEnvironmentSecret: testPodEnvironmentSecretNameAPIError,
815+
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
816+
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
793817
},
794818
},
795-
err: fmt.Errorf("could not read Secret PodEnvironmentSecretName: Secret PodEnvironmentSecret not found"),
819+
err: fmt.Errorf("could not read Secret PodEnvironmentSecretName: Secret PodEnvironmentSecret API error"),
796820
},
797821
{
798822
subTest: "Pod environment vars reference all keys from secret configured by PodEnvironmentSecret",
799823
opConfig: config.Config{
800824
Resources: config.Resources{
801-
PodEnvironmentSecret: testPodEnvironmentSecretName,
825+
PodEnvironmentSecret: testPodEnvironmentSecretName,
826+
ResourceCheckInterval: time.Duration(testResourceCheckInterval),
827+
ResourceCheckTimeout: time.Duration(testResourceCheckTimeout),
802828
},
803829
},
804830
envVars: []v1.EnvVar{

0 commit comments

Comments
 (0)