Skip to content

Commit 2144c89

Browse files
committed
feat: add builtin providers and fix helm
Signed-off-by: FogDong <[email protected]>
1 parent 9d55737 commit 2144c89

File tree

10 files changed

+600
-10
lines changed

10 files changed

+600
-10
lines changed

charts/vela-workflow/templates/workflow-controller.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ spec:
142142
- "--feature-gates=EnableSuspendOnFailure={{- .Values.workflow.enableSuspendOnFailure | toString -}}"
143143
- "--feature-gates=EnableBackupWorkflowRecord={{- .Values.backup.enabled | toString -}}"
144144
- "--group-by-label={{ .Values.workflow.groupByLabel }}"
145+
- "--enable-external-package-for-default-compiler={{- .Values.workflow.enableExternalPackageForDefaultCompiler | toString -}}"
146+
- "--enable-external-package-watch-for-default-compiler={{- .Values.workflow.enableExternalPackageWatchForDefaultCompiler | toString -}}"
145147
{{ if .Values.backup.enable }}
146148
- "--backup-strategy={{ .Values.backup.strategy }}"
147149
- "--backup-ignore-strategy={{ .Values.backup.ignoreStrategy }}"

charts/vela-workflow/values.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ workflow:
2525
enableSuspendOnFailure: false
2626
enablePatchStatusAtOnce: false
2727
enableWatchEventListener: false
28+
enableExternalPackageForDefaultCompiler: true
29+
enableExternalPackageWatchForDefaultCompiler: fasle
2830
backoff:
2931
maxTime:
3032
waitState: 60

cmd/main.go

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import (
5555
"github.com/kubevela/workflow/pkg/common"
5656
"github.com/kubevela/workflow/pkg/features"
5757
"github.com/kubevela/workflow/pkg/monitor/watcher"
58+
"github.com/kubevela/workflow/pkg/providers"
5859
"github.com/kubevela/workflow/pkg/types"
5960
"github.com/kubevela/workflow/pkg/utils"
6061
"github.com/kubevela/workflow/pkg/webhook"
@@ -122,6 +123,8 @@ func main() {
122123
flag.BoolVar(&backupCleanOnBackup, "backup-clean-on-backup", false, "Set the auto clean for backup workflow records, default is false")
123124
flag.StringVar(&backupConfigSecretName, "backup-config-secret-name", "backup-config", "Set the secret name for backup workflow configs, default is backup-config")
124125
flag.StringVar(&backupConfigSecretNamespace, "backup-config-secret-namespace", "vela-system", "Set the secret namespace for backup workflow configs, default is backup-config")
126+
flag.BoolVar(&providers.EnableExternalPackageForDefaultCompiler, "enable-external-package-for-default-compiler", true, "Enable external package for default compiler")
127+
flag.BoolVar(&providers.EnableExternalPackageWatchForDefaultCompiler, "enable-external-package-watch-for-default-compiler", false, "Enable external package watch for default compiler")
125128
multicluster.AddClusterGatewayClientFlags(flag.CommandLine)
126129
feature.DefaultMutableFeatureGate.AddFlag(flag.CommandLine)
127130
sharding.AddControllerFlags(flag.CommandLine)

controllers/testdata/multi-suspend.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ spec:
99
cue:
1010
template: |
1111
import (
12-
"vela/op"
12+
"vela/builtin"
1313
)
14-
suspend1: op.#Suspend & {}
15-
suspend2: op.#Suspend & {}
14+
suspend1: builtin.#Suspend & {}
15+
suspend2: builtin.#Suspend & {}

controllers/testdata/suspend-and-deploy.yaml

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ spec:
1010
template: |
1111
import (
1212
"vela/kube"
13-
"vela/op"
13+
"vela/builtin"
1414
)
1515
16-
suspend: op.#Suspend & {duration: "1s"}
16+
suspend: builtin.#Suspend & {$params: duration: "1s"}
1717
output: kube.#Apply & {
1818
$params: {
1919
cluster: parameter.cluster
@@ -41,8 +41,8 @@ spec:
4141
}
4242
}
4343
}
44-
wait: op.#ConditionalWait & {
45-
continue: output.$returns.value.status.readyReplicas == parameter.replicas
44+
wait: builtin.#ConditionalWait & {
45+
$params: continue: output.$returns.value.status.readyReplicas == parameter.replicas
4646
}
4747
parameter: {
4848
image: string

controllers/testdata/test-apply.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ spec:
99
template: |
1010
import (
1111
"vela/kube"
12-
"vela/op"
12+
"vela/builtin"
1313
)
1414
1515
output: kube.#Apply & {
@@ -41,9 +41,9 @@ spec:
4141
}
4242
}
4343
}
44-
wait: op.#ConditionalWait & {
44+
wait: builtin.#ConditionalWait & {
4545
if len(output.$returns.value.status) > 0 if output.$returns.value.status.readyReplicas == 1 {
46-
continue: true
46+
$params: continue: true
4747
}
4848
}
4949
parameter: {

pkg/providers/builtin/workspace.cue

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// workspace.cue
2+
3+
#DoVar: {
4+
#do: "var"
5+
#provider: "builtin"
6+
7+
$params: {
8+
// +usage=The method to call on the variable
9+
method: *"Get" | "Put"
10+
// +usage=The path to the variable
11+
path: string
12+
// +usage=The value of the variable
13+
value?: _
14+
}
15+
16+
$returns?: {
17+
// +usage=The value of the variable
18+
value: _
19+
}
20+
}
21+
22+
#ConditionalWait: {
23+
#do: "wait"
24+
#provider: "builtin"
25+
26+
$params: {
27+
// +usage=If continue is false, the step will wait for continue to be true.
28+
continue: *false | bool
29+
// +usage=Optional message that will be shown in workflow step status, note that the message might be override by other actions.
30+
message?: string
31+
}
32+
}
33+
34+
#Suspend: {
35+
#do: "suspend"
36+
#provider: "builtin"
37+
38+
$params: {
39+
// +usage=Specify the wait duration time to resume automaticlly such as "30s", "1min" or "2m15s"
40+
duration?: string
41+
// +usage=Optional message that will be shown in workflow step status, note that the message might be override by other actions.
42+
message?: string
43+
}
44+
}
45+
46+
#Break: {
47+
#do: "break"
48+
#provider: "builtin"
49+
50+
$params: {
51+
// +usage=Optional message that will be shown in workflow step status, note that the message might be override by other actions.
52+
message?: string
53+
}
54+
}
55+
56+
#Fail: {
57+
#do: "fail"
58+
#provider: "builtin"
59+
60+
$params: {
61+
// +usage=Optional message that will be shown in workflow step status, note that the message might be override by other actions.
62+
message?: string
63+
}
64+
}
65+
66+
#Message: {
67+
#do: "message"
68+
#provider: "builtin"
69+
70+
$params: {
71+
// +usage=Optional message that will be shown in workflow step status, note that the message might be override by other actions.
72+
message?: string
73+
}
74+
}
75+
76+
#Steps: {
77+
...
78+
}
79+

