github.com/oam-dev/kubevela@v1.9.11/pkg/policy/envbinding/patch_test.go (about) 1 /* 2 Copyright 2021. The KubeVela 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 envbinding 18 19 import ( 20 "testing" 21 22 "github.com/stretchr/testify/require" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 25 "github.com/oam-dev/kubevela/apis/core.oam.dev/common" 26 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1" 27 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 28 "github.com/oam-dev/kubevela/pkg/oam/util" 29 ) 30 31 func Test_EnvBindApp_GenerateConfiguredApplication(t *testing.T) { 32 testCases := map[string]struct { 33 baseApp *v1beta1.Application 34 envName string 35 envPatch v1alpha1.EnvPatch 36 expectedApp *v1beta1.Application 37 selector *v1alpha1.EnvSelector 38 }{ 39 "normal-test": { 40 baseApp: baseApp, 41 envName: "prod", 42 envPatch: v1alpha1.EnvPatch{ 43 Components: []v1alpha1.EnvComponentPatch{{ 44 Name: "express-server", 45 Type: "webservice", 46 Properties: util.Object2RawExtension(map[string]interface{}{ 47 "image": "busybox", 48 }), 49 Traits: []v1alpha1.EnvTraitPatch{{ 50 Type: "ingress-1-20", 51 Properties: util.Object2RawExtension(map[string]interface{}{ 52 "domain": "newTestsvc.example.com", 53 }), 54 }}, 55 }}, 56 }, 57 expectedApp: &v1beta1.Application{ 58 TypeMeta: metav1.TypeMeta{ 59 APIVersion: "v1beta1", 60 Kind: "Application", 61 }, 62 ObjectMeta: metav1.ObjectMeta{ 63 Name: "test", 64 }, 65 Spec: v1beta1.ApplicationSpec{ 66 Components: []common.ApplicationComponent{{ 67 Name: "express-server", 68 Type: "webservice", 69 Properties: util.Object2RawExtension(map[string]interface{}{ 70 "image": "busybox", 71 "port": 8000, 72 }), 73 Traits: []common.ApplicationTrait{{ 74 Type: "ingress-1-20", 75 Properties: util.Object2RawExtension(map[string]interface{}{ 76 "domain": "newTestsvc.example.com", 77 "http": map[string]interface{}{ 78 "/": 8000, 79 }, 80 }), 81 }}, 82 }}, 83 }, 84 }, 85 }, 86 "add-component": { 87 baseApp: baseApp, 88 envName: "prod", 89 envPatch: v1alpha1.EnvPatch{ 90 Components: []v1alpha1.EnvComponentPatch{{ 91 Name: "express-server", 92 Type: "webservice", 93 Traits: []v1alpha1.EnvTraitPatch{{ 94 Type: "labels", 95 Properties: util.Object2RawExtension(map[string]interface{}{ 96 "test": "label", 97 }), 98 }}, 99 }, { 100 Name: "new-server", 101 Type: "worker", 102 Properties: util.Object2RawExtension(map[string]interface{}{ 103 "image": "busybox", 104 "cmd": []string{"sleep", "1000"}, 105 }), 106 Traits: []v1alpha1.EnvTraitPatch{{ 107 Type: "labels", 108 Properties: util.Object2RawExtension(map[string]interface{}{ 109 "test": "label", 110 }), 111 }}, 112 }}, 113 }, 114 expectedApp: &v1beta1.Application{ 115 TypeMeta: metav1.TypeMeta{ 116 APIVersion: "v1beta1", 117 Kind: "Application", 118 }, 119 ObjectMeta: metav1.ObjectMeta{ 120 Name: "test", 121 }, 122 Spec: v1beta1.ApplicationSpec{ 123 Components: []common.ApplicationComponent{{ 124 Name: "express-server", 125 Type: "webservice", 126 Properties: util.Object2RawExtension(map[string]interface{}{ 127 "image": "crccheck/hello-world", 128 "port": 8000, 129 }), 130 Traits: []common.ApplicationTrait{{ 131 Type: "ingress-1-20", 132 Properties: util.Object2RawExtension(map[string]interface{}{ 133 "domain": "testsvc.example.com", 134 "http": map[string]interface{}{ 135 "/": 8000, 136 }, 137 }), 138 }, { 139 Type: "labels", 140 Properties: util.Object2RawExtension(map[string]interface{}{ 141 "test": "label", 142 }), 143 }}, 144 }, { 145 Name: "new-server", 146 Type: "worker", 147 Properties: util.Object2RawExtension(map[string]interface{}{ 148 "image": "busybox", 149 "cmd": []string{"sleep", "1000"}, 150 }), 151 Traits: []common.ApplicationTrait{{ 152 Type: "labels", 153 Properties: util.Object2RawExtension(map[string]interface{}{ 154 "test": "label", 155 }), 156 }}, 157 }}, 158 }, 159 }, 160 }, 161 "disable-trait": { 162 baseApp: baseApp, 163 envName: "prod", 164 envPatch: v1alpha1.EnvPatch{ 165 Components: []v1alpha1.EnvComponentPatch{{ 166 Name: "express-server", 167 Type: "webservice", 168 Traits: []v1alpha1.EnvTraitPatch{{ 169 Type: "ingress-1-20", 170 Disable: true, 171 }}, 172 }}, 173 }, 174 expectedApp: &v1beta1.Application{ 175 TypeMeta: metav1.TypeMeta{ 176 APIVersion: "v1beta1", 177 Kind: "Application", 178 }, 179 ObjectMeta: metav1.ObjectMeta{ 180 Name: "test", 181 }, 182 Spec: v1beta1.ApplicationSpec{ 183 Components: []common.ApplicationComponent{{ 184 Name: "express-server", 185 Type: "webservice", 186 Properties: util.Object2RawExtension(map[string]interface{}{ 187 "image": "crccheck/hello-world", 188 "port": 8000, 189 }), 190 Traits: []common.ApplicationTrait{}, 191 }}, 192 }, 193 }, 194 }, 195 "component-selector": { 196 baseApp: baseApp, 197 envName: "prod", 198 envPatch: v1alpha1.EnvPatch{ 199 Components: []v1alpha1.EnvComponentPatch{{ 200 Name: "new-server", 201 Type: "worker", 202 Properties: util.Object2RawExtension(map[string]interface{}{ 203 "image": "busybox", 204 }), 205 }}, 206 }, 207 selector: &v1alpha1.EnvSelector{ 208 Components: []string{"new-server"}, 209 }, 210 expectedApp: &v1beta1.Application{ 211 TypeMeta: metav1.TypeMeta{ 212 APIVersion: "v1beta1", 213 Kind: "Application", 214 }, 215 ObjectMeta: metav1.ObjectMeta{ 216 Name: "test", 217 }, 218 Spec: v1beta1.ApplicationSpec{ 219 Components: []common.ApplicationComponent{{ 220 Name: "new-server", 221 Type: "worker", 222 Properties: util.Object2RawExtension(map[string]interface{}{ 223 "image": "busybox", 224 }), 225 }}, 226 }, 227 }, 228 }, 229 "empty-component-selector": { 230 baseApp: baseApp, 231 envName: "prod", 232 envPatch: v1alpha1.EnvPatch{ 233 Components: []v1alpha1.EnvComponentPatch{{ 234 Name: "new-server", 235 Type: "worker", 236 Properties: util.Object2RawExtension(map[string]interface{}{ 237 "image": "busybox", 238 }), 239 }}, 240 }, 241 selector: &v1alpha1.EnvSelector{ 242 Components: []string{}, 243 }, 244 expectedApp: &v1beta1.Application{ 245 TypeMeta: metav1.TypeMeta{ 246 APIVersion: "v1beta1", 247 Kind: "Application", 248 }, 249 ObjectMeta: metav1.ObjectMeta{ 250 Name: "test", 251 }, 252 Spec: v1beta1.ApplicationSpec{ 253 Components: []common.ApplicationComponent{}, 254 }, 255 }, 256 }, 257 "patch-external-revision": { 258 baseApp: baseApp, 259 envName: "prod", 260 envPatch: v1alpha1.EnvPatch{ 261 Components: []v1alpha1.EnvComponentPatch{{ 262 Name: "express-server", 263 Type: "webservice", 264 ExternalRevision: "external-rev", 265 }}, 266 }, 267 expectedApp: &v1beta1.Application{ 268 TypeMeta: metav1.TypeMeta{ 269 APIVersion: "v1beta1", 270 Kind: "Application", 271 }, 272 ObjectMeta: metav1.ObjectMeta{ 273 Name: "test", 274 }, 275 Spec: v1beta1.ApplicationSpec{ 276 Components: []common.ApplicationComponent{{ 277 Name: "express-server", 278 Type: "webservice", 279 Properties: util.Object2RawExtension(map[string]interface{}{ 280 "image": "crccheck/hello-world", 281 "port": 8000, 282 }), 283 ExternalRevision: "external-rev", 284 Traits: []common.ApplicationTrait{{ 285 Type: "ingress-1-20", 286 Properties: util.Object2RawExtension(map[string]interface{}{ 287 "domain": "testsvc.example.com", 288 "http": map[string]interface{}{ 289 "/": 8000, 290 }, 291 }), 292 }}, 293 }}, 294 }, 295 }, 296 }, 297 "patch-all-comp": { 298 baseApp: &v1beta1.Application{ 299 Spec: v1beta1.ApplicationSpec{ 300 Components: []common.ApplicationComponent{{ 301 Name: "express-server", 302 Type: "webservice", 303 Properties: util.Object2RawExtension(map[string]interface{}{ 304 "image": "crccheck/hello-world", 305 }), 306 Traits: []common.ApplicationTrait{{ 307 Type: "ingress", 308 Properties: util.Object2RawExtension(map[string]interface{}{ 309 "domain": "a.example.com", 310 }), 311 }, { 312 Type: "ingress-1-20", 313 Properties: util.Object2RawExtension(map[string]interface{}{ 314 "domain": "a-1-20.example.com", 315 }), 316 }}, 317 }, { 318 Name: "express-worker", 319 Type: "worker", 320 Properties: util.Object2RawExtension(map[string]interface{}{ 321 "image": "crccheck/hello-world", 322 }), 323 }}, 324 }, 325 }, 326 envName: "prod", 327 envPatch: v1alpha1.EnvPatch{ 328 Components: []v1alpha1.EnvComponentPatch{{ 329 Name: "", 330 Type: "", 331 Properties: util.Object2RawExtension(map[string]interface{}{ 332 "image": "busybox", 333 }), 334 Traits: []v1alpha1.EnvTraitPatch{{ 335 Type: "ingress", 336 Properties: util.Object2RawExtension(map[string]interface{}{ 337 "domain": "b.example.com", 338 }), 339 }}, 340 }}, 341 }, 342 expectedApp: &v1beta1.Application{ 343 Spec: v1beta1.ApplicationSpec{ 344 Components: []common.ApplicationComponent{{ 345 Name: "express-server", 346 Type: "webservice", 347 Properties: util.Object2RawExtension(map[string]interface{}{ 348 "image": "busybox", 349 }), 350 Traits: []common.ApplicationTrait{{ 351 Type: "ingress", 352 Properties: util.Object2RawExtension(map[string]interface{}{ 353 "domain": "b.example.com", 354 }), 355 }, { 356 Type: "ingress-1-20", 357 Properties: util.Object2RawExtension(map[string]interface{}{ 358 "domain": "a-1-20.example.com", 359 }), 360 }}, 361 }, { 362 Name: "express-worker", 363 Type: "worker", 364 Properties: util.Object2RawExtension(map[string]interface{}{ 365 "image": "busybox", 366 }), 367 Traits: []common.ApplicationTrait{{ 368 Type: "ingress", 369 Properties: util.Object2RawExtension(map[string]interface{}{ 370 "domain": "b.example.com", 371 }), 372 }}, 373 }}, 374 }, 375 }, 376 }, 377 "patch-type-comp": { 378 baseApp: &v1beta1.Application{ 379 Spec: v1beta1.ApplicationSpec{ 380 Components: []common.ApplicationComponent{{ 381 Name: "express-server", 382 Type: "webservice", 383 Properties: util.Object2RawExtension(map[string]interface{}{ 384 "image": "crccheck/hello-world", 385 }), 386 Traits: []common.ApplicationTrait{{ 387 Type: "ingress", 388 Properties: util.Object2RawExtension(map[string]interface{}{ 389 "domain": "a.example.com", 390 }), 391 }, { 392 Type: "ingress-1-20", 393 Properties: util.Object2RawExtension(map[string]interface{}{ 394 "domain": "a-1-20.example.com", 395 }), 396 }}, 397 }, { 398 Name: "express-worker", 399 Type: "worker", 400 Properties: util.Object2RawExtension(map[string]interface{}{ 401 "image": "crccheck/hello-world", 402 }), 403 }}, 404 }, 405 }, 406 envName: "prod", 407 envPatch: v1alpha1.EnvPatch{ 408 Components: []v1alpha1.EnvComponentPatch{{ 409 Name: "", 410 Type: "webservice", 411 Properties: util.Object2RawExtension(map[string]interface{}{ 412 "image": "busybox", 413 }), 414 Traits: []v1alpha1.EnvTraitPatch{{ 415 Type: "ingress", 416 Properties: util.Object2RawExtension(map[string]interface{}{ 417 "domain": "b.example.com", 418 }), 419 }}, 420 }}, 421 }, 422 expectedApp: &v1beta1.Application{ 423 Spec: v1beta1.ApplicationSpec{ 424 Components: []common.ApplicationComponent{{ 425 Name: "express-server", 426 Type: "webservice", 427 Properties: util.Object2RawExtension(map[string]interface{}{ 428 "image": "busybox", 429 }), 430 Traits: []common.ApplicationTrait{{ 431 Type: "ingress", 432 Properties: util.Object2RawExtension(map[string]interface{}{ 433 "domain": "b.example.com", 434 }), 435 }, { 436 Type: "ingress-1-20", 437 Properties: util.Object2RawExtension(map[string]interface{}{ 438 "domain": "a-1-20.example.com", 439 }), 440 }}, 441 }, { 442 Name: "express-worker", 443 Type: "worker", 444 Properties: util.Object2RawExtension(map[string]interface{}{ 445 "image": "crccheck/hello-world", 446 }), 447 }}, 448 }, 449 }, 450 }, 451 "patch-without-type-specified": { 452 baseApp: &v1beta1.Application{ 453 Spec: v1beta1.ApplicationSpec{ 454 Components: []common.ApplicationComponent{{ 455 Name: "express-server", 456 Type: "webservice", 457 Properties: util.Object2RawExtension(map[string]interface{}{ 458 "image": "crccheck/hello-world", 459 }), 460 Traits: []common.ApplicationTrait{{ 461 Type: "ingress", 462 Properties: util.Object2RawExtension(map[string]interface{}{ 463 "domain": "a.example.com", 464 }), 465 }, { 466 Type: "ingress-1-20", 467 Properties: util.Object2RawExtension(map[string]interface{}{ 468 "domain": "a-1-20.example.com", 469 }), 470 }}, 471 }, { 472 Name: "express-worker", 473 Type: "worker", 474 Properties: util.Object2RawExtension(map[string]interface{}{ 475 "image": "crccheck/hello-world", 476 }), 477 }}, 478 }, 479 }, 480 envName: "prod", 481 envPatch: v1alpha1.EnvPatch{ 482 Components: []v1alpha1.EnvComponentPatch{{ 483 Name: "express-worker", 484 Type: "", 485 Properties: util.Object2RawExtension(map[string]interface{}{ 486 "image": "busybox", 487 }), 488 Traits: []v1alpha1.EnvTraitPatch{{ 489 Type: "ingress", 490 Properties: util.Object2RawExtension(map[string]interface{}{ 491 "domain": "b.example.com", 492 }), 493 }}, 494 }}, 495 }, 496 expectedApp: &v1beta1.Application{ 497 Spec: v1beta1.ApplicationSpec{ 498 Components: []common.ApplicationComponent{{ 499 Name: "express-server", 500 Type: "webservice", 501 Properties: util.Object2RawExtension(map[string]interface{}{ 502 "image": "crccheck/hello-world", 503 }), 504 Traits: []common.ApplicationTrait{{ 505 Type: "ingress", 506 Properties: util.Object2RawExtension(map[string]interface{}{ 507 "domain": "a.example.com", 508 }), 509 }, { 510 Type: "ingress-1-20", 511 Properties: util.Object2RawExtension(map[string]interface{}{ 512 "domain": "a-1-20.example.com", 513 }), 514 }}, 515 }, { 516 Name: "express-worker", 517 Type: "worker", 518 Properties: util.Object2RawExtension(map[string]interface{}{ 519 "image": "busybox", 520 }), 521 Traits: []common.ApplicationTrait{{ 522 Type: "ingress", 523 Properties: util.Object2RawExtension(map[string]interface{}{ 524 "domain": "b.example.com", 525 }), 526 }}, 527 }}, 528 }, 529 }, 530 }, 531 } 532 533 for name, tc := range testCases { 534 t.Run(name, func(t *testing.T) { 535 app, err := PatchApplication(tc.baseApp, &tc.envPatch, tc.selector) 536 r := require.New(t) 537 r.NoError(err) 538 r.Equal(tc.expectedApp, app) 539 }) 540 } 541 } 542 543 var baseApp = &v1beta1.Application{ 544 TypeMeta: metav1.TypeMeta{ 545 APIVersion: "v1beta1", 546 Kind: "Application", 547 }, 548 ObjectMeta: metav1.ObjectMeta{ 549 Name: "test", 550 }, 551 Spec: v1beta1.ApplicationSpec{ 552 Components: []common.ApplicationComponent{{ 553 Name: "express-server", 554 Type: "webservice", 555 Properties: util.Object2RawExtension(map[string]interface{}{ 556 "image": "crccheck/hello-world", 557 "port": 8000, 558 }), 559 Traits: []common.ApplicationTrait{{ 560 Type: "ingress-1-20", 561 Properties: util.Object2RawExtension(map[string]interface{}{ 562 "domain": "testsvc.example.com", 563 "http": map[string]interface{}{ 564 "/": 8000, 565 }, 566 }), 567 }}, 568 }}, 569 }, 570 }