Version: v1.8

Built-in Workflow Operations

This document introduces the CUE operations that can be used in the workflow step definitions. You need to import the vela/op package to use these operations.

Built-in Workflow Operations - 图1tip

Before reading this section, make sure you understand how to customize workflow and learn the basics of CUE

Makes the workflow step wait until the condition is met.

Parameters

  1. #ConditionalWait: {
  2. // +usage=If continue is false, the step will wait for continue to be true.
  3. continue: bool
  4. // +usage=Optional message that will be shown in workflow step status, note that the message might be override by other actions.
  5. message?: string
  6. }

Example

  1. import "vela/op"
  2. myRead: op.#Read & {
  3. value: {
  4. kind: "Deployment"
  5. apiVersion: "apps/v1"
  6. metadata: name: "test-app"
  7. }
  8. }
  9. wait: op.#ConditionalWait & {
  10. continue: myRead.value.status.phase == "running"
  11. }

Make the workflow step failed.

Parameters

  1. #Fail: {
  2. // +usage=Optional message that will be shown in workflow step status, note that the message might be override by other actions.
  3. message?: string
  4. }

Example

  1. import "vela/op"
  2. fail: op.#Fail & {
  3. message: "error in the step"
  4. }

Output the log or configure the log source for this step. If op.#Log is used in a step definition, then you can use vela workflow logs <name> to view the log for that step.

Parameters

  1. #Log: {
  2. // +usage=The data to print in the controller logs
  3. data?: {...} | string
  4. // +usage=The log level of the data
  5. level: *3 | int
  6. // +usage=The log source of this step. You can specify it from a url or resources. Note that if you set source in multiple op.#Log, only the latest one will work
  7. source?: close({
  8. // +usage=Specify the log source url of this step
  9. url: string
  10. }) | close({
  11. // +usage=Specify the log resources of this step
  12. resources?: [...{
  13. // +usage=Specify the name of the resource
  14. name?: string
  15. // +usage=Specify the cluster of the resource
  16. cluster?: string
  17. // +usage=Specify the namespace of the resource
  18. namespace?: string
  19. // +usage=Specify the label selector of the resource
  20. labelSelector?: {...}
  21. }]
  22. })
  23. }

Example

  1. import "vela/op"
  2. myLog: op.#Log & {
  3. data: "my custom log"
  4. resources: [{
  5. labelsSelector: {"test-key": "test-value"}
  6. }]
  7. }

Write message to the workflow step status.

Parameters

  1. #Message: {
  2. // +usage=Optional message that will be shown in workflow step status, note that the message might be override by other actions.
  3. message?: string
  4. }

Example

  1. import "vela/op"
  2. msg: op.#Message & {
  3. message: "custom message"
  4. }

Used to save or read user-defined data in the context of workflow.

Parameters

  1. #DoVar: {
  2. // +usage=The method to call on the variable
  3. method: *"Get" | "Put"
  4. // +usage=The path to the variable
  5. path: string
  6. // +usage=The value of the variable
  7. value?: _
  8. }

Example

  1. put: op.ws.#DoVar & {
  2. method: "Put"
  3. path: "foo.score"
  4. value: 100
  5. }
  6. // The user can get the data saved above through get.value (100)
  7. get: op.ws.#DoVar & {
  8. method: "Get"
  9. path: "foo.score"
  10. }

Send HTTP request to the specified URL.

Parameters

  1. #HTTPDo: {
  2. // +usage=The method of HTTP request
  3. method: *"GET" | "POST" | "PUT" | "DELETE"
  4. // +usage=The url to request
  5. url: string
  6. // +usage=The request config
  7. request?: {
  8. // +usage=The timeout of this request
  9. timeout?: string
  10. // +usage=The request body
  11. body?: string
  12. // +usage=The header of the request
  13. header?: [string]: string
  14. // +usage=The trailer of the request
  15. trailer?: [string]: string
  16. // +usage=The rate limiter of the request
  17. ratelimiter?: {
  18. limit: int
  19. period: string
  20. }
  21. }
  22. // +usgae=The tls config of the request
  23. tls_config?: secret: string
  24. // +usage=The response of the request will be filled in this field after the action is executed
  25. response: {
  26. // +usage=The body of the response
  27. body: string
  28. // +usage=The header of the response
  29. header?: [string]: [...string]
  30. // +usage=The trailer of the response
  31. trailer?: [string]: [...string]
  32. // +usage=The status code of the response
  33. statusCode: int
  34. }
  35. }

Example

  1. import "vela/op"
  2. myRequest: op.#HTTPDo & {
  3. method: "POST"
  4. url: "http://my-url.com"
  5. request: {
  6. body: {
  7. "hello": "body"
  8. }
  9. }
  10. }

Send HTTP GET request to the specified URL.

Parameters

Same as HTTPDo, but method has been specified as GET.

