kubevela.github.io/docs/platform-engineers/workflow/cue-actions.md

13 KiB

title
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"
}