From 0011552afd056b357b2677bdd6b7bd340c73c9f4 Mon Sep 17 00:00:00 2001 From: rileydakota Date: Fri, 10 Jun 2022 18:42:51 -0400 Subject: [PATCH 1/2] add autodetect support for imdsv2 in aws --- cmd/kubeletmein/generate.go | 6 +++++ pkg/autodetect/autodetect.go | 37 ++++++++++++++++++++++++++----- pkg/autodetect/autodetect_test.go | 34 ++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 6 deletions(-) diff --git a/cmd/kubeletmein/generate.go b/cmd/kubeletmein/generate.go index fab0a06..cff61bc 100644 --- a/cmd/kubeletmein/generate.go +++ b/cmd/kubeletmein/generate.go @@ -55,6 +55,12 @@ func Generate(c *config.Config) *cobra.Command { if err != nil { return err } + case "eks-imdsv2": + logger.Info("EKS using IMDSv2 detected") + err := eks.Generate(c) + if err != nil { + return err + } case "autodetect": logger.Debug("autodetect? We should not have got here") default: diff --git a/pkg/autodetect/autodetect.go b/pkg/autodetect/autodetect.go index 40c18d3..db26132 100644 --- a/pkg/autodetect/autodetect.go +++ b/pkg/autodetect/autodetect.go @@ -12,8 +12,10 @@ type Providers map[string]Provider // Provider stores the details of each cloud provider type Provider struct { Path string - Header map[string]string + RequestHeader map[string]string + ResponseHeader map[string]string ExpectedStatusCode int + Method string } // Client wraps http.Client so we can mock @@ -30,17 +32,30 @@ var ( PublicCloudProviders = Providers{ "gke": Provider{ Path: "/", - Header: map[string]string{"Server": "Metadata Server for VM"}, + Method: "GET", + RequestHeader: map[string]string{}, + ResponseHeader: map[string]string{"Server": "Metadata Server for VM"}, ExpectedStatusCode: http.StatusOK, }, "do": Provider{ Path: "/metadata/v1/id", - Header: map[string]string{"Content-Type": "text/plain; charset=utf-8"}, + Method: "GET", + RequestHeader: map[string]string{}, + ResponseHeader: map[string]string{"Content-Type": "text/plain; charset=utf-8"}, ExpectedStatusCode: http.StatusOK, }, "eks": Provider{ Path: "/", - Header: map[string]string{"Server": "EC2ws"}, + Method: "GET", + RequestHeader: map[string]string{}, + ResponseHeader: map[string]string{"Server": "EC2ws"}, + ExpectedStatusCode: http.StatusOK, + }, + "eks-imdsv2": Provider{ + Path: "/latest/api/token", + Method: "POST", + RequestHeader: map[string]string{"X-aws-ec2-metadata-token-ttl-seconds": "21600"}, + ResponseHeader: map[string]string{"Server": "EC2ws"}, ExpectedStatusCode: http.StatusOK, }, } @@ -72,7 +87,17 @@ func (c *Client) GetProvider() string { } func checkProvider(hc *http.Client, provider Provider) bool { - rs, err := hc.Get(metadataServerURL + provider.Path) + + rq, err := http.NewRequest(provider.Method, metadataServerURL+provider.Path, nil) + if err != nil { + return false + } + + for k, v := range provider.RequestHeader { + rq.Header.Add(k, v) + } + + rs, err := hc.Do(rq) if err != nil { return false } @@ -81,7 +106,7 @@ func checkProvider(hc *http.Client, provider Provider) bool { return false } - for k, v := range provider.Header { + for k, v := range provider.ResponseHeader { header := rs.Header.Get(k) if header != v { logger.Debug("header %s does not match expected value %s, got %s", k, v, header) diff --git a/pkg/autodetect/autodetect_test.go b/pkg/autodetect/autodetect_test.go index 6af5e56..bac2846 100644 --- a/pkg/autodetect/autodetect_test.go +++ b/pkg/autodetect/autodetect_test.go @@ -26,6 +26,10 @@ func newMetadataServer(t *testing.T, testServer *testServer) *httptest.Server { case "eks": // AWS EKS mux.HandleFunc("/", testServer.eksHandler) + + case "eks-imdsv2": + // AWS EKS when using IMDSv2 + mux.HandleFunc("/latest/api/token", testServer.eksImdsv2Handler) } return httptest.NewServer(mux) @@ -80,6 +84,14 @@ func (s *testServer) eksHandler(w http.ResponseWriter, r *http.Request) { w.Write([]byte(responseData)) } +func (s *testServer) eksImdsv2Handler(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Server", "EC2ws") + + responseData := `AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==` + + w.Write([]byte(responseData)) +} + func TestAutoDetectGKE(t *testing.T) { ts := &testServer{ t: t, @@ -179,6 +191,28 @@ func TestAutoDetectEKS(t *testing.T) { } +func TestAutoDetectEKSImdsV2(t *testing.T) { + ts := &testServer{ + t: t, + cloudProvider: "eks-imdsv2", + } + + server := newMetadataServer(t, ts) + defer server.Close() + + metadataServerURL = server.URL + + pc, err := New(&http.Client{}, nil) + if err != nil { + t.Errorf("err: %v", err) + } + + provider := pc.GetProvider() + + assert.Equal(t, "eks-imdsv2", provider, "should be equal") + +} + func TestCheckProviderEKS(t *testing.T) { ts := &testServer{ t: t, From fbd5ff19a21f483c242d386366b0422a0e844bd1 Mon Sep 17 00:00:00 2001 From: rileydakota Date: Fri, 10 Jun 2022 19:05:38 -0400 Subject: [PATCH 2/2] fix http method for eks-imdsv2 --- pkg/autodetect/autodetect.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/autodetect/autodetect.go b/pkg/autodetect/autodetect.go index db26132..0414866 100644 --- a/pkg/autodetect/autodetect.go +++ b/pkg/autodetect/autodetect.go @@ -53,7 +53,7 @@ var ( }, "eks-imdsv2": Provider{ Path: "/latest/api/token", - Method: "POST", + Method: "PUT", RequestHeader: map[string]string{"X-aws-ec2-metadata-token-ttl-seconds": "21600"}, ResponseHeader: map[string]string{"Server": "EC2ws"}, ExpectedStatusCode: http.StatusOK,