From d20fd07c8b8002f02584011c0e43455538a554cb Mon Sep 17 00:00:00 2001 From: FogDong Date: Mon, 31 Oct 2022 16:08:53 +0800 Subject: [PATCH 1/2] Feat: add example of multiple apps and fix read me Signed-off-by: FogDong --- README.md | 100 +++--------------- examples/definitions/apply-app.cue | 54 ++++++++++ examples/definitions/read-app.cue | 40 +++++++ examples/multiple-apps.md | 85 +++++++++++++++ examples/request-and-notify.md | 54 ++++++++++ examples/run-with-template.md | 40 +++++++ {static => examples/static}/slack-fail.png | Bin {static => examples/static}/slack-success.png | Bin examples/workflow-run/apply-applications.yaml | 62 +++++++++++ 9 files changed, 347 insertions(+), 88 deletions(-) create mode 100644 examples/definitions/apply-app.cue create mode 100644 examples/definitions/read-app.cue create mode 100644 examples/multiple-apps.md create mode 100644 examples/request-and-notify.md create mode 100644 examples/run-with-template.md rename {static => examples/static}/slack-fail.png (100%) rename {static => examples/static}/slack-success.png (100%) create mode 100644 examples/workflow-run/apply-applications.yaml diff --git a/README.md b/README.md index 6676af9..3c70b3d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -# KubeVela Workflow +

KubeVela Workflow

