Skip to main content
版本:v1.7

自定义工作流

提示

在阅读本部分之前,请确保你已经了解 KubeVela 中 工作流节点定义(WorkflowStepDefinition) 的概念且学习掌握了 CUE 的基本知识

本节将以工作流步骤定义的例子展开说明,介绍如何使用 CUE 通过工作流步骤定义WorkflowStepDefinition 来自定义应用部署计划的工作流步骤。

交付一个简单的工作流步骤​

我们可以通过 vela def <def-name> --type workflow-step > <def-name>.cue 来生成一个 workflow-step 类型的 Definition CUE 文件。

我们以一个发送 HTTP 请求的自定义步骤为例,首先初始化这个 Definition 文件:

vela def init request --type workflow-step --desc "Send request to the url" > request.cue

初始化完成后,我们可以在 request.cue 中看到如下内容:

request: {
alias: ""
annotations: {}
attributes: {}
description: "Send request to the url"
labels: {}
type: "workflow-step"
}

template: {
}

template 中是这个工作流步骤的执行逻辑。我们先在 template 中定义 parameter,用于接收用户传入的参数:

template: {
parameter: {
url: string
method: *"GET" | "POST" | "PUT" | "DELETE"
body?: {...}
header?: [string]: string
}
}

CUE 提供了一系列基础内置包,如:regexp, json, strings, math 等。

同时,KubeVela 也默认提供了 vela/op 包,其中包含了一系列内置的工作流 CUE 操作符,如:发送 HTTP 请求,操作 K8s 资源,打印日志等,来帮助你更好地编写工作流步骤。

我们在这引用 KubeVela 内置的 vela/op 包以及 CUE 官方的 encoding/json,使用 op.#HTTPDo 根据用户的参数发送 HTTP 请求,并使用 json.Marshal() 来进行数据类型的转换。

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

request: {
alias: ""
annotations: {}
attributes: {}
description: "Send request to the url"
labels: {}
type: "workflow-step"
}

template: {
http: op.#HTTPDo & {
method: parameter.method
url: parameter.url
request: {
if parameter.body != _|_ {
body: json.Marshal(parameter.body)
}
if parameter.header != _|_ {
header: parameter.header
}
}
}
parameter: {
url: string
method: *"GET" | "POST" | "PUT" | "DELETE"
body?: {...}
header?: [string]: string
}
}

如果 HTTP 请求返回的状态码大于 400,则我们希望这个步骤的状态是失败的。使用 op.#Fail 是步骤的状态变为失败。这样一个发送请求的自定义步骤最终为:

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

request: {
alias: ""
annotations: {}
attributes: {}
description: "Send request to the url"
labels: {}
type: "workflow-step"
}

template: {
http: op.#HTTPDo & {
method: parameter.method
url: parameter.url
request: {
if parameter.body != _|_ {
body: json.Marshal(parameter.body)
}
if parameter.header != _|_ {
header: parameter.header
}
}
}
fail: op.#Steps & {
if http.response.statusCode > 400 {
requestFail: op.#Fail & {
message: "request of \(parameter.url) is fail: \(http.response.statusCode)"
}
}
}
response: json.Unmarshal(http.response.body)
parameter: {
url: string
method: *"GET" | "POST" | "PUT" | "DELETE"
body?: {...}
header?: [string]: string
}
}

使用 vela def apply -f request.cue 将这个 Definition 部署到集群中,接着,我们就可以直接在应用部署计划中使用这个自定义步骤了。

部署如下应用部署计划:工作流的第一步会发送一个 HTTP 请求,得到 KubeVela 仓库的信息;同时,这个步骤会将 KubeVela 仓库的 Star 数作为 Output,下一个步骤将使用这个 Output 作为参数,并将其作为消息内容发送到 Slack 消息中:

提示

有关于参数传递的更多信息,请参考 工作流参数传递。

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: request-http
namespace: default
spec:
components: []
workflow:
steps:
- name: request
type: request
properties:
url: https://api.github.com/repos/kubevela/kubevela
outputs:
- name: stars
valueFrom: |
import "strconv"
"Current star count: " + strconv.FormatInt(response["stargazers_count"], 10)
- name: notification
type: notification
inputs:
- from: stars
parameterKey: slack.message.text
properties:
slack:
url:
value: <your slack url>

自定义健康检查和状态​

如果你希望在工作流步骤中等待一段时间,直到某个条件满足,或者直到某个资源的状态变为 Ready,你可以使用 op.#ConditionalWait。

以等待 Deployment 的状态为例,先使用 op.#Apply 部署一个 Deployment,再使用 op.#ConditionalWait 来等待这个 Deployment 的状态变为 Ready:

import (
"vela/op"
)

"apply-deployment": {
alias: ""
annotations: {}
attributes: {}
description: ""
labels: {}
type: "workflow-step"
}

template: {
output: op.#Apply & {
value: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: {
name: context.stepName
namespace: context.namespace
}
spec: {
selector: matchLabels: wr: context.stepName
template: {
metadata: labels: wr: context.stepName
spec: containers: [{
name: context.stepName
image: parameter.image
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
}]
}
}
}
}
wait: op.#ConditionalWait & {
continue: output.value.status.readyReplicas == 1
}
parameter: {
image: string
cmd?: [...string]
}
}

工作流步骤定义中的 Context 运行时信息​

KubeVela 让你可以在运行时,通过 context 关键字来引用一些信息。

在工作流步骤定义中,你可以使用如下 Context 信息:

Context VariableDescriptionType
context.name应用部署计划的名称string
context.appName应用部署计划的名称string
context.namespace应用部署计划的命名空间string
context.appRevision应用部署计划的版本string
context.stepName当前步骤的名称string
context.stepSessionID当前步骤的 IDstring
context.spanID当前步骤此次执行的 Trace IDstring
context.workflowName应用部署计划 Annotation 中声明的工作流名称string
context.publishVersion应用部署计划 Annotation 中声明的版本string

Kubernetes 中的 WorkflowStepDefinition​

KubeVela 通过 CUE 完全可编程,同时它利用 Kubernetes 作为控制平面并与 YAML 中的 API 保持一致。

因此,CUE Definition 在应用到集群时将被转换为 Kubernetes API。

工作流步骤定义将采用以下 API 格式:

apiVersion: core.oam.dev/v1beta1
kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: <Function description>
spec:
schematic:
cue: # Details of workflow steps defined by CUE language
template: <CUE format template>

更多例子​

你还可以在以下例子中找到更多的工作流步骤定义: