@@ -3,35 +3,38 @@ package dataupload_test
33import (
44 "crypto/x509"
55 "encoding/pem"
6+ "errors"
67 "fmt"
78 "net/http"
9+ "os"
810 "testing"
911 "time"
1012
1113 "github.com/stretchr/testify/require"
1214
1315 "github.com/jetstack/preflight/api"
1416 "github.com/jetstack/preflight/pkg/internal/cyberark/dataupload"
17+ "github.com/jetstack/preflight/pkg/internal/cyberark/identity"
18+ "github.com/jetstack/preflight/pkg/internal/cyberark/servicediscovery"
19+ "github.com/jetstack/preflight/pkg/testutil"
20+
21+ "k8s.io/klog/v2"
22+ "k8s.io/klog/v2/ktesting"
23+ _ "k8s.io/klog/v2/ktesting/init"
1524)
1625
17- func TestCyberArkClient_PostDataReadingsWithOptions (t * testing.T ) {
26+ func TestCyberArkClient_PostDataReadingsWithOptions_MockAPI (t * testing.T ) {
1827 fakeTime := time .Unix (123 , 0 )
19- defaultPayload := api.DataReadingsPost {
20- AgentMetadata : & api.AgentMetadata {
21- Version : "test-version" ,
22- ClusterID : "test" ,
23- },
24- DataGatherTime : fakeTime ,
25- DataReadings : []* api.DataReading {
26- {
27- ClusterID : "success-cluster-id" ,
28- DataGatherer : "test-gatherer" ,
29- Timestamp : api.Time {Time : fakeTime },
30- Data : map [string ]interface {}{"test" : "data" },
31- SchemaVersion : "v1" ,
32- },
28+ defaultDataReadings := []* api.DataReading {
29+ {
30+ ClusterID : "success-cluster-id" ,
31+ DataGatherer : "test-gatherer" ,
32+ Timestamp : api.Time {Time : fakeTime },
33+ Data : map [string ]interface {}{"test" : "data" },
34+ SchemaVersion : "v1" ,
3335 },
3436 }
37+
3538 defaultOpts := dataupload.Options {
3639 ClusterName : "success-cluster-id" ,
3740 }
@@ -45,14 +48,14 @@ func TestCyberArkClient_PostDataReadingsWithOptions(t *testing.T) {
4548
4649 tests := []struct {
4750 name string
48- payload api.DataReadingsPost
51+ readings [] * api.DataReading
4952 authenticate func (req * http.Request ) error
5053 opts dataupload.Options
5154 requireFn func (t * testing.T , err error )
5255 }{
5356 {
5457 name : "successful upload" ,
55- payload : defaultPayload ,
58+ readings : defaultDataReadings ,
5659 opts : defaultOpts ,
5760 authenticate : setToken ("success-token" ),
5861 requireFn : func (t * testing.T , err error ) {
@@ -61,7 +64,7 @@ func TestCyberArkClient_PostDataReadingsWithOptions(t *testing.T) {
6164 },
6265 {
6366 name : "error when cluster name is empty" ,
64- payload : defaultPayload ,
67+ readings : defaultDataReadings ,
6568 opts : dataupload.Options {ClusterName : "" },
6669 authenticate : setToken ("success-token" ),
6770 requireFn : func (t * testing.T , err error ) {
@@ -70,16 +73,27 @@ func TestCyberArkClient_PostDataReadingsWithOptions(t *testing.T) {
7073 },
7174 {
7275 name : "error when bearer token is incorrect" ,
73- payload : defaultPayload ,
76+ readings : defaultDataReadings ,
7477 opts : defaultOpts ,
7578 authenticate : setToken ("fail-token" ),
7679 requireFn : func (t * testing.T , err error ) {
7780 require .ErrorContains (t , err , "while retrieving snapshot upload URL: received response with status code 500: should authenticate using the correct bearer token" )
7881 },
7982 },
83+ {
84+ name : "error contains authenticate error" ,
85+ readings : defaultDataReadings ,
86+ opts : defaultOpts ,
87+ authenticate : func (_ * http.Request ) error {
88+ return errors .New ("simulated-authenticate-error" )
89+ },
90+ requireFn : func (t * testing.T , err error ) {
91+ require .ErrorContains (t , err , "while retrieving snapshot upload URL: failed to authenticate request: simulated-authenticate-error" )
92+ },
93+ },
8094 {
8195 name : "invalid JSON from server (RetrievePresignedUploadURL step)" ,
82- payload : defaultPayload ,
96+ readings : defaultDataReadings ,
8397 opts : dataupload.Options {ClusterName : "invalid-json-retrieve-presigned" },
8498 authenticate : setToken ("success-token" ),
8599 requireFn : func (t * testing.T , err error ) {
@@ -88,7 +102,7 @@ func TestCyberArkClient_PostDataReadingsWithOptions(t *testing.T) {
88102 },
89103 {
90104 name : "500 from server (RetrievePresignedUploadURL step)" ,
91- payload : defaultPayload ,
105+ readings : defaultDataReadings ,
92106 opts : dataupload.Options {ClusterName : "invalid-response-post-data" },
93107 authenticate : setToken ("success-token" ),
94108 requireFn : func (t * testing.T , err error ) {
@@ -99,6 +113,9 @@ func TestCyberArkClient_PostDataReadingsWithOptions(t *testing.T) {
99113
100114 for _ , tc := range tests {
101115 t .Run (tc .name , func (t * testing.T ) {
116+ logger := ktesting .NewLogger (t , ktesting .DefaultConfig )
117+ ctx := klog .NewContext (t .Context (), logger )
118+
102119 server := dataupload .MockDataUploadServer ()
103120 defer server .Close ()
104121
@@ -111,8 +128,67 @@ func TestCyberArkClient_PostDataReadingsWithOptions(t *testing.T) {
111128 cyberArkClient , err := dataupload .NewCyberArkClient (certPool , server .Server .URL , tc .authenticate )
112129 require .NoError (t , err )
113130
114- err = cyberArkClient .PostDataReadingsWithOptions (t . Context () , tc .payload , tc .opts )
131+ err = cyberArkClient .PostDataReadingsWithOptions (ctx , tc .readings , tc .opts )
115132 tc .requireFn (t , err )
116133 })
117134 }
118135}
136+
137+ // TestCyberArkClient_PostDataReadingsWithOptions_RealAPI demonstrates that the dataupload code works with the real inventory API.
138+ // An API token is obtained by authenticating with the ARK_USERNAME and ARK_SECRET from the environment.
139+ // ARK_SUBDOMAIN should be your tenant subdomain.
140+ // ARK_PLATFORM_DOMAIN should be either integration-cyberark.cloud or cyberark.cloud
141+ //
142+ // To enable verbose request logging:
143+ //
144+ // go test ./pkg/internal/cyberark/dataupload/... \
145+ // -v -count 1 -run TestCyberArkClient_PostDataReadingsWithOptions_RealAPI -args -testing.v 6
146+ func TestCyberArkClient_PostDataReadingsWithOptions_RealAPI (t * testing.T ) {
147+ platformDomain := os .Getenv ("ARK_PLATFORM_DOMAIN" )
148+ subdomain := os .Getenv ("ARK_SUBDOMAIN" )
149+ username := os .Getenv ("ARK_USERNAME" )
150+ secret := os .Getenv ("ARK_SECRET" )
151+
152+ if platformDomain == "" || subdomain == "" || username == "" || secret == "" {
153+ t .Skip ("Skipping because one of the following environment variables is unset or empty: ARK_PLATFORM_DOMAIN, ARK_SUBDOMAIN, ARK_USERNAME, ARK_SECRET" )
154+ return
155+ }
156+
157+ logger := ktesting .NewLogger (t , ktesting .DefaultConfig )
158+ ctx := klog .NewContext (t .Context (), logger )
159+
160+ const (
161+ discoveryContextServiceName = "inventory"
162+ separator = "."
163+ )
164+
165+ serviceURL := fmt .Sprintf ("https://%s%s%s.%s" , subdomain , separator , discoveryContextServiceName , platformDomain )
166+
167+ var (
168+ identityClient * identity.Client
169+ err error
170+ )
171+ if platformDomain == "cyberark.cloud" {
172+ identityClient , err = identity .New (ctx , subdomain )
173+ } else {
174+ discoveryClient := servicediscovery .New (servicediscovery .WithIntegrationEndpoint ())
175+ identityClient , err = identity .NewWithDiscoveryClient (ctx , discoveryClient , subdomain )
176+ }
177+ require .NoError (t , err )
178+
179+ err = identityClient .LoginUsernamePassword (ctx , username , []byte (secret ))
180+ require .NoError (t , err )
181+
182+ cyberArkClient , err := dataupload .NewCyberArkClient (nil , serviceURL , identityClient .AuthenticateRequest )
183+ require .NoError (t , err )
184+
185+ dataReadings := testutil .ParseDataReadings (t , testutil .ReadGZIP (t , "testdata/example-1/datareadings.json.gz" ))
186+ err = cyberArkClient .PostDataReadingsWithOptions (
187+ ctx ,
188+ dataReadings ,
189+ dataupload.Options {
190+ ClusterName : "bb068932-c80d-460d-88df-34bc7f3f3297" ,
191+ },
192+ )
193+ require .NoError (t , err )
194+ }
0 commit comments