+ [![Go Report Card](https://goreportcard.com/badge/github.com/kubevela/workflow)](https://goreportcard.com/report/github.com/kubevela/workflow) [![codecov](https://codecov.io/gh/kubevela/workflow/branch/main/graph/badge.svg)](https://codecov.io/gh/kubevela/workflow) [![LICENSE](https://img.shields.io/github/license/kubevela/workflow.svg?style=flat-square)](/LICENSE) @@ -35,10 +36,12 @@ During the evolution of the [OAM](https://oam.dev/) and [KubeVela project](https ### As a standalone workflow engine -- Glue and orchestrate operations, such as restart application, scale up/down, read-notify processes. -- Orchestrate delivery process without day-2 management, just deploy. The workflow will not keep reconciliation, no garbage collection when workflow object deleted or updated. The most common use case is to initialize your infrastructure for some environment. +Unlike the workflow in the KubeVela Application, this workflow will only be executed once, and will **not keep reconciliation**, **no garbage collection** when the workflow object deleted or updated. You can use it for **one-time** operations like: + +- Glue and orchestrate operations, such as control the deploy process of multiple resources(e.g. your Applications), scale up/down, read-notify processes, or the sequence between http requests. +- Orchestrate delivery process without day-2 management, just deploy. The most common use case is to initialize your infrastructure for some environment. -Please refer to the [installation](#installation) and [quick start](#quick-start) sections. +Please refer to the [installation](#installation) and [quick start](#quick-start) sections for more. ### As an SDK @@ -82,95 +85,16 @@ You can either run a WorkflowRun directly or from a Workflow Template. ### Run a WorkflowRun directly -```yaml -apiVersion: core.oam.dev/v1alpha1 -kind: WorkflowRun -metadata: - name: request-http - namespace: default -spec: - workflowSpec: - steps: - - name: request - type: request - properties: - url: https://api.github.com/repos/kubevela/workflow - 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: - - name: failed-notification - type: notification - if: status.request.failed - properties: - slack: - url: - value: - message: - text: "Failed to request github" - -``` - -Above workflow will send a request to the GitHub API and get the star count of the workflow repository as an output, then use the output as a message to send a notification to your Slack channel. - -Apply the WorkflowRun, you can get a message from Slack like: +Please refer to the following examples: -![slack-success](./static/slack-success.png) - -If you change the `url` to an invalid one, you will get a failed notification: - -![slack-failed](./static/slack-fail.png) +- [Control the delivery process of multiple resources(e.g. your Applications)](./examples/multiple-apps) +- [Request a specified URL and then use the response as a message to notify](./examples/request-and-notify) ### Run a WorkflowRun from a Workflow Template -You can also create a Workflow Template and run it with a WorkflowRun with different context. - -Workflow Template: - -```yaml -apiVersion: core.oam.dev/v1alpha1 -kind: Workflow -metadata: - name: deploy-template - namespace: default -steps: - - name: apply - type: apply-deployment - if: context.env == "dev" - properties: - image: nginx - - name: apply-test - type: apply-deployment - if: context.env == "test" - properties: - image: crccheck/hello-world -``` - -WorkflowRun: - -```yaml -apiVersion: core.oam.dev/v1alpha1 -kind: WorkflowRun -metadata: - name: deploy-run - namespace: default -spec: - context: - env: dev - workflowRef: deploy-template -``` +Please refer to the following examples: -If you apply the WorkflowRun with `dev` in `context.env`, then you'll get a deployment with `nginx` image. If you change the `env` to `test`, you'll get a deployment with `crccheck/hello-world` image. +- [Run the Workflow Template with different context to control the process](./examples/run-with-template)

Features

diff --git a/examples/definitions/apply-app.cue b/examples/definitions/apply-app.cue new file mode 100644 index 0000000..32e22e7 --- /dev/null +++ b/examples/definitions/apply-app.cue @@ -0,0 +1,54 @@ +import ( + "vela/op" + "encoding/yaml" +) + +"apply-app": { + alias: "" + annotations: {} + attributes: {} + description: "Apply application from data or ref to the cluster" + labels: {} + type: "workflow-step" +} + +template: { + app: op.#Steps & { + if parameter.data != _|_ { + apply: op.#Apply & { + value: parameter.data + } + } + if parameter.ref != _|_ { + if parameter.ref.type == "configMap" { + cm: op.#Read & { + value: { + apiVersion: "v1" + kind: "ConfigMap" + metadata: { + name: parameter.ref.name + namespace: parameter.ref.namespace + } + } + } + template: cm.value.data[parameter.ref.key] + apply: op.#Apply & { + value: yaml.Unmarshal(template) + } + } + } + } + wait: op.#ConditionalWait & { + continue: app.apply.value.status.status == "running" + } + parameter: close({ + data?: {...} + }) | close({ + ref?: { + name: string + namespace: *context.namespace | string + type: *"configMap" | string + key: *"application" | string + } + }) +} diff --git a/examples/definitions/read-app.cue b/examples/definitions/read-app.cue new file mode 100644 index 0000000..9d3bd73 --- /dev/null +++ b/examples/definitions/read-app.cue @@ -0,0 +1,40 @@ +import ( + "vela/op" + "encoding/yaml" + "strings" +) + +"read-app": { + alias: "" + annotations: {} + attributes: {} + description: "Read application from the cluster" + labels: {} + type: "workflow-step" +} + +template: { + read: op.#Read & { + value: { + apiVersion: "core.oam.dev/v1beta1" + kind: "Application" + metadata: { + name: parameter.name + namespace: parameter.namespace + } + } + } + message: op.#Steps & { + if read.err != _|_ { + if strings.Contains(read.err, "not found") { + msg: op.#Message & { + message: "Application not found" + } + } + } + } + parameter: { + name: string + namespace: *context.namespace | string + } +} diff --git a/examples/multiple-apps.md b/examples/multiple-apps.md new file mode 100644 index 0000000..b68e340 --- /dev/null +++ b/examples/multiple-apps.md @@ -0,0 +1,85 @@ +# Control the delivery process of multiple applications + +> Note: You need to install the definitions in the [example directory](https://github.com/kubevela/workflow/tree/main/examples/definitions) first to run the example. + +Apply the following workflow to control the delivery process of multiple applications: + +```yaml +apiVersion: core.oam.dev/v1alpha1 +kind: WorkflowRun +metadata: + name: apply-applications + namespace: default + annotations: + workflowrun.oam.dev/debug: "true" +spec: + workflowSpec: + steps: + - name: check-app-exist + type: read-app + properties: + name: webservice-app + - name: apply-app1 + type: apply-app + if: status["check-app-exist"].message == "Application not found" + properties: + data: + apiVersion: core.oam.dev/v1beta1 + kind: Application + metadata: + name: webservice-app + spec: + components: + - name: express-server + type: webservice + properties: + image: crccheck/hello-world + ports: + - port: 8000 + - name: suspend + type: suspend + timeout: 24h + - name: apply-app2 + type: apply-app + properties: + ref: + name: my-app + key: application + type: configMap +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-app + namespace: default +data: + application: | + apiVersion: core.oam.dev/v1beta1 + kind: Application + metadata: + name: webservice-app2 + spec: + components: + - name: express-server2 + type: webservice + properties: + image: crccheck/hello-world + ports: + - port: 8000 +``` + +Above workflow will first try to read the Application called `webservice-app` from the cluster, if the Application is not found, this step's status message will be `Application not found`. The second step will deploy the `webservice-app` Application if `webservice-app` is not exist in the cluster. After that, the `suspend` step will suspend the delivery process for manual approve. + +``` +$ kubectl get wr +NAME PHASE AGE +apply-applications suspending 2s +``` + +You can use `vela workflow resume` to resume this workflow, note that if the workflow has not been resumed in 24 hours, the workflow will failed of timeout: + +``` +vela workflow resume apply-applications +``` + +After the workflow is resumed, it will deploy an another Application from the data in ConfigMap with key `application`. diff --git a/examples/request-and-notify.md b/examples/request-and-notify.md new file mode 100644 index 0000000..50f116c --- /dev/null +++ b/examples/request-and-notify.md @@ -0,0 +1,54 @@ +# Use Workflow for request and notify + +> Note: You need to install the [notification step definition](https://github.com/kubevela/kubevela/blob/master/vela-templates/definitions/internal/workflowstep/notification.cue) and definitions in the [example directory](https://github.com/kubevela/workflow/tree/main/examples/definitions) first to run the example. + +Apply the following workflow for request a specified URL first and then use the response as a message to your slack channel. + +```yaml +apiVersion: core.oam.dev/v1alpha1 +kind: WorkflowRun +metadata: + name: request-http + namespace: default +spec: + workflowSpec: + steps: + - name: request + type: request + properties: + url: https://api.github.com/repos/kubevela/workflow + 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: + - name: failed-notification + type: notification + if: status.request.failed + properties: + slack: + url: + value: + message: + text: "Failed to request github" + +``` + +Above workflow will send a request to the GitHub API and get the star count of the workflow repository as an output, then use the output as a message to send a notification to your Slack channel. + +Apply the WorkflowRun, you can get a message from Slack like: + +![slack-success](./static/slack-success.png) + +If you change the `url` to an invalid one, you will get a failed notification: + +![slack-failed](./static/slack-fail.png) \ No newline at end of file diff --git a/examples/run-with-template.md b/examples/run-with-template.md new file mode 100644 index 0000000..cd6f54b --- /dev/null +++ b/examples/run-with-template.md @@ -0,0 +1,40 @@ +# Run your workflow with template + +You can also create a Workflow Template and run it with a WorkflowRun with different context. + +Apply the following Workflow Template first: + +```yaml +apiVersion: core.oam.dev/v1alpha1 +kind: Workflow +metadata: + name: deploy-template + namespace: default +steps: + - name: apply + type: apply-deployment + if: context.env == "dev" + properties: + image: nginx + - name: apply-test + type: apply-deployment + if: context.env == "test" + properties: + image: crccheck/hello-world +``` + +Apply the following WorkflowRun: + +```yaml +apiVersion: core.oam.dev/v1alpha1 +kind: WorkflowRun +metadata: + name: deploy-run + namespace: default +spec: + context: + env: dev + workflowRef: deploy-template +``` + +If you apply the WorkflowRun with `dev` in `context.env`, then you'll get a deployment with `nginx` image. If you change the `env` to `test`, you'll get a deployment with `crccheck/hello-world` image. \ No newline at end of file diff --git a/static/slack-fail.png b/examples/static/slack-fail.png similarity index 100% rename from static/slack-fail.png rename to examples/static/slack-fail.png diff --git a/static/slack-success.png b/examples/static/slack-success.png similarity index 100% rename from static/slack-success.png rename to examples/static/slack-success.png diff --git a/examples/workflow-run/apply-applications.yaml b/examples/workflow-run/apply-applications.yaml new file mode 100644 index 0000000..eedc1cd --- /dev/null +++ b/examples/workflow-run/apply-applications.yaml @@ -0,0 +1,62 @@ +apiVersion: core.oam.dev/v1alpha1 +kind: WorkflowRun +metadata: + name: apply-applications + namespace: default + annotations: + workflowrun.oam.dev/debug: "true" +spec: + workflowSpec: + steps: + - name: check-app-exist + type: read-app + properties: + name: webservice-app + - name: apply-app1 + type: apply-app + if: status["check-app-exist"].message == "Application not found" + properties: + data: + apiVersion: core.oam.dev/v1beta1 + kind: Application + metadata: + name: webservice-app + spec: + components: + - name: express-server + type: webservice + properties: + image: crccheck/hello-world + ports: + - port: 8000 + - name: suspend + type: suspend + timeout: 24h + - name: apply-app2 + type: apply-app + properties: + ref: + name: my-app + key: application + type: configMap +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: my-app + namespace: default +data: + application: | + apiVersion: core.oam.dev/v1beta1 + kind: Application + metadata: + name: webservice-app2 + spec: + components: + - name: express-server2 + type: webservice + properties: + image: crccheck/hello-world + ports: + - port: 8000 + \ No newline at end of file From 6a5c9d7b62fc33fb17dafa1ff9b294c1d909759a Mon Sep 17 00:00:00 2001 From: FogDong Date: Tue, 1 Nov 2022 12:02:45 +0800 Subject: [PATCH 2/2] fix note Signed-off-by: FogDong --- README.md | 10 +++-- examples/definitions/apply-app.cue | 54 ----------------------- examples/definitions/apply-deployment.cue | 45 ------------------- examples/definitions/read-app.cue | 40 ----------------- examples/definitions/request.cue | 42 ------------------ examples/multiple-apps.md | 4 +- examples/request-and-notify.md | 4 +- examples/run-with-template.md | 3 ++ 8 files changed, 15 insertions(+), 187 deletions(-) delete mode 100644 examples/definitions/apply-app.cue delete mode 100644 examples/definitions/apply-deployment.cue delete mode 100644 examples/definitions/read-app.cue delete mode 100644 examples/definitions/request.cue diff --git a/README.md b/README.md index 3c70b3d..13221c3 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ You just need to initialize a workflow instance and generate all the task runner ### Install Workflow -You can install workflow with Helm: +#### Helm ```shell helm repo add kubevela https://kubevela.github.io/charts @@ -61,6 +61,8 @@ helm repo update helm install --create-namespace -n vela-system vela-workflow kubevela/vela-workflow ``` +#### KubeVela Addon + If you have installed KubeVela, you can install Workflow with the KubeVela Addon: ```shell @@ -73,7 +75,9 @@ Please checkout: [Install Vela CLI](https://kubevela.io/docs/installation/kubern ### Install built-in steps in KubeVela(Optional) -Use `vela def apply ` to install built-in steps in [KubeVela](https://github.com/kubevela/kubevela/tree/master/vela-templates/definitions/internal/workflowstep). +Use `vela def apply ` to install built-in step definitions in [KubeVela](https://github.com/kubevela/kubevela/tree/master/vela-templates/definitions/internal/workflowstep) and [Workflow Addon](https://github.com/kubevela/catalog/tree/master/addons/vela-workflow/definitions). + +> Note that if you installed Workflow using KubeVela Addon, then the definitions in the addon will be installed automatically. Checkout this [doc](https://kubevela.io/docs/end-user/workflow/built-in-workflow-defs) for more details. @@ -81,8 +85,6 @@ Checkout this [doc](https://kubevela.io/docs/end-user/workflow/built-in-workflow You can either run a WorkflowRun directly or from a Workflow Template. -> Note: You need to install the [notification step definition](https://github.com/kubevela/kubevela/blob/master/vela-templates/definitions/internal/workflowstep/notification.cue) and definitions in the [example directory](https://github.com/kubevela/workflow/tree/main/examples/definitions) first to run the example. - ### Run a WorkflowRun directly Please refer to the following examples: diff --git a/examples/definitions/apply-app.cue b/examples/definitions/apply-app.cue deleted file mode 100644 index 32e22e7..0000000 --- a/examples/definitions/apply-app.cue +++ /dev/null @@ -1,54 +0,0 @@ -import ( - "vela/op" - "encoding/yaml" -) - -"apply-app": { - alias: "" - annotations: {} - attributes: {} - description: "Apply application from data or ref to the cluster" - labels: {} - type: "workflow-step" -} - -template: { - app: op.#Steps & { - if parameter.data != _|_ { - apply: op.#Apply & { - value: parameter.data - } - } - if parameter.ref != _|_ { - if parameter.ref.type == "configMap" { - cm: op.#Read & { - value: { - apiVersion: "v1" - kind: "ConfigMap" - metadata: { - name: parameter.ref.name - namespace: parameter.ref.namespace - } - } - } - template: cm.value.data[parameter.ref.key] - apply: op.#Apply & { - value: yaml.Unmarshal(template) - } - } - } - } - wait: op.#ConditionalWait & { - continue: app.apply.value.status.status == "running" - } - parameter: close({ - data?: {...} - }) | close({ - ref?: { - name: string - namespace: *context.namespace | string - type: *"configMap" | string - key: *"application" | string - } - }) -} diff --git a/examples/definitions/apply-deployment.cue b/examples/definitions/apply-deployment.cue deleted file mode 100644 index 952c3da..0000000 --- a/examples/definitions/apply-deployment.cue +++ /dev/null @@ -1,45 +0,0 @@ -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] - } -} diff --git a/examples/definitions/read-app.cue b/examples/definitions/read-app.cue deleted file mode 100644 index 9d3bd73..0000000 --- a/examples/definitions/read-app.cue +++ /dev/null @@ -1,40 +0,0 @@ -import ( - "vela/op" - "encoding/yaml" - "strings" -) - -"read-app": { - alias: "" - annotations: {} - attributes: {} - description: "Read application from the cluster" - labels: {} - type: "workflow-step" -} - -template: { - read: op.#Read & { - value: { - apiVersion: "core.oam.dev/v1beta1" - kind: "Application" - metadata: { - name: parameter.name - namespace: parameter.namespace - } - } - } - message: op.#Steps & { - if read.err != _|_ { - if strings.Contains(read.err, "not found") { - msg: op.#Message & { - message: "Application not found" - } - } - } - } - parameter: { - name: string - namespace: *context.namespace | string - } -} diff --git a/examples/definitions/request.cue b/examples/definitions/request.cue deleted file mode 100644 index ae2e966..0000000 --- a/examples/definitions/request.cue +++ /dev/null @@ -1,42 +0,0 @@ -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 - } -} diff --git a/examples/multiple-apps.md b/examples/multiple-apps.md index b68e340..b02c9b5 100644 --- a/examples/multiple-apps.md +++ b/examples/multiple-apps.md @@ -1,6 +1,8 @@ # Control the delivery process of multiple applications -> Note: You need to install the definitions in the [example directory](https://github.com/kubevela/workflow/tree/main/examples/definitions) first to run the example. +> Note: The example uses following definitions, please use `vela def apply -f ` to install them first. +> - [Definition `read-app`](https://github.com/kubevela/catalog/blob/master/addons/vela-workflow/definitions/read-app.cue) +> - [Definition `apply-app`](https://github.com/kubevela/catalog/blob/master/addons/vela-workflow/definitions/apply-app.cue) Apply the following workflow to control the delivery process of multiple applications: diff --git a/examples/request-and-notify.md b/examples/request-and-notify.md index 50f116c..28f767a 100644 --- a/examples/request-and-notify.md +++ b/examples/request-and-notify.md @@ -1,6 +1,8 @@ # Use Workflow for request and notify -> Note: You need to install the [notification step definition](https://github.com/kubevela/kubevela/blob/master/vela-templates/definitions/internal/workflowstep/notification.cue) and definitions in the [example directory](https://github.com/kubevela/workflow/tree/main/examples/definitions) first to run the example. +> Note: The example uses following definitions, please use `vela def apply -f ` to install them first. +> - [Definition `request`](https://github.com/kubevela/catalog/blob/master/addons/vela-workflow/definitions/request.cue) +> - [Definition `notification`](https://github.com/kubevela/kubevela/blob/master/vela-templates/definitions/internal/workflowstep/notification.cue) Apply the following workflow for request a specified URL first and then use the response as a message to your slack channel. diff --git a/examples/run-with-template.md b/examples/run-with-template.md index cd6f54b..f43cd69 100644 --- a/examples/run-with-template.md +++ b/examples/run-with-template.md @@ -1,5 +1,8 @@ # Run your workflow with template +> Note: The example uses following definitions, please use `vela def apply -f ` to install them first. +> - [Definition `apply-deployment`](https://github.com/kubevela/catalog/blob/master/addons/vela-workflow/definitions/apply-deployment.cue) + You can also create a Workflow Template and run it with a WorkflowRun with different context. Apply the following Workflow Template first: