github.com/verrazzano/verrazzano@v1.7.1/pkg/rancherutil/rancher_config_test.go (about) 1 // Copyright (c) 2022, 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package rancherutil 5 6 import ( 7 "bytes" 8 "io" 9 "net/http" 10 "os" 11 "strings" 12 "testing" 13 "time" 14 15 "github.com/verrazzano/verrazzano/pkg/nginxutil" 16 17 "github.com/golang/mock/gomock" 18 "github.com/stretchr/testify/assert" 19 pkgconst "github.com/verrazzano/verrazzano/pkg/constants" 20 "github.com/verrazzano/verrazzano/pkg/log/vzlog" 21 "github.com/verrazzano/verrazzano/pkg/test/mockmatchers" 22 "github.com/verrazzano/verrazzano/platform-operator/mocks" 23 corev1 "k8s.io/api/core/v1" 24 networkv1 "k8s.io/api/networking/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 "k8s.io/apimachinery/pkg/util/wait" 27 "sigs.k8s.io/controller-runtime/pkg/client" 28 "sigs.k8s.io/controller-runtime/pkg/client/fake" 29 ) 30 31 var ( 32 testToken = "test" 33 userID = "usertest" 34 ) 35 36 // TestCreateRancherRequest tests the creation of a Rancher request sender to make sure that 37 // HTTP requests are properly constructed and sent to Rancher 38 func TestCreateRancherRequest(t *testing.T) { 39 DeleteStoredTokens() 40 cli := createTestObjects() 41 log := vzlog.DefaultLogger() 42 43 testPath := "test/path" 44 testBody := "test-body" 45 46 savedRancherHTTPClient := RancherHTTPClient 47 defer func() { 48 RancherHTTPClient = savedRancherHTTPClient 49 }() 50 51 savedRetry := DefaultRetry 52 defer func() { 53 DefaultRetry = savedRetry 54 }() 55 DefaultRetry = wait.Backoff{ 56 Steps: 1, 57 Duration: 1 * time.Millisecond, 58 Factor: 1.0, 59 Jitter: 0.1, 60 } 61 62 mocker := gomock.NewController(t) 63 httpMock := mocks.NewMockRequestSender(mocker) 64 httpMock = expectHTTPRequests(httpMock, testPath, testBody) 65 RancherHTTPClient = httpMock 66 67 // Test with the Verrazzano cluster user 68 rc, err := NewVerrazzanoClusterRancherConfig(cli, DefaultRancherIngressHostPrefix+nginxutil.IngressNGINXNamespace(), log) 69 assert.NoError(t, err) 70 71 response, body, err := SendRequest(http.MethodGet, testPath, map[string]string{}, "", rc, log) 72 assert.NoError(t, err) 73 assert.Equal(t, testBody, body) 74 assert.Equal(t, http.StatusOK, response.StatusCode) 75 76 // Test with the admin user 77 rc, err = NewAdminRancherConfig(cli, DefaultRancherIngressHostPrefix+nginxutil.IngressNGINXNamespace(), log) 78 assert.NoError(t, err) 79 80 response, body, err = SendRequest(http.MethodGet, testPath, map[string]string{}, "", rc, log) 81 assert.NoError(t, err) 82 assert.Equal(t, testBody, body) 83 assert.Equal(t, http.StatusOK, response.StatusCode) 84 85 response, _, err = SendRequest(http.MethodPost, tokensPath, map[string]string{}, "", rc, log) 86 assert.NoError(t, err) 87 88 response, _, err = SendRequest(http.MethodGet, tokensPath+testToken, map[string]string{}, "", rc, log) 89 assert.NoError(t, err) 90 } 91 92 func createTestObjects() client.WithWatch { 93 return fake.NewClientBuilder().WithRuntimeObjects( 94 &networkv1.Ingress{ 95 ObjectMeta: metav1.ObjectMeta{ 96 Namespace: rancherNamespace, 97 Name: rancherIngressName, 98 }, 99 Spec: networkv1.IngressSpec{ 100 Rules: []networkv1.IngressRule{ 101 { 102 Host: "test-rancher.com", 103 }, 104 }, 105 }, 106 }, 107 &corev1.Secret{ 108 ObjectMeta: metav1.ObjectMeta{ 109 Namespace: pkgconst.VerrazzanoMultiClusterNamespace, 110 Name: pkgconst.VerrazzanoClusterRancherName, 111 }, 112 Data: map[string][]byte{ 113 "password": []byte(""), 114 }, 115 }, 116 &corev1.Secret{ 117 ObjectMeta: metav1.ObjectMeta{ 118 Namespace: rancherNamespace, 119 Name: rancherAdminSecret, 120 }, 121 Data: map[string][]byte{ 122 "password": []byte(""), 123 }, 124 }).Build() 125 } 126 127 func expectHTTPRequests(httpMock *mocks.MockRequestSender, testPath, testBody string) *mocks.MockRequestSender { 128 loginURLParts := strings.Split(loginPath, "?") 129 loginURIPath := loginURLParts[0] 130 httpMock.EXPECT(). 131 Do(gomock.Not(gomock.Nil()), mockmatchers.MatchesURI(tokensPath+testToken)). 132 DoAndReturn(func(httpClient *http.Client, req *http.Request) (*http.Response, error) { 133 var resp *http.Response 134 r := io.NopCloser(bytes.NewReader([]byte(testBody))) 135 resp = &http.Response{ 136 StatusCode: http.StatusOK, 137 Body: r, 138 } 139 return resp, nil 140 }) 141 httpMock.EXPECT(). 142 Do(gomock.Not(gomock.Nil()), mockmatchers.MatchesURI(tokensPath)). 143 DoAndReturn(func(httpClient *http.Client, req *http.Request) (*http.Response, error) { 144 var resp *http.Response 145 r := io.NopCloser(bytes.NewReader([]byte(testBody))) 146 resp = &http.Response{ 147 StatusCode: http.StatusCreated, 148 Body: r, 149 } 150 return resp, nil 151 }).Times(1) 152 httpMock.EXPECT(). 153 Do(gomock.Not(gomock.Nil()), mockmatchers.MatchesURI(testPath)). 154 DoAndReturn(func(httpClient *http.Client, req *http.Request) (*http.Response, error) { 155 var resp *http.Response 156 r := io.NopCloser(bytes.NewReader([]byte(testBody))) 157 resp = &http.Response{ 158 StatusCode: http.StatusOK, 159 Body: r, 160 } 161 return resp, nil 162 }).Times(2) 163 httpMock.EXPECT(). 164 Do(gomock.Not(gomock.Nil()), mockmatchers.MatchesURI(loginURIPath)). 165 DoAndReturn(func(httpClient *http.Client, req *http.Request) (*http.Response, error) { 166 r := io.NopCloser(bytes.NewReader([]byte(`{"token":"unit-test-token"}`))) 167 resp := &http.Response{ 168 StatusCode: http.StatusCreated, 169 Body: r, 170 Request: &http.Request{Method: http.MethodPost}, 171 } 172 return resp, nil 173 }).Times(2) 174 return httpMock 175 } 176 func TestGetTokenWithFilter(t *testing.T) { 177 clusterIDForTest := "clusteridfortest" 178 DeleteStoredTokens() 179 cli := createTestObjects() 180 log := vzlog.DefaultLogger() 181 loginURLParts := strings.Split(loginPath, "?") 182 loginURIPath := loginURLParts[0] 183 testBodyForTokens, _ := os.Open("testdata/bodyfortokentest.json") 184 arrayBytes, _ := io.ReadAll(testBodyForTokens) 185 savedRancherHTTPClient := RancherHTTPClient 186 defer func() { 187 RancherHTTPClient = savedRancherHTTPClient 188 }() 189 190 savedRetry := DefaultRetry 191 defer func() { 192 DefaultRetry = savedRetry 193 }() 194 195 DefaultRetry = wait.Backoff{ 196 Steps: 1, 197 Duration: 1 * time.Millisecond, 198 Factor: 1.0, 199 Jitter: 0.1, 200 } 201 202 mocker := gomock.NewController(t) 203 httpMock := mocks.NewMockRequestSender(mocker) 204 httpMock.EXPECT(). 205 Do(gomock.Not(gomock.Nil()), mockmatchers.MatchesURI(loginURIPath)). 206 DoAndReturn(func(httpClient *http.Client, req *http.Request) (*http.Response, error) { 207 r := io.NopCloser(bytes.NewReader([]byte(`{"token":"unit-test-token"}`))) 208 resp := &http.Response{ 209 StatusCode: http.StatusCreated, 210 Body: r, 211 Request: &http.Request{Method: http.MethodPost}, 212 } 213 return resp, nil 214 }).Times(1) 215 httpMock.EXPECT(). 216 Do(gomock.Not(gomock.Nil()), mockmatchers.MatchesURI(tokensPath)). 217 DoAndReturn(func(httpClient *http.Client, req *http.Request) (*http.Response, error) { 218 var resp *http.Response 219 r := io.NopCloser(bytes.NewReader([]byte(arrayBytes))) 220 resp = &http.Response{ 221 StatusCode: http.StatusOK, 222 Body: r, 223 } 224 return resp, nil 225 }).Times(1) 226 RancherHTTPClient = httpMock 227 rc, err := NewAdminRancherConfig(cli, DefaultRancherIngressHostPrefix+nginxutil.IngressNGINXNamespace(), log) 228 assert.NoError(t, err) 229 createdTimeAsString, _, err := GetTokenWithFilter(rc, log, userID, clusterIDForTest) 230 assert.NoError(t, err) 231 assert.Equal(t, createdTimeAsString, "2023-07-13T19:32:38Z") 232 }