k8s.io/client-go@v0.22.2/tools/auth/exec/exec_test.go (about) 1 /* 2 Copyright 2020 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package exec 18 19 import ( 20 "strings" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/runtime" 26 "k8s.io/apimachinery/pkg/runtime/schema" 27 clientauthenticationv1 "k8s.io/client-go/pkg/apis/clientauthentication/v1" 28 clientauthenticationv1alpha1 "k8s.io/client-go/pkg/apis/clientauthentication/v1alpha1" 29 clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1" 30 "k8s.io/client-go/rest" 31 ) 32 33 // restInfo holds the rest.Client fields that we care about for test assertions. 34 type restInfo struct { 35 host string 36 tlsClientConfig rest.TLSClientConfig 37 proxyURL string 38 } 39 40 func TestLoadExecCredential(t *testing.T) { 41 t.Parallel() 42 43 tests := []struct { 44 name string 45 data []byte 46 wantExecCredential runtime.Object 47 wantRESTInfo restInfo 48 wantErrorPrefix string 49 }{ 50 { 51 name: "v1 happy path", 52 data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{ 53 Spec: clientauthenticationv1.ExecCredentialSpec{ 54 Cluster: &clientauthenticationv1.Cluster{ 55 Server: "https://some-server/some/path", 56 TLSServerName: "some-server-name", 57 InsecureSkipTLSVerify: true, 58 CertificateAuthorityData: []byte("some-ca-data"), 59 ProxyURL: "https://some-proxy-url:12345", 60 Config: runtime.RawExtension{ 61 Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`), 62 }, 63 }, 64 }, 65 }), 66 wantExecCredential: &clientauthenticationv1.ExecCredential{ 67 TypeMeta: metav1.TypeMeta{ 68 Kind: "ExecCredential", 69 APIVersion: clientauthenticationv1.SchemeGroupVersion.String(), 70 }, 71 Spec: clientauthenticationv1.ExecCredentialSpec{ 72 Cluster: &clientauthenticationv1.Cluster{ 73 Server: "https://some-server/some/path", 74 TLSServerName: "some-server-name", 75 InsecureSkipTLSVerify: true, 76 CertificateAuthorityData: []byte("some-ca-data"), 77 ProxyURL: "https://some-proxy-url:12345", 78 Config: runtime.RawExtension{ 79 Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`), 80 }, 81 }, 82 }, 83 }, 84 wantRESTInfo: restInfo{ 85 host: "https://some-server/some/path", 86 tlsClientConfig: rest.TLSClientConfig{ 87 Insecure: true, 88 ServerName: "some-server-name", 89 CAData: []byte("some-ca-data"), 90 }, 91 proxyURL: "https://some-proxy-url:12345", 92 }, 93 }, 94 { 95 name: "v1beta1 happy path", 96 data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{ 97 Spec: clientauthenticationv1beta1.ExecCredentialSpec{ 98 Cluster: &clientauthenticationv1beta1.Cluster{ 99 Server: "https://some-server/some/path", 100 TLSServerName: "some-server-name", 101 InsecureSkipTLSVerify: true, 102 CertificateAuthorityData: []byte("some-ca-data"), 103 ProxyURL: "https://some-proxy-url:12345", 104 Config: runtime.RawExtension{ 105 Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`), 106 }, 107 }, 108 }, 109 }), 110 wantExecCredential: &clientauthenticationv1beta1.ExecCredential{ 111 TypeMeta: metav1.TypeMeta{ 112 Kind: "ExecCredential", 113 APIVersion: clientauthenticationv1beta1.SchemeGroupVersion.String(), 114 }, 115 Spec: clientauthenticationv1beta1.ExecCredentialSpec{ 116 Cluster: &clientauthenticationv1beta1.Cluster{ 117 Server: "https://some-server/some/path", 118 TLSServerName: "some-server-name", 119 InsecureSkipTLSVerify: true, 120 CertificateAuthorityData: []byte("some-ca-data"), 121 ProxyURL: "https://some-proxy-url:12345", 122 Config: runtime.RawExtension{ 123 Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`), 124 }, 125 }, 126 }, 127 }, 128 wantRESTInfo: restInfo{ 129 host: "https://some-server/some/path", 130 tlsClientConfig: rest.TLSClientConfig{ 131 Insecure: true, 132 ServerName: "some-server-name", 133 CAData: []byte("some-ca-data"), 134 }, 135 proxyURL: "https://some-proxy-url:12345", 136 }, 137 }, 138 { 139 name: "v1 nil config", 140 data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{ 141 Spec: clientauthenticationv1.ExecCredentialSpec{ 142 Cluster: &clientauthenticationv1.Cluster{ 143 Server: "https://some-server/some/path", 144 TLSServerName: "some-server-name", 145 InsecureSkipTLSVerify: true, 146 CertificateAuthorityData: []byte("some-ca-data"), 147 ProxyURL: "https://some-proxy-url:12345", 148 }, 149 }, 150 }), 151 wantExecCredential: &clientauthenticationv1.ExecCredential{ 152 TypeMeta: metav1.TypeMeta{ 153 Kind: "ExecCredential", 154 APIVersion: clientauthenticationv1.SchemeGroupVersion.String(), 155 }, 156 Spec: clientauthenticationv1.ExecCredentialSpec{ 157 Cluster: &clientauthenticationv1.Cluster{ 158 Server: "https://some-server/some/path", 159 TLSServerName: "some-server-name", 160 InsecureSkipTLSVerify: true, 161 CertificateAuthorityData: []byte("some-ca-data"), 162 ProxyURL: "https://some-proxy-url:12345", 163 }, 164 }, 165 }, 166 wantRESTInfo: restInfo{ 167 host: "https://some-server/some/path", 168 tlsClientConfig: rest.TLSClientConfig{ 169 Insecure: true, 170 ServerName: "some-server-name", 171 CAData: []byte("some-ca-data"), 172 }, 173 proxyURL: "https://some-proxy-url:12345", 174 }, 175 }, 176 { 177 name: "v1beta1 nil config", 178 data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{ 179 Spec: clientauthenticationv1beta1.ExecCredentialSpec{ 180 Cluster: &clientauthenticationv1beta1.Cluster{ 181 Server: "https://some-server/some/path", 182 TLSServerName: "some-server-name", 183 InsecureSkipTLSVerify: true, 184 CertificateAuthorityData: []byte("some-ca-data"), 185 ProxyURL: "https://some-proxy-url:12345", 186 }, 187 }, 188 }), 189 wantExecCredential: &clientauthenticationv1beta1.ExecCredential{ 190 TypeMeta: metav1.TypeMeta{ 191 Kind: "ExecCredential", 192 APIVersion: clientauthenticationv1beta1.SchemeGroupVersion.String(), 193 }, 194 Spec: clientauthenticationv1beta1.ExecCredentialSpec{ 195 Cluster: &clientauthenticationv1beta1.Cluster{ 196 Server: "https://some-server/some/path", 197 TLSServerName: "some-server-name", 198 InsecureSkipTLSVerify: true, 199 CertificateAuthorityData: []byte("some-ca-data"), 200 ProxyURL: "https://some-proxy-url:12345", 201 }, 202 }, 203 }, 204 wantRESTInfo: restInfo{ 205 host: "https://some-server/some/path", 206 tlsClientConfig: rest.TLSClientConfig{ 207 Insecure: true, 208 ServerName: "some-server-name", 209 CAData: []byte("some-ca-data"), 210 }, 211 proxyURL: "https://some-proxy-url:12345", 212 }, 213 }, 214 { 215 name: "v1 invalid cluster", 216 data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{ 217 Spec: clientauthenticationv1.ExecCredentialSpec{ 218 Cluster: &clientauthenticationv1.Cluster{ 219 ProxyURL: "invalid- url\n", 220 }, 221 }, 222 }), 223 wantErrorPrefix: "cannot create rest.Config", 224 }, 225 { 226 name: "v1beta1 invalid cluster", 227 data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{ 228 Spec: clientauthenticationv1beta1.ExecCredentialSpec{ 229 Cluster: &clientauthenticationv1beta1.Cluster{ 230 ProxyURL: "invalid- url\n", 231 }, 232 }, 233 }), 234 wantErrorPrefix: "cannot create rest.Config", 235 }, 236 { 237 name: "v1 nil cluster", 238 data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{}), 239 wantErrorPrefix: "ExecCredential does not contain cluster information", 240 }, 241 { 242 name: "v1beta1 nil cluster", 243 data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{}), 244 wantErrorPrefix: "ExecCredential does not contain cluster information", 245 }, 246 { 247 name: "v1alpha1", 248 data: marshal(t, clientauthenticationv1alpha1.SchemeGroupVersion, &clientauthenticationv1alpha1.ExecCredential{}), 249 wantErrorPrefix: "ExecCredential does not contain cluster information", 250 }, 251 { 252 name: "invalid object kind", 253 data: marshal(t, metav1.SchemeGroupVersion, &metav1.Status{}), 254 wantErrorPrefix: "invalid group/kind: wanted ExecCredential.client.authentication.k8s.io, got Status", 255 }, 256 { 257 name: "bad data", 258 data: []byte("bad data"), 259 wantErrorPrefix: "decode: ", 260 }, 261 } 262 for _, test := range tests { 263 test := test 264 t.Run(test.name, func(t *testing.T) { 265 t.Parallel() 266 267 execCredential, restConfig, err := LoadExecCredential(test.data) 268 if test.wantErrorPrefix != "" { 269 if err == nil { 270 t.Error("wanted error, got success") 271 } else if !strings.HasPrefix(err.Error(), test.wantErrorPrefix) { 272 t.Errorf("wanted '%s', got '%s'", test.wantErrorPrefix, err.Error()) 273 } 274 } else if err != nil { 275 t.Error(err) 276 } else { 277 if diff := cmp.Diff(test.wantExecCredential, execCredential); diff != "" { 278 t.Error(diff) 279 } 280 281 if diff := cmp.Diff(test.wantRESTInfo.host, restConfig.Host); diff != "" { 282 t.Error(diff) 283 } 284 if diff := cmp.Diff(test.wantRESTInfo.tlsClientConfig, restConfig.TLSClientConfig); diff != "" { 285 t.Error(diff) 286 } 287 288 proxyURL, err := restConfig.Proxy(nil) 289 if err != nil { 290 t.Fatal(err) 291 } 292 if diff := cmp.Diff(test.wantRESTInfo.proxyURL, proxyURL.String()); diff != "" { 293 t.Error(diff) 294 } 295 } 296 }) 297 } 298 } 299 300 func marshal(t *testing.T, gv schema.GroupVersion, obj runtime.Object) []byte { 301 t.Helper() 302 303 data, err := runtime.Encode(codecs.LegacyCodec(gv), obj) 304 if err != nil { 305 t.Fatal(err) 306 } 307 308 return data 309 }