Skip to main content
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.

tip

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

Process Control​

ConditionalWait​

Makes the workflow step wait until the condition is met.

Parameters

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

Example

import "vela/op"

myRead: op.#Read & {
value: {
kind: "Deployment"
apiVersion: "apps/v1"
metadata: name: "test-app"
}
}

wait: op.#ConditionalWait & {
continue: myRead.value.status.phase == "running"
}

Fail​

Make the workflow step failed.

Parameters

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

Example

import "vela/op"

fail: op.#Fail & {
message: "error in the step"
}

Data Control​

Log​

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

#Log: {
// +usage=The data to print in the controller logs
data?: {...} | string
// +usage=The log level of the data
level: *3 | int
// +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
source?: close({
// +usage=Specify the log source url of this step
url: string
}) | close({
// +usage=Specify the log resources of this step
resources?: [...{
// +usage=Specify the name of the resource
name?: string
// +usage=Specify the cluster of the resource
cluster?: string
// +usage=Specify the namespace of the resource
namespace?: string
// +usage=Specify the label selector of the resource
labelSelector?: {...}
}]
})
}

Example

import "vela/op"

myLog: op.#Log & {
data: "my custom log"
resources: [{
labelsSelector: {"test-key": "test-value"}
}]
}

Message​

Write message to the workflow step status.

Parameters

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

Example

import "vela/op"

msg: op.#Message & {
message: "custom message"
}

DoVar​

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

Parameters

#DoVar: {
// +usage=The method to call on the variable
method: *"Get" | "Put"
// +usage=The path to the variable
path: string
// +usage=The value of the variable
value?: _
}

Example

put: op.ws.#DoVar & {
method: "Put"
path: "foo.score"
value: 100
}

// The user can get the data saved above through get.value (100)
get: op.ws.#DoVar & {
method: "Get"
path: "foo.score"
}

Requests​

HTTPDo​

Send HTTP request to the specified URL.

Parameters

#HTTPDo: {
// +usage=The method of HTTP request
method: *"GET" | "POST" | "PUT" | "DELETE"
// +usage=The url to request
url: string
// +usage=The request config
request?: {
// +usage=The timeout of this request
timeout?: string
// +usage=The request body
body?: string
// +usage=The header of the request
header?: [string]: string
// +usage=The trailer of the request
trailer?: [string]: string
// +usage=The rate limiter of the request
ratelimiter?: {
limit: int
period: string
}
}
// +usgae=The tls config of the request
tls_config?: secret: string
// +usage=The response of the request will be filled in this field after the action is executed
response: {
// +usage=The body of the response
body: string
// +usage=The header of the response
header?: [string]: [...string]
// +usage=The trailer of the response
trailer?: [string]: [...string]
// +usage=The status code of the response
statusCode: int
}
}

Example

import "vela/op"

myRequest: op.#HTTPDo & {
method: "POST"
url: "http://my-url.com"
request: {
body: {
"hello": "body"
}
}
}

HTTPGet​

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.

HTTPPost​

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.

HTTPPut​

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.

HTTPDelete​

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.

SendEmail​

Send emails.

Parameters

#SendEmail {
// +usage=The info of the sender
from: {
// +usage=The address of the sender
address: string
// +usage=The alias of the sender
alias?: string
// +usage=The password of the sender
password: string
// +usage=The host of the sender server
host: string
// +usage=The port of the sender server
port: int
}
// +usgae=The email address list of the recievers
to: [...string]
// +usage=The content of the email
content: {
// +usage=The subject of the email
subject: string
// +usage=The body of the email
body: string
}
}

Example

import "vela/op"

myEmail: op.#SendEmail & {
from: {
address: "hello@mail.com"
password: "password"
host: "myhost"
port: 465
}
to: ["world@mail.com", "next@workflow.com"]
content: {
subject: "Hello Vela"
body: "Hello Vela, this is a test email"
}
}

Resource Management​

Apply​

Apply resources in the Kubernetes cluster.

Parameters

#Apply: {
// +usage=The cluster to use
cluster: *"" | string
// +usage=The resource to apply
value: {...}
}

Example

import "vela/op"
myApply: op.#Apply & {
value: {
kind: "Deployment"
apiVersion: "apps/v1"
metadata: name: "test-app"
spec: {
replicas: 2
...
}
}
}

ApplyInParallel​

Apply resources in parallel in the Kubernetes cluster.

Parameters

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

Example

