Merge pull request #747 from enj/enj/i/delete_race

certs_expirer: be specific about what secret to delete
This commit is contained in:
Mo Khan 2021-07-28 10:32:17 -04:00 committed by GitHub
commit ef33846d7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 4 deletions

View File

@ -90,7 +90,12 @@ func (c *certsExpirerController) Sync(ctx controllerlib.Context) error {
err := c.k8sClient.
CoreV1().
Secrets(c.namespace).
Delete(ctx.Context, c.certsSecretResourceName, metav1.DeleteOptions{})
Delete(ctx.Context, c.certsSecretResourceName, metav1.DeleteOptions{
Preconditions: &metav1.Preconditions{
UID: &secret.UID,
ResourceVersion: &secret.ResourceVersion,
},
})
if err != nil {
// Do return an error here so that the controller library will reschedule
// us to try deleting this cert again.

View File

@ -18,8 +18,11 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
kubeinformers "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes"
kubernetesfake "k8s.io/client-go/kubernetes/fake"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
kubetesting "k8s.io/client-go/testing"
"go.pinniped.dev/internal/controllerlib"
@ -223,6 +226,9 @@ func TestExpirerControllerSync(t *testing.T) {
test.configKubeAPIClient(kubeAPIClient)
}
testRV := "rv_001"
testUID := types.UID("uid_002")
kubeInformerClient := kubernetesfake.NewSimpleClientset()
name := certsSecretResourceName
namespace := "some-namespace"
@ -231,6 +237,8 @@ func TestExpirerControllerSync(t *testing.T) {
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
ResourceVersion: testRV,
UID: testUID,
},
Data: map[string][]byte{},
}
@ -245,10 +253,12 @@ func TestExpirerControllerSync(t *testing.T) {
0,
)
trackDeleteClient := &clientWrapper{Interface: kubeAPIClient, opts: &[]metav1.DeleteOptions{}}
c := NewCertsExpirerController(
namespace,
certsSecretResourceName,
kubeAPIClient,
trackDeleteClient,
kubeInformers.Core().V1().Secrets(),
controllerlib.WithInformer,
test.renewBefore,
@ -285,6 +295,46 @@ func TestExpirerControllerSync(t *testing.T) {
}
acActions := kubeAPIClient.Actions()
require.Equal(t, exActions, acActions)
if test.wantDelete {
require.Len(t, *trackDeleteClient.opts, 1)
require.Equal(t, metav1.DeleteOptions{
Preconditions: &metav1.Preconditions{
UID: &testUID,
ResourceVersion: &testRV,
},
}, (*trackDeleteClient.opts)[0])
} else {
require.Len(t, *trackDeleteClient.opts, 0)
}
})
}
}
type clientWrapper struct {
kubernetes.Interface
opts *[]metav1.DeleteOptions
}
func (c *clientWrapper) CoreV1() corev1client.CoreV1Interface {
return &coreWrapper{CoreV1Interface: c.Interface.CoreV1(), opts: c.opts}
}
type coreWrapper struct {
corev1client.CoreV1Interface
opts *[]metav1.DeleteOptions
}
func (c *coreWrapper) Secrets(namespace string) corev1client.SecretInterface {
return &secretsWrapper{SecretInterface: c.CoreV1Interface.Secrets(namespace), opts: c.opts}
}
type secretsWrapper struct {
corev1client.SecretInterface
opts *[]metav1.DeleteOptions
}
func (s *secretsWrapper) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error {
*s.opts = append(*s.opts, opts)
return s.SecretInterface.Delete(ctx, name, opts)
}