@@ -3,28 +3,18 @@ package client_test
33import (
44 "context"
55 "crypto/x509"
6- "io"
7- "net/http"
8- "net/http/httptest"
9- "os"
106 "strings"
117 "testing"
128
139 "github.com/jetstack/preflight/api"
1410 "github.com/jetstack/preflight/pkg/client"
11+ "github.com/jetstack/preflight/pkg/testutil"
1512
1613 "github.com/jetstack/venafi-connection-lib/api/v1alpha1"
1714 "github.com/stretchr/testify/assert"
1815 "github.com/stretchr/testify/require"
19- corev1 "k8s.io/api/core/v1"
20- rbacv1 "k8s.io/api/rbac/v1"
21- "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
22- "k8s.io/apimachinery/pkg/runtime"
2316 "k8s.io/apimachinery/pkg/types"
24- "k8s.io/apimachinery/pkg/util/yaml"
25- "k8s.io/client-go/rest"
2617 ctrlruntime "sigs.k8s.io/controller-runtime/pkg/client"
27- "sigs.k8s.io/controller-runtime/pkg/envtest"
2818)
2919
3020// These are using envtest (slow) rather than a fake clientset (fast) because
@@ -44,7 +34,7 @@ func TestVenConnClient_PostDataReadingsWithOptions(t *testing.T) {
4434 t .Parallel ()
4535
4636 t .Run ("valid accessToken" , run (testcase {
47- given : undent (`
37+ given : testutil . Undent (`
4838 apiVersion: jetstack.io/v1alpha1
4939 kind: VenafiConnection
5040 metadata:
@@ -63,7 +53,7 @@ func TestVenConnClient_PostDataReadingsWithOptions(t *testing.T) {
6353 // Why isn't it possible to use the 'apiKey' field? Although the
6454 // Kubernetes Discovery endpoint works with an API key, we have decided
6555 // to not support it because it isn't recommended.
66- given : undent (`
56+ given : testutil . Undent (`
6757 apiVersion: jetstack.io/v1alpha1
6858 kind: VenafiConnection
6959 metadata:
@@ -84,7 +74,7 @@ func TestVenConnClient_PostDataReadingsWithOptions(t *testing.T) {
8474 // debugging and making the venafi connection work, and then find out
8575 // that it doesn't work. The reason is because as of now, we don't first
8676 // check if the user has used the 'tpp' field before running Get.
87- given : undent (`
77+ given : testutil . Undent (`
8878 apiVersion: jetstack.io/v1alpha1
8979 kind: VenafiConnection
9080 metadata:
@@ -171,9 +161,9 @@ type testcase struct {
171161
172162func run (test testcase ) func (t * testing.T ) {
173163 return func (t * testing.T ) {
174- fakeVenafiCloud , certCloud := fakeVenafiCloud (t )
175- fakeTPP , certTPP := fakeTPP (t )
176- _ , restconf , kclient := startEnvtest (t )
164+ fakeVenafiCloud , certCloud , _ := testutil . FakeVenafiCloud (t )
165+ fakeTPP , certTPP := testutil . FakeTPP (t )
166+ _ , restconf , kclient := testutil . WithEnvtest (t )
177167
178168 certPool := x509 .NewCertPool ()
179169 certPool .AddCert (certCloud )
@@ -210,8 +200,8 @@ func run(test testcase) func(t *testing.T) {
210200 test .given = strings .ReplaceAll (test .given , "FAKE_TPP_URL" , fakeTPP .URL )
211201
212202 var given []ctrlruntime.Object
213- given = append (given , parse (rbac )... )
214- given = append (given , parse ( undent (`
203+ given = append (given , testutil . Parse (rbac )... )
204+ given = append (given , testutil . Parse ( testutil . Undent (`
215205 apiVersion: v1
216206 kind: Secret
217207 metadata:
@@ -252,7 +242,7 @@ func run(test testcase) func(t *testing.T) {
252242 - kind: ServiceAccount
253243 name: venafi-connection
254244 namespace: venafi` ))... )
255- given = append (given , parse (test .given )... )
245+ given = append (given , testutil . Parse (test .given )... )
256246 for _ , obj := range given {
257247 require .NoError (t , kclient .Create (context .Background (), obj ))
258248 }
@@ -269,186 +259,3 @@ func run(test testcase) func(t *testing.T) {
269259 assert .Equal (t , test .expectReadyCondMsg , got .Status .Conditions [0 ].Message )
270260 }
271261}
272-
273- func fakeVenafiCloud (t * testing.T ) (* httptest.Server , * x509.Certificate ) {
274- server := httptest .NewTLSServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
275- t .Logf ("fake api.venafi.cloud received request: %s %s" , r .Method , r .URL .Path )
276- accessToken := strings .TrimPrefix (r .Header .Get ("Authorization" ), "Bearer " )
277- apiKey := r .Header .Get ("tppl-api-key" )
278- if accessToken != "VALID_ACCESS_TOKEN" && apiKey != "VALID_API_KEY" {
279- w .WriteHeader (http .StatusUnauthorized )
280- return
281- }
282- if r .URL .Path == "/v1/tlspk/upload/clusterdata/no" {
283- if r .URL .Query ().Get ("name" ) != "test cluster name" {
284- w .WriteHeader (http .StatusBadRequest )
285- return
286- }
287- _ , _ = w .Write ([]byte (`{"status":"ok","organization":"756db001-280e-11ee-84fb-991f3177e2d0"}` ))
288- } else if r .URL .Path == "/v1/useraccounts" {
289- w .WriteHeader (http .StatusOK )
290- _ , _ = w .Write ([]byte (`{"user": {"username": "user","id": "76a126f0-280e-11ee-84fb-991f3177e2d0"}}` ))
291-
292- } else if r .URL .Path == "/v1/oauth2/v2.0/756db001-280e-11ee-84fb-991f3177e2d0/token" {
293- _ , _ = w .Write ([]byte (`{"access_token":"VALID_ACCESS_TOKEN","expires_in":900,"token_type":"bearer"}` ))
294- } else {
295- w .WriteHeader (http .StatusInternalServerError )
296- _ , _ = w .Write ([]byte (`{"error":"unexpected path in the test server","path":"` + r .URL .Path + `"}` ))
297- }
298- }))
299- t .Cleanup (server .Close )
300-
301- cert , err := x509 .ParseCertificate (server .TLS .Certificates [0 ].Certificate [0 ])
302- require .NoError (t , err )
303-
304- return server , cert
305- }
306-
307- func fakeTPP (t testing.TB ) (* httptest.Server , * x509.Certificate ) {
308- server := httptest .NewTLSServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
309- t .Logf ("fake tpp.example.com received request: %s %s" , r .Method , r .URL .Path )
310-
311- accessToken := strings .TrimPrefix (r .Header .Get ("Authorization" ), "Bearer " )
312-
313- if r .URL .Path == "/vedsdk/Identity/Self" {
314- if accessToken != "VALID_ACCESS_TOKEN" {
315- w .WriteHeader (http .StatusUnauthorized )
316- return
317- }
318- _ , _ = w .Write ([]byte (`{"Identities":[{"Name":"TEST"}]}` ))
319- } else if r .URL .Path == "/vedsdk/certificates/checkpolicy" {
320- _ , _ = w .Write ([]byte (`{"Policy":{"Subject":{"Organization":{"Value": "test-org"}}}}` ))
321- } else {
322- w .WriteHeader (http .StatusInternalServerError )
323- _ , _ = w .Write ([]byte (`{"error":"unexpected path in the test server","path":"` + r .URL .Path + `"}` ))
324- }
325- }))
326- t .Cleanup (server .Close )
327-
328- cert , err := x509 .ParseCertificate (server .TLS .Certificates [0 ].Certificate [0 ])
329- require .NoError (t , err )
330-
331- return server , cert
332- }
333-
334- // To see the API server logs, set:
335- //
336- // export KUBEBUILDER_ATTACH_CONTROL_PLANE_OUTPUT=true
337- func startEnvtest (t testing.TB ) (_ * envtest.Environment , _ * rest.Config , kclient ctrlruntime.WithWatch ) {
338- // If KUBEBUILDER_ASSETS isn't set, show a warning to the user.
339- if os .Getenv ("KUBEBUILDER_ASSETS" ) == "" {
340- t .Fatalf ("KUBEBUILDER_ASSETS isn't set. You can run this test using `make test`.\n " +
341- "But if you prefer not to use `make`, run these two commands first:\n " +
342- " make _bin/tools/{kube-apiserver,etcd}\n " +
343- " export KUBEBUILDER_ASSETS=$PWD/_bin/tools" )
344- }
345- envtest := & envtest.Environment {
346- ErrorIfCRDPathMissing : true ,
347- CRDDirectoryPaths : []string {"../../deploy/charts/venafi-kubernetes-agent/crd_bases/jetstack.io_venaficonnections.yaml" },
348- }
349-
350- restconf , err := envtest .Start ()
351- t .Cleanup (func () {
352- t .Log ("Waiting for envtest to exit" )
353- e := envtest .Stop ()
354- require .NoError (t , e )
355- })
356- require .NoError (t , err )
357-
358- sch := runtime .NewScheme ()
359- _ = v1alpha1 .AddToScheme (sch )
360- _ = corev1 .AddToScheme (sch )
361- _ = rbacv1 .AddToScheme (sch )
362-
363- kclient , err = ctrlruntime .NewWithWatch (restconf , ctrlruntime.Options {Scheme : sch })
364- require .NoError (t , err )
365-
366- return envtest , restconf , kclient
367- }
368-
369- // Undent removes leading indentation/white-space from given string and returns
370- // it as a string. Useful for inlining YAML manifests in Go code. Inline YAML
371- // manifests in the Go test files makes it easier to read the test case as
372- // opposed to reading verbose-y Go structs.
373- //
374- // This was copied from https://github.com/jimeh/undent/blob/main/undent.go, all
375- // credit goes to the author, Jim Myhrberg.
376- func undent (s string ) string {
377- const (
378- tab = 9
379- lf = 10
380- spc = 32
381- )
382-
383- if len (s ) == 0 {
384- return ""
385- }
386-
387- // find smallest indent relative to each line-feed
388- min := 99999999999
389- count := 0
390-
391- lfs := make ([]int , 0 , strings .Count (s , "\n " ))
392- if s [0 ] != lf {
393- lfs = append (lfs , - 1 )
394- }
395-
396- indent := 0
397- for i := 0 ; i < len (s ); i ++ {
398- if s [i ] == lf {
399- lfs = append (lfs , i )
400- indent = 0
401- } else if indent < min {
402- switch s [i ] {
403- case spc , tab :
404- indent ++
405- default :
406- if indent > 0 {
407- count ++
408- }
409- if indent < min {
410- min = indent
411- }
412- }
413- }
414- }
415-
416- // extract each line without indentation
417- out := make ([]byte , 0 , len (s )- (min * count ))
418-
419- for i := 0 ; i < len (lfs ); i ++ {
420- offset := lfs [i ] + 1
421- end := len (s )
422- if i + 1 < len (lfs ) {
423- end = lfs [i + 1 ] + 1
424- }
425-
426- if offset + min < end {
427- out = append (out , s [offset + min :end ]... )
428- } else if offset < end {
429- out = append (out , s [offset :end ]... )
430- }
431- }
432-
433- return string (out )
434- }
435-
436- // Parses the YAML manifest. Useful for inlining YAML manifests in Go test
437- // files, to be used in conjunction with `undent`.
438- func parse (yamlmanifest string ) []ctrlruntime.Object {
439- dec := yaml .NewYAMLOrJSONDecoder (strings .NewReader (yamlmanifest ), 4096 )
440- var objs []ctrlruntime.Object
441- for {
442- obj := & unstructured.Unstructured {}
443- err := dec .Decode (obj )
444- if err == io .EOF {
445- break
446- }
447- if err != nil {
448- panic (err )
449- }
450-
451- objs = append (objs , obj )
452- }
453- return objs
454- }
0 commit comments