Skip to content

Commit 8bf36b0

Browse files
authored
Merge branch 'main' into mtls
2 parents f77538d + 799f0c3 commit 8bf36b0

File tree

3 files changed

+78
-2
lines changed

3 files changed

+78
-2
lines changed

translator/util/eksdetector/eksdetector.go

+46-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ package eksdetector
55

66
import (
77
"context"
8+
"encoding/base64"
9+
"encoding/json"
810
"fmt"
11+
"strings"
912
"sync"
1013

1114
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -15,6 +18,7 @@ import (
1518

1619
type Detector interface {
1720
getConfigMap(namespace string, name string) (map[string]string, error)
21+
getIssuer() (string, error)
1822
}
1923

2024
type EksDetector struct {
@@ -55,7 +59,8 @@ var (
5559
}
5660

5761
// IsEKS checks if the agent is running on EKS. This is done by using the kubernetes API to determine if the aws-auth
58-
// configmap exists in the kube-system namespace
62+
// configmap exists in the kube-system namespace or by extracting the "iss" field from the service account token and
63+
// checking if it contains "eks" as a fall-back
5964
IsEKS = func() IsEKSCache {
6065
once.Do(func() {
6166
var errors error
@@ -71,6 +76,11 @@ var (
7176
awsAuth, err := eksDetector.getConfigMap(authConfigNamespace, authConfigConfigMap)
7277
if err == nil {
7378
value = awsAuth != nil
79+
} else {
80+
issuer, err := eksDetector.getIssuer()
81+
if err == nil {
82+
value = strings.Contains(strings.ToLower(issuer), "eks")
83+
}
7484
}
7585
}
7686
isEKSCacheSingleton = IsEKSCache{Value: value, Err: errors}
@@ -90,6 +100,41 @@ func (d *EksDetector) getConfigMap(namespace string, name string) (map[string]st
90100
return configMap.Data, nil
91101
}
92102

103+
// getIssuer retrieves the issuer ("iss") from the service account token
104+
func (d *EksDetector) getIssuer() (string, error) {
105+
conf, err := getInClusterConfig()
106+
if err != nil {
107+
return "", fmt.Errorf("failed to get in-cluster config: %w", err)
108+
}
109+
110+
token := conf.BearerToken
111+
if token == "" {
112+
return "", fmt.Errorf("empty token in config")
113+
}
114+
115+
parts := strings.Split(token, ".")
116+
if len(parts) < 2 {
117+
return "", fmt.Errorf("missing payload")
118+
}
119+
120+
decoded, err := base64.RawURLEncoding.DecodeString(parts[1])
121+
if err != nil {
122+
return "", fmt.Errorf("failed to decode token payload: %w", err)
123+
}
124+
125+
var claims map[string]interface{}
126+
if err = json.Unmarshal(decoded, &claims); err != nil {
127+
return "", fmt.Errorf("failed to unmarshal token payload: %w", err)
128+
}
129+
130+
iss, ok := claims["iss"].(string)
131+
if !ok {
132+
return "", fmt.Errorf("issuer field not found in token")
133+
}
134+
135+
return iss, nil
136+
}
137+
93138
func getClient() (kubernetes.Interface, error) {
94139
//Get cluster config
95140
confs, err := getInClusterConfig()

translator/util/eksdetector/eksdetector_test.go

+26
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package eksdetector
55

66
import (
7+
"encoding/base64"
78
"fmt"
89
"testing"
910

@@ -54,9 +55,17 @@ func TestEKS(t *testing.T) {
5455
}
5556

5657
testDetector.On("getConfigMap", authConfigNamespace, authConfigConfigMap).Return(map[string]string{conventions.AttributeK8SClusterName: "my-cluster"}, nil)
58+
5759
isEks := IsEKS()
5860
assert.True(t, isEks.Value)
5961
assert.NoError(t, isEks.Err)
62+
63+
testDetector.On("getConfigMap", authConfigNamespace, authConfigConfigMap).Return(nil, fmt.Errorf("configmap not found"))
64+
testDetector.On("getIssuer").Return("https://oidc.eks.us-west-2.amazonaws.com/id/someid", nil)
65+
66+
isEks = IsEKS()
67+
assert.True(t, isEks.Value)
68+
assert.NoError(t, isEks.Err)
6069
}
6170

6271
func Test_getConfigMap(t *testing.T) {
@@ -82,6 +91,23 @@ func Test_getConfigMap(t *testing.T) {
8291
assert.NotNil(t, res)
8392
}
8493

94+
func Test_getIssuer(t *testing.T) {
95+
client := fake.NewSimpleClientset()
96+
testDetector := &EksDetector{Clientset: client}
97+
98+
payload := `{"iss":"https://oidc.eks.us-west-2.amazonaws.com/id/someid"}`
99+
encodedPayload := base64.RawURLEncoding.EncodeToString([]byte(payload))
100+
dummyToken := "header." + encodedPayload + ".signature"
101+
102+
getInClusterConfig = func() (*rest.Config, error) {
103+
return &rest.Config{BearerToken: dummyToken}, nil
104+
}
105+
106+
issuer, err := testDetector.getIssuer()
107+
assert.NoError(t, err)
108+
assert.Equal(t, "https://oidc.eks.us-west-2.amazonaws.com/id/someid", issuer)
109+
}
110+
85111
func Test_getClientError(t *testing.T) {
86112
//InClusterConfig error
87113
getInClusterConfig = func() (*rest.Config, error) {

translator/util/eksdetector/eksdetectortestutil.go

+6-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ var (
2525
return &EksDetector{Clientset: fake.NewSimpleClientset()}, nil
2626
}
2727

28-
// TestIsEKSCacheEKS os used for unit testing EKS route
28+
// TestIsEKSCacheEKS is used for unit testing EKS route
2929
TestIsEKSCacheEKS = func() IsEKSCache {
3030
return IsEKSCache{Value: true, Err: nil}
3131
}
@@ -44,3 +44,8 @@ func (detector *MockDetector) getConfigMap(namespace string, name string) (map[s
4444
args := detector.Called(namespace, name)
4545
return args.Get(0).(map[string]string), args.Error(1)
4646
}
47+
48+
func (detector *MockDetector) getIssuer() (string, error) {
49+
args := detector.Called()
50+
return args.Get(0).(string), args.Error(1)
51+
}

0 commit comments

Comments
 (0)