Example

Please refer the example in HTTPDo.

Send HTTP POST request to the specified URL.

Parameters

Same as HTTPDo, but method has been specified as POST.

Example

Please refer the example in HTTPDo.

Send HTTP PUT request to the specified URL.

Parameters

Same as HTTPDo, but method has been specified as PUT.

Example

Please refer the example in HTTPDo.

Send HTTP DELETE request to the specified URL.

Parameters

Same as HTTPDo, but method has been specified as DELETE.

Example

Please refer the example in HTTPDo.

Send emails.

Parameters

  1. #SendEmail {
  2. // +usage=The info of the sender
  3. from: {
  4. // +usage=The address of the sender
  5. address: string
  6. // +usage=The alias of the sender
  7. alias?: string
  8. // +usage=The password of the sender
  9. password: string
  10. // +usage=The host of the sender server
  11. host: string
  12. // +usage=The port of the sender server
  13. port: int
  14. }
  15. // +usgae=The email address list of the recievers
  16. to: [...string]
  17. // +usage=The content of the email
  18. content: {
  19. // +usage=The subject of the email
  20. subject: string
  21. // +usage=The body of the email
  22. body: string
  23. }
  24. }

Example

  1. import "vela/op"
  2. myEmail: op.#SendEmail & {
  3. from: {
  4. address: "hello@mail.com"
  5. password: "password"
  6. host: "myhost"
  7. port: 465
  8. }
  9. to: ["world@mail.com", "next@workflow.com"]
  10. content: {
  11. subject: "Hello Vela"
  12. body: "Hello Vela, this is a test email"
  13. }
  14. }

Apply resources in the Kubernetes cluster.

Parameters

  1. #Apply: {
  2. // +usage=The cluster to use
  3. cluster: *"" | string
  4. // +usage=The resource to apply
  5. value: {...}
  6. }

Example

  1. import "vela/op"
  2. myApply: op.#Apply & {
  3. value: {
  4. kind: "Deployment"
  5. apiVersion: "apps/v1"
  6. metadata: name: "test-app"
  7. spec: {
  8. replicas: 2
  9. ...
  10. }
  11. }
  12. }

Apply resources in parallel in the Kubernetes cluster.

Parameters

  1. #ApplyInParallel: {
  2. // +usage=The cluster to use
  3. cluster: *"" | string
  4. // +usage=The resources to apply in parallel
  5. value: [...{...}]
  6. }

Example

  1. import "vela/op"
  2. myApply: op.#ApplyInParallel & {
  3. value: [{
  4. kind: "Deployment"
  5. apiVersion: "apps/v1"
  6. metadata: name: "test-app"
  7. spec: {
  8. replicas: 2
  9. ...
  10. }
  11. }, {
  12. kind: "Deployment"
  13. apiVersion: "apps/v1"
  14. metadata: name: "test-app2"
  15. spec: {
  16. replicas: 2
  17. ...
  18. }
  19. }]
  20. }

Read resources in the Kubernetes cluster.

Parameters

  1. #Read: {
  2. // +usage=The cluster to use
  3. cluster: *"" | string
  4. // +usage=The resource to read, this field will be filled with the resource read from the cluster after the action is executed
  5. value?: {...}
  6. ...
  7. }

Example

  1. import "vela/op"
  2. myRead: op.#Read & {
  3. value: {
  4. kind: "Deployment"
  5. apiVersion: "apps/v1"
  6. metadata: name: "test-app"
  7. }
  8. }

List resources in the Kubernetes cluster.

Parameters

  1. #List: {
  2. // +usage=The cluster to use
  3. cluster: *"" | string
  4. // +usage=The resource to list
  5. resource: {
  6. // +usage=The api version of the resource
  7. apiVersion: string
  8. // +usage=The kind of the resource
  9. kind: string
  10. }
  11. // +usage=The filter to list the resources
  12. filter?: {
  13. // +usage=The namespace to list the resources
  14. namespace?: *"" | string
  15. // +usage=The label selector to filter the resources
  16. matchingLabels?: {...}
  17. }
  18. // +usage=The listed resources will be filled in this field after the action is executed
  19. list?: {...}
  20. ...
  21. }

Example

  1. import "vela/op"
  2. myList: op.#List & {
  3. resource: {
  4. kind: "Deployment"
  5. apiVersion: "apps/v1"
  6. }
  7. filter: {
  8. matchingLabels: {
  9. "mylabel": "myvalue"
  10. }
  11. }
  12. }

Delete resources in the Kubernetes cluster.

