github.com/oam-dev/kubevela@v1.9.11/test/e2e-test/definition_revision_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 controllers_test 18 19 import ( 20 "context" 21 "fmt" 22 "time" 23 24 . "github.com/onsi/ginkgo/v2" 25 . "github.com/onsi/gomega" 26 "github.com/pkg/errors" 27 appsv1 "k8s.io/api/apps/v1" 28 batchv1 "k8s.io/api/batch/v1" 29 corev1 "k8s.io/api/core/v1" 30 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 31 "sigs.k8s.io/controller-runtime/pkg/client" 32 33 "github.com/oam-dev/kubevela/apis/core.oam.dev/common" 34 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 35 "github.com/oam-dev/kubevela/pkg/oam" 36 "github.com/oam-dev/kubevela/pkg/oam/util" 37 ) 38 39 var _ = Describe("Test application of the specified definition version", func() { 40 ctx := context.Background() 41 42 var namespace string 43 var ns corev1.Namespace 44 45 BeforeEach(func() { 46 namespace = randomNamespaceName("defrev-e2e-test") 47 ns = corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: namespace}} 48 49 Eventually(func() error { 50 return k8sClient.Create(ctx, &ns) 51 }, time.Second*3, time.Microsecond*300).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{})) 52 53 labelV1 := labelWithNoTemplate.DeepCopy() 54 labelV1.Spec.Schematic.CUE.Template = labelV1Template 55 labelV1.SetNamespace(namespace) 56 Expect(k8sClient.Create(ctx, labelV1)).Should(Succeed()) 57 58 labelV1DefRev := new(v1beta1.DefinitionRevision) 59 Eventually(func() error { 60 return k8sClient.Get(ctx, client.ObjectKey{Name: "label-v1", Namespace: namespace}, labelV1DefRev) 61 }, 15*time.Second, time.Second).Should(BeNil()) 62 63 labelV2 := new(v1beta1.TraitDefinition) 64 Eventually(func() error { 65 err := k8sClient.Get(ctx, client.ObjectKey{Name: "label", Namespace: namespace}, labelV2) 66 if err != nil { 67 return err 68 } 69 labelV2.Spec.Schematic.CUE.Template = labelV2Template 70 return k8sClient.Update(ctx, labelV2) 71 }, 15*time.Second, time.Second).Should(BeNil()) 72 73 labelV2DefRev := new(v1beta1.DefinitionRevision) 74 Eventually(func() error { 75 return k8sClient.Get(ctx, client.ObjectKey{Name: "label-v2", Namespace: namespace}, labelV2DefRev) 76 }, 15*time.Second, time.Second).Should(BeNil()) 77 78 webserviceV1 := webServiceWithNoTemplate.DeepCopy() 79 webserviceV1.Spec.Schematic.CUE.Template = webServiceV1Template 80 webserviceV1.SetNamespace(namespace) 81 Expect(k8sClient.Create(ctx, webserviceV1)).Should(Succeed()) 82 83 webserviceV1DefRev := new(v1beta1.DefinitionRevision) 84 Eventually(func() error { 85 return k8sClient.Get(ctx, client.ObjectKey{Name: "webservice-v1", Namespace: namespace}, webserviceV1DefRev) 86 }, 15*time.Second, time.Second).Should(BeNil()) 87 88 webserviceV2 := new(v1beta1.ComponentDefinition) 89 Eventually(func() error { 90 err := k8sClient.Get(ctx, client.ObjectKey{Name: "webservice", Namespace: namespace}, webserviceV2) 91 if err != nil { 92 return err 93 } 94 webserviceV2.Spec.Schematic.CUE.Template = webServiceV2Template 95 return k8sClient.Update(ctx, webserviceV2) 96 }, 15*time.Second, time.Second).Should(BeNil()) 97 98 webserviceV2DefRev := new(v1beta1.DefinitionRevision) 99 Eventually(func() error { 100 return k8sClient.Get(ctx, client.ObjectKey{Name: "webservice-v2", Namespace: namespace}, webserviceV2DefRev) 101 }, 15*time.Second, time.Second).Should(BeNil()) 102 103 jobV1 := jobComponentDef.DeepCopy() 104 jobV1.SetNamespace(namespace) 105 Expect(k8sClient.Create(ctx, jobV1)).Should(Succeed()) 106 107 jobV1Rev := new(v1beta1.DefinitionRevision) 108 Eventually(func() error { 109 return k8sClient.Get(ctx, client.ObjectKey{Name: "job-v1.2.1", Namespace: namespace}, jobV1Rev) 110 }, 15*time.Second, time.Second).Should(BeNil()) 111 }) 112 113 AfterEach(func() { 114 By("Clean up resources after a test") 115 k8sClient.DeleteAllOf(ctx, &v1beta1.Application{}, client.InNamespace(namespace)) 116 k8sClient.DeleteAllOf(ctx, &v1beta1.ComponentDefinition{}, client.InNamespace(namespace)) 117 k8sClient.DeleteAllOf(ctx, &v1beta1.WorkloadDefinition{}, client.InNamespace(namespace)) 118 k8sClient.DeleteAllOf(ctx, &v1beta1.TraitDefinition{}, client.InNamespace(namespace)) 119 k8sClient.DeleteAllOf(ctx, &v1beta1.DefinitionRevision{}, client.InNamespace(namespace)) 120 121 By(fmt.Sprintf("Delete the entire namespaceName %s", ns.Name)) 122 Expect(k8sClient.Delete(ctx, &ns, client.PropagationPolicy(metav1.DeletePropagationForeground))).Should(Succeed()) 123 }) 124 125 It("Test deploy application which containing cue rendering module", func() { 126 var ( 127 appName = "test-website-app" 128 comp1Name = "front" 129 comp2Name = "backend" 130 ) 131 132 workerV1 := workerWithNoTemplate.DeepCopy() 133 workerV1.Spec.Workload = common.WorkloadTypeDescriptor{ 134 Definition: common.WorkloadGVK{ 135 APIVersion: "batch/v1", 136 Kind: "Job", 137 }, 138 } 139 workerV1.Spec.Schematic.CUE.Template = workerV1Template 140 workerV1.SetNamespace(namespace) 141 Expect(k8sClient.Create(ctx, workerV1)).Should(Succeed()) 142 143 workerV1DefRev := new(v1beta1.DefinitionRevision) 144 Eventually(func() error { 145 return k8sClient.Get(ctx, client.ObjectKey{Name: "worker-v1", Namespace: namespace}, workerV1DefRev) 146 }, 15*time.Second, time.Second).Should(BeNil()) 147 148 workerV2 := new(v1beta1.ComponentDefinition) 149 Eventually(func() error { 150 err := k8sClient.Get(ctx, client.ObjectKey{Name: "worker", Namespace: namespace}, workerV2) 151 if err != nil { 152 return err 153 } 154 workerV1.Spec.Workload = common.WorkloadTypeDescriptor{ 155 Definition: common.WorkloadGVK{ 156 APIVersion: "apps/v1", 157 Kind: "Deployment", 158 }, 159 } 160 workerV2.Spec.Schematic.CUE.Template = workerV2Template 161 return k8sClient.Update(ctx, workerV2) 162 }, 15*time.Second, time.Second).Should(BeNil()) 163 164 workerV2DefRev := new(v1beta1.DefinitionRevision) 165 Eventually(func() error { 166 return k8sClient.Get(ctx, client.ObjectKey{Name: "worker-v2", Namespace: namespace}, workerV2DefRev) 167 }, 15*time.Second, time.Second).Should(BeNil()) 168 169 app := v1beta1.Application{ 170 ObjectMeta: metav1.ObjectMeta{ 171 Name: appName, 172 Namespace: namespace, 173 }, 174 Spec: v1beta1.ApplicationSpec{ 175 Components: []common.ApplicationComponent{ 176 { 177 Name: comp1Name, 178 Type: "webservice", 179 Properties: util.Object2RawExtension(map[string]interface{}{ 180 "image": "nginx", 181 }), 182 Traits: []common.ApplicationTrait{ 183 { 184 Type: "label", 185 Properties: util.Object2RawExtension(map[string]interface{}{ 186 "labels": map[string]string{ 187 "hello": "world", 188 }, 189 }), 190 }, 191 }, 192 }, 193 { 194 Name: comp2Name, 195 Type: "worker", 196 Properties: util.Object2RawExtension(map[string]interface{}{ 197 "image": "busybox", 198 "cmd": []string{"sleep", "1000"}, 199 }), 200 }, 201 }, 202 }, 203 } 204 205 By("Create application") 206 Eventually(func() error { 207 return k8sClient.Create(ctx, app.DeepCopy()) 208 }, 10*time.Second, 500*time.Millisecond).Should(Succeed()) 209 210 By("Verify the workload(deployment) is created successfully") 211 webServiceDeploy := &appsv1.Deployment{} 212 deployName := comp1Name 213 Eventually(func() error { 214 return k8sClient.Get(ctx, client.ObjectKey{Name: deployName, Namespace: namespace}, webServiceDeploy) 215 }, 30*time.Second, 3*time.Second).Should(Succeed()) 216 217 workerDeploy := &appsv1.Deployment{} 218 deployName = comp2Name 219 Eventually(func() error { 220 return k8sClient.Get(ctx, client.ObjectKey{Name: deployName, Namespace: namespace}, workerDeploy) 221 }, 30*time.Second, 3*time.Second).Should(Succeed()) 222 223 By("Verify trait is applied to the workload") 224 webserviceLabels := webServiceDeploy.GetLabels() 225 Expect(webserviceLabels["hello"]).Should(Equal("world")) 226 227 By("Update Application and Specify the Definition version in Application") 228 app = v1beta1.Application{ 229 ObjectMeta: metav1.ObjectMeta{ 230 Name: appName, 231 Namespace: namespace, 232 }, 233 Spec: v1beta1.ApplicationSpec{ 234 Components: []common.ApplicationComponent{ 235 { 236 Name: comp1Name, 237 Type: "webservice@v1", 238 Properties: util.Object2RawExtension(map[string]interface{}{ 239 "image": "nginx", 240 }), 241 Traits: []common.ApplicationTrait{ 242 { 243 Type: "label@v1", 244 Properties: util.Object2RawExtension(map[string]interface{}{ 245 "labels": map[string]string{ 246 "hello": "kubevela", 247 }, 248 }), 249 }, 250 }, 251 }, 252 { 253 Name: comp2Name, 254 Type: "worker@v1", 255 Properties: util.Object2RawExtension(map[string]interface{}{ 256 "image": "busybox", 257 "cmd": []string{"sleep", "1000"}, 258 }), 259 }, 260 }, 261 }, 262 } 263 Expect(k8sClient.Patch(ctx, &app, client.Merge)).Should(Succeed()) 264 265 By("Wait for dispatching v2 resources successfully") 266 Eventually(func() error { 267 RequestReconcileNow(ctx, &app) 268 rt := &v1beta1.ResourceTracker{} 269 if err := k8sClient.Get(ctx, client.ObjectKey{Name: fmt.Sprintf("%s-v2-%s", appName, namespace)}, rt); err != nil { 270 return err 271 } 272 if len(rt.Spec.ManagedResources) != 0 { 273 return nil 274 } 275 return errors.New("v2 resources have not been dispatched") 276 }, 10*time.Second, 500*time.Millisecond).Should(Succeed()) 277 278 By("Verify the workload(deployment) is created successfully") 279 webServiceV1Deploy := &appsv1.Deployment{} 280 deployName = comp1Name 281 Eventually(func() error { 282 return k8sClient.Get(ctx, client.ObjectKey{Name: deployName, Namespace: namespace}, webServiceV1Deploy) 283 }, 30*time.Second, 3*time.Second).Should(Succeed()) 284 285 By("Verify the workload(job) is created successfully") 286 workerJob := &batchv1.Job{} 287 jobName := comp2Name 288 Eventually(func() error { 289 return k8sClient.Get(ctx, client.ObjectKey{Name: jobName, Namespace: namespace}, workerJob) 290 }, 30*time.Second, 3*time.Second).Should(Succeed()) 291 292 By("Verify trait is applied to the workload") 293 webserviceV1Labels := webServiceV1Deploy.GetLabels() 294 Expect(webserviceV1Labels["hello"]).Should(Equal("kubevela")) 295 296 By("Check Application is rendered by the specified version of the Definition") 297 Expect(webServiceV1Deploy.Labels["componentdefinition.oam.dev/version"]).Should(Equal("v1")) 298 Expect(webServiceV1Deploy.Labels["traitdefinition.oam.dev/version"]).Should(Equal("v1")) 299 300 By("Application specifies the wrong version of the Definition, it will raise an error") 301 app = v1beta1.Application{ 302 ObjectMeta: metav1.ObjectMeta{ 303 Name: appName, 304 Namespace: namespace, 305 }, 306 Spec: v1beta1.ApplicationSpec{ 307 Components: []common.ApplicationComponent{ 308 { 309 Name: comp1Name, 310 Type: "webservice@v10", 311 Properties: util.Object2RawExtension(map[string]interface{}{ 312 "image": "nginx", 313 "cmd": []string{"sleep", "1000"}, 314 }), 315 }, 316 }, 317 }, 318 } 319 Expect(k8sClient.Patch(ctx, &app, client.Merge)).Should(HaveOccurred()) 320 }) 321 322 It("Test deploy application which specify the name of component", func() { 323 compName := "job" 324 app := v1beta1.Application{ 325 ObjectMeta: metav1.ObjectMeta{ 326 Name: "test-defrevision-app-with-job", 327 Namespace: namespace, 328 }, 329 Spec: v1beta1.ApplicationSpec{ 330 Components: []common.ApplicationComponent{ 331 { 332 Name: compName, 333 Type: "job@v1.2.1", 334 Properties: util.Object2RawExtension(map[string]interface{}{ 335 "image": "busybox", 336 "cmd": []string{"sleep", "1000"}, 337 }), 338 }, 339 }, 340 }, 341 } 342 Expect(k8sClient.Create(ctx, &app)).Should(Succeed()) 343 344 By("Verify the workload(job) is created successfully") 345 busyBoxJob := &batchv1.Job{} 346 jobName := compName 347 Eventually(func() error { 348 return k8sClient.Get(ctx, client.ObjectKey{Name: jobName, Namespace: namespace}, busyBoxJob) 349 }, 30*time.Second, 3*time.Second).Should(Succeed()) 350 }) 351 352 // refer to https://github.com/oam-dev/kubevela/discussions/1810#discussioncomment-914295 353 It("Test k8s resources created by application whether with correct label", func() { 354 var ( 355 appName = "test-resources-labels" 356 compName = "web" 357 ) 358 359 exposeV1 := exposeWithNoTemplate.DeepCopy() 360 exposeV1.Spec.Schematic.CUE.Template = exposeV1Template 361 exposeV1.SetNamespace(namespace) 362 Expect(k8sClient.Create(ctx, exposeV1)).Should(Succeed()) 363 364 exposeV1DefRev := new(v1beta1.DefinitionRevision) 365 Eventually(func() error { 366 return k8sClient.Get(ctx, client.ObjectKey{Name: "expose-v1", Namespace: namespace}, exposeV1DefRev) 367 }, 15*time.Second, time.Second).Should(BeNil()) 368 369 exposeV2 := new(v1beta1.TraitDefinition) 370 Eventually(func() error { 371 err := k8sClient.Get(ctx, client.ObjectKey{Name: "expose", Namespace: namespace}, exposeV2) 372 if err != nil { 373 return err 374 } 375 exposeV2.Spec.Schematic.CUE.Template = exposeV2Template 376 return k8sClient.Update(ctx, exposeV2) 377 }, 15*time.Second, time.Second).Should(BeNil()) 378 379 exposeV2DefRev := new(v1beta1.DefinitionRevision) 380 Eventually(func() error { 381 return k8sClient.Get(ctx, client.ObjectKey{Name: "expose-v2", Namespace: namespace}, exposeV2DefRev) 382 }, 15*time.Second, time.Second).Should(BeNil()) 383 384 app := v1beta1.Application{ 385 ObjectMeta: metav1.ObjectMeta{ 386 Name: appName, 387 Namespace: namespace, 388 }, 389 Spec: v1beta1.ApplicationSpec{ 390 Components: []common.ApplicationComponent{ 391 { 392 Name: compName, 393 Type: "webservice@v1", 394 Properties: util.Object2RawExtension(map[string]interface{}{ 395 "image": "crccheck/hello-world", 396 "port": 8000, 397 }), 398 Traits: []common.ApplicationTrait{ 399 { 400 Type: "expose@v1", 401 Properties: util.Object2RawExtension(map[string]interface{}{ 402 "port": []int{8000}, 403 }), 404 }, 405 }, 406 }, 407 }, 408 }, 409 } 410 411 By("Create application") 412 Eventually(func() error { 413 return k8sClient.Create(ctx, app.DeepCopy()) 414 }, 10*time.Second, 500*time.Millisecond).Should(Succeed()) 415 416 By("Verify the workload(deployment) is created successfully") 417 webServiceDeploy := &appsv1.Deployment{} 418 deployName := compName 419 Eventually(func() error { 420 return k8sClient.Get(ctx, client.ObjectKey{Name: deployName, Namespace: namespace}, webServiceDeploy) 421 }, 30*time.Second, 3*time.Second).Should(Succeed()) 422 423 By("Verify the workload label generated by KubeVela") 424 workloadLabel := webServiceDeploy.GetLabels()[oam.WorkloadTypeLabel] 425 Expect(workloadLabel).Should(Equal("webservice-v1")) 426 427 By("Verify the traPIt(service) is created successfully") 428 exposeSVC := &corev1.Service{} 429 Eventually(func() error { 430 return k8sClient.Get(ctx, client.ObjectKey{Name: compName, Namespace: namespace}, exposeSVC) 431 }, 30*time.Second, 3*time.Second).Should(Succeed()) 432 433 By("Verify the trait label generated by KubeVela") 434 traitLabel := exposeSVC.GetLabels()[oam.TraitTypeLabel] 435 Expect(traitLabel).Should(Equal("expose-v1")) 436 }) 437 }) 438 439 var webServiceWithNoTemplate = &v1beta1.ComponentDefinition{ 440 TypeMeta: metav1.TypeMeta{ 441 Kind: "ComponentDefinition", 442 APIVersion: "core.oam.dev/v1beta1", 443 }, 444 ObjectMeta: metav1.ObjectMeta{ 445 Name: "webservice", 446 }, 447 Spec: v1beta1.ComponentDefinitionSpec{ 448 Workload: common.WorkloadTypeDescriptor{ 449 Definition: common.WorkloadGVK{ 450 APIVersion: "apps/v1", 451 Kind: "Deployment", 452 }, 453 }, 454 Schematic: &common.Schematic{ 455 CUE: &common.CUE{ 456 Template: "", 457 }, 458 }, 459 }, 460 } 461 462 var workerWithNoTemplate = &v1beta1.ComponentDefinition{ 463 TypeMeta: metav1.TypeMeta{ 464 Kind: "ComponentDefinition", 465 APIVersion: "core.oam.dev/v1beta1", 466 }, 467 ObjectMeta: metav1.ObjectMeta{ 468 Name: "worker", 469 }, 470 Spec: v1beta1.ComponentDefinitionSpec{ 471 Schematic: &common.Schematic{ 472 CUE: &common.CUE{ 473 Template: "", 474 }, 475 }, 476 }, 477 } 478 479 var jobComponentDef = &v1beta1.ComponentDefinition{ 480 TypeMeta: metav1.TypeMeta{ 481 Kind: "ComponentDefinition", 482 APIVersion: "core.oam.dev/v1beta1", 483 }, 484 ObjectMeta: metav1.ObjectMeta{ 485 Name: "job", 486 Annotations: map[string]string{ 487 oam.AnnotationDefinitionRevisionName: "1.2.1", 488 }, 489 }, 490 Spec: v1beta1.ComponentDefinitionSpec{ 491 Workload: common.WorkloadTypeDescriptor{ 492 Definition: common.WorkloadGVK{ 493 APIVersion: "batch/v1", 494 Kind: "Job", 495 }, 496 }, 497 Schematic: &common.Schematic{ 498 CUE: &common.CUE{ 499 Template: workerV1Template, 500 }, 501 }, 502 }, 503 } 504 505 var KUBEWorker = &v1beta1.ComponentDefinition{ 506 TypeMeta: metav1.TypeMeta{ 507 Kind: "ComponentDefinition", 508 APIVersion: "core.oam.dev/v1beta1", 509 }, 510 ObjectMeta: metav1.ObjectMeta{ 511 Name: "kube-worker", 512 }, 513 } 514 515 var HELMWorker = &v1beta1.ComponentDefinition{ 516 TypeMeta: metav1.TypeMeta{ 517 Kind: "ComponentDefinition", 518 APIVersion: "core.oam.dev/v1beta1", 519 }, 520 ObjectMeta: metav1.ObjectMeta{ 521 Name: "helm-worker", 522 }, 523 } 524 525 var labelWithNoTemplate = &v1beta1.TraitDefinition{ 526 TypeMeta: metav1.TypeMeta{ 527 Kind: "TraitDefinition", 528 APIVersion: "core.oam.dev/v1beta1", 529 }, 530 ObjectMeta: metav1.ObjectMeta{ 531 Name: "label", 532 }, 533 Spec: v1beta1.TraitDefinitionSpec{ 534 Schematic: &common.Schematic{ 535 CUE: &common.CUE{ 536 Template: "", 537 }, 538 }, 539 }, 540 } 541 542 var exposeWithNoTemplate = &v1beta1.TraitDefinition{ 543 TypeMeta: metav1.TypeMeta{ 544 Kind: "TraitDefinition", 545 APIVersion: "core.oam.dev/v1beta1", 546 }, 547 ObjectMeta: metav1.ObjectMeta{ 548 Name: "expose", 549 }, 550 Spec: v1beta1.TraitDefinitionSpec{ 551 Schematic: &common.Schematic{ 552 CUE: &common.CUE{ 553 Template: "", 554 }, 555 }, 556 }, 557 } 558 559 var webServiceV1Template = `output: { 560 apiVersion: "apps/v1" 561 kind: "Deployment" 562 metadata: labels: { 563 "componentdefinition.oam.dev/version": "v1" 564 } 565 spec: { 566 selector: matchLabels: { 567 "app.oam.dev/component": context.name 568 } 569 template: { 570 metadata: labels: { 571 "app.oam.dev/component": context.name 572 } 573 spec: { 574 containers: [{ 575 name: context.name 576 image: parameter.image 577 if parameter["cmd"] != _|_ { 578 command: parameter.cmd 579 } 580 if parameter["env"] != _|_ { 581 env: parameter.env 582 } 583 if context["config"] != _|_ { 584 env: context.config 585 } 586 ports: [{ 587 containerPort: parameter.port 588 }] 589 if parameter["cpu"] != _|_ { 590 resources: { 591 limits: 592 cpu: parameter.cpu 593 requests: 594 cpu: parameter.cpu 595 } 596 } 597 }] 598 } 599 } 600 } 601 } 602 parameter: { 603 image: string 604 cmd?: [...string] 605 port: *80 | int 606 env?: [...{ 607 name: string 608 value?: string 609 valueFrom?: { 610 secretKeyRef: { 611 name: string 612 key: string 613 } 614 } 615 }] 616 cpu?: string 617 } 618 ` 619 620 var webServiceV2Template = `output: { 621 apiVersion: "apps/v1" 622 kind: "Deployment" 623 spec: { 624 selector: matchLabels: { 625 "app.oam.dev/component": context.name 626 } 627 template: { 628 metadata: labels: { 629 "app.oam.dev/component": context.name 630 if parameter.addRevisionLabel { 631 "app.oam.dev/appRevision": context.appRevision 632 } 633 } 634 spec: { 635 containers: [{ 636 name: context.name 637 image: parameter.image 638 if parameter["cmd"] != _|_ { 639 command: parameter.cmd 640 } 641 if parameter["env"] != _|_ { 642 env: parameter.env 643 } 644 if context["config"] != _|_ { 645 env: context.config 646 } 647 ports: [{ 648 containerPort: parameter.port 649 }] 650 if parameter["cpu"] != _|_ { 651 resources: { 652 limits: 653 cpu: parameter.cpu 654 requests: 655 cpu: parameter.cpu 656 } 657 } 658 }] 659 } 660 } 661 } 662 } 663 parameter: { 664 image: string 665 cmd?: [...string] 666 port: *80 | int 667 env?: [...{ 668 name: string 669 value?: string 670 valueFrom?: { 671 secretKeyRef: { 672 name: string 673 key: string 674 } 675 } 676 }] 677 cpu?: string 678 addRevisionLabel: *false | bool 679 } 680 ` 681 682 var workerV1Template = `output: { 683 apiVersion: "batch/v1" 684 kind: "Job" 685 spec: { 686 parallelism: parameter.count 687 completions: parameter.count 688 template: spec: { 689 restartPolicy : parameter.restart 690 containers: [{ 691 name: context.name 692 image: parameter.image 693 if parameter["cmd"] != _|_ { 694 command: parameter.cmd 695 } 696 }] 697 } 698 } 699 } 700 parameter: { 701 count: *1 | int 702 image: string 703 restart: *"Never" | string 704 cmd?: [...string] 705 } 706 ` 707 708 var workerV2Template = `output: { 709 apiVersion: "apps/v1" 710 kind: "Deployment" 711 spec: { 712 selector: matchLabels: { 713 "app.oam.dev/component": context.name 714 } 715 template: { 716 metadata: labels: { 717 "app.oam.dev/component": context.name 718 } 719 spec: { 720 containers: [{ 721 name: context.name 722 image: parameter.image 723 724 if parameter["cmd"] != _|_ { 725 command: parameter.cmd 726 } 727 }] 728 } 729 } 730 } 731 } 732 parameter: { 733 image: string 734 cmd?: [...string] 735 } 736 ` 737 738 var labelV1Template = `patch: { 739 metadata: labels: { 740 for k, v in parameter.labels { 741 "\(k)": v 742 } 743 "traitdefinition.oam.dev/version": "v1" 744 } 745 } 746 parameter: { 747 labels: [string]: string 748 } 749 ` 750 751 var labelV2Template = `patch: { 752 metadata: labels: { 753 for k, v in parameter.labels { 754 "\(k)": v 755 } 756 } 757 } 758 parameter: { 759 labels: [string]: string 760 } 761 ` 762 763 var KUBEWorkerV1Template = `apiVersion: apps/v1 764 kind: Deployment 765 spec: 766 selector: 767 matchLabels: 768 app: nginx 769 template: 770 metadata: 771 labels: 772 app: nginx 773 spec: 774 containers: 775 - name: nginx 776 ports: 777 - containerPort: 80 778 ` 779 780 var KUBEWorkerV2Template = `apiVersion: "batch/v1" 781 kind: "Job" 782 spec: 783 parallelism: 1 784 completions: 1 785 template: 786 spec: 787 restartPolicy: "Never" 788 containers: 789 - name: "job" 790 image: "busybox" 791 command: 792 - "sleep" 793 - "1000" 794 ` 795 796 var exposeV1Template = ` 797 outputs: service: { 798 apiVersion: "v1" 799 kind: "Service" 800 metadata: 801 name: context.name 802 spec: { 803 selector: 804 "app.oam.dev/component": context.name 805 ports: [ 806 for p in parameter.port { 807 port: p 808 targetPort: p 809 }, 810 ] 811 } 812 } 813 parameter: { 814 // +usage=Specify the exposion ports 815 port: [...int] 816 } 817 ` 818 819 var exposeV2Template = ` 820 outputs: service: { 821 apiVersion: "v1" 822 kind: "Service" 823 metadata: 824 name: context.name 825 spec: { 826 selector: { 827 "app.oam.dev/component": context.name 828 } 829 ports: [ 830 for k, v in parameter.http { 831 port: v 832 targetPort: v 833 }, 834 ] 835 } 836 } 837 838 outputs: ingress: { 839 apiVersion: "networking.k8s.io/v1beta1" 840 kind: "Ingress" 841 metadata: 842 name: context.name 843 spec: { 844 rules: [{ 845 host: parameter.domain 846 http: { 847 paths: [ 848 for k, v in parameter.http { 849 path: k 850 backend: { 851 serviceName: context.name 852 servicePort: v 853 } 854 }, 855 ] 856 } 857 }] 858 } 859 } 860 861 parameter: { 862 domain: string 863 http: [string]: int 864 } 865 `