github.com/enmand/kubernetes@v1.2.0-alpha.0/pkg/credentialprovider/keyring_test.go (about) 1 /* 2 Copyright 2014 The Kubernetes Authors All rights reserved. 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 credentialprovider 18 19 import ( 20 "encoding/base64" 21 "fmt" 22 "testing" 23 ) 24 25 func TestUrlsMatch(t *testing.T) { 26 tests := []struct { 27 globUrl string 28 targetUrl string 29 matchExpected bool 30 }{ 31 // match when there is no path component 32 { 33 globUrl: "*.kubernetes.io", 34 targetUrl: "prefix.kubernetes.io", 35 matchExpected: true, 36 }, 37 { 38 globUrl: "prefix.*.io", 39 targetUrl: "prefix.kubernetes.io", 40 matchExpected: true, 41 }, 42 { 43 globUrl: "prefix.kubernetes.*", 44 targetUrl: "prefix.kubernetes.io", 45 matchExpected: true, 46 }, 47 { 48 globUrl: "*-good.kubernetes.io", 49 targetUrl: "prefix-good.kubernetes.io", 50 matchExpected: true, 51 }, 52 // match with path components 53 { 54 globUrl: "*.kubernetes.io/blah", 55 targetUrl: "prefix.kubernetes.io/blah", 56 matchExpected: true, 57 }, 58 { 59 globUrl: "prefix.*.io/foo", 60 targetUrl: "prefix.kubernetes.io/foo/bar", 61 matchExpected: true, 62 }, 63 // match with path components and ports 64 { 65 globUrl: "*.kubernetes.io:1111/blah", 66 targetUrl: "prefix.kubernetes.io:1111/blah", 67 matchExpected: true, 68 }, 69 { 70 globUrl: "prefix.*.io:1111/foo", 71 targetUrl: "prefix.kubernetes.io:1111/foo/bar", 72 matchExpected: true, 73 }, 74 // no match when number of parts mismatch 75 { 76 globUrl: "*.kubernetes.io", 77 targetUrl: "kubernetes.io", 78 matchExpected: false, 79 }, 80 { 81 globUrl: "*.*.kubernetes.io", 82 targetUrl: "prefix.kubernetes.io", 83 matchExpected: false, 84 }, 85 { 86 globUrl: "*.*.kubernetes.io", 87 targetUrl: "kubernetes.io", 88 matchExpected: false, 89 }, 90 // no match when some parts mismatch 91 { 92 globUrl: "kubernetes.io", 93 targetUrl: "kubernetes.com", 94 matchExpected: false, 95 }, 96 { 97 globUrl: "k*.io", 98 targetUrl: "quay.io", 99 matchExpected: false, 100 }, 101 // no match when ports mismatch 102 { 103 globUrl: "*.kubernetes.io:1234/blah", 104 targetUrl: "prefix.kubernetes.io:1111/blah", 105 matchExpected: false, 106 }, 107 { 108 globUrl: "prefix.*.io/foo", 109 targetUrl: "prefix.kubernetes.io:1111/foo/bar", 110 matchExpected: false, 111 }, 112 } 113 for _, test := range tests { 114 matched, _ := urlsMatchStr(test.globUrl, test.targetUrl) 115 if matched != test.matchExpected { 116 t.Errorf("Expected match result of %s and %s to be %t, but was %t", 117 test.globUrl, test.targetUrl, test.matchExpected, matched) 118 } 119 } 120 } 121 122 func TestDockerKeyringForGlob(t *testing.T) { 123 tests := []struct { 124 globUrl string 125 targetUrl string 126 }{ 127 { 128 globUrl: "hello.kubernetes.io", 129 targetUrl: "hello.kubernetes.io", 130 }, 131 { 132 globUrl: "*.docker.io", 133 targetUrl: "prefix.docker.io", 134 }, 135 { 136 globUrl: "prefix.*.io", 137 targetUrl: "prefix.docker.io", 138 }, 139 { 140 globUrl: "prefix.docker.*", 141 targetUrl: "prefix.docker.io", 142 }, 143 { 144 globUrl: "*.docker.io/path", 145 targetUrl: "prefix.docker.io/path", 146 }, 147 { 148 globUrl: "prefix.*.io/path", 149 targetUrl: "prefix.docker.io/path/subpath", 150 }, 151 { 152 globUrl: "prefix.docker.*/path", 153 targetUrl: "prefix.docker.io/path", 154 }, 155 { 156 globUrl: "*.docker.io:8888", 157 targetUrl: "prefix.docker.io:8888", 158 }, 159 { 160 globUrl: "prefix.*.io:8888", 161 targetUrl: "prefix.docker.io:8888", 162 }, 163 { 164 globUrl: "prefix.docker.*:8888", 165 targetUrl: "prefix.docker.io:8888", 166 }, 167 { 168 globUrl: "*.docker.io/path:1111", 169 targetUrl: "prefix.docker.io/path:1111", 170 }, 171 { 172 globUrl: "prefix.*.io/path:1111", 173 targetUrl: "prefix.docker.io/path/subpath:1111", 174 }, 175 { 176 globUrl: "prefix.docker.*/path:1111", 177 targetUrl: "prefix.docker.io/path:1111", 178 }, 179 } 180 for _, test := range tests { 181 email := "foo@bar.baz" 182 username := "foo" 183 password := "bar" 184 auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password))) 185 sampleDockerConfig := fmt.Sprintf(`{ 186 "https://%s": { 187 "email": %q, 188 "auth": %q 189 } 190 }`, test.globUrl, email, auth) 191 192 keyring := &BasicDockerKeyring{} 193 if cfg, err := readDockerConfigFileFromBytes([]byte(sampleDockerConfig)); err != nil { 194 t.Errorf("Error processing json blob %q, %v", sampleDockerConfig, err) 195 } else { 196 keyring.Add(cfg) 197 } 198 199 creds, ok := keyring.Lookup(test.targetUrl + "/foo/bar") 200 if !ok { 201 t.Errorf("Didn't find expected URL: %s", test.targetUrl) 202 return 203 } 204 val := creds[0] 205 206 if username != val.Username { 207 t.Errorf("Unexpected username value, want: %s, got: %s", username, val.Username) 208 } 209 if password != val.Password { 210 t.Errorf("Unexpected password value, want: %s, got: %s", password, val.Password) 211 } 212 if email != val.Email { 213 t.Errorf("Unexpected email value, want: %s, got: %s", email, val.Email) 214 } 215 } 216 } 217 218 func TestKeyringMiss(t *testing.T) { 219 tests := []struct { 220 globUrl string 221 lookupUrl string 222 }{ 223 { 224 globUrl: "hello.kubernetes.io", 225 lookupUrl: "world.mesos.org/foo/bar", 226 }, 227 { 228 globUrl: "*.docker.com", 229 lookupUrl: "prefix.docker.io", 230 }, 231 { 232 globUrl: "suffix.*.io", 233 lookupUrl: "prefix.docker.io", 234 }, 235 { 236 globUrl: "prefix.docker.c*", 237 lookupUrl: "prefix.docker.io", 238 }, 239 } 240 for _, test := range tests { 241 email := "foo@bar.baz" 242 username := "foo" 243 password := "bar" 244 auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password))) 245 sampleDockerConfig := fmt.Sprintf(`{ 246 "https://%s": { 247 "email": %q, 248 "auth": %q 249 } 250 }`, test.globUrl, email, auth) 251 252 keyring := &BasicDockerKeyring{} 253 if cfg, err := readDockerConfigFileFromBytes([]byte(sampleDockerConfig)); err != nil { 254 t.Errorf("Error processing json blob %q, %v", sampleDockerConfig, err) 255 } else { 256 keyring.Add(cfg) 257 } 258 259 _, ok := keyring.Lookup(test.lookupUrl + "/foo/bar") 260 if ok { 261 t.Errorf("Expected not to find URL %s, but found", test.lookupUrl) 262 } 263 } 264 265 } 266 267 func TestKeyringMissWithDockerHubCredentials(t *testing.T) { 268 url := defaultRegistryHost 269 email := "foo@bar.baz" 270 username := "foo" 271 password := "bar" 272 auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password))) 273 sampleDockerConfig := fmt.Sprintf(`{ 274 "https://%s": { 275 "email": %q, 276 "auth": %q 277 } 278 }`, url, email, auth) 279 280 keyring := &BasicDockerKeyring{} 281 if cfg, err := readDockerConfigFileFromBytes([]byte(sampleDockerConfig)); err != nil { 282 t.Errorf("Error processing json blob %q, %v", sampleDockerConfig, err) 283 } else { 284 keyring.Add(cfg) 285 } 286 287 val, ok := keyring.Lookup("world.mesos.org/foo/bar") 288 if ok { 289 t.Errorf("Found unexpected credential: %+v", val) 290 } 291 } 292 293 func TestKeyringHitWithUnqualifiedDockerHub(t *testing.T) { 294 url := defaultRegistryHost 295 email := "foo@bar.baz" 296 username := "foo" 297 password := "bar" 298 auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password))) 299 sampleDockerConfig := fmt.Sprintf(`{ 300 "https://%s": { 301 "email": %q, 302 "auth": %q 303 } 304 }`, url, email, auth) 305 306 keyring := &BasicDockerKeyring{} 307 if cfg, err := readDockerConfigFileFromBytes([]byte(sampleDockerConfig)); err != nil { 308 t.Errorf("Error processing json blob %q, %v", sampleDockerConfig, err) 309 } else { 310 keyring.Add(cfg) 311 } 312 313 creds, ok := keyring.Lookup("google/docker-registry") 314 if !ok { 315 t.Errorf("Didn't find expected URL: %s", url) 316 return 317 } 318 if len(creds) > 1 { 319 t.Errorf("Got more hits than expected: %s", creds) 320 } 321 val := creds[0] 322 323 if username != val.Username { 324 t.Errorf("Unexpected username value, want: %s, got: %s", username, val.Username) 325 } 326 if password != val.Password { 327 t.Errorf("Unexpected password value, want: %s, got: %s", password, val.Password) 328 } 329 if email != val.Email { 330 t.Errorf("Unexpected email value, want: %s, got: %s", email, val.Email) 331 } 332 } 333 334 func TestKeyringHitWithUnqualifiedLibraryDockerHub(t *testing.T) { 335 url := defaultRegistryHost 336 email := "foo@bar.baz" 337 username := "foo" 338 password := "bar" 339 auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password))) 340 sampleDockerConfig := fmt.Sprintf(`{ 341 "https://%s": { 342 "email": %q, 343 "auth": %q 344 } 345 }`, url, email, auth) 346 347 keyring := &BasicDockerKeyring{} 348 if cfg, err := readDockerConfigFileFromBytes([]byte(sampleDockerConfig)); err != nil { 349 t.Errorf("Error processing json blob %q, %v", sampleDockerConfig, err) 350 } else { 351 keyring.Add(cfg) 352 } 353 354 creds, ok := keyring.Lookup("jenkins") 355 if !ok { 356 t.Errorf("Didn't find expected URL: %s", url) 357 return 358 } 359 if len(creds) > 1 { 360 t.Errorf("Got more hits than expected: %s", creds) 361 } 362 val := creds[0] 363 364 if username != val.Username { 365 t.Errorf("Unexpected username value, want: %s, got: %s", username, val.Username) 366 } 367 if password != val.Password { 368 t.Errorf("Unexpected password value, want: %s, got: %s", password, val.Password) 369 } 370 if email != val.Email { 371 t.Errorf("Unexpected email value, want: %s, got: %s", email, val.Email) 372 } 373 } 374 375 func TestKeyringHitWithQualifiedDockerHub(t *testing.T) { 376 url := defaultRegistryHost 377 email := "foo@bar.baz" 378 username := "foo" 379 password := "bar" 380 auth := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", username, password))) 381 sampleDockerConfig := fmt.Sprintf(`{ 382 "https://%s": { 383 "email": %q, 384 "auth": %q 385 } 386 }`, url, email, auth) 387 388 keyring := &BasicDockerKeyring{} 389 if cfg, err := readDockerConfigFileFromBytes([]byte(sampleDockerConfig)); err != nil { 390 t.Errorf("Error processing json blob %q, %v", sampleDockerConfig, err) 391 } else { 392 keyring.Add(cfg) 393 } 394 395 creds, ok := keyring.Lookup(url + "/google/docker-registry") 396 if !ok { 397 t.Errorf("Didn't find expected URL: %s", url) 398 return 399 } 400 if len(creds) > 2 { 401 t.Errorf("Got more hits than expected: %s", creds) 402 } 403 val := creds[0] 404 405 if username != val.Username { 406 t.Errorf("Unexpected username value, want: %s, got: %s", username, val.Username) 407 } 408 if password != val.Password { 409 t.Errorf("Unexpected password value, want: %s, got: %s", password, val.Password) 410 } 411 if email != val.Email { 412 t.Errorf("Unexpected email value, want: %s, got: %s", email, val.Email) 413 } 414 } 415 416 func TestIsDefaultRegistryMatch(t *testing.T) { 417 samples := []map[bool]string{ 418 {true: "foo/bar"}, 419 {true: "docker.io/foo/bar"}, 420 {true: "index.docker.io/foo/bar"}, 421 {true: "foo"}, 422 {false: ""}, 423 {false: "registry.tld/foo/bar"}, 424 {false: "registry:5000/foo/bar"}, 425 {false: "myhostdocker.io/foo/bar"}, 426 } 427 for _, sample := range samples { 428 for expected, imageName := range sample { 429 if got := isDefaultRegistryMatch(imageName); got != expected { 430 t.Errorf("Expected '%s' to be %t, got %t", imageName, expected, got) 431 } 432 } 433 } 434 } 435 436 type testProvider struct { 437 Count int 438 } 439 440 // Enabled implements dockerConfigProvider 441 func (d *testProvider) Enabled() bool { 442 return true 443 } 444 445 // Provide implements dockerConfigProvider 446 func (d *testProvider) Provide() DockerConfig { 447 d.Count += 1 448 return DockerConfig{} 449 } 450 451 func TestLazyKeyring(t *testing.T) { 452 provider := &testProvider{ 453 Count: 0, 454 } 455 lazy := &lazyDockerKeyring{ 456 Providers: []DockerConfigProvider{ 457 provider, 458 }, 459 } 460 461 if provider.Count != 0 { 462 t.Errorf("Unexpected number of Provide calls: %v", provider.Count) 463 } 464 lazy.Lookup("foo") 465 if provider.Count != 1 { 466 t.Errorf("Unexpected number of Provide calls: %v", provider.Count) 467 } 468 lazy.Lookup("foo") 469 if provider.Count != 2 { 470 t.Errorf("Unexpected number of Provide calls: %v", provider.Count) 471 } 472 lazy.Lookup("foo") 473 if provider.Count != 3 { 474 t.Errorf("Unexpected number of Provide calls: %v", provider.Count) 475 } 476 }