Skip to content

Commit 80122a3

Browse files
Add Kubernetes distribution to S3 request user agent (awslabs#717)
*Issue:* N/A Updated the user-agent logic so we track two things separately: whether the cluster is OpenShift how the driver was installed (eks-addon, helm, or kustomize) *Description of changes:* Helm now always sets INSTALLATION_TYPE (eks-addon for addon installs, otherwise helm) Kustomize sets INSTALLATION_TYPE=kustomize Driver reads that env var (falls back to unknown if missing) User-agent format now includes [install/<method>](vscode-file://vscode-app/Applications/Visual%20Studio%20Code.app/Contents/Resources/app/out/vs/code/electron-browser/workbench/workbench.html) and openshift when relevant Related tests were updated *Testing* On EKS self-managed, logs show openshift=false, install=helm By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. --------- Signed-off-by: Priyankakarumuru1 <prikaru@amazon.com> Co-authored-by: Jensen Tong <jetong@amazon.co.uk>
1 parent a9631ee commit 80122a3

9 files changed

Lines changed: 187 additions & 18 deletions

File tree

charts/aws-mountpoint-s3-csi-driver/templates/node.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ spec:
9494
value: {{ .Values.mountpointPod.namespace }}
9595
- name: EKS_POD_IDENTITY_AGENT_CONTAINER_CREDENTIALS_FULL_URI
9696
value: {{ .Values.eksPodIdentityAgent.containerCredentialsFullURI }}
97+
- name: INSTALLATION_TYPE
98+
value: {{ if .Values.isEKSAddon }}eks-addon{{ else }}helm{{ end }}
9799
{{- with .Values.awsAccessSecret }}
98100
- name: AWS_ACCESS_KEY_ID
99101
valueFrom:

deploy/kubernetes/base/node.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ spec:
7676
value: mount-s3
7777
- name: EKS_POD_IDENTITY_AGENT_CONTAINER_CREDENTIALS_FULL_URI
7878
value: http://169.254.170.23/v1/credentials
79+
- name: INSTALLATION_TYPE
80+
value: kustomize
7981
- name: AWS_ACCESS_KEY_ID
8082
valueFrom:
8183
secretKeyRef:

pkg/cluster/cluster.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package cluster
22

33
import (
4+
"os"
5+
"strings"
6+
47
"github.com/go-logr/logr"
58
"k8s.io/client-go/discovery"
69
"k8s.io/client-go/rest"
@@ -14,6 +17,15 @@ const (
1417
OpenShift // OpenShift K8s
1518
)
1619

20+
func (v Variant) String() string {
21+
switch v {
22+
case OpenShift:
23+
return "openshift"
24+
default:
25+
return "kubernetes"
26+
}
27+
}
28+
1729
var defaultMountpointUID = new(int64(1000))
1830

1931
// DetectVariant determines Kubernetes variant by checking API groups.
@@ -42,6 +54,20 @@ func DetectVariant(client *rest.Config, log logr.Logger) Variant {
4254
return DefaultKubernetes
4355
}
4456

57+
// InstallationMethod returns the installation method for the CSI driver.
58+
// It reads the INSTALLATION_TYPE environment variable and returns its value,
59+
// falling back to "unknown" if the variable is not set.
60+
// Known values: eks-addon, helm, kustomize.
61+
func InstallationMethod() string {
62+
method := strings.ToLower(strings.TrimSpace(os.Getenv("INSTALLATION_TYPE")))
63+
switch method {
64+
case "eks-addon", "helm", "kustomize":
65+
return method
66+
}
67+
68+
return "unknown"
69+
}
70+
4571
// MountpointPodUserID returns the appropriate RunAsUser for Mountpoint Pod based on the cluster variant.
4672
func (c Variant) MountpointPodUserID() *int64 {
4773
if c == OpenShift {

pkg/cluster/cluster_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,74 @@ import (
77
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/util/testutil/assert"
88
)
99

10+
func TestVariantString(t *testing.T) {
11+
testCases := []struct {
12+
name string
13+
variant cluster.Variant
14+
expected string
15+
}{
16+
{
17+
name: "Default Kubernetes should return kubernetes",
18+
variant: cluster.DefaultKubernetes,
19+
expected: "kubernetes",
20+
},
21+
{
22+
name: "OpenShift should return openshift",
23+
variant: cluster.OpenShift,
24+
expected: "openshift",
25+
},
26+
}
27+
28+
for _, testCase := range testCases {
29+
t.Run(testCase.name, func(t *testing.T) {
30+
assert.Equals(t, testCase.expected, testCase.variant.String())
31+
})
32+
}
33+
}
34+
35+
func TestInstallationMethod(t *testing.T) {
36+
t.Setenv("INSTALLATION_TYPE", "")
37+
38+
testCases := []struct {
39+
name string
40+
input string
41+
expected string
42+
}{
43+
{
44+
name: "empty value should return unknown",
45+
input: "",
46+
expected: "unknown",
47+
},
48+
{
49+
name: "kustomize should be recognized",
50+
input: "kustomize",
51+
expected: "kustomize",
52+
},
53+
{
54+
name: "eks-addon should be recognized",
55+
input: "eks-addon",
56+
expected: "eks-addon",
57+
},
58+
{
59+
name: "value should be sanitized and lowercased",
60+
input: " HELM ",
61+
expected: "helm",
62+
},
63+
{
64+
name: "unknown value should return unknown",
65+
input: "operator",
66+
expected: "unknown",
67+
},
68+
}
69+
70+
for _, testCase := range testCases {
71+
t.Run(testCase.name, func(t *testing.T) {
72+
t.Setenv("INSTALLATION_TYPE", testCase.input)
73+
assert.Equals(t, testCase.expected, cluster.InstallationMethod())
74+
})
75+
}
76+
}
77+
1078
func TestMountpointPodUserID(t *testing.T) {
1179
testCases := []struct {
1280
name string

pkg/driver/driver.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import (
4343
"sigs.k8s.io/controller-runtime/pkg/manager/signals"
4444

4545
crdv2 "github.com/awslabs/mountpoint-s3-csi-driver/pkg/api/v2"
46+
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/cluster"
4647
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/node"
4748
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/node/credentialprovider"
4849
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/node/mounter"
@@ -99,10 +100,13 @@ func NewDriver(endpoint string, mpVersion string, nodeID string) (*Driver, error
99100
klog.Errorf("failed to get kubernetes version: %v", err)
100101
}
101102

102-
version := version.GetVersion()
103-
klog.Infof("Driver version: %v, Git commit: %v, build date: %v, nodeID: %v, mount-s3 version: %v, kubernetes version: %v",
104-
version.DriverVersion, version.GitCommit, version.BuildDate, nodeID, mpVersion, kubernetesVersion)
103+
log := klog.NewKlogr()
104+
variant := cluster.DetectVariant(config, log)
105+
installMethod := cluster.InstallationMethod()
105106

107+
version := version.GetVersion()
108+
klog.Infof("Driver version: %v, Git commit: %v, build date: %v, nodeID: %v, mount-s3 version: %v, kubernetes version: %v, variant: %s, install: %v",
109+
version.DriverVersion, version.GitCommit, version.BuildDate, nodeID, mpVersion, kubernetesVersion, variant.String(), installMethod)
106110
// `credentialprovider.RegionFromIMDSOnce` is a `sync.OnceValues` and it only makes request to IMDS once,
107111
// this call is basically here to pre-warm the cache of IMDS call.
108112
go func() {
@@ -129,7 +133,7 @@ func NewDriver(endpoint string, mpVersion string, nodeID string) (*Driver, error
129133
go unmounter.StartPeriodicCleanup(stopCh)
130134

131135
podMounter, err := mounter.NewPodMounter(podWatcher, s3paCache, credProvider, mpMounter, nil, nil,
132-
kubernetesVersion, nodeID)
136+
kubernetesVersion, nodeID, variant)
133137
if err != nil {
134138
klog.Fatalln(err)
135139
}

pkg/driver/node/mounter/pod_mounter.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"sigs.k8s.io/controller-runtime/pkg/client"
1717

1818
crdv2 "github.com/awslabs/mountpoint-s3-csi-driver/pkg/api/v2"
19+
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/cluster"
1920
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/node/credentialprovider"
2021
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/node/envprovider"
2122
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/node/targetpath"
@@ -56,6 +57,7 @@ type PodMounter struct {
5657
mountSyscall mountSyscall
5758
bindMountSyscall bindMountSyscall
5859
kubernetesVersion string
60+
variant cluster.Variant
5961
credProvider credentialprovider.ProviderInterface
6062
nodeID string
6163
}
@@ -68,8 +70,9 @@ func NewPodMounter(
6870
mount *mpmounter.Mounter,
6971
mountSyscall mountSyscall,
7072
bindMountSyscall bindMountSyscall,
71-
kubernetesVersion,
73+
kubernetesVersion string,
7274
nodeID string,
75+
variant cluster.Variant,
7376
) (*PodMounter, error) {
7477
return &PodMounter{
7578
podWatcher: podWatcher,
@@ -80,6 +83,7 @@ func NewPodMounter(
8083
mountSyscall: mountSyscall,
8184
bindMountSyscall: bindMountSyscall,
8285
kubernetesVersion: kubernetesVersion,
86+
variant: variant,
8387
nodeID: nodeID,
8488
}, nil
8589
}
@@ -214,7 +218,7 @@ func (pm *PodMounter) mountS3AtSource(ctx context.Context, source string, mpPod
214218
env.Set(envprovider.EnvMaxAttempts, maxAttempts)
215219
}
216220

217-
args.Set(mountpoint.ArgUserAgentPrefix, UserAgent(authenticationSource, pm.kubernetesVersion))
221+
args.Set(mountpoint.ArgUserAgentPrefix, UserAgent(authenticationSource, pm.kubernetesVersion, pm.variant))
218222

219223
podMountSockPath := mppod.PathOnHost(podPath, mppod.KnownPathMountSock)
220224
podMountErrorPath := mppod.PathOnHost(podPath, mppod.KnownPathMountError)

pkg/driver/node/mounter/pod_mounter_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"k8s.io/mount-utils"
2222

2323
crdv2 "github.com/awslabs/mountpoint-s3-csi-driver/pkg/api/v2"
24+
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/cluster"
2425
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/node/credentialprovider"
2526
mock_credentialprovider "github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/node/credentialprovider/mocks"
2627
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/node/envprovider"
@@ -166,7 +167,7 @@ func setup(t *testing.T) *testCtx {
166167
assert.NoError(t, err)
167168

168169
podMounter, err := mounter.NewPodMounter(podWatcher, s3paCache, mockCredProvider, mpmounter.NewWithMount(fakeMounter), mountSyscall,
169-
mountBindSyscall, testK8sVersion, nodeName)
170+
mountBindSyscall, testK8sVersion, nodeName, cluster.DefaultKubernetes)
170171
assert.NoError(t, err)
171172

172173
testCtx.podMounter = podMounter
@@ -228,7 +229,7 @@ func TestPodMounter(t *testing.T) {
228229
assert.Equals(t, mountoptions.Options{
229230
BucketName: testCtx.bucketName,
230231
Args: []string{
231-
"--user-agent-prefix=" + mounter.UserAgent(credentialprovider.AuthenticationSourceDriver, testK8sVersion),
232+
"--user-agent-prefix=" + mounter.UserAgent(credentialprovider.AuthenticationSourceDriver, testK8sVersion, cluster.DefaultKubernetes),
232233
},
233234
Env: envprovider.Default().List(),
234235
}, got)

pkg/driver/node/mounter/user_agent.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,23 @@ package mounter
1919
import (
2020
"strings"
2121

22+
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/cluster"
2223
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/version"
2324
)
2425

2526
const (
2627
userAgentCsiDriverPrefix = "s3-csi-driver/"
2728
userAgentK8sPrefix = "k8s/"
2829
userAgentCredentialSourcePrefix = "credential-source#"
30+
userAgentOpenShiftPrefix = "md/openshift"
31+
userAgentInstallPrefix = "md/install#"
2932
)
3033

3134
// UserAgent returns user-agent for the CSI driver.
32-
func UserAgent(authenticationSource string, kubernetesVersion string) string {
35+
// The format is: s3-csi-driver/VERSION credential-source#SOURCE k8s/VERSION [md/openshift] md/install#METHOD
36+
func UserAgent(authenticationSource string, kubernetesVersion string, variant cluster.Variant) string {
3337
var b strings.Builder
38+
installMethod := cluster.InstallationMethod()
3439

3540
// s3-csi-driver/v0.0.0
3641
b.WriteString(userAgentCsiDriverPrefix)
@@ -48,5 +53,16 @@ func UserAgent(authenticationSource string, kubernetesVersion string) string {
4853
b.WriteString(kubernetesVersion)
4954
}
5055

56+
if variant == cluster.OpenShift {
57+
// md/openshift (version will be added in a follow-up)
58+
b.WriteRune(' ')
59+
b.WriteString(userAgentOpenShiftPrefix)
60+
}
61+
62+
// md/install#helm
63+
b.WriteRune(' ')
64+
b.WriteString(userAgentInstallPrefix)
65+
b.WriteString(installMethod)
66+
5167
return b.String()
5268
}

pkg/driver/node/mounter/user_agent_test.go

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,42 +19,88 @@ package mounter
1919
import (
2020
"testing"
2121

22+
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/cluster"
2223
"github.com/awslabs/mountpoint-s3-csi-driver/pkg/driver/node/credentialprovider"
2324
)
2425

2526
func TestUserAgent(t *testing.T) {
2627
tests := map[string]struct {
2728
k8sVersion string
2829
authenticationSource string
30+
variant cluster.Variant
31+
installationType string
2932
result string
3033
}{
3134
"empty versions": {
32-
result: "s3-csi-driver/ credential-source#",
35+
installationType: "unknown",
36+
result: "s3-csi-driver/ credential-source# md/install#unknown",
37+
},
38+
"empty installation type fallback": {
39+
installationType: "",
40+
result: "s3-csi-driver/ credential-source# md/install#unknown",
3341
},
3442
"stock k8s version": {
35-
k8sVersion: "v1.29.6",
36-
result: "s3-csi-driver/ credential-source# k8s/v1.29.6",
43+
k8sVersion: "v1.29.6",
44+
installationType: "unknown",
45+
result: "s3-csi-driver/ credential-source# k8s/v1.29.6 md/install#unknown",
3746
},
3847
"eks k8s version": {
39-
k8sVersion: "v1.30.2-eks-db838b0",
40-
result: "s3-csi-driver/ credential-source# k8s/v1.30.2-eks-db838b0",
48+
k8sVersion: "v1.30.2-eks-db838b0",
49+
installationType: "unknown",
50+
result: "s3-csi-driver/ credential-source# k8s/v1.30.2-eks-db838b0 md/install#unknown",
4151
},
4252
"driver authentication source": {
4353
k8sVersion: "v1.30.2-eks-db838b0",
4454
authenticationSource: credentialprovider.AuthenticationSourceDriver,
45-
result: "s3-csi-driver/ credential-source#driver k8s/v1.30.2-eks-db838b0",
55+
installationType: "unknown",
56+
result: "s3-csi-driver/ credential-source#driver k8s/v1.30.2-eks-db838b0 md/install#unknown",
4657
},
4758
"pod authentication source": {
4859
k8sVersion: "v1.30.2-eks-db838b0",
4960
authenticationSource: credentialprovider.AuthenticationSourcePod,
50-
result: "s3-csi-driver/ credential-source#pod k8s/v1.30.2-eks-db838b0",
61+
installationType: "unknown",
62+
result: "s3-csi-driver/ credential-source#pod k8s/v1.30.2-eks-db838b0 md/install#unknown",
63+
},
64+
"eks addon installation method": {
65+
k8sVersion: "v1.30.2-eks-db838b0",
66+
authenticationSource: credentialprovider.AuthenticationSourcePod,
67+
installationType: "eks-addon",
68+
result: "s3-csi-driver/ credential-source#pod k8s/v1.30.2-eks-db838b0 md/install#eks-addon",
69+
},
70+
"helm installation method": {
71+
k8sVersion: "v1.28.0",
72+
authenticationSource: credentialprovider.AuthenticationSourceDriver,
73+
installationType: "helm",
74+
result: "s3-csi-driver/ credential-source#driver k8s/v1.28.0 md/install#helm",
75+
},
76+
"openshift with helm": {
77+
k8sVersion: "v1.33.6",
78+
authenticationSource: credentialprovider.AuthenticationSourcePod,
79+
variant: cluster.OpenShift,
80+
installationType: "helm",
81+
result: "s3-csi-driver/ credential-source#pod k8s/v1.33.6 md/openshift md/install#helm",
82+
},
83+
"openshift with kustomize": {
84+
k8sVersion: "v1.33.6",
85+
authenticationSource: credentialprovider.AuthenticationSourcePod,
86+
variant: cluster.OpenShift,
87+
installationType: "kustomize",
88+
result: "s3-csi-driver/ credential-source#pod k8s/v1.33.6 md/openshift md/install#kustomize",
89+
},
90+
"invalid installation method": {
91+
k8sVersion: "v1.30.0",
92+
authenticationSource: credentialprovider.AuthenticationSourceDriver,
93+
installationType: "operator",
94+
result: "s3-csi-driver/ credential-source#driver k8s/v1.30.0 md/install#unknown",
5195
},
5296
}
5397

5498
for name, test := range tests {
5599
t.Run(name, func(t *testing.T) {
56-
if got, expected := UserAgent(test.authenticationSource, test.k8sVersion), test.result; got != expected {
57-
t.Fatalf("UserAgent(%q, %q) returned %q; expected %q", test.authenticationSource, test.k8sVersion, got, expected)
100+
t.Setenv("INSTALLATION_TYPE", test.installationType)
101+
102+
if got, expected := UserAgent(test.authenticationSource, test.k8sVersion, test.variant), test.result; got != expected {
103+
t.Fatalf("UserAgent(%q, %q, %q) returned %q; expected %q", test.authenticationSource, test.k8sVersion, test.variant.String(), got, expected)
58104
}
59105
})
60106
}

0 commit comments

Comments
 (0)