Parameters

  1. #Delete: {
  2. // +usage=The cluster to use
  3. cluster: *"" | string
  4. // +usage=The resource to delete
  5. value: {
  6. // +usage=The api version of the resource
  7. apiVersion: string
  8. // +usage=The kind of the resource
  9. kind: string
  10. // +usage=The metadata of the resource
  11. metadata: {
  12. // +usage=The name of the resource
  13. name?: string
  14. // +usage=The namespace of the resource
  15. namespace: *"default" | string
  16. }
  17. }
  18. // +usage=The filter to delete the resources
  19. filter?: {
  20. // +usage=The namespace to list the resources
  21. namespace?: string
  22. // +usage=The label selector to filter the resources
  23. matchingLabels?: {...}
  24. }
  25. }

Example

  1. import "vela/op"
  2. myDelete: op.#Delete & {
  3. resource: {
  4. kind: "Deployment"
  5. apiVersion: "apps/v1"
  6. metadata: name: "my-app"
  7. }
  8. }

Load all the components and its traits in the application.

Parameters

  1. #Load: {
  2. // +usage=If specify `app`, use specified application to load its component resources otherwise use current application
  3. app?: string
  4. // +usage=The value of the components will be filled in this field after the action is executed, you can use value[componentName] to refer a specified component
  5. value?: {...}
  6. }

Example

  1. import "vela/op"
  2. // You can use `load.value.[componentName] to refer the component.
  3. load: op.#Load & {}
  4. mycomp: load.value["my-comp"]

Create or update resources corresponding to the component in Kubernetes cluster. Note that need to use Load first to apply the resources.

Parameters

  1. #ApplyComponent: {
  2. // +usage=The cluster to use
  3. cluster: *"" | string
  4. // +usage=The env to use
  5. env: *"" | string
  6. // +usage=The namespace to apply
  7. namespace: *"" | string
  8. // +usage=Whether to wait healthy of the applied component
  9. waitHealthy: *true | bool
  10. // +usage=The value of the component resource
  11. value: {...}
  12. // +usage=The patcher that will be applied to the resource, you can define the strategy of list merge through comments. Reference doc here: https://kubevela.io/docs/platform-engineers/traits/patch-trait#patch-in-workflow-step
  13. patch?: {...}
  14. }

Example

  1. import "vela/op"
  2. load: op.#Load & {}
  3. apply: op.#ApplyComponent & {
  4. value: load.value["my-comp"]
  5. }

Create or update resources corresponding to the application in Kubernetes cluster.

Parameters

  1. #ApplyApplication: {}

Example

  1. import "vela/op"
  2. apply: op.#ApplyApplication & {}

A combination of a set of operations that can be used to implement complex operation logic.

Parameters

  1. #Steps: {}

Example

  1. import "vela/op"
  2. env: "prod"
  3. app: op.#Steps & {
  4. if env == "prod" {
  5. load: op.#Load & {
  6. component: "component-name"
  7. }
  8. apply: op.#Apply & {
  9. value: load.value.workload
  10. }
  11. }
  12. if env != "prod" {
  13. request: op.#HTTPGet & {
  14. url: "http://my-url.com"
  15. }
  16. }
  17. }

Send a request to the specified Slack URL. #Slack is actually a secondary wrapper for #HTTPPost, we will deprecate this operation in the next version. You can use #HTTPPost instead, like:

  1. import (
  2. "vela/op"
  3. "encoding/json"
  4. )
  5. message: {
  6. "hello": "world"
  7. }
  8. mySlack: op.#HTTPPost & {
  9. url: "slackURL"
  10. request: {
  11. body: json.Marshal(message)
  12. header: "Content-Type": "application/json"
  13. }
  14. }

Parameters

  1. #Slack: {
  2. message: {...}
  3. slackUrl: string
  4. }

Example

  1. import "vela/op"
  2. myMessage: {
  3. "hello": "world"
  4. }
  5. myRequest: op.#Slack & {
  6. message: myMessage
  7. slackUrl: "slackURL"
  8. }

Send a request to the specified DingTalk URL. #DingTalk is actually a secondary wrapper of #HTTPPost, we will deprecate this operation in the next version. You can use #HTTPPost instead, please refer to the example in Slack action.

Parameters

  1. #DingTalk: {
  2. message: {...}
  3. dingUrl: string
  4. }

Example

  1. import "vela/op"
  2. myMessage: {
  3. "hello": "world"
  4. }
  5. myRequest: op.#DingTalk & {
  6. message: myMessage
  7. dingUrl: "dingURL"
  8. }

Send a request to the specified Lark URL. #Lark is actually a secondary wrapper of #HTTPPost, we will deprecate this operation in the next version. You can use #HTTPPost instead, please refer to the example in Slack action.

Parameters

  1. #Lark: {
  2. message: {...}
  3. larkUrl: string
  4. }

Example

  1. import "vela/op"
  2. myMessage: {
  3. "hello": "world"
  4. }
  5. myRequest: op.#Lark & {
  6. message: myMessage
  7. larkUrl: "larkURL"
  8. }

Last updated on May 6, 2023 by Tianxin Dong