diff --git a/main.go b/main.go index 17294659d..d155a9815 100644 --- a/main.go +++ b/main.go @@ -88,6 +88,8 @@ func main() { saLookupGracePeriod := flag.Duration("service-account-lookup-grace-period", 0, "The grace period for service account to be available in cache before not mutating a pod. Defaults to 0, what deactivates waiting. Carefully use values higher than a bunch of milliseconds as it may have significant impact on Kubernetes' pod scheduling performance.") + resyncPeriod := flag.Duration("resync-period", 60*time.Second, "The period to resync the SA informer cache, in seconds.") + klog.InitFlags(goflag.CommandLine) // Add klog CommandLine flags to pflag CommandLine goflag.CommandLine.VisitAll(func(f *goflag.Flag) { @@ -118,13 +120,13 @@ func main() { if err != nil { klog.Fatalf("Error creating clientset: %v", err.Error()) } - informerFactory := informers.NewSharedInformerFactory(clientset, 60*time.Second) + informerFactory := informers.NewSharedInformerFactory(clientset, *resyncPeriod) var cmInformer v1.ConfigMapInformer var nsInformerFactory informers.SharedInformerFactory if *watchConfigMap { klog.Infof("Watching ConfigMap pod-identity-webhook in %s namespace", *namespaceName) - nsInformerFactory = informers.NewSharedInformerFactoryWithOptions(clientset, 60*time.Second, informers.WithNamespace(*namespaceName)) + nsInformerFactory = informers.NewSharedInformerFactoryWithOptions(clientset, *resyncPeriod, informers.WithNamespace(*namespaceName)) cmInformer = nsInformerFactory.Core().V1().ConfigMaps() } @@ -237,7 +239,18 @@ func main() { } // Reuse metrics port to avoid exposing a new port metricsMux.HandleFunc("/debug/alpha/cache", debugger.Handle) + metricsMux.HandleFunc("/debug/alpha/cache/clear", debugger.Clear) // Expose other debug paths + mux.Handle("/debug/alpha/deny", handler.Apply( + http.HandlerFunc(debugger.Deny), + handler.InstrumentRoute(), + handler.Logging(), + )) + mux.Handle("/debug/alpha/500", handler.Apply( + http.HandlerFunc(debugger.InternalServerError), + handler.InstrumentRoute(), + handler.Logging(), + )) } tlsConfig := &tls.Config{} diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go index 55b5885f7..44d78e47f 100644 --- a/pkg/cache/cache.go +++ b/pkg/cache/cache.go @@ -65,6 +65,7 @@ type ServiceAccountCache interface { GetCommonConfigurations(name, namespace string) (useRegionalSTS bool, tokenExpiration int64) // ToJSON returns cache contents as JSON string ToJSON() string + Clear() } type serviceAccountCache struct { @@ -398,3 +399,8 @@ func (c *serviceAccountCache) start(stop chan struct{}) { func (c *serviceAccountCache) Start(stop chan struct{}) { go c.start(stop) } + +func (c *serviceAccountCache) Clear() { + c.saCache = map[string]*Entry{} + c.cmCache = map[string]*Entry{} +} diff --git a/pkg/cache/debug/debug.go b/pkg/cache/debug/debug.go index c1c612e60..f081bec39 100644 --- a/pkg/cache/debug/debug.go +++ b/pkg/cache/debug/debug.go @@ -1,10 +1,14 @@ package debug import ( + "encoding/json" "fmt" "github.com/aws/amazon-eks-pod-identity-webhook/pkg/cache" + "k8s.io/api/admission/v1beta1" "k8s.io/klog/v2" "net/http" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type Dumper struct { @@ -18,3 +22,31 @@ func (c *Dumper) Handle(w http.ResponseWriter, r *http.Request) { http.Error(w, fmt.Sprintf("could not write response: %v", err), http.StatusInternalServerError) } } + +func (c *Dumper) Clear(w http.ResponseWriter, r *http.Request) { + c.Cache.Clear() +} + +func (c *Dumper) InternalServerError(w http.ResponseWriter, r *http.Request) { + http.Error(w, "test error", http.StatusInternalServerError) +} + +func (c *Dumper) Deny(w http.ResponseWriter, r *http.Request) { + admissionReview := &v1beta1.AdmissionReview{ + Response: &v1beta1.AdmissionResponse{ + Allowed: false, + Result: &metav1.Status{ + Message: "Test deny message", + }, + }, + } + resp, err := json.Marshal(admissionReview) + if err != nil { + klog.Errorf("Can't encode response: %v", err) + http.Error(w, fmt.Sprintf("could not encode response: %v", err), http.StatusInternalServerError) + } + if _, err := w.Write(resp); err != nil { + klog.Errorf("Can't write response: %v", err) + http.Error(w, fmt.Sprintf("could not write response: %v", err), http.StatusInternalServerError) + } +} diff --git a/pkg/cache/fake.go b/pkg/cache/fake.go index eeae6629e..106813611 100644 --- a/pkg/cache/fake.go +++ b/pkg/cache/fake.go @@ -98,3 +98,7 @@ func (f *FakeServiceAccountCache) ToJSON() string { } return string(contents) } + +func (f *FakeServiceAccountCache) Clear() { + f.cache = map[string]*Entry{} +}