Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for debugging #245

Merged
merged 2 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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()
}

Expand Down Expand Up @@ -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{}
Expand Down
6 changes: 6 additions & 0 deletions pkg/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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{}
}
32 changes: 32 additions & 0 deletions pkg/cache/debug/debug.go
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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)
}
}
4 changes: 4 additions & 0 deletions pkg/cache/fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,7 @@ func (f *FakeServiceAccountCache) ToJSON() string {
}
return string(contents)
}

func (f *FakeServiceAccountCache) Clear() {
f.cache = map[string]*Entry{}
}
Loading