Skip to content

Commit 1db0745

Browse files
authored
Merge pull request #2248 from mittachaitu/add_indicator
feat: add telemetry as part of mount options for blobfuse mounts
2 parents d9b66f7 + e0bd109 commit 1db0745

File tree

3 files changed

+172
-4
lines changed

3 files changed

+172
-4
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,4 +178,4 @@ delete-metrics-svc:
178178

179179
.PHONY: blobfuse-proxy
180180
blobfuse-proxy:
181-
CGO_ENABLED=0 GOOS=linux GOARCH=$(ARCH) go build -mod vendor -ldflags="-s -w" -o _output/${ARCH}/blobfuse-proxy ./pkg/blobfuse-proxy
181+
CGO_ENABLED=0 GOOS=linux GOARCH=$(ARCH) go build -mod vendor -ldflags="-s -w -X ${PKG}/pkg/blobfuse-proxy/server.driverVersion=${IMAGE_VERSION}" -o _output/${ARCH}/blobfuse-proxy ./pkg/blobfuse-proxy

pkg/blobfuse-proxy/server/server.go

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@ import (
3434
)
3535

3636
var (
37-
mutex sync.Mutex
37+
mutex sync.Mutex
38+
driverVersion string
3839
)
3940

41+
// telemetryTagPrefix is used to identify the mounts done via blobcsi driver
42+
const telemetryTagPrefix = "blobpartner-csi/"
43+
4044
type BlobfuseVersion int
4145

4246
const (
@@ -47,12 +51,14 @@ const (
4751
type MountServer struct {
4852
blobfuseVersion BlobfuseVersion
4953
mount_azure_blob.UnimplementedMountServiceServer
54+
exec func(name string, arg ...string) *exec.Cmd
5055
}
5156

5257
// NewMountServer returns a new Mountserver
5358
func NewMountServiceServer() *MountServer {
5459
mountServer := &MountServer{}
5560
mountServer.blobfuseVersion = getBlobfuseVersion()
61+
mountServer.exec = exec.Command
5662
return mountServer
5763
}
5864

@@ -82,13 +88,15 @@ func (server *MountServer) MountAzureBlob(_ context.Context,
8288
klog.V(2).Infof("append --disable-version-check to mount args")
8389
args = args + " " + "--disable-version-check=true"
8490
}
91+
// Adding telemetry tag to know that blob is been mounted through AKS CSI Driver
92+
args = addTelemetryTagToArgs(args)
8593
args = util.TrimDuplicatedSpace(args)
8694
klog.V(2).Infof("mount with v2, protocol: %s, args: %s", protocol, args)
87-
cmd = exec.Command("blobfuse2", strings.Split(args, " ")...)
95+
cmd = server.exec("blobfuse2", strings.Split(args, " ")...)
8896
} else {
8997
args = util.TrimDuplicatedSpace(args)
9098
klog.V(2).Infof("mount with v1, protocol: %s, args: %s", protocol, args)
91-
cmd = exec.Command("blobfuse", strings.Split(args, " ")...)
99+
cmd = server.exec("blobfuse", strings.Split(args, " ")...)
92100
}
93101

94102
cmd.Env = append(os.Environ(), authEnv...)
@@ -158,3 +166,37 @@ func getBlobfuseVersion() BlobfuseVersion {
158166
klog.V(2).Info("proxy default using blobfuse V1 for mounting")
159167
return BlobfuseV1
160168
}
169+
170+
// Adding CSI driver specific telemetry tag if not present to
171+
// know that blob is been mounted through CSI Driver
172+
func addTelemetryTagToArgs(args string) string {
173+
telemetryTag := telemetryTagPrefix + driverVersion
174+
if !strings.Contains(args, "--telemetry") {
175+
klog.V(2).Infof("append --telemetry=%s to mount args", telemetryTag)
176+
args = args + " " + "--telemetry=" + telemetryTag
177+
} else {
178+
// If telemetry flag is already present, check for aks tag if not present
179+
// then user might have their own telemetry tag append aks tag to it
180+
if !strings.Contains(args, telemetryTagPrefix) {
181+
argSlice := strings.Fields(args)
182+
telemetryIndex := -1
183+
for i, arg := range argSlice {
184+
if strings.HasPrefix(arg, "--telemetry=") {
185+
telemetryIndex = i
186+
break
187+
}
188+
}
189+
if telemetryIndex != -1 {
190+
// Update the telemetry tag, appending our tag if not present
191+
telemetryVal := strings.TrimPrefix(argSlice[telemetryIndex], "--telemetry=")
192+
// Avoid duplicating the tag if already present
193+
if !strings.Contains(telemetryVal, telemetryTag) {
194+
argSlice[telemetryIndex] = "--telemetry=" + telemetryTag + "," + telemetryVal
195+
args = strings.Join(argSlice, " ")
196+
klog.V(2).Infof("updated --telemetry tag in mount args: %s", args)
197+
}
198+
}
199+
}
200+
}
201+
return args
202+
}

pkg/blobfuse-proxy/server/server_test.go

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package server
1818

1919
import (
2020
"context"
21+
"os/exec"
22+
"strings"
2123
"testing"
2224

2325
"github.com/stretchr/testify/require"
@@ -64,3 +66,127 @@ func TestServerMountAzureBlob(t *testing.T) {
6466
})
6567
}
6668
}
69+
70+
// fakeExecCommand is used to mock exec.Command for testing, it returns list of args
71+
func fakeExecCommandEchoArgs(_ string, args ...string) *exec.Cmd {
72+
return exec.Command("echo", append([]string{"-n"}, args...)...)
73+
}
74+
75+
func TestAddTelemetryTagToArgs(t *testing.T) {
76+
driverVersion = "fake-version-ut"
77+
t.Parallel()
78+
testCases := []struct {
79+
name string
80+
args string
81+
expectedArgs string
82+
}{
83+
{
84+
name: "args_without_telemetry_option",
85+
args: "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp",
86+
expectedArgs: "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp --telemetry=" + telemetryTagPrefix + driverVersion,
87+
},
88+
{
89+
name: "args_with_some_telemetry_option",
90+
args: "--account-name=testaccount --container-name=testcontainer --telemetry=app1-volume1 --tmp-path=/tmp/blobfuse-tmp",
91+
expectedArgs: "--account-name=testaccount --container-name=testcontainer --telemetry=" + telemetryTagPrefix + driverVersion + ",app1-volume1 --tmp-path=/tmp/blobfuse-tmp",
92+
},
93+
{
94+
name: "args_with_csi_driver_telemetry_option",
95+
args: "--account-name=testaccount --container-name=testcontainer --telemetry=" + telemetryTagPrefix + driverVersion + ",app1-volume1 --tmp-path=/tmp/blobfuse-tmp",
96+
expectedArgs: "--account-name=testaccount --container-name=testcontainer --telemetry=" + telemetryTagPrefix + driverVersion + ",app1-volume1 --tmp-path=/tmp/blobfuse-tmp",
97+
},
98+
{
99+
name: "args_with_some_telemetry_option_only",
100+
args: "--telemetry=app1-volume1",
101+
expectedArgs: "--telemetry=" + telemetryTagPrefix + driverVersion + ",app1-volume1",
102+
},
103+
{
104+
name: "args_with_multiple_telemetry_options",
105+
args: "--account-name=testaccount --container-name=testcontainer --telemetry=app1 --tmp-path=/tmp/blobfuse-tmp --telemetry=app2",
106+
expectedArgs: "--account-name=testaccount --container-name=testcontainer --telemetry=" + telemetryTagPrefix + driverVersion + ",app1 --tmp-path=/tmp/blobfuse-tmp --telemetry=app2",
107+
},
108+
}
109+
for i := range testCases {
110+
tc := testCases[i]
111+
112+
t.Run(tc.name, func(t *testing.T) {
113+
t.Parallel()
114+
actualArgs := addTelemetryTagToArgs(tc.args)
115+
require.Equal(t, tc.expectedArgs, actualArgs)
116+
})
117+
}
118+
}
119+
120+
func TestServerMountAzureBlob_Telemetry(t *testing.T) {
121+
driverVersion = "fake-version"
122+
t.Parallel()
123+
testCases := []struct {
124+
name string
125+
args string
126+
code codes.Code
127+
mountServer MountServer
128+
areValidTelemetryArgs func(cmdArgs string) bool
129+
}{
130+
{
131+
name: "mount_with_telemetry_tag_blobfusev2",
132+
args: "--account-name=testaccount --container-name=testcontainer --telemetry=volume1-app1 --tmp-path=/tmp/blobfuse-tmp",
133+
mountServer: MountServer{
134+
blobfuseVersion: BlobfuseV2,
135+
exec: fakeExecCommandEchoArgs,
136+
},
137+
code: codes.OK,
138+
areValidTelemetryArgs: func(cmdArgs string) bool {
139+
expectedTelemetryArg := "--telemetry=" + telemetryTagPrefix + driverVersion + ",volume1-app1"
140+
return strings.Contains(cmdArgs, expectedTelemetryArg)
141+
},
142+
},
143+
{
144+
name: "mount_without_telemetry_tag_blobfusev2",
145+
args: "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp",
146+
mountServer: MountServer{
147+
blobfuseVersion: BlobfuseV2,
148+
exec: fakeExecCommandEchoArgs,
149+
},
150+
code: codes.OK,
151+
areValidTelemetryArgs: func(cmdArgs string) bool {
152+
expectedTelemetryArg := "--telemetry=" + telemetryTagPrefix + driverVersion
153+
return strings.Contains(cmdArgs, expectedTelemetryArg)
154+
},
155+
},
156+
{
157+
name: "mount_with_blobfusev1",
158+
args: "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp",
159+
mountServer: MountServer{
160+
blobfuseVersion: BlobfuseV1,
161+
exec: fakeExecCommandEchoArgs,
162+
},
163+
code: codes.OK,
164+
areValidTelemetryArgs: func(cmdArgs string) bool {
165+
// No telemetry arg should be added for blobfuse v1
166+
return !strings.Contains(cmdArgs, "--telemetry=") && cmdArgs == "--account-name=testaccount --container-name=testcontainer --tmp-path=/tmp/blobfuse-tmp"
167+
},
168+
},
169+
}
170+
171+
for i := range testCases {
172+
tc := testCases[i]
173+
174+
t.Run(tc.name, func(t *testing.T) {
175+
t.Parallel()
176+
177+
req := mount_azure_blob.MountAzureBlobRequest{
178+
MountArgs: tc.args,
179+
AuthEnv: []string{},
180+
}
181+
res, err := tc.mountServer.MountAzureBlob(context.Background(), &req)
182+
if tc.code == codes.OK {
183+
require.NoError(t, err)
184+
require.NotNil(t, res)
185+
require.True(t, tc.areValidTelemetryArgs(res.Output), "telemetry args are mismatching in command args: %s", res.Output)
186+
} else {
187+
require.Error(t, err)
188+
require.NotNil(t, res)
189+
}
190+
})
191+
}
192+
}

0 commit comments

Comments
 (0)