mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-09-05 15:47:02 +00:00
Merge branch 'main' into initial_ldap
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020 the Pinniped contributors. All Rights Reserved.
|
||||
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package supervisorstorage
|
||||
@@ -59,7 +59,7 @@ func GarbageCollectorController(
|
||||
return isSecretWithGCAnnotation(oldObj) || isSecretWithGCAnnotation(newObj)
|
||||
},
|
||||
DeleteFunc: func(obj metav1.Object) bool { return false }, // ignore all deletes
|
||||
ParentFunc: nil,
|
||||
ParentFunc: pinnipedcontroller.SingletonQueue(),
|
||||
},
|
||||
controllerlib.InformerOption{},
|
||||
),
|
||||
@@ -67,16 +67,20 @@ func GarbageCollectorController(
|
||||
}
|
||||
|
||||
func (c *garbageCollectorController) Sync(ctx controllerlib.Context) error {
|
||||
// make sure we have a consistent, static meaning for the current time during the sync loop
|
||||
frozenClock := clock.NewFakeClock(c.clock.Now())
|
||||
|
||||
// The Sync method is triggered upon any change to any Secret, which would make this
|
||||
// controller too chatty, so it rate limits itself to a more reasonable interval.
|
||||
// Note that even during a period when no secrets are changing, it will still run
|
||||
// at the informer's full-resync interval (as long as there are some secrets).
|
||||
if c.clock.Now().Sub(c.timeOfMostRecentSweep) < minimumRepeatInterval {
|
||||
if since := frozenClock.Since(c.timeOfMostRecentSweep); since < minimumRepeatInterval {
|
||||
ctx.Queue.AddAfter(ctx.Key, minimumRepeatInterval-since)
|
||||
return nil
|
||||
}
|
||||
|
||||
plog.Info("starting storage garbage collection sweep")
|
||||
c.timeOfMostRecentSweep = c.clock.Now()
|
||||
c.timeOfMostRecentSweep = frozenClock.Now()
|
||||
|
||||
listOfSecrets, err := c.secretInformer.Lister().List(labels.Everything())
|
||||
if err != nil {
|
||||
@@ -97,7 +101,7 @@ func (c *garbageCollectorController) Sync(ctx controllerlib.Context) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if garbageCollectAfterTime.Before(c.clock.Now()) {
|
||||
if garbageCollectAfterTime.Before(frozenClock.Now()) {
|
||||
err = c.kubeClient.CoreV1().Secrets(secret.Namespace).Delete(ctx.Context, secret.Name, metav1.DeleteOptions{})
|
||||
if err != nil {
|
||||
plog.WarningErr("failed to garbage collect resource", err, logKV(secret))
|
||||
|
||||
@@ -66,6 +66,10 @@ func TestGarbageCollectorControllerInformerFilters(t *testing.T) {
|
||||
r.True(subject.Update(secretWithAnnotation, otherSecret))
|
||||
r.True(subject.Update(otherSecret, secretWithAnnotation))
|
||||
})
|
||||
|
||||
it("returns the same singleton key", func() {
|
||||
r.Equal(controllerlib.Key{}, subject.Parent(secretWithAnnotation))
|
||||
})
|
||||
})
|
||||
|
||||
when("any Secret with the required annotation is deleted", func() {
|
||||
@@ -136,9 +140,10 @@ func TestGarbageCollectorControllerSync(t *testing.T) {
|
||||
Context: cancelContext,
|
||||
Name: subject.Name(),
|
||||
Key: controllerlib.Key{
|
||||
Namespace: "",
|
||||
Name: "",
|
||||
Namespace: "foo",
|
||||
Name: "bar",
|
||||
},
|
||||
Queue: &testQueue{t: t},
|
||||
}
|
||||
|
||||
// Must start informers before calling TestRunSynchronously()
|
||||
@@ -262,16 +267,23 @@ func TestGarbageCollectorControllerSync(t *testing.T) {
|
||||
// Run sync once with the current time set to frozenTime.
|
||||
r.NoError(controllerlib.TestSync(t, subject, *syncContext))
|
||||
require.Empty(t, kubeClient.Actions())
|
||||
r.False(syncContext.Queue.(*testQueue).called)
|
||||
|
||||
// Run sync again when not enough time has passed since the most recent run, so no delete
|
||||
// operations should happen even though there is a expired secret now.
|
||||
fakeClock.Step(29 * time.Second)
|
||||
r.NoError(controllerlib.TestSync(t, subject, *syncContext))
|
||||
require.Empty(t, kubeClient.Actions())
|
||||
r.True(syncContext.Queue.(*testQueue).called)
|
||||
r.Equal(controllerlib.Key{Namespace: "foo", Name: "bar"}, syncContext.Queue.(*testQueue).key) // assert key is passed through
|
||||
r.Equal(time.Second, syncContext.Queue.(*testQueue).duration) // assert that we get the exact requeue time
|
||||
|
||||
syncContext.Queue = &testQueue{t: t} // reset the queue for the next sync
|
||||
|
||||
// Step to the exact threshold and run Sync again. Now we are past the rate limiting period.
|
||||
fakeClock.Step(1*time.Second + 1*time.Millisecond)
|
||||
fakeClock.Step(time.Second)
|
||||
r.NoError(controllerlib.TestSync(t, subject, *syncContext))
|
||||
r.False(syncContext.Queue.(*testQueue).called)
|
||||
|
||||
// It should have deleted the expired secret.
|
||||
r.ElementsMatch(
|
||||
@@ -381,3 +393,23 @@ func TestGarbageCollectorControllerSync(t *testing.T) {
|
||||
})
|
||||
}, spec.Parallel(), spec.Report(report.Terminal{}))
|
||||
}
|
||||
|
||||
type testQueue struct {
|
||||
t *testing.T
|
||||
|
||||
called bool
|
||||
key controllerlib.Key
|
||||
duration time.Duration
|
||||
|
||||
controllerlib.Queue // panic if any other methods called
|
||||
}
|
||||
|
||||
func (q *testQueue) AddAfter(key controllerlib.Key, duration time.Duration) {
|
||||
q.t.Helper()
|
||||
|
||||
require.False(q.t, q.called, "AddAfter should only be called once")
|
||||
|
||||
q.called = true
|
||||
q.key = key
|
||||
q.duration = duration
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user