github.com/oam-dev/cluster-gateway@v1.9.0/pkg/apis/cluster/v1alpha1/transport_test.go (about) 1 package v1alpha1 2 3 import ( 4 "context" 5 "net" 6 "net/http" 7 "net/url" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 14 k8snet "k8s.io/apimachinery/pkg/util/net" 15 "k8s.io/client-go/rest" 16 "k8s.io/utils/pointer" 17 ) 18 19 func TestClusterRestConfigConversion(t *testing.T) { 20 testToken := "test-token" 21 testCAData := []byte(`test-ca`) 22 testCertData := []byte(`test-cert`) 23 testKeyData := []byte(`test-key`) 24 proxyURLData := []byte(`socks5://localhost:1080`) 25 proxyURL, _ := url.Parse(string(proxyURLData)) 26 testDialFunc := func(ctx context.Context, net, addr string) (net.Conn, error) { 27 return nil, nil 28 } 29 DialerGetter = func(ctx context.Context) (k8snet.DialFunc, error) { 30 return testDialFunc, nil 31 } 32 cases := []struct { 33 name string 34 clusterGateway *ClusterGateway 35 expectedCfg *rest.Config 36 expectFailure bool 37 }{ 38 { 39 name: "normal cluster-gateway with SA token + host-port should work", 40 clusterGateway: &ClusterGateway{ 41 Spec: ClusterGatewaySpec{ 42 Access: ClusterAccess{ 43 Endpoint: &ClusterEndpoint{ 44 Type: ClusterEndpointTypeConst, 45 Const: &ClusterEndpointConst{ 46 Address: "https://foo.bar:33", 47 CABundle: testCAData, 48 }, 49 }, 50 Credential: &ClusterAccessCredential{ 51 Type: CredentialTypeServiceAccountToken, 52 ServiceAccountToken: testToken, 53 }, 54 }, 55 }, 56 }, 57 expectedCfg: &rest.Config{ 58 Host: "https://foo.bar:33", 59 BearerToken: testToken, 60 Timeout: 40 * time.Second, 61 TLSClientConfig: rest.TLSClientConfig{ 62 ServerName: "foo.bar", 63 CAData: testCAData, 64 }, 65 }, 66 }, 67 { 68 name: "normal cluster-gateway with X509 + host-port should work", 69 clusterGateway: &ClusterGateway{ 70 Spec: ClusterGatewaySpec{ 71 Access: ClusterAccess{ 72 Endpoint: &ClusterEndpoint{ 73 Type: ClusterEndpointTypeConst, 74 Const: &ClusterEndpointConst{ 75 Address: "https://foo.bar:33", 76 CABundle: testCAData, 77 }, 78 }, 79 Credential: &ClusterAccessCredential{ 80 Type: CredentialTypeX509Certificate, 81 X509: &X509{ 82 Certificate: testCertData, 83 PrivateKey: testKeyData, 84 }, 85 }, 86 }, 87 }, 88 }, 89 expectedCfg: &rest.Config{ 90 Host: "https://foo.bar:33", 91 Timeout: 40 * time.Second, 92 TLSClientConfig: rest.TLSClientConfig{ 93 ServerName: "foo.bar", 94 CAData: testCAData, 95 CertData: testCertData, 96 KeyData: testKeyData, 97 }, 98 }, 99 }, 100 { 101 name: "https port defaulting should work", 102 clusterGateway: &ClusterGateway{ 103 Spec: ClusterGatewaySpec{ 104 Access: ClusterAccess{ 105 Endpoint: &ClusterEndpoint{ 106 Type: ClusterEndpointTypeConst, 107 Const: &ClusterEndpointConst{ 108 Address: "https://foo.bar", 109 CABundle: testCAData, 110 }, 111 }, 112 Credential: &ClusterAccessCredential{ 113 Type: CredentialTypeServiceAccountToken, 114 ServiceAccountToken: testToken, 115 }, 116 }, 117 }, 118 }, 119 expectedCfg: &rest.Config{ 120 Host: "https://foo.bar", 121 Timeout: 40 * time.Second, 122 BearerToken: testToken, 123 TLSClientConfig: rest.TLSClientConfig{ 124 ServerName: "foo.bar", 125 CAData: testCAData, 126 }, 127 }, 128 }, 129 { 130 name: "insecure (no CA bundle) should work", 131 clusterGateway: &ClusterGateway{ 132 Spec: ClusterGatewaySpec{ 133 Access: ClusterAccess{ 134 Endpoint: &ClusterEndpoint{ 135 Type: ClusterEndpointTypeConst, 136 Const: &ClusterEndpointConst{ 137 Address: "https://foo.bar:33", 138 Insecure: pointer.Bool(true), 139 }, 140 }, 141 Credential: &ClusterAccessCredential{ 142 Type: CredentialTypeServiceAccountToken, 143 ServiceAccountToken: testToken, 144 }, 145 }, 146 }, 147 }, 148 expectedCfg: &rest.Config{ 149 Host: "https://foo.bar:33", 150 Timeout: 40 * time.Second, 151 BearerToken: testToken, 152 TLSClientConfig: rest.TLSClientConfig{ 153 ServerName: "foo.bar", 154 Insecure: true, 155 }, 156 }, 157 }, 158 { 159 name: "cluster-proxy egress should work", 160 clusterGateway: &ClusterGateway{ 161 ObjectMeta: metav1.ObjectMeta{ 162 Name: "my-cluster", 163 }, 164 Spec: ClusterGatewaySpec{ 165 Access: ClusterAccess{ 166 Endpoint: &ClusterEndpoint{ 167 Type: ClusterEndpointTypeClusterProxy, 168 }, 169 Credential: &ClusterAccessCredential{ 170 Type: CredentialTypeServiceAccountToken, 171 ServiceAccountToken: testToken, 172 }, 173 }, 174 }, 175 }, 176 expectedCfg: &rest.Config{ 177 Host: "my-cluster", 178 Timeout: 40 * time.Second, 179 BearerToken: testToken, 180 Dial: testDialFunc, 181 TLSClientConfig: rest.TLSClientConfig{ 182 Insecure: true, 183 }, 184 }, 185 }, 186 { 187 name: "proxy-url should work", 188 clusterGateway: &ClusterGateway{ 189 ObjectMeta: metav1.ObjectMeta{ 190 Name: "my-cluster", 191 }, 192 Spec: ClusterGatewaySpec{ 193 Access: ClusterAccess{ 194 Endpoint: &ClusterEndpoint{ 195 Type: ClusterEndpointTypeConst, 196 Const: &ClusterEndpointConst{ 197 Address: "https://foo.bar:33", 198 ProxyURL: pointer.String(string(proxyURLData)), 199 }, 200 }, 201 Credential: &ClusterAccessCredential{ 202 Type: CredentialTypeServiceAccountToken, 203 ServiceAccountToken: testToken, 204 }, 205 }, 206 }, 207 }, 208 expectedCfg: &rest.Config{ 209 Host: "https://foo.bar:33", 210 Timeout: 40 * time.Second, 211 BearerToken: testToken, 212 Proxy: http.ProxyURL(proxyURL), 213 TLSClientConfig: rest.TLSClientConfig{ 214 ServerName: "foo.bar", 215 }, 216 }, 217 }, 218 { 219 name: "dynamic credential: service account token", 220 clusterGateway: &ClusterGateway{ 221 ObjectMeta: metav1.ObjectMeta{ 222 Name: "my-cluster", 223 }, 224 Spec: ClusterGatewaySpec{ 225 Access: ClusterAccess{ 226 Endpoint: &ClusterEndpoint{ 227 Type: ClusterEndpointTypeConst, 228 Const: &ClusterEndpointConst{ 229 Address: "https://k8s.example.com", 230 CABundle: testCAData, 231 }, 232 }, 233 Credential: &ClusterAccessCredential{ 234 Type: CredentialTypeDynamic, 235 ServiceAccountToken: testToken, 236 }, 237 }, 238 }, 239 }, 240 expectedCfg: &rest.Config{ 241 Host: "https://k8s.example.com", 242 Timeout: 40 * time.Second, 243 BearerToken: testToken, 244 TLSClientConfig: rest.TLSClientConfig{ 245 ServerName: "k8s.example.com", 246 CAData: testCAData, 247 }, 248 }, 249 }, 250 { 251 name: "dynamic credential: certificate + private key", 252 clusterGateway: &ClusterGateway{ 253 ObjectMeta: metav1.ObjectMeta{ 254 Name: "my-cluster", 255 }, 256 Spec: ClusterGatewaySpec{ 257 Access: ClusterAccess{ 258 Endpoint: &ClusterEndpoint{ 259 Type: ClusterEndpointTypeConst, 260 Const: &ClusterEndpointConst{ 261 Address: "https://k8s.example.com", 262 CABundle: testCAData, 263 }, 264 }, 265 Credential: &ClusterAccessCredential{ 266 Type: CredentialTypeDynamic, 267 X509: &X509{ 268 Certificate: testCertData, 269 PrivateKey: testKeyData, 270 }, 271 }, 272 }, 273 }, 274 }, 275 expectedCfg: &rest.Config{ 276 Host: "https://k8s.example.com", 277 Timeout: 40 * time.Second, 278 TLSClientConfig: rest.TLSClientConfig{ 279 ServerName: "k8s.example.com", 280 CertData: testCertData, 281 KeyData: testKeyData, 282 CAData: testCAData, 283 }, 284 }, 285 }, 286 } 287 for _, c := range cases { 288 t.Run(c.name, func(t *testing.T) { 289 cfg, err := NewConfigFromCluster(context.TODO(), c.clusterGateway) 290 if err != nil { 291 if c.expectFailure { 292 return 293 } 294 require.NoError(t, err) 295 } 296 if cfg.Dial != nil { 297 assert.ObjectsAreEqual(c.expectedCfg.Dial, cfg.Dial) 298 c.expectedCfg.Dial = nil 299 cfg.Dial = nil 300 } 301 if cfg.Proxy != nil { 302 assert.NotNil(t, c.expectedCfg.Proxy) 303 cfg.Proxy = nil 304 c.expectedCfg.Proxy = nil 305 } 306 assert.Equal(t, c.expectedCfg, cfg) 307 }) 308 } 309 310 }