github.com/oam-dev/kubevela@v1.9.11/e2e/plugin/plugin_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 plugin 18 19 import ( 20 "fmt" 21 "os" 22 "time" 23 24 . "github.com/onsi/ginkgo/v2" 25 . "github.com/onsi/gomega" 26 "sigs.k8s.io/controller-runtime/pkg/client" 27 28 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" 29 "github.com/oam-dev/kubevela/e2e" 30 ) 31 32 var _ = Describe("Test Kubectl Plugin", func() { 33 namespace := "default" 34 componentDefName := "test-webservice" 35 traitDefName := "test-ingress" 36 37 Context("Test kubectl vela dry-run", func() { 38 It("Test dry-run application use definitions which applied to the cluster", func() { 39 By("check definitions which application used whether applied to the cluster") 40 var cd v1beta1.ComponentDefinition 41 Eventually(func() error { 42 err := k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: componentDefName}, &cd) 43 return err 44 }, 5*time.Second, time.Second).Should(BeNil()) 45 46 var td v1beta1.TraitDefinition 47 Eventually(func() error { 48 err := k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: traitDefName}, &td) 49 return err 50 }, 5*time.Second, time.Second).Should(BeNil()) 51 52 By("dry-run application") 53 err := os.WriteFile("dry-run-app.yaml", []byte(application), 0644) 54 Expect(err).NotTo(HaveOccurred()) 55 Eventually(func() string { 56 output, _ := e2e.Exec("kubectl-vela dry-run -f dry-run-app.yaml -n default -x default") 57 return output 58 }, 10*time.Second, time.Second).Should(ContainSubstring(dryRunResult)) 59 }) 60 61 It("Test dry-run application use definitions in local", func() { 62 Eventually(func() string { 63 output, _ := e2e.Exec("kubectl-vela dry-run -f dry-run-app.yaml -n default -d definitions") 64 return output 65 }, 10*time.Second, time.Second).Should(ContainSubstring(dryRunResult)) 66 }) 67 }) 68 69 Context("Test kubectl vela live-diff", func() { 70 applicationName := "test-vela-app" 71 72 It("Test live-diff application use definition which applied to the cluster", func() { 73 By("check definitions which application used whether applied to the cluster") 74 var cd v1beta1.ComponentDefinition 75 Eventually(func() error { 76 err := k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: componentDefName}, &cd) 77 return err 78 }, 5*time.Second).Should(BeNil()) 79 80 var td v1beta1.TraitDefinition 81 Eventually(func() error { 82 err := k8sClient.Get(ctx, client.ObjectKey{Namespace: namespace, Name: traitDefName}, &td) 83 return err 84 }, 5*time.Second).Should(BeNil()) 85 86 By("get appRevision") 87 var appRev v1beta1.ApplicationRevision 88 var appRevName = fmt.Sprintf("%s-v1", applicationName) 89 Eventually(func() error { 90 err := k8sClient.Get(ctx, client.ObjectKey{Namespace: "default", Name: appRevName}, &appRev) 91 return err 92 }, 5*time.Second).Should(BeNil()) 93 94 Eventually(func() bool { 95 var tempApp v1beta1.Application 96 _ = k8sClient.Get(ctx, client.ObjectKey{Namespace: "default", Name: app.Name}, &tempApp) 97 return tempApp.Status.LatestRevision != nil 98 }, 20*time.Second, time.Second).Should(BeTrue()) 99 100 By("live-diff application") 101 err := os.WriteFile("live-diff-app.yaml", []byte(newApplication), 0644) 102 Expect(err).NotTo(HaveOccurred()) 103 output, err := e2e.Exec("kubectl-vela live-diff -f live-diff-app.yaml") 104 Expect(err).NotTo(HaveOccurred()) 105 Expect(output).Should(ContainSubstring(livediffResult)) 106 }) 107 108 It("Test dry-run application use definitions in local", func() { 109 Eventually(func() bool { 110 var tempApp v1beta1.Application 111 _ = k8sClient.Get(ctx, client.ObjectKey{Namespace: "default", Name: app.Name}, &tempApp) 112 return tempApp.Status.LatestRevision != nil 113 }, 20*time.Second, time.Second).Should(BeTrue()) 114 115 output, err := e2e.Exec("kubectl-vela live-diff -f live-diff-app.yaml -d definitions") 116 Expect(err).NotTo(HaveOccurred()) 117 Expect(output).Should(ContainSubstring(livediffResult)) 118 }) 119 }) 120 121 Context("Test kubectl vela show", func() { 122 It("Test show componentDefinition reference", func() { 123 cdName := "test-show-task" 124 output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", cdName)) 125 Expect(err).NotTo(HaveOccurred()) 126 Expect(output).Should(ContainSubstring(showCdResult)) 127 }) 128 It("Test show traitDefinition reference", func() { 129 tdName := "test-sidecar" 130 output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", tdName)) 131 Expect(err).NotTo(HaveOccurred()) 132 Expect(output).Should(ContainSubstring(showTdResult)) 133 }) 134 It("Test show traitDefinition def with cue single map parameter", func() { 135 tdName := "annotations" 136 output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", tdName)) 137 Expect(err).NotTo(HaveOccurred()) 138 Expect(output).Should(ContainSubstring("map[string]:(null|string)")) 139 }) 140 It("Test show webservice def with cue ignore annotation ", func() { 141 tdName := "webservice" 142 output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", tdName)) 143 Expect(err).NotTo(HaveOccurred()) 144 Expect(output).ShouldNot(ContainSubstring("addRevisionLabel")) 145 }) 146 It("Test show webservice def with cue ignore annotation ", func() { 147 tdName := "mywebservice" 148 output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", tdName)) 149 Expect(err).NotTo(HaveOccurred()) 150 Expect(output).ShouldNot(ContainSubstring("addRevisionLabel")) 151 Expect(output).ShouldNot(ContainSubstring("mySecretKey")) 152 }) 153 }) 154 }) 155 156 var application = ` 157 apiVersion: core.oam.dev/v1beta1 158 kind: Application 159 metadata: 160 name: test-vela-app 161 namespace: default 162 spec: 163 components: 164 - name: express-server 165 type: test-webservice 166 properties: 167 image: crccheck/hello-world 168 port: 80 169 traits: 170 - type: test-ingress 171 properties: 172 domain: testsvc.example.com 173 http: 174 "/": 80 175 ` 176 177 var newApplication = ` 178 apiVersion: core.oam.dev/v1beta1 179 kind: Application 180 metadata: 181 name: test-vela-app 182 namespace: default 183 spec: 184 components: 185 - name: new-express-server 186 type: test-webservice 187 properties: 188 image: crccheck/hello-world 189 port: 5000 190 cpu: "0.5" 191 traits: 192 - type: test-ingress 193 properties: 194 domain: new-testsvc.example.com 195 http: 196 "/": 8080 197 ` 198 199 var componentDef = ` 200 apiVersion: core.oam.dev/v1beta1 201 kind: ComponentDefinition 202 metadata: 203 name: test-webservice 204 namespace: default 205 annotations: 206 definition.oam.dev/description: "Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers." 207 spec: 208 workload: 209 definition: 210 apiVersion: apps/v1 211 kind: Deployment 212 schematic: 213 cue: 214 template: | 215 output: { 216 apiVersion: "apps/v1" 217 kind: "Deployment" 218 spec: { 219 selector: matchLabels: { 220 "app.oam.dev/component": context.name 221 } 222 223 template: { 224 metadata: labels: { 225 "app.oam.dev/component": context.name 226 if parameter.addRevisionLabel { 227 "app.oam.dev/appRevision": context.appRevision 228 } 229 } 230 231 spec: { 232 containers: [{ 233 name: context.name 234 image: parameter.image 235 236 if parameter["cmd"] != _|_ { 237 command: parameter.cmd 238 } 239 240 if parameter["env"] != _|_ { 241 env: parameter.env 242 } 243 244 if context["config"] != _|_ { 245 env: context.config 246 } 247 248 ports: [{ 249 containerPort: parameter.port 250 }] 251 252 if parameter["cpu"] != _|_ { 253 resources: { 254 limits: 255 cpu: parameter.cpu 256 requests: 257 cpu: parameter.cpu 258 } 259 } 260 261 if parameter["volumes"] != _|_ { 262 volumeMounts: [ for v in parameter.volumes { 263 { 264 mountPath: v.mountPath 265 name: v.name 266 }}] 267 } 268 }] 269 270 if parameter["volumes"] != _|_ { 271 volumes: [ for v in parameter.volumes { 272 { 273 name: v.name 274 if v.type == "pvc" { 275 persistentVolumeClaim: { 276 claimName: v.claimName 277 } 278 } 279 if v.type == "configMap" { 280 configMap: { 281 defaultMode: v.defaultMode 282 name: v.cmName 283 if v.items != _|_ { 284 items: v.items 285 } 286 } 287 } 288 if v.type == "secret" { 289 secret: { 290 defaultMode: v.defaultMode 291 secretName: v.secretName 292 if v.items != _|_ { 293 items: v.items 294 } 295 } 296 } 297 if v.type == "emptyDir" { 298 emptyDir: { 299 medium: v.medium 300 } 301 } 302 }}] 303 } 304 } 305 } 306 } 307 } 308 parameter: { 309 // +usage=Which image would you like to use for your service 310 // +short=i 311 image: string 312 313 // +usage=Commands to run in the container 314 cmd?: [...string] 315 316 // +usage=Which port do you want customer traffic sent to 317 // +short=p 318 port: *80 | int 319 // +usage=Define arguments by using environment variables 320 env?: [...{ 321 // +usage=Environment variable name 322 name: string 323 // +usage=The value of the environment variable 324 value?: string 325 // +usage=Specifies a source the value of this var should come from 326 valueFrom?: { 327 // +usage=Selects a key of a secret in the pod's namespace 328 secretKeyRef: { 329 // +usage=The name of the secret in the pod's namespace to select from 330 name: string 331 // +usage=The key of the secret to select from. Must be a valid secret key 332 key: string 333 } 334 } 335 }] 336 337 cpu?: string 338 339 // If addRevisionLabel is true, the appRevision label will be added to the underlying pods 340 addRevisionLabel: *false | bool 341 342 // +usage=Declare volumes and volumeMounts 343 volumes?: [...{ 344 name: string 345 mountPath: string 346 // +usage=Specify volume type, options: "pvc","configMap","secret","emptyDir" 347 type: "pvc" | "configMap" | "secret" | "emptyDir" 348 if type == "pvc" { 349 claimName: string 350 } 351 if type == "configMap" { 352 defaultMode: *420 | int 353 cmName: string 354 items?: [...{ 355 key: string 356 path: string 357 mode: *511 | int 358 }] 359 } 360 if type == "secret" { 361 defaultMode: *420 | int 362 secretName: string 363 items?: [...{ 364 key: string 365 path: string 366 mode: *511 | int 367 }] 368 } 369 if type == "emptyDir" { 370 medium: *"" | "Memory" 371 } 372 }] 373 } 374 375 ` 376 377 var traitDef = ` 378 apiVersion: core.oam.dev/v1beta1 379 kind: TraitDefinition 380 metadata: 381 annotations: 382 definition.oam.dev/description: "Configures K8s ingress and service to enable web traffic for your service. 383 Please use route trait in cap center for advanced usage." 384 name: test-ingress 385 namespace: default 386 spec: 387 status: 388 customStatus: |- 389 if len(context.outputs.ingress.status.loadBalancer.ingress) > 0 { 390 message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host + ", IP: " + context.outputs.ingress.status.loadBalancer.ingress[0].ip 391 } 392 if len(context.outputs.ingress.status.loadBalancer.ingress) == 0 { 393 message: "No loadBalancer found, visiting by using 'vela port-forward " + context.appName + " --route'\n" 394 } 395 healthPolicy: | 396 isHealth: len(context.outputs.service.spec.clusterIP) > 0 397 appliesToWorkloads: 398 - deployments.apps 399 podDisruptive: false 400 schematic: 401 cue: 402 template: | 403 parameter: { 404 domain: string 405 http: [string]: int 406 } 407 408 // trait template can have multiple outputs in one trait 409 outputs: service: { 410 apiVersion: "v1" 411 kind: "Service" 412 metadata: 413 name: context.name 414 spec: { 415 selector: { 416 "app.oam.dev/component": context.name 417 } 418 ports: [ 419 for k, v in parameter.http { 420 port: v 421 targetPort: v 422 }, 423 ] 424 } 425 } 426 427 outputs: ingress: { 428 apiVersion: "networking.k8s.io/v1beta1" 429 kind: "Ingress" 430 metadata: 431 name: context.name 432 spec: { 433 rules: [{ 434 host: parameter.domain 435 http: { 436 paths: [ 437 for k, v in parameter.http { 438 path: k 439 backend: { 440 serviceName: context.name 441 servicePort: v 442 } 443 }, 444 ] 445 } 446 }] 447 } 448 } 449 450 ` 451 452 var traitDefWithKube = ` 453 apiVersion: core.oam.dev/v1beta1 454 kind: TraitDefinition 455 metadata: 456 name: service-kube 457 namespace: default 458 spec: 459 appliesToWorkloads: 460 - webservice 461 - worker 462 - backend 463 podDisruptive: true 464 schematic: 465 kube: 466 template: 467 apiVersion: v1 468 kind: Service 469 metadata: 470 name: my-service 471 spec: 472 ports: 473 - protocol: TCP 474 port: 80 475 targetPort: 9376 476 parameters: 477 - name: targetPort 478 required: true 479 type: number 480 fieldPaths: 481 - "spec.template.spec.ports[0].targetPort" 482 description: "target port num for service provider." 483 ` 484 485 var componentWithDeepCue = ` 486 # Test for deeper parameter in cue Template 487 apiVersion: core.oam.dev/v1beta1 488 kind: ComponentDefinition 489 metadata: 490 name: mywebservice 491 namespace: default 492 annotations: 493 definition.oam.dev/description: "Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers." 494 spec: 495 workload: 496 definition: 497 apiVersion: apps/v1 498 kind: Deployment 499 schematic: 500 cue: 501 template: | 502 output: { 503 apiVersion: "apps/v1" 504 kind: "Deployment" 505 spec: { 506 selector: matchLabels: { 507 "app.oam.dev/component": context.name 508 } 509 510 template: { 511 metadata: labels: { 512 "app.oam.dev/component": context.name 513 if parameter.addRevisionLabel { 514 "app.oam.dev/appRevision": context.appRevision 515 } 516 } 517 518 spec: { 519 containers: [{ 520 name: context.name 521 image: parameter.image 522 523 if parameter["env"] != _|_ { 524 env: parameter.env 525 } 526 }] 527 } 528 } 529 } 530 } 531 parameter: { 532 // +usage=Which image would you like to use for your service 533 // +short=i 534 image: string 535 536 // +ignore 537 // +usage=If addRevisionLabel is true, the appRevision label will be added to the underlying pods 538 addRevisionLabel: *false | bool 539 540 // +usage=Define arguments by using environment variables 541 env?: [...{ 542 // +usage=Environment variable name 543 name: string 544 // +usage=The value of the environment variable 545 value?: string 546 // +usage=Specifies a source the value of this var should come from 547 valueFrom?: { 548 // +usage=Selects a key of a secret in the pod's namespace 549 secretKeyRef: { 550 // +usage=The name of the secret in the pod's namespace to select from 551 name: string 552 // +ignore 553 // +usage=The key of the secret to select from. Must be a valid secret key 554 mySecretKey: string 555 } 556 } 557 }] 558 } 559 ` 560 561 var dryRunResult = `--- 562 # Application(test-vela-app) -- Component(express-server) 563 --- 564 565 apiVersion: apps/v1 566 kind: Deployment 567 metadata: 568 annotations: {} 569 labels: 570 app.oam.dev/appRevision: "" 571 app.oam.dev/component: express-server 572 app.oam.dev/name: test-vela-app 573 app.oam.dev/namespace: default 574 app.oam.dev/resourceType: WORKLOAD 575 workload.oam.dev/type: test-webservice 576 name: express-server 577 namespace: default 578 spec: 579 selector: 580 matchLabels: 581 app.oam.dev/component: express-server 582 template: 583 metadata: 584 labels: 585 app.oam.dev/component: express-server 586 spec: 587 containers: 588 - image: crccheck/hello-world 589 name: express-server 590 ports: 591 - containerPort: 80 592 593 --- 594 ## From the trait test-ingress 595 apiVersion: v1 596 kind: Service 597 metadata: 598 annotations: {} 599 labels: 600 app.oam.dev/appRevision: "" 601 app.oam.dev/component: express-server 602 app.oam.dev/name: test-vela-app 603 app.oam.dev/namespace: default 604 app.oam.dev/resourceType: TRAIT 605 trait.oam.dev/resource: service 606 trait.oam.dev/type: test-ingress 607 name: express-server 608 namespace: default 609 spec: 610 ports: 611 - port: 80 612 targetPort: 80 613 selector: 614 app.oam.dev/component: express-server 615 616 --- 617 ## From the trait test-ingress 618 apiVersion: networking.k8s.io/v1beta1 619 kind: Ingress 620 metadata: 621 annotations: {} 622 labels: 623 app.oam.dev/appRevision: "" 624 app.oam.dev/component: express-server 625 app.oam.dev/name: test-vela-app 626 app.oam.dev/namespace: default 627 app.oam.dev/resourceType: TRAIT 628 trait.oam.dev/resource: ingress 629 trait.oam.dev/type: test-ingress 630 name: express-server 631 namespace: default 632 spec: 633 rules: 634 - host: testsvc.example.com 635 http: 636 paths: 637 - backend: 638 serviceName: express-server 639 servicePort: 80 640 path: / 641 642 --- 643 ` 644 645 var livediffResult = `Application (test-vela-app) has been modified(*) 646 apiVersion: core.oam.dev/v1beta1 647 kind: Application 648 metadata: 649 creationTimestamp: null 650 - finalizers: 651 - - app.oam.dev/resource-tracker-finalizer 652 name: test-vela-app 653 namespace: default 654 spec: 655 components: 656 - - name: express-server 657 + - name: new-express-server 658 properties: 659 + cpu: "0.5" 660 image: crccheck/hello-world 661 - port: 80 662 + port: 5000 663 traits: 664 - properties: 665 - domain: testsvc.example.com 666 + domain: new-testsvc.example.com 667 http: 668 - /: 80 669 + /: 8080 670 type: test-ingress 671 type: test-webservice 672 status: {} 673 674 * Component (express-server) has been removed(-) 675 - apiVersion: apps/v1 676 - kind: Deployment 677 - metadata: 678 - labels: 679 - app.oam.dev/component: express-server 680 - app.oam.dev/name: test-vela-app 681 - app.oam.dev/namespace: default 682 - app.oam.dev/resourceType: WORKLOAD 683 - workload.oam.dev/type: test-webservice 684 - name: express-server 685 - namespace: default 686 - spec: 687 - selector: 688 - matchLabels: 689 - app.oam.dev/component: express-server 690 - template: 691 - metadata: 692 - labels: 693 - app.oam.dev/component: express-server 694 - spec: 695 - containers: 696 - - image: crccheck/hello-world 697 - name: express-server 698 - ports: 699 - - containerPort: 80 700 701 * Component (express-server) / Trait (test-ingress/service) has been removed(-) 702 - apiVersion: v1 703 - kind: Service 704 - metadata: 705 - labels: 706 - app.oam.dev/component: express-server 707 - app.oam.dev/name: test-vela-app 708 - app.oam.dev/namespace: default 709 - app.oam.dev/resourceType: TRAIT 710 - trait.oam.dev/resource: service 711 - trait.oam.dev/type: test-ingress 712 - name: express-server 713 - namespace: default 714 - spec: 715 - ports: 716 - - port: 80 717 - targetPort: 80 718 - selector: 719 - app.oam.dev/component: express-server 720 721 * Component (express-server) / Trait (test-ingress/ingress) has been removed(-) 722 - apiVersion: networking.k8s.io/v1beta1 723 - kind: Ingress 724 - metadata: 725 - labels: 726 - app.oam.dev/component: express-server 727 - app.oam.dev/name: test-vela-app 728 - app.oam.dev/namespace: default 729 - app.oam.dev/resourceType: TRAIT 730 - trait.oam.dev/resource: ingress 731 - trait.oam.dev/type: test-ingress 732 - name: express-server 733 - namespace: default 734 - spec: 735 - rules: 736 - - host: testsvc.example.com 737 - http: 738 - paths: 739 - - backend: 740 - serviceName: express-server 741 - servicePort: 80 742 - path: / 743 744 * Component (new-express-server) has been added(+) 745 + apiVersion: apps/v1 746 + kind: Deployment 747 + metadata: 748 + labels: 749 + app.oam.dev/component: new-express-server 750 + app.oam.dev/name: test-vela-app 751 + app.oam.dev/namespace: default 752 + app.oam.dev/resourceType: WORKLOAD 753 + workload.oam.dev/type: test-webservice 754 + name: new-express-server 755 + namespace: default 756 + spec: 757 + selector: 758 + matchLabels: 759 + app.oam.dev/component: new-express-server 760 + template: 761 + metadata: 762 + labels: 763 + app.oam.dev/component: new-express-server 764 + spec: 765 + containers: 766 + - image: crccheck/hello-world 767 + name: new-express-server 768 + ports: 769 + - containerPort: 5000 770 + resources: 771 + limits: 772 + cpu: "0.5" 773 + requests: 774 + cpu: "0.5" 775 776 * Component (new-express-server) / Trait (test-ingress/service) has been added(+) 777 + apiVersion: v1 778 + kind: Service 779 + metadata: 780 + labels: 781 + app.oam.dev/component: new-express-server 782 + app.oam.dev/name: test-vela-app 783 + app.oam.dev/namespace: default 784 + app.oam.dev/resourceType: TRAIT 785 + trait.oam.dev/resource: service 786 + trait.oam.dev/type: test-ingress 787 + name: new-express-server 788 + namespace: default 789 + spec: 790 + ports: 791 + - port: 8080 792 + targetPort: 8080 793 + selector: 794 + app.oam.dev/component: new-express-server 795 796 * Component (new-express-server) / Trait (test-ingress/ingress) has been added(+) 797 + apiVersion: networking.k8s.io/v1beta1 798 + kind: Ingress 799 + metadata: 800 + labels: 801 + app.oam.dev/component: new-express-server 802 + app.oam.dev/name: test-vela-app 803 + app.oam.dev/namespace: default 804 + app.oam.dev/resourceType: TRAIT 805 + trait.oam.dev/resource: ingress 806 + trait.oam.dev/type: test-ingress 807 + name: new-express-server 808 + namespace: default 809 + spec: 810 + rules: 811 + - host: new-testsvc.example.com 812 + http: 813 + paths: 814 + - backend: 815 + serviceName: new-express-server 816 + servicePort: 8080 817 + path: / 818 ` 819 820 var testShowComponentDef = ` 821 apiVersion: core.oam.dev/v1beta1 822 kind: ComponentDefinition 823 metadata: 824 name: test-show-task 825 namespace: vela-system 826 spec: 827 workload: 828 definition: 829 apiVersion: batch/v1 830 kind: Job 831 schematic: 832 cue: 833 template: | 834 output: { 835 apiVersion: "batch/v1" 836 kind: "Job" 837 spec: { 838 parallelism: parameter.count 839 completions: parameter.count 840 template: spec: { 841 restartPolicy: parameter.restart 842 containers: [{ 843 name: context.name 844 image: parameter.image 845 846 if parameter["cmd"] != _|_ { 847 command: parameter.cmd 848 } 849 }] 850 } 851 } 852 } 853 parameter: { 854 // +usage=specify number of tasks to run in parallel 855 // +short=c 856 count: *1 | int 857 858 // +usage=Which image would you like to use for your service 859 // +short=i 860 image: string 861 862 // +usage=Define the job restart policy, the value can only be Never or OnFailure. By default, it's Never. 863 restart: *"Never" | string 864 865 // +usage=Commands to run in the container 866 cmd?: [...string] 867 } 868 ` 869 870 var testShowTraitDef = ` 871 apiVersion: core.oam.dev/v1beta1 872 kind: TraitDefinition 873 metadata: 874 name: test-sidecar 875 namespace: vela-system 876 spec: 877 appliesToWorkloads: 878 - deployments.apps 879 schematic: 880 cue: 881 template: |- 882 patch: { 883 // +patchKey=name 884 spec: template: spec: containers: [parameter] 885 } 886 parameter: { 887 name: string 888 image: string 889 command?: [...string] 890 } 891 ` 892 893 var showCdResult = `# Specification 894 +---------+--------------------------------------------------------------------------------------------------+----------+----------+---------+ 895 | NAME | DESCRIPTION | TYPE | REQUIRED | DEFAULT | 896 +---------+--------------------------------------------------------------------------------------------------+----------+----------+---------+ 897 | count | specify number of tasks to run in parallel. | int | false | 1 | 898 | image | Which image would you like to use for your service. | string | true | | 899 | restart | Define the job restart policy, the value can only be Never or OnFailure. By default, it's Never. | string | false | Never | 900 | cmd | Commands to run in the container. | []string | false | | 901 +---------+--------------------------------------------------------------------------------------------------+----------+----------+---------+ 902 903 904 ` 905 906 var showTdResult = `# Specification 907 +---------+-------------+----------+----------+---------+ 908 | NAME | DESCRIPTION | TYPE | REQUIRED | DEFAULT | 909 +---------+-------------+----------+----------+---------+ 910 | name | | string | true | | 911 | image | | string | true | | 912 | command | | []string | false | | 913 +---------+-------------+----------+----------+---------+ 914 915 916 `