pkg/providers/builtin/workspace.go

+214
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/*
2+
Copyright 2022 The KubeVela Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package builtin
18+
19+
import (
20+
"context"
21+
_ "embed"
22+
"encoding/json"
23+
"fmt"
24+
"strings"
25+
"time"
26+
27+
"cuelang.org/go/cue/cuecontext"
28+
29+
cuexruntime "github.com/kubevela/pkg/cue/cuex/runtime"
30+
31+
"github.com/kubevela/workflow/api/v1alpha1"
32+
"github.com/kubevela/workflow/pkg/cue/model"
33+
"github.com/kubevela/workflow/pkg/errors"
34+
providertypes "github.com/kubevela/workflow/pkg/providers/types"
35+
)
36+
37+
const (
38+
// ProviderName is provider name.
39+
ProviderName = "builtin"
40+
// ResumeTimeStamp is resume time stamp.
41+
ResumeTimeStamp = "resumeTimeStamp"
42+
// SuspendTimeStamp is suspend time stamp.
43+
SuspendTimeStamp = "suspendTimeStamp"
44+
)
45+
46+
// VarVars .
47+
type VarVars struct {
48+
Method string `json:"method"`
49+
Path string `json:"path"`
50+
Value any `json:"value"`
51+
}
52+
53+
// VarReturnVars
54+
type VarReturnVars struct {
55+
Value any `json:"value"`
56+
}
57+
58+
type VarReturns = providertypes.Returns[VarReturnVars]
59+
60+
// VarParams .
61+
type VarParams = providertypes.Params[VarVars]
62+
63+
// DoVar get & put variable from context.
64+
func DoVar(_ context.Context, params *VarParams) (*VarReturns, error) {
65+
wfCtx := params.RuntimeParams.WorkflowContext
66+
path := params.Params.Path
67+
68+
switch params.Params.Method {
69+
case "Get":
70+
value, err := wfCtx.GetVar(strings.Split(path, ".")...)
71+
if err != nil {
72+
return nil, err
73+
}
74+
b, err := value.MarshalJSON()
75+
if err != nil {
76+
return nil, err
77+
}
78+
var v any
79+
if err := json.Unmarshal(b, &v); err != nil {
80+
return nil, err
81+
}
82+
return &VarReturns{
83+
Returns: VarReturnVars{
84+
Value: v,
85+
},
86+
}, nil
87+
case "Put":
88+
b, err := json.Marshal(params.Params.Value)
89+
if err != nil {
90+
return nil, err
91+
}
92+
if err := wfCtx.SetVar(cuecontext.New().CompileBytes(b), strings.Split(path, ".")...); err != nil {
93+
return nil, err
94+
}
95+
return nil, nil
96+
}
97+
return nil, nil
98+
}
99+
100+
// ActionVars .
101+
type ActionVars struct {
102+
Message string `json:"message,omitempty"`
103+
}
104+
105+
// ActionParams .
106+
type ActionParams = providertypes.Params[ActionVars]
107+
108+
// WaitVars .
109+
type WaitVars struct {
110+
Continue bool `json:"continue"`
111+
ActionVars
112+
}
113+
114+
// WaitParams .
115+
type WaitParams = providertypes.Params[WaitVars]
116+
117+
// Wait let workflow wait.
118+
func Wait(_ context.Context, params *WaitParams) (*any, error) {
119+
if params.Params.Continue {
120+
return nil, nil
121+
}
122+
params.Action.Wait(params.Params.Message)
123+
return nil, errors.GenericActionError(errors.ActionWait)
124+
}
125+
126+
// Break let workflow terminate.
127+
func Break(_ context.Context, params *ActionParams) (*any, error) {
128+
params.Action.Terminate(params.Params.Message)
129+
return nil, errors.GenericActionError(errors.ActionTerminate)
130+
}
131+
132+
// Fail let the step fail, its status is failed and reason is Action
133+
func Fail(_ context.Context, params *ActionParams) (*any, error) {
134+
params.Action.Fail(params.Params.Message)
135+
return nil, errors.GenericActionError(errors.ActionTerminate)
136+
}
137+
138+
// SuspendVars .
139+
type SuspendVars struct {
140+
Duration string `json:"duration,omitempty"`
141+
ActionVars
142+
}
143+
144+
// SuspendParams .
145+
type SuspendParams = providertypes.Params[SuspendVars]
146+
147+
// Suspend let the step suspend, its status is suspending and reason is Suspend
148+
func Suspend(_ context.Context, params *SuspendParams) (*any, error) {
149+
pCtx := params.ProcessContext
150+
wfCtx := params.WorkflowContext
151+
act := params.Action
152+
stepID := fmt.Sprint(pCtx.GetData(model.ContextStepSessionID))
153+
timestamp := wfCtx.GetMutableValue(stepID, ResumeTimeStamp)
154+
155+
var msg string
156+
if msg == "" {
157+
msg = fmt.Sprintf("Suspended by field %s", params.FieldLabel)
158+
}
159+
if timestamp != "" {
160+
t, err := time.Parse(time.RFC3339, timestamp)
161+
if err != nil {
162+
return nil, fmt.Errorf("failed to parse timestamp %s: %w", timestamp, err)
163+
}
164+
if time.Now().After(t) {
165+
act.Resume("")
166+
return nil, nil
167+
}
168+
act.Suspend(msg)
169+
return nil, errors.GenericActionError(errors.ActionSuspend)
170+
}
171+
if params.Params.Duration != "" {
172+
d, err := time.ParseDuration(params.Params.Duration)
173+
if err != nil {
174+
return nil, fmt.Errorf("failed to parse duration %s: %w", params.Params.Duration, err)
175+
}
176+
wfCtx.SetMutableValue(time.Now().Add(d).Format(time.RFC3339), stepID, ResumeTimeStamp)
177+
}
178+
if ts := wfCtx.GetMutableValue(stepID, params.FieldLabel, SuspendTimeStamp); ts != "" {
179+
if act.GetStatus().Phase == v1alpha1.WorkflowStepPhaseRunning {
180+
// if it is already suspended before and has been resumed, we should not suspend it again.
181+
return nil, nil
182+
}
183+
} else {
184+
wfCtx.SetMutableValue(time.Now().Format(time.RFC3339), stepID, params.FieldLabel, SuspendTimeStamp)
185+
}
186+
act.Suspend(msg)
187+
return nil, errors.GenericActionError(errors.ActionSuspend)
188+
}
189+
190+
// Message writes message to step status, note that the message will be overwritten by the next message.
191+
func Message(_ context.Context, params *ActionParams) (*any, error) {
192+
params.Action.Message(params.Params.Message)
193+
return nil, nil
194+
}
195+
196+
//go:embed workspace.cue
197+
var template string
198+
199+
// GetTemplate returns the cue template.
200+
func GetTemplate() string {
201+
return template
202+
}
203+
204+
// GetProviders returns the cue providers.
205+
func GetProviders() map[string]cuexruntime.ProviderFn {
206+
return map[string]cuexruntime.ProviderFn{
207+
"wait": providertypes.GenericProviderFn[WaitVars, any](Wait),
208+
"break": providertypes.GenericProviderFn[ActionVars, any](Break),
209+
"fail": providertypes.GenericProviderFn[ActionVars, any](Fail),
210+
"message": providertypes.GenericProviderFn[ActionVars, any](Message),
211+
"var": providertypes.GenericProviderFn[VarVars, VarReturns](DoVar),
212+
"suspend": providertypes.GenericProviderFn[SuspendVars, any](Suspend),
213+
}
214+
}

0 commit comments

Comments
 (0)