knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/apis/duck/v1beta1/destination_test.go (about) 1 /* 2 Copyright 2019 The Knative 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 v1beta1 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 corev1 "k8s.io/api/core/v1" 25 "knative.dev/pkg/apis" 26 ) 27 28 const ( 29 kind = "SomeKind" 30 apiVersion = "v1mega1" 31 name = "a-name" 32 ) 33 34 var ( 35 testCert = `-----BEGIN CERTIFICATE----- 36 MIIDmjCCAoKgAwIBAgIUYzA4bTMXevuk3pl2Mn8hpCYL2C0wDQYJKoZIhvcNAQEL 37 BQAwLzELMAkGA1UEBhMCVVMxIDAeBgNVBAMMF0tuYXRpdmUtRXhhbXBsZS1Sb290 38 LUNBMB4XDTIzMDQwNTEzMTUyNFoXDTI2MDEyMzEzMTUyNFowbTELMAkGA1UEBhMC 39 VVMxEjAQBgNVBAgMCVlvdXJTdGF0ZTERMA8GA1UEBwwIWW91ckNpdHkxHTAbBgNV 40 BAoMFEV4YW1wbGUtQ2VydGlmaWNhdGVzMRgwFgYDVQQDDA9sb2NhbGhvc3QubG9j 41 YWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC5teo+En6U5nhqn7Sc 42 uanqswUmPlgs9j/8l21Rhb4T+ezlYKGQGhbJyFFMuiCE1Rjn8bpCwi7Nnv12Y2nz 43 FhEv2Jx0yL3Tqx0Q593myqKDq7326EtbO7wmDT0XD03twH5i9XZ0L0ihPWn1mjUy 44 WxhnHhoFpXrsnQECJorZY6aTrFbGVYelIaj5AriwiqyL0fET8pueI2GwLjgWHFSH 45 X8XsGAlcLUhkQG0Z+VO9usy4M1Wpt+cL6cnTiQ+sRmZ6uvaj8fKOT1Slk/oUeAi4 46 WqFkChGzGzLik0QrhKGTdw3uUvI1F2sdQj0GYzXaWqRz+tP9qnXdzk1GrszKKSlm 47 WBTLAgMBAAGjcDBuMB8GA1UdIwQYMBaAFJJcCftus4vj98N0zQQautsjEu82MAkG 48 A1UdEwQCMAAwCwYDVR0PBAQDAgTwMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAdBgNV 49 HQ4EFgQUnu/3vqA3VEzm128x/hLyZzR9JlgwDQYJKoZIhvcNAQELBQADggEBAFc+ 50 1cKt/CNjHXUsirgEhry2Mm96R6Yxuq//mP2+SEjdab+FaXPZkjHx118u3PPX5uTh 51 gTT7rMfka6J5xzzQNqJbRMgNpdEFH1bbc11aYuhi0khOAe0cpQDtktyuDJQMMv3/ 52 3wu6rLr6fmENo0gdcyUY9EiYrglWGtdXhlo4ySRY8UZkUScG2upvyOhHTxVCAjhP 53 efbMkNjmDuZOMK+wqanqr5YV6zMPzkQK7DspfRgasMAQmugQu7r2MZpXg8Ilhro1 54 s/wImGnMVk5RzpBVrq2VB9SkX/ThTVYEC/Sd9BQM364MCR+TA1l8/ptaLFLuwyw8 55 O2dgzikq8iSy1BlRsVw= 56 -----END CERTIFICATE-----` 57 58 csr = `-----BEGIN CERTIFICATE REQUEST----- 59 MIICvDCCAaQCAQAwdzELMAkGA1UEBhMCVVMxDTALBgNVBAgMBFV0YWgxDzANBgNV 60 BAcMBkxpbmRvbjEWMBQGA1UECgwNRGlnaUNlcnQgSW5jLjERMA8GA1UECwwIRGln 61 aUNlcnQxHTAbBgNVBAMMFGV4YW1wbGUuZGlnaWNlcnQuY29tMIIBIjANBgkqhkiG 62 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8+To7d+2kPWeBv/orU3LVbJwDrSQbeKamCmo 63 wp5bqDxIwV20zqRb7APUOKYoVEFFOEQs6T6gImnIolhbiH6m4zgZ/CPvWBOkZc+c 64 1Po2EmvBz+AD5sBdT5kzGQA6NbWyZGldxRthNLOs1efOhdnWFuhI162qmcflgpiI 65 WDuwq4C9f+YkeJhNn9dF5+owm8cOQmDrV8NNdiTqin8q3qYAHHJRW28glJUCZkTZ 66 wIaSR6crBQ8TbYNE0dc+Caa3DOIkz1EOsHWzTx+n0zKfqcbgXi4DJx+C1bjptYPR 67 BPZL8DAeWuA8ebudVT44yEp82G96/Ggcf7F33xMxe0yc+Xa6owIDAQABoAAwDQYJ 68 KoZIhvcNAQEFBQADggEBAB0kcrFccSmFDmxox0Ne01UIqSsDqHgL+XmHTXJwre6D 69 hJSZwbvEtOK0G3+dr4Fs11WuUNt5qcLsx5a8uk4G6AKHMzuhLsJ7XZjgmQXGECpY 70 Q4mC3yT3ZoCGpIXbw+iP3lmEEXgaQL0Tx5LFl/okKbKYwIqNiyKWOMj7ZR/wxWg/ 71 ZDGRs55xuoeLDJ/ZRFf9bI+IaCUd1YrfYcHIl3G87Av+r49YVwqRDT0VDV7uLgqn 72 29XI1PpVUNCPQGn9p/eX6Qo7vpDaPybRtA2R7XLKjQaF9oXWeCUqy1hvJac9QFO2 73 97Ob1alpHPoZ7mWiEuJwjBPii6a9M9G30nUo39lBi1w= 74 -----END CERTIFICATE REQUEST-----` 75 76 invaidCert = "certificate" 77 ) 78 79 func TestValidateDestination(t *testing.T) { 80 ctx := context.Background() 81 82 validRef := corev1.ObjectReference{ 83 Kind: kind, 84 APIVersion: apiVersion, 85 Name: name, 86 } 87 88 validURL := apis.URL{ 89 Scheme: "http", 90 Host: "host", 91 } 92 93 tests := map[string]struct { 94 dest *Destination 95 want string 96 }{ 97 "nil valid": { 98 dest: nil, 99 want: "", 100 }, 101 "valid ref": { 102 dest: &Destination{ 103 Ref: &validRef, 104 }, 105 want: "", 106 }, 107 "invalid ref, missing name": { 108 dest: &Destination{ 109 Ref: &corev1.ObjectReference{ 110 Kind: kind, 111 APIVersion: apiVersion, 112 }, 113 }, 114 want: "missing field(s): ref.name", 115 }, 116 "invalid ref, missing api version": { 117 dest: &Destination{ 118 Ref: &corev1.ObjectReference{ 119 Kind: kind, 120 Name: apiVersion, 121 }, 122 }, 123 want: "missing field(s): ref.apiVersion", 124 }, 125 "invalid ref, missing kind": { 126 dest: &Destination{ 127 Ref: &corev1.ObjectReference{ 128 APIVersion: apiVersion, 129 Name: name, 130 }, 131 }, 132 want: "missing field(s): ref.kind", 133 }, 134 "valid [apiVersion, kind, name]": { 135 dest: &Destination{ 136 DeprecatedKind: kind, 137 DeprecatedAPIVersion: apiVersion, 138 DeprecatedName: name, 139 }, 140 want: "", 141 }, 142 "invalid [apiVersion, kind, name], missing name": { 143 dest: &Destination{ 144 DeprecatedKind: kind, 145 DeprecatedAPIVersion: apiVersion, 146 }, 147 want: "missing field(s): name", 148 }, 149 "invalid [apiVersion, kind, name], missing api version": { 150 dest: &Destination{ 151 DeprecatedKind: kind, 152 DeprecatedName: name, 153 }, 154 want: "missing field(s): apiVersion", 155 }, 156 "invalid [apiVersion, kind, name], missing kind": { 157 dest: &Destination{ 158 DeprecatedAPIVersion: apiVersion, 159 DeprecatedName: name, 160 }, 161 want: "missing field(s): kind", 162 }, 163 "valid uri": { 164 dest: &Destination{ 165 URI: &validURL, 166 }, 167 }, 168 "invalid, uri has no host": { 169 dest: &Destination{ 170 URI: &apis.URL{ 171 Scheme: "http", 172 }, 173 }, 174 want: "invalid value: Relative URI is not allowed when Ref and [apiVersion, kind, name] is absent: uri", 175 }, 176 "invalid, uri is not absolute url": { 177 dest: &Destination{ 178 URI: &apis.URL{ 179 Host: "host", 180 }, 181 }, 182 want: "invalid value: Relative URI is not allowed when Ref and [apiVersion, kind, name] is absent: uri", 183 }, 184 "invalid, both ref and [apiVersion, kind, name] are present ": { 185 dest: &Destination{ 186 Ref: &corev1.ObjectReference{ 187 Kind: "SomeKind", 188 APIVersion: "v1mega1", 189 Name: "a-name", 190 }, 191 DeprecatedKind: kind, 192 DeprecatedAPIVersion: apiVersion, 193 DeprecatedName: name, 194 }, 195 want: "Ref and [apiVersion, kind, name] can't be both present: [apiVersion, kind, name], ref", 196 }, 197 "invalid, both uri and ref, uri is absolute URL": { 198 dest: &Destination{ 199 URI: &validURL, 200 Ref: &validRef, 201 }, 202 want: "Absolute URI is not allowed when Ref or [apiVersion, kind, name] is present: [apiVersion, kind, name], ref, uri", 203 }, 204 "invalid, both uri and [apiVersion, kind, name], uri is absolute URL": { 205 dest: &Destination{ 206 URI: &validURL, 207 DeprecatedKind: kind, 208 DeprecatedAPIVersion: apiVersion, 209 DeprecatedName: name, 210 }, 211 want: "Absolute URI is not allowed when Ref or [apiVersion, kind, name] is present: [apiVersion, kind, name], ref, uri", 212 }, 213 "invalid, both ref, [apiVersion, kind, name] and uri are nil": { 214 dest: &Destination{}, 215 want: "expected at least one, got none: [apiVersion, kind, name], ref, uri", 216 }, 217 "valid, both uri and ref, uri is not a absolute URL": { 218 dest: &Destination{ 219 URI: &apis.URL{ 220 Path: "/handler", 221 }, 222 Ref: &validRef, 223 }, 224 }, 225 "valid, both uri and [apiVersion, kind, name], uri is not a absolute URL": { 226 dest: &Destination{ 227 URI: &apis.URL{ 228 Path: "/handler", 229 }, 230 DeprecatedKind: kind, 231 DeprecatedAPIVersion: apiVersion, 232 DeprecatedName: name, 233 }, 234 }, 235 "valid, CACert is valid": { 236 dest: &Destination{ 237 URI: &apis.URL{ 238 Path: "/handler", 239 }, 240 Ref: &validRef, 241 CACerts: &testCert, 242 }, 243 }, 244 "invalid,CACert is invalid": { 245 dest: &Destination{ 246 URI: &apis.URL{ 247 Path: "/handler", 248 }, 249 Ref: &validRef, 250 CACerts: &invaidCert, 251 }, 252 want: "invalid value: CA Cert provided is invalid: caCert", 253 }, 254 "invalid,CSR provided not CA Cert": { 255 dest: &Destination{ 256 URI: &apis.URL{ 257 Path: "/handler", 258 }, 259 Ref: &validRef, 260 CACerts: &csr, 261 }, 262 want: "invalid value: CA Cert provided is not a certificate: caCert", 263 }, 264 } 265 266 for name, tc := range tests { 267 t.Run(name, func(t *testing.T) { 268 gotErr := tc.dest.Validate(ctx) 269 270 if tc.want != "" { 271 if got, want := gotErr.Error(), tc.want; got != want { 272 t.Errorf("%s: Error() = %v, wanted %v", name, got, want) 273 } 274 } else if gotErr != nil { 275 t.Errorf("%s: Validate() = %v, wanted nil", name, gotErr) 276 } 277 }) 278 } 279 } 280 281 func TestValidateDestinationDisallowDeprecated(t *testing.T) { 282 ctx := context.Background() 283 284 validRef := corev1.ObjectReference{ 285 Kind: kind, 286 APIVersion: apiVersion, 287 Name: name, 288 } 289 290 validURL := apis.URL{ 291 Scheme: "http", 292 Host: "host", 293 } 294 295 tests := map[string]struct { 296 dest *Destination 297 want string 298 }{ 299 "nil valid": { 300 dest: nil, 301 want: "", 302 }, 303 "valid ref": { 304 dest: &Destination{ 305 Ref: &validRef, 306 }, 307 want: "", 308 }, 309 "invalid ref, missing name": { 310 dest: &Destination{ 311 Ref: &corev1.ObjectReference{ 312 Kind: kind, 313 APIVersion: apiVersion, 314 }, 315 }, 316 want: "missing field(s): ref.name", 317 }, 318 "invalid ref, missing api version": { 319 dest: &Destination{ 320 Ref: &corev1.ObjectReference{ 321 Kind: kind, 322 Name: apiVersion, 323 }, 324 }, 325 want: "missing field(s): ref.apiVersion", 326 }, 327 "invalid ref, missing kind": { 328 dest: &Destination{ 329 Ref: &corev1.ObjectReference{ 330 APIVersion: apiVersion, 331 Name: name, 332 }, 333 }, 334 want: "missing field(s): ref.kind", 335 }, 336 "invalid deprecated [apiVersion, kind, name]": { 337 dest: &Destination{ 338 DeprecatedKind: kind, 339 DeprecatedAPIVersion: apiVersion, 340 DeprecatedName: name, 341 }, 342 want: "invalid value: apiVersion is not allowed here, it's a deprecated value: apiVersion\ninvalid value: kind is not allowed here, it's a deprecated value: kind\ninvalid value: name is not allowed here, it's a deprecated value: name", 343 }, 344 "invalid deprecated [apiVersion, kind]": { 345 dest: &Destination{ 346 DeprecatedKind: kind, 347 DeprecatedAPIVersion: apiVersion, 348 }, 349 want: "invalid value: apiVersion is not allowed here, it's a deprecated value: apiVersion\ninvalid value: kind is not allowed here, it's a deprecated value: kind", 350 }, 351 "invalid deprecated [kind, name]": { 352 dest: &Destination{ 353 DeprecatedKind: kind, 354 DeprecatedName: name, 355 }, 356 want: "invalid value: kind is not allowed here, it's a deprecated value: kind\ninvalid value: name is not allowed here, it's a deprecated value: name", 357 }, 358 "invalid deprecated [apiVersion, name]": { 359 dest: &Destination{ 360 DeprecatedAPIVersion: apiVersion, 361 DeprecatedName: name, 362 }, 363 want: "invalid value: apiVersion is not allowed here, it's a deprecated value: apiVersion\ninvalid value: name is not allowed here, it's a deprecated value: name", 364 }, 365 "valid uri": { 366 dest: &Destination{ 367 URI: &validURL, 368 }, 369 }, 370 "invalid, uri has no host": { 371 dest: &Destination{ 372 URI: &apis.URL{ 373 Scheme: "http", 374 }, 375 }, 376 want: "invalid value: Relative URI is not allowed when Ref and [apiVersion, kind, name] is absent: uri", 377 }, 378 "invalid, uri is not absolute url": { 379 dest: &Destination{ 380 URI: &apis.URL{ 381 Host: "host", 382 }, 383 }, 384 want: "invalid value: Relative URI is not allowed when Ref and [apiVersion, kind, name] is absent: uri", 385 }, 386 "invalid deprecated, both ref and [apiVersion, kind, name] are present ": { 387 dest: &Destination{ 388 Ref: &corev1.ObjectReference{ 389 Kind: "SomeKind", 390 APIVersion: "v1mega1", 391 Name: "a-name", 392 }, 393 DeprecatedKind: kind, 394 DeprecatedAPIVersion: apiVersion, 395 DeprecatedName: name, 396 }, 397 want: "invalid value: apiVersion is not allowed here, it's a deprecated value: apiVersion\ninvalid value: kind is not allowed here, it's a deprecated value: kind\ninvalid value: name is not allowed here, it's a deprecated value: name", 398 }, 399 "invalid, both uri and ref, uri is absolute URL": { 400 dest: &Destination{ 401 URI: &validURL, 402 Ref: &validRef, 403 }, 404 want: "Absolute URI is not allowed when Ref or [apiVersion, kind, name] is present: [apiVersion, kind, name], ref, uri", 405 }, 406 "invalid, both uri and [apiVersion, kind, name], uri is absolute URL": { 407 dest: &Destination{ 408 URI: &validURL, 409 DeprecatedKind: kind, 410 DeprecatedAPIVersion: apiVersion, 411 DeprecatedName: name, 412 }, 413 want: "invalid value: apiVersion is not allowed here, it's a deprecated value: apiVersion\ninvalid value: kind is not allowed here, it's a deprecated value: kind\ninvalid value: name is not allowed here, it's a deprecated value: name", 414 }, 415 "invalid, both ref, [apiVersion, kind, name] and uri are nil": { 416 dest: &Destination{}, 417 want: "expected at least one, got none: [apiVersion, kind, name], ref, uri", 418 }, 419 "valid, both uri and ref, uri is not a absolute URL": { 420 dest: &Destination{ 421 URI: &apis.URL{ 422 Path: "/handler", 423 }, 424 Ref: &validRef, 425 }, 426 }, 427 "invalid deprecated, both uri and [apiVersion, kind, name], uri is not a absolute URL": { 428 dest: &Destination{ 429 URI: &apis.URL{ 430 Path: "/handler", 431 }, 432 DeprecatedKind: kind, 433 DeprecatedAPIVersion: apiVersion, 434 DeprecatedName: name, 435 }, 436 want: "invalid value: apiVersion is not allowed here, it's a deprecated value: apiVersion\ninvalid value: kind is not allowed here, it's a deprecated value: kind\ninvalid value: name is not allowed here, it's a deprecated value: name", 437 }, 438 } 439 440 for name, tc := range tests { 441 t.Run(name, func(t *testing.T) { 442 gotErr := tc.dest.ValidateDisallowDeprecated(ctx) 443 444 if tc.want != "" { 445 if got, want := gotErr.Error(), tc.want; got != want { 446 t.Errorf("%s: Error() = %v, wanted %v", name, got, want) 447 } 448 } else if gotErr != nil { 449 t.Errorf("%s: Validate() = %v, wanted nil", name, gotErr) 450 } 451 }) 452 } 453 } 454 455 func TestDestination_GetRef(t *testing.T) { 456 ref := &corev1.ObjectReference{ 457 APIVersion: apiVersion, 458 Kind: kind, 459 Name: name, 460 } 461 tests := map[string]struct { 462 dest *Destination 463 want *corev1.ObjectReference 464 }{ 465 "nil destination": { 466 dest: nil, 467 want: nil, 468 }, 469 "uri": { 470 dest: &Destination{ 471 URI: &apis.URL{ 472 Host: "foo", 473 }, 474 }, 475 want: nil, 476 }, 477 "ref": { 478 dest: &Destination{ 479 Ref: ref, 480 }, 481 want: ref, 482 }, 483 "deprecated ref": { 484 dest: &Destination{ 485 DeprecatedAPIVersion: ref.APIVersion, 486 DeprecatedKind: ref.Kind, 487 DeprecatedName: ref.Name, 488 }, 489 want: ref, 490 }, 491 } 492 493 for n, tc := range tests { 494 t.Run(n, func(t *testing.T) { 495 got := tc.dest.GetRef() 496 if diff := cmp.Diff(tc.want, got); diff != "" { 497 t.Error("Unexpected result (-want +got):", diff) 498 } 499 }) 500 } 501 }