Skip to content

Commit 3cbe4bd

Browse files
Merge pull request #719 from jetstack/x-cybr-telemetry
[VC-45001] Add telemetry header to all API requests
2 parents 32d6bf1 + acceb73 commit 3cbe4bd

File tree

8 files changed

+111
-3
lines changed

8 files changed

+111
-3
lines changed

internal/cyberark/api/telemetry.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package api
2+
3+
import (
4+
"encoding/base64"
5+
"net/http"
6+
"net/url"
7+
8+
"github.com/jetstack/preflight/pkg/version"
9+
)
10+
11+
// Integrations working with the Identity Security Platform, should add metadata
12+
// in their API calls, to provide insights into how customers utilize each API.
13+
//
14+
// - IntegrationName (in): The vendor integration name (required)
15+
// - IntegrationType (it): Integration Type (required)
16+
// - IntegrationVersion (iv): The plugin version being used (required)
17+
// - VendorName (vn): Vendor name (required)
18+
// - VendorVersion (vv): Version of the vendor product in which the plugin is used (if applicable)
19+
20+
const (
21+
// TelemetryHeaderKey is the name of the HTTP header to use for telemetry
22+
TelemetryHeaderKey = "X-Cybr-Telemetry"
23+
)
24+
25+
var (
26+
telemetryValues url.Values
27+
telemetryValueEncoded string
28+
)
29+
30+
func init() {
31+
telemetryValues = url.Values{}
32+
telemetryValues.Set("in", "cyberark-disco-agent")
33+
telemetryValues.Set("vn", "CyberArk")
34+
telemetryValues.Set("it", "KubernetesAgent")
35+
telemetryValues.Set("iv", version.PreflightVersion)
36+
telemetryValueEncoded = base64.URLEncoding.EncodeToString([]byte(telemetryValues.Encode()))
37+
}
38+
39+
// SetTelemetryRequestHeader adds the x-cybr-telemetry header to the given HTTP
40+
// request, with information about this integration.
41+
func SetTelemetryRequestHeader(req *http.Request) {
42+
req.Header.Set(TelemetryHeaderKey, telemetryValueEncoded)
43+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package api
2+
3+
import (
4+
"encoding/base64"
5+
"net/http"
6+
"net/url"
7+
"testing"
8+
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
// Test the SetTelemetryRequestHeader function
13+
func TestSetTelemetryRequestHeader(t *testing.T) {
14+
// Create a new HTTP request
15+
req, err := http.NewRequestWithContext(t.Context(), http.MethodGet, "http://example.com", nil)
16+
require.NoError(t, err, "failed to create HTTP request")
17+
18+
// Call the function to set the telemetry header
19+
SetTelemetryRequestHeader(req)
20+
21+
base64Value := req.Header.Get(TelemetryHeaderKey)
22+
// Check that the header is set
23+
require.NotEmpty(t, base64Value, "telemetry header should be set")
24+
25+
queryString, err := base64.URLEncoding.DecodeString(base64Value)
26+
require.NoError(t, err, "failed to decode telemetry header value")
27+
28+
values, err := url.ParseQuery(string(queryString))
29+
require.NoError(t, err, "failed to parse telemetry header value")
30+
require.Equal(t, telemetryValues, values, "telemetry header value should match expected values")
31+
}

internal/cyberark/dataupload/dataupload.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414

1515
"k8s.io/apimachinery/pkg/runtime"
1616

17+
arkapi "github.com/jetstack/preflight/internal/cyberark/api"
1718
"github.com/jetstack/preflight/pkg/version"
1819
)
1920

@@ -168,6 +169,9 @@ func (c *CyberArkClient) retrievePresignedUploadURL(ctx context.Context, checksu
168169
}
169170
version.SetUserAgent(req)
170171

172+
// Add telemetry headers
173+
arkapi.SetTelemetryRequestHeader(req)
174+
171175
res, err := c.httpClient.Do(req)
172176
if err != nil {
173177
return "", err

internal/cyberark/dataupload/mock.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/stretchr/testify/require"
1616
"k8s.io/client-go/transport"
1717

18+
arkapi "github.com/jetstack/preflight/internal/cyberark/api"
1819
"github.com/jetstack/preflight/pkg/version"
1920
)
2021

@@ -82,6 +83,12 @@ func (mds *mockDataUploadServer) handleSnapshotLinks(w http.ResponseWriter, r *h
8283
return
8384
}
8485

86+
if r.Header.Get(arkapi.TelemetryHeaderKey) == "" {
87+
w.WriteHeader(http.StatusInternalServerError)
88+
_, _ = w.Write([]byte("should set telemetry header on all requests"))
89+
return
90+
}
91+
8592
if r.Header.Get("Content-Type") != "application/json" {
8693
http.Error(w, "should send JSON on all requests", http.StatusInternalServerError)
8794
return
@@ -159,6 +166,12 @@ func (mds *mockDataUploadServer) handlePresignedUpload(w http.ResponseWriter, r
159166
return
160167
}
161168

169+
if r.Header.Get(arkapi.TelemetryHeaderKey) != "" {
170+
w.WriteHeader(http.StatusInternalServerError)
171+
_, _ = w.Write([]byte("should NOT set telemetry header on requests to presigned URL"))
172+
return
173+
}
174+
162175
amzChecksum := r.Header.Get("X-Amz-Checksum-Sha256")
163176
if amzChecksum == "" {
164177
http.Error(w, "should set x-amz-checksum-sha256 header on all requests", http.StatusInternalServerError)

internal/cyberark/identity/identity.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"k8s.io/klog/v2"
1414

15+
arkapi "github.com/jetstack/preflight/internal/cyberark/api"
1516
"github.com/jetstack/preflight/pkg/logs"
1617
"github.com/jetstack/preflight/pkg/version"
1718
)
@@ -422,4 +423,6 @@ func setIdentityHeaders(r *http.Request) {
422423
r.Header.Set("Content-Type", "application/json")
423424
r.Header.Set("X-IDAP-NATIVE-CLIENT", "true") //nolint: canonicalheader
424425
version.SetUserAgent(r)
426+
// Add telemetry headers
427+
arkapi.SetTelemetryRequestHeader(r)
425428
}

internal/cyberark/identity/mock.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,10 @@ import (
88
"net/http/httptest"
99
"testing"
1010

11+
"github.com/stretchr/testify/assert"
1112
"k8s.io/client-go/transport"
1213

14+
arkapi "github.com/jetstack/preflight/internal/cyberark/api"
1315
"github.com/jetstack/preflight/pkg/version"
1416

1517
_ "embed"
@@ -108,6 +110,10 @@ func checkRequestHeaders(r *http.Request) error {
108110
errs = append(errs, fmt.Errorf("should set X-IDAP-NATIVE-CLIENT header to true on all requests"))
109111
}
110112

113+
if r.Header.Get(arkapi.TelemetryHeaderKey) == "" {
114+
errs = append(errs, fmt.Errorf("should set telemetry header on all requests"))
115+
}
116+
111117
return errors.Join(errs...)
112118
}
113119

@@ -120,9 +126,8 @@ func (mis *mockIdentityServer) handleStartAuthentication(w http.ResponseWriter,
120126
return
121127
}
122128

123-
if err := checkRequestHeaders(r); err != nil {
129+
if err := checkRequestHeaders(r); !assert.NoError(mis.t, err, "request headers are not correct") {
124130
w.WriteHeader(http.StatusForbidden)
125-
fmt.Fprintf(w, `{"message":"issues with headers sent to mock server: %s"}`, err.Error())
126131
return
127132
}
128133

internal/cyberark/servicediscovery/discovery.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os"
1111
"path"
1212

13+
arkapi "github.com/jetstack/preflight/internal/cyberark/api"
1314
"github.com/jetstack/preflight/pkg/version"
1415
)
1516

@@ -109,7 +110,8 @@ func (c *Client) DiscoverServices(ctx context.Context, subdomain string) (*Servi
109110

110111
request.Header.Set("Accept", "application/json")
111112
version.SetUserAgent(request)
112-
113+
// Add telemetry headers
114+
arkapi.SetTelemetryRequestHeader(request)
113115
resp, err := c.client.Do(request)
114116
if err != nil {
115117
return nil, fmt.Errorf("failed to perform HTTP request: %s", err)

internal/cyberark/servicediscovery/mock.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"k8s.io/client-go/transport"
1515

16+
arkapi "github.com/jetstack/preflight/internal/cyberark/api"
1617
"github.com/jetstack/preflight/pkg/version"
1718

1819
_ "embed"
@@ -92,6 +93,12 @@ func (mds *mockDiscoveryServer) ServeHTTP(w http.ResponseWriter, r *http.Request
9293
return
9394
}
9495

96+
if r.Header.Get(arkapi.TelemetryHeaderKey) == "" {
97+
w.WriteHeader(http.StatusInternalServerError)
98+
_, _ = w.Write([]byte("should set telemetry header on all requests"))
99+
return
100+
}
101+
95102
if r.Header.Get("Accept") != "application/json" {
96103
w.WriteHeader(http.StatusInternalServerError)
97104
_, _ = w.Write([]byte("should request JSON on all requests"))

0 commit comments

Comments
 (0)