import "vela/op"
myApply: op.#ApplyInParallel & {
value: [{
kind: "Deployment"
apiVersion: "apps/v1"
metadata: name: "test-app"
spec: {
replicas: 2
...
}
}, {
kind: "Deployment"
apiVersion: "apps/v1"
metadata: name: "test-app2"
spec: {
replicas: 2
...
}
}]
}

Read​

Read resources in the Kubernetes cluster.

Parameters

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

Example

import "vela/op"
myRead: op.#Read & {
value: {
kind: "Deployment"
apiVersion: "apps/v1"
metadata: name: "test-app"
}
}

List​

List resources in the Kubernetes cluster.

Parameters

#List: {
// +usage=The cluster to use
cluster: *"" | string
// +usage=The resource to list
resource: {
// +usage=The api version of the resource
apiVersion: string
// +usage=The kind of the resource
kind: string
}
// +usage=The filter to list the resources
filter?: {
// +usage=The namespace to list the resources
namespace?: *"" | string
// +usage=The label selector to filter the resources
matchingLabels?: {...}
}
// +usage=The listed resources will be filled in this field after the action is executed
list?: {...}
...
}

Example

import "vela/op"
myList: op.#List & {
resource: {
kind: "Deployment"
apiVersion: "apps/v1"
}
filter: {
matchingLabels: {
"mylabel": "myvalue"
}
}
}

Delete​

Delete resources in the Kubernetes cluster.

Parameters


#Delete: {
// +usage=The cluster to use
cluster: *"" | string
// +usage=The resource to delete
value: {
// +usage=The api version of the resource
apiVersion: string
// +usage=The kind of the resource
kind: string
// +usage=The metadata of the resource
metadata: {
// +usage=The name of the resource
name?: string
// +usage=The namespace of the resource
namespace: *"default" | string
}
}
// +usage=The filter to delete the resources
filter?: {
// +usage=The namespace to list the resources
namespace?: string
// +usage=The label selector to filter the resources
matchingLabels?: {...}
}
}

Example

import "vela/op"
myDelete: op.#Delete & {
resource: {
kind: "Deployment"
apiVersion: "apps/v1"
metadata: name: "my-app"
}
}

Application Operations​

Load​

Load all the components and its traits in the application.

Parameters

#Load: {
// +usage=If specify `app`, use specified application to load its component resources otherwise use current application
app?: string
// +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
value?: {...}
}

Example

import "vela/op"

// You can use `load.value.[componentName] to refer the component.
load: op.#Load & {}

mycomp: load.value["my-comp"]

ApplyComponent​

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

Parameters

#ApplyComponent: {
// +usage=The cluster to use
cluster: *"" | string
// +usage=The env to use
env: *"" | string
// +usage=The namespace to apply
namespace: *"" | string
// +usage=Whether to wait healthy of the applied component
waitHealthy: *true | bool
// +usage=The value of the component resource
value: {...}
// +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
patch?: {...}
}

Example

import "vela/op"
load: op.#Load & {}

apply: op.#ApplyComponent & {
value: load.value["my-comp"]
}

ApplyApplication​

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

Parameters

#ApplyApplication: {}

Example

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

Special Operations​

Steps​

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

Parameters

#Steps: {}

Example

import "vela/op"

env: "prod"

app: op.#Steps & {
if env == "prod" {
load: op.#Load & {
component: "component-name"
}
apply: op.#Apply & {
value: load.value.workload
}
}
if env != "prod" {
request: op.#HTTPGet & {
url: "http://my-url.com"
}
}
}

Deprecated Operations​

Slack​

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:

import (
"vela/op"
"encoding/json"
)

message: {
"hello": "world"
}

mySlack: op.#HTTPPost & {
url: "slackURL"
request: {
body: json.Marshal(message)
header: "Content-Type": "application/json"
}
}

Parameters

#Slack: {
message: {...}
slackUrl: string
}

Example

import "vela/op"


myMessage: {
"hello": "world"
}

myRequest: op.#Slack & {
message: myMessage
slackUrl: "slackURL"
}

DingTalk​

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

#DingTalk: {
message: {...}
dingUrl: string
}

Example

import "vela/op"


myMessage: {
"hello": "world"
}

myRequest: op.#DingTalk & {
message: myMessage
dingUrl: "dingURL"
}

Lark​

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

#Lark: {
message: {...}
larkUrl: string
}

Example

import "vela/op"


myMessage: {
"hello": "world"
}

myRequest: op.#Lark & {
message: myMessage
larkUrl: "larkURL"
}