Refactor: use cuex engine (#6575)

* refactor: use cuex engine

Signed-off-by: FogDong <fog@bentoml.com>

* fix: fix lint

Signed-off-by: FogDong <fog@bentoml.com>

* fix: fix unit test

Signed-off-by: FogDong <fog@bentoml.com>

* fix: fix static check and sdk tests

Signed-off-by: FogDong <fog@bentoml.com>

* fix: fix testdata

Signed-off-by: FogDong <fog@bentoml.com>

* fix: fix velaql unit test

Signed-off-by: FogDong <fog@bentoml.com>

* fix: fix docgen parser

Signed-off-by: FogDong <fog@bentoml.com>

* fix: fix cuegen

Signed-off-by: FogDong <fog@bentoml.com>

* fix: fix velaql

Signed-off-by: FogDong <fog@bentoml.com>

* fix: delete useless print

Signed-off-by: FogDong <fog@bentoml.com>

* fix: set client for ql

Signed-off-by: FogDong <fog@bentoml.com>

* fix: fix mt tests

Signed-off-by: FogDong <fog@bentoml.com>

* fix: set kubeclient in generator

Signed-off-by: FogDong <fog@bentoml.com>

* fix: use pass kube client

Signed-off-by: FogDong <fog@bentoml.com>

* fix: simplify ql

Signed-off-by: FogDong <fog@bentoml.com>

* fix: fix lint

Signed-off-by: FogDong <fog@bentoml.com>

* fix: add wf debug back

Signed-off-by: FogDong <fog@bentoml.com>

* fix: add loader

Signed-off-by: FogDong <fog@bentoml.com>

---------

Signed-off-by: FogDong <fog@bentoml.com>
This commit is contained in:
Tianxin Dong 2024-07-27 17:44:20 +08:00 committed by GitHub
parent a565b48ae6
commit 4f8bf44684
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
202 changed files with 3150 additions and 3845 deletions

1
.gitignore vendored
View File

@ -41,6 +41,7 @@ _tmp/
references/cmd/cli/fake/source.go
references/cmd/cli/fake/chart_source.go
references/vela-sdk-gen/*
charts/vela-core/crds/_.yaml
.test_vela
tmp/

View File

@ -41,9 +41,8 @@ fmt: goimports installcue
$(CUE) fmt ./vela-templates/definitions/internal/*
$(CUE) fmt ./vela-templates/definitions/deprecated/*
$(CUE) fmt ./vela-templates/definitions/registry/*
$(CUE) fmt ./pkg/stdlib/pkgs/*
$(CUE) fmt ./pkg/stdlib/op.cue
$(CUE) fmt ./pkg/workflow/template/static/*
$(CUE) fmt ./pkg/workflow/providers/legacy/...
## sdk_fmt: Run go fmt against code
sdk_fmt:

View File

@ -203,7 +203,7 @@ func TestResourceTrackerCompression(t *testing.T) {
"../../../charts/vela-core/crds/core.oam.dev_componentdefinitions.yaml",
"../../../charts/vela-core/templates/kubevela-controller.yaml",
"../../../charts/vela-core/README.md",
"../../../pkg/velaql/providers/query/testdata/machinelearning.seldon.io_seldondeployments.yaml",
"../../../pkg/workflow/providers/legacy/query/testdata/machinelearning.seldon.io_seldondeployments.yaml",
}
for _, p := range paths {
b, err := os.ReadFile(p)

View File

@ -34,7 +34,7 @@ spec:
}
}
}
} @step(1)
}
outputs: {
eps_port_name_filtered: *[] | [...]
@ -42,7 +42,7 @@ spec:
eps_port_name_filtered: collect.list
}
if parameter.portName != _|_ {
eps_port_name_filtered: [ for ep in collect.list if parameter.portName == ep.endpoint.portName {ep}]
eps_port_name_filtered: [for ep in collect.list if parameter.portName == ep.endpoint.portName {ep}]
}
eps_port_filtered: *[] | [...]
@ -50,12 +50,12 @@ spec:
eps_port_filtered: eps_port_name_filtered
}
if parameter.port != _|_ {
eps_port_filtered: [ for ep in eps_port_name_filtered if parameter.port == ep.endpoint.port {ep}]
eps_port_filtered: [for ep in eps_port_name_filtered if parameter.port == ep.endpoint.port {ep}]
}
eps: eps_port_filtered
eps: eps_port_filtered
endpoints: *[] | [...]
if parameter.outer != _|_ {
tmps: [ for ep in eps {
tmps: [for ep in eps {
ep
if ep.endpoint.inner == _|_ {
outer: true
@ -64,7 +64,7 @@ spec:
outer: !ep.endpoint.inner
}
}]
endpoints: [ for ep in tmps if (!parameter.outer || ep.outer) {ep}]
endpoints: [for ep in tmps if (!parameter.outer || ep.outer) {ep}]
}
if parameter.outer == _|_ {
endpoints: eps_port_filtered
@ -73,7 +73,7 @@ spec:
wait: op.#ConditionalWait & {
continue: len(outputs.endpoints) > 0
} @step(2)
}
value: {
if len(outputs.endpoints) > 0 {

View File

@ -32,7 +32,7 @@ spec:
_params: #PatchParams
name: _params.containerName
_baseContainers: context.output.spec.template.spec.containers
_matchContainers_: [ for _container_ in _baseContainers if _container_.name == name {_container_}]
_matchContainers_: [for _container_ in _baseContainers if _container_.name == name {_container_}]
_baseContainer: *_|_ | {...}
if len(_matchContainers_) == 0 {
err: "container \(name) not found"
@ -73,7 +73,7 @@ spec:
}
// +patchStrategy=replace
args: [ for a in _args if _delArgs[a] == _|_ {a}] + [ for a in _addArgs if _delArgs[a] == _|_ && _argsMap[a] == _|_ {a}]
args: [for a in _args if _delArgs[a] == _|_ {a}] + [for a in _addArgs if _delArgs[a] == _|_ && _argsMap[a] == _|_ {a}]
}
}
// +patchStrategy=open
@ -97,7 +97,7 @@ spec:
}
if parameter.containers != _|_ {
// +patchKey=name
containers: [ for c in parameter.containers {
containers: [for c in parameter.containers {
if c.containerName == "" {
err: "container name must be set for containers"
}
@ -113,5 +113,5 @@ spec:
containers: [...#PatchParams]
})
errs: [ for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]
errs: [for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]

View File

@ -29,7 +29,7 @@ spec:
_params: #PatchParams
name: _params.containerName
_baseContainers: context.output.spec.template.spec.containers
_matchContainers_: [ for _container_ in _baseContainers if _container_.name == name {_container_}]
_matchContainers_: [for _container_ in _baseContainers if _container_.name == name {_container_}]
_baseContainer: *_|_ | {...}
if len(_matchContainers_) == 0 {
err: "container \(name) not found"
@ -62,7 +62,7 @@ spec:
}
if parameter.containers != _|_ {
// +patchKey=name
containers: [ for c in parameter.containers {
containers: [for c in parameter.containers {
if c.containerName == "" {
err: "containerName must be set for containers"
}
@ -78,5 +78,5 @@ spec:
containers: [...#PatchParams]
})
errs: [ for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]
errs: [for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]

View File

@ -42,7 +42,7 @@ spec:
_params: #PatchParams
name: _params.containerName
_baseContainers: context.output.spec.template.spec.containers
_matchContainers_: [ for _container_ in _baseContainers if _container_.name == name {_container_}]
_matchContainers_: [for _container_ in _baseContainers if _container_.name == name {_container_}]
_baseContainer: *_|_ | {...}
if len(_matchContainers_) == 0 {
err: "container \(name) not found"
@ -52,7 +52,7 @@ spec:
_basePorts: _baseContainer.ports
if _basePorts == _|_ {
// +patchStrategy=replace
ports: [ for port in _params.ports {
ports: [for port in _params.ports {
containerPort: port.containerPort
protocol: port.protocol
if port.hostPort != _|_ {
@ -67,7 +67,7 @@ spec:
_basePortsMap: {for _basePort in _basePorts {(strings.ToLower(_basePort.protocol) + strconv.FormatInt(_basePort.containerPort, 10)): _basePort}}
_portsMap: {for port in _params.ports {(strings.ToLower(port.protocol) + strconv.FormatInt(port.containerPort, 10)): port}}
// +patchStrategy=replace
ports: [ for portVar in _basePorts {
ports: [for portVar in _basePorts {
containerPort: portVar.containerPort
protocol: portVar.protocol
name: portVar.name
@ -80,7 +80,7 @@ spec:
hostIP: _portsMap[_uniqueKey].hostIP
}
}
}] + [ for port in _params.ports if _basePortsMap[strings.ToLower(port.protocol)+strconv.FormatInt(port.containerPort, 10)] == _|_ {
}] + [for port in _params.ports if _basePortsMap[strings.ToLower(port.protocol)+strconv.FormatInt(port.containerPort, 10)] == _|_ {
if port.containerPort != _|_ {
containerPort: port.containerPort
}
@ -115,7 +115,7 @@ spec:
}
if parameter.containers != _|_ {
// +patchKey=name
containers: [ for c in parameter.containers {
containers: [for c in parameter.containers {
if c.containerName == "" {
err: "container name must be set for containers"
}
@ -131,5 +131,5 @@ spec:
containers: [...#PatchParams]
})
errs: [ for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]
errs: [for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]

View File

@ -25,7 +25,7 @@ spec:
] | []
configMap: *[
for v in parameter.volumeMounts.configMap {
for v in parameter.volumeMounts.configMap {
{
mountPath: v.mountPath
if v.subPath != _|_ {
@ -49,7 +49,7 @@ spec:
] | []
emptyDir: *[
for v in parameter.volumeMounts.emptyDir {
for v in parameter.volumeMounts.emptyDir {
{
mountPath: v.mountPath
if v.subPath != _|_ {
@ -61,7 +61,7 @@ spec:
] | []
hostPath: *[
for v in parameter.volumeMounts.hostPath {
for v in parameter.volumeMounts.hostPath {
{
mountPath: v.mountPath
if v.subPath != _|_ {
@ -83,7 +83,7 @@ spec:
] | []
configMap: *[
for v in parameter.volumeMounts.configMap {
for v in parameter.volumeMounts.configMap {
{
name: v.name
configMap: {
@ -113,7 +113,7 @@ spec:
] | []
emptyDir: *[
for v in parameter.volumeMounts.emptyDir {
for v in parameter.volumeMounts.emptyDir {
{
name: v.name
emptyDir: medium: v.medium
@ -122,7 +122,7 @@ spec:
] | []
hostPath: *[
for v in parameter.volumeMounts.hostPath {
for v in parameter.volumeMounts.hostPath {
{
name: v.name
hostPath: path: v.path
@ -223,7 +223,7 @@ spec:
}
}
if parameter["volumes"] != _|_ if parameter["volumeMounts"] == _|_ {
volumeMounts: [ for v in parameter.volumes {
volumeMounts: [for v in parameter.volumes {
{
mountPath: v.mountPath
name: v.name
@ -234,7 +234,7 @@ spec:
}
}]
if parameter["volumes"] != _|_ if parameter["volumeMounts"] == _|_ {
volumes: [ for v in parameter.volumes {
volumes: [for v in parameter.volumes {
{
name: v.name
if v.type == "pvc" {
@ -267,13 +267,13 @@ spec:
volumes: deDupVolumesArray
}
if parameter["imagePullSecrets"] != _|_ {
imagePullSecrets: [ for v in parameter.imagePullSecrets {
imagePullSecrets: [for v in parameter.imagePullSecrets {
name: v
},
]
}
if parameter.hostAliases != _|_ {
hostAliases: [ for v in parameter.hostAliases {
hostAliases: [for v in parameter.hostAliases {
ip: v.ip
hostnames: v.hostnames
},

View File

@ -162,7 +162,7 @@ spec:
}]
}
if parameter["ports"] != _|_ {
ports: [ for v in parameter.ports {
ports: [for v in parameter.ports {
{
containerPort: v.port
protocol: v.protocol
@ -206,7 +206,7 @@ spec:
}
if parameter["volumes"] != _|_ && parameter["volumeMounts"] == _|_ {
volumeMounts: [ for v in parameter.volumes {
volumeMounts: [for v in parameter.volumes {
{
mountPath: v.mountPath
name: v.name
@ -233,14 +233,14 @@ spec:
}
if parameter["imagePullSecrets"] != _|_ {
imagePullSecrets: [ for v in parameter.imagePullSecrets {
imagePullSecrets: [for v in parameter.imagePullSecrets {
name: v
},
]
}
if parameter["volumes"] != _|_ && parameter["volumeMounts"] == _|_ {
volumes: [ for v in parameter.volumes {
volumes: [for v in parameter.volumes {
{
name: v.name
if v.type == "pvc" {

View File

@ -38,14 +38,14 @@ spec:
namespace: parameter.namespace
}
}
} @step(1)
}
template: configMap.value.data["application"]
apply: op.#Apply & {
apply: op.#Apply & {
value: yaml.Unmarshal(template)
} @step(2)
}
wait: op.#ConditionalWait & {
continue: apply.value.status.status == "running"
} @step(3)
}
}
if dependsOn.err == _|_ {

View File

@ -31,7 +31,7 @@ spec:
name: _params.containerName
_delKeys: {for k in _params.unset {(k): ""}}
_baseContainers: context.output.spec.template.spec.containers
_matchContainers_: [ for _container_ in _baseContainers if _container_.name == name {_container_}]
_matchContainers_: [for _container_ in _baseContainers if _container_.name == name {_container_}]
_baseContainer: *_|_ | {...}
if len(_matchContainers_) == 0 {
err: "container \(name) not found"
@ -41,7 +41,7 @@ spec:
_baseEnv: _baseContainer.env
if _baseEnv == _|_ {
// +patchStrategy=replace
env: [ for k, v in _params.env if _delKeys[k] == _|_ {
env: [for k, v in _params.env if _delKeys[k] == _|_ {
name: k
value: v
}]
@ -49,7 +49,7 @@ spec:
if _baseEnv != _|_ {
_baseEnvMap: {for envVar in _baseEnv {(envVar.name): envVar}}
// +patchStrategy=replace
env: [ for envVar in _baseEnv if _delKeys[envVar.name] == _|_ && !_params.replace {
env: [for envVar in _baseEnv if _delKeys[envVar.name] == _|_ && !_params.replace {
name: envVar.name
if _params.env[envVar.name] != _|_ {
value: _params.env[envVar.name]
@ -62,7 +62,7 @@ spec:
valueFrom: envVar.valueFrom
}
}
}] + [ for k, v in _params.env if _delKeys[k] == _|_ && (_params.replace || _baseEnvMap[k] == _|_) {
}] + [for k, v in _params.env if _delKeys[k] == _|_ && (_params.replace || _baseEnvMap[k] == _|_) {
name: k
value: v
}]
@ -88,7 +88,7 @@ spec:
}
if parameter.containers != _|_ {
// +patchKey=name
containers: [ for c in parameter.containers {
containers: [for c in parameter.containers {
if c.containerName == "" {
err: "containerName must be set for containers"
}
@ -104,5 +104,5 @@ spec:
containers: [...#PatchParams]
})
errs: [ for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]
errs: [for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]

View File

@ -37,14 +37,14 @@ spec:
if parameter.kind == "Secret" {
stringData: parameter.data
}
} @step(1)
}
getPlacements: op.#GetPlacementsFromTopologyPolicies & {
policies: *[] | [...string]
if parameter.topology != _|_ {
policies: [parameter.topology]
}
} @step(2)
}
apply: op.#Steps & {
for p in getPlacements.placements {
@ -53,7 +53,7 @@ spec:
cluster: p.cluster
}
}
} @step(3)
}
parameter: {
// +usage=Specify the name of the export destination

View File

@ -48,14 +48,14 @@ spec:
addresses: [{ip: parameter.ip}]
ports: [{port: parameter.targetPort}]
}]
}] @step(1)
}]
getPlacements: op.#GetPlacementsFromTopologyPolicies & {
policies: *[] | [...string]
if parameter.topology != _|_ {
policies: [parameter.topology]
}
} @step(2)
}
apply: op.#Steps & {
for p in getPlacements.placements {
@ -66,7 +66,7 @@ spec:
}
}
}
} @step(3)
}
parameter: {
// +usage=Specify the name of the export destination

View File

@ -44,7 +44,7 @@ spec:
]
}
if parameter["ports"] != _|_ {
ports: [ for v in parameter.ports {
ports: [for v in parameter.ports {
port: v.port
targetPort: v.port
if v.name != _|_ {

View File

@ -161,11 +161,11 @@ spec:
}
let ingressMetaName = context.name + nameSuffix
let ig = [for i in context.outputs if (i.kind == "Ingress") && (i.metadata.name == ingressMetaName) {i}][0]
igs: *null | string
igs: *{} | {}
if ig != _|_ if ig.status != _|_ if ig.status.loadbalancer != _|_ {
igs: ig.status.loadbalancer.ingress[0]
}
igr: *null | string
igr: *{} | {}
if ig != _|_ if ig.spec != _|_ {
igr: ig.spec.rules[0]
}
@ -185,7 +185,7 @@ spec:
if igr.host != _|_ {
message: "Visiting URL: " + igr.host + "\n"
}
if igs.host == _|_ {
if igr.host == _|_ {
message: "Host not specified, visit the cluster or load balancer in front of the cluster\n"
}
}

View File

@ -29,14 +29,14 @@ spec:
}
}
}
dbHost: op.#ConvertString & {bt: base64.Decode(null, output.value.data["DB_HOST"])}
dbPort: op.#ConvertString & {bt: base64.Decode(null, output.value.data["DB_PORT"])}
dbName: op.#ConvertString & {bt: base64.Decode(null, output.value.data["DB_NAME"])}
dbHost: op.#ConvertString & {bt: base64.Decode(null, output.value.data["DB_HOST"])}
dbPort: op.#ConvertString & {bt: base64.Decode(null, output.value.data["DB_PORT"])}
dbName: op.#ConvertString & {bt: base64.Decode(null, output.value.data["DB_NAME"])}
username: op.#ConvertString & {bt: base64.Decode(null, output.value.data["DB_USER"])}
password: op.#ConvertString & {bt: base64.Decode(null, output.value.data["DB_PASSWORD"])}
env: [
{name: "url", value: "jdbc://" + dbHost.str + ":" + dbPort.str + "/" + dbName.str + "?characterEncoding=utf8&useSSL=false"},
{name: "url", value: "jdbc://" + dbHost.str + ":" + dbPort.str + "/" + dbName.str + "?characterEncoding=utf8&useSSL=false"},
{name: "username", value: username.str},
{name: "password", value: password.str},
]

View File

@ -42,7 +42,7 @@ spec:
patch: metadata: annotations: {
"dev.nocalhost/application-name": context.appName
"dev.nocalhost/application-namespace": context.namespace
"dev.nocalhost": json.Marshal({
"dev.nocalhost": json.Marshal({
name: context.name
serviceType: parameter.serviceType
containers: [
@ -126,14 +126,14 @@ spec:
workDir: *"/home/nocalhost-dev" | string
storageClass?: string
command: {
run: *["sh", "run.sh"] | [...string]
run: *["sh", "run.sh"] | [...string]
debug: *["sh", "debug.sh"] | [...string]
}
debug?: remoteDebugPort?: int
hotReload: *true | bool
sync: {
type: *"send" | string
filePattern: *["./"] | [...string]
type: *"send" | string
filePattern: *["./"] | [...string]
ignoreFilePattern: *[".git", ".vscode", ".idea", ".gradle", "build"] | [...string]
}
env?: [...{

View File

@ -69,7 +69,7 @@ spec:
picUrl?: string
}
link?: #link
link?: #link
markdown?: close({
text: string
title: string
@ -230,7 +230,7 @@ spec:
}
stringValue: op.#ConvertString & {bt: base64.Decode(null, read.value.data[parameter.dingding.url.secretRef.key])}
ding2: op.#DingTalk & {
ding2: op.#DingTalk & {
message: parameter.dingding.message
dingUrl: stringValue.str
}
@ -259,7 +259,7 @@ spec:
}
stringValue: op.#ConvertString & {bt: base64.Decode(null, read.value.data[parameter.lark.url.secretRef.key])}
lark2: op.#Lark & {
lark2: op.#Lark & {
message: parameter.lark.message
larkUrl: stringValue.str
}
@ -288,7 +288,7 @@ spec:
}
stringValue: op.#ConvertString & {bt: base64.Decode(null, read.value.data[parameter.slack.url.secretRef.key])}
slack2: op.#Slack & {
slack2: op.#Slack & {
message: parameter.slack.message
slackUrl: stringValue.str
}
@ -327,7 +327,7 @@ spec:
}
stringValue: op.#ConvertString & {bt: base64.Decode(null, read.value.data[parameter.email.from.password.secretRef.key])}
email2: op.#SendEmail & {
email2: op.#SendEmail & {
from: {
address: parameter.email.from.address
if parameter.email.from.alias != _|_ {

View File

@ -42,8 +42,8 @@ spec:
// +patchStrategy=retainKeys
patch: spec: template: spec: serviceAccountName: parameter.name
_clusterPrivileges: [ if parameter.privileges != _|_ for p in parameter.privileges if p.scope == "cluster" {p}]
_namespacePrivileges: [ if parameter.privileges != _|_ for p in parameter.privileges if p.scope == "namespace" {p}]
_clusterPrivileges: [if parameter.privileges != _|_ for p in parameter.privileges if p.scope == "cluster" {p}]
_namespacePrivileges: [if parameter.privileges != _|_ for p in parameter.privileges if p.scope == "namespace" {p}]
outputs: {
if parameter.create {
"service-account": {
@ -58,7 +58,7 @@ spec:
apiVersion: "rbac.authorization.k8s.io/v1"
kind: "ClusterRole"
metadata: name: "\(context.namespace):\(parameter.name)"
rules: [ for p in _clusterPrivileges {
rules: [for p in _clusterPrivileges {
verbs: p.verbs
if p.apiGroups != _|_ {
apiGroups: p.apiGroups
@ -95,7 +95,7 @@ spec:
apiVersion: "rbac.authorization.k8s.io/v1"
kind: "Role"
metadata: name: parameter.name
rules: [ for p in _namespacePrivileges {
rules: [for p in _namespacePrivileges {
verbs: p.verbs
if p.apiGroups != _|_ {
apiGroups: p.apiGroups

View File

@ -32,7 +32,7 @@ spec:
env: parameter.env
}
if parameter["volumes"] != _|_ {
volumeMounts: [ for v in parameter.volumes {
volumeMounts: [for v in parameter.volumes {
{
mountPath: v.path
name: v.name

View File

@ -74,7 +74,7 @@ spec:
_params: #StartupProbeParams
name: _params.containerName
_baseContainers: context.output.spec.template.spec.containers
_matchContainers_: [ for _container_ in _baseContainers if _container_.name == name {_container_}]
_matchContainers_: [for _container_ in _baseContainers if _container_.name == name {_container_}]
if len(_matchContainers_) == 0 {
err: "container \(name) not found"
}
@ -151,7 +151,7 @@ spec:
}
if parameter.probes != _|_ {
// +patchKey=name
containers: [ for c in parameter.probes {
containers: [for c in parameter.probes {
if c.name == "" {
err: "containerName must be set when specifying startup probe for multiple containers"
}
@ -167,5 +167,5 @@ spec:
probes: [...#StartupProbeParams]
})
errs: [ for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]
errs: [for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]

View File

@ -149,7 +149,7 @@ spec:
]
volumeDevicesList: *[
for v in parameter.pvc if v.volumeMode == "Block" {
for v in parameter.pvc if v.volumeMode == "Block" {
{
name: "pvc-" + v.name
devicePath: v.mountPath
@ -262,13 +262,13 @@ spec:
parameter: {
// +usage=Declare pvc type storage
pvc?: [...{
name: string
mountOnly: *false | bool
mountPath: string
subPath?: string
volumeMode: *"Filesystem" | string
volumeName?: string
accessModes: *["ReadWriteOnce"] | [...string]
name: string
mountOnly: *false | bool
mountPath: string
subPath?: string
volumeMode: *"Filesystem" | string
volumeName?: string
accessModes: *["ReadWriteOnce"] | [...string]
storageClassName?: string
resources?: {
requests: storage: =~"^([1-9][0-9]{0,63})(E|P|T|G|M|K|Ei|Pi|Ti|Gi|Mi|Ki)$"

View File

@ -63,7 +63,7 @@ spec:
}
if parameter["volumes"] != _|_ {
volumeMounts: [ for v in parameter.volumes {
volumeMounts: [for v in parameter.volumes {
{
mountPath: v.mountPath
name: v.name
@ -72,7 +72,7 @@ spec:
}]
if parameter["volumes"] != _|_ {
volumes: [ for v in parameter.volumes {
volumes: [for v in parameter.volumes {
{
name: v.name
if v.type == "pvc" {
@ -103,7 +103,7 @@ spec:
}
if parameter["imagePullSecrets"] != _|_ {
imagePullSecrets: [ for v in parameter.imagePullSecrets {
imagePullSecrets: [for v in parameter.imagePullSecrets {
name: v
},
]

View File

@ -29,11 +29,11 @@ spec:
namespace: context.namespace
}
}
} @step(1)
value: json.Marshal(read.value) @step(2)
}
value: json.Marshal(read.value)
}
if parameter.data != _|_ {
value: json.Marshal(parameter.data) @step(3)
value: json.Marshal(parameter.data)
}
}
webhook: op.#Steps & {
@ -44,7 +44,7 @@ spec:
body: data.value
header: "Content-Type": "application/json"
}
} @step(4)
}
}
if parameter.url.secretRef != _|_ && parameter.url.value == _|_ {
read: op.#Read & {
@ -56,16 +56,16 @@ spec:
namespace: context.namespace
}
}
} @step(5)
}
stringValue: op.#ConvertString & {bt: base64.Decode(null, read.value.data[parameter.url.secretRef.key])} @step(6)
http: op.#HTTPPost & {
stringValue: op.#ConvertString & {bt: base64.Decode(null, read.value.data[parameter.url.secretRef.key])}
http: op.#HTTPPost & {
url: stringValue.str
request: {
body: data.value
header: "Content-Type": "application/json"
}
} @step(7)
}
}
}

View File

@ -163,7 +163,7 @@ spec:
}]
}
if parameter["ports"] != _|_ {
ports: [ for v in parameter.ports {
ports: [for v in parameter.ports {
{
containerPort: {
if v.containerPort != _|_ {v.containerPort}
@ -221,7 +221,7 @@ spec:
}
if parameter["volumes"] != _|_ && parameter["volumeMounts"] == _|_ {
volumeMounts: [ for v in parameter.volumes {
volumeMounts: [for v in parameter.volumes {
{
mountPath: v.mountPath
name: v.name
@ -248,14 +248,14 @@ spec:
}
if parameter["imagePullSecrets"] != _|_ {
imagePullSecrets: [ for v in parameter.imagePullSecrets {
imagePullSecrets: [for v in parameter.imagePullSecrets {
name: v
},
]
}
if parameter["volumes"] != _|_ && parameter["volumeMounts"] == _|_ {
volumes: [ for v in parameter.volumes {
volumes: [for v in parameter.volumes {
{
name: v.name
if v.type == "pvc" {

View File

@ -171,7 +171,7 @@ spec:
}
if parameter["volumes"] != _|_ && parameter["volumeMounts"] == _|_ {
volumeMounts: [ for v in parameter.volumes {
volumeMounts: [for v in parameter.volumes {
{
mountPath: v.mountPath
name: v.name
@ -193,14 +193,14 @@ spec:
}]
if parameter["imagePullSecrets"] != _|_ {
imagePullSecrets: [ for v in parameter.imagePullSecrets {
imagePullSecrets: [for v in parameter.imagePullSecrets {
name: v
},
]
}
if parameter["volumes"] != _|_ && parameter["volumeMounts"] == _|_ {
volumes: [ for v in parameter.volumes {
volumes: [for v in parameter.volumes {
{
name: v.name
if v.type == "pvc" {

View File

@ -29,7 +29,6 @@ import (
"github.com/kubevela/pkg/controller/sharding"
"github.com/kubevela/pkg/meta"
"github.com/kubevela/pkg/util/profiling"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/pkg/errors"
"github.com/spf13/cobra"
utilfeature "k8s.io/apiserver/pkg/util/feature"
@ -165,15 +164,6 @@ func run(ctx context.Context, s *options.CoreOptions) error {
return err
}
pd, err := packages.NewPackageDiscover(mgr.GetConfig())
if err != nil {
klog.Error(err, "Failed to create CRD discovery for CUE package client")
if !packages.IsCUEParseErr(err) {
return err
}
}
s.ControllerArgs.PackageDiscover = pd
if !sharding.EnableSharding {
if err = prepareRun(ctx, mgr, s); err != nil {
return err

View File

@ -143,7 +143,7 @@ var _ = Describe("Test Kubectl Plugin", func() {
Expect(err).NotTo(HaveOccurred())
Expect(output).ShouldNot(ContainSubstring("addRevisionLabel"))
})
It("Test show webservice def with cue ignore annotation ", func() {
It("Test show webservice def with cue ignore annotation2 ", func() {
tdName := "mywebservice"
output, err := e2e.Exec(fmt.Sprintf("kubectl-vela show %s -n default", tdName))
Expect(err).NotTo(HaveOccurred())

26
go.mod
View File

@ -3,7 +3,7 @@ module github.com/oam-dev/kubevela
go 1.22
require (
cuelang.org/go v0.5.0
cuelang.org/go v0.9.2
github.com/AlecAivazis/survey/v2 v2.1.1
github.com/FogDong/uitable v0.0.5
github.com/Masterminds/semver/v3 v3.2.1
@ -57,9 +57,8 @@ require (
github.com/prometheus/client_golang v1.16.0
github.com/prometheus/client_model v0.4.0
github.com/rivo/tview v0.0.0-20221128165837-db36428c92d9
github.com/rogpeppe/go-internal v1.10.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0
github.com/spf13/cobra v1.8.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.4
github.com/tidwall/gjson v1.14.4
@ -68,7 +67,8 @@ require (
github.com/xlab/treeprint v1.2.0
go.uber.org/multierr v1.11.0
golang.org/x/crypto v0.25.0
golang.org/x/oauth2 v0.12.0
golang.org/x/mod v0.17.0
golang.org/x/oauth2 v0.20.0
golang.org/x/sync v0.7.0
golang.org/x/term v0.22.0
golang.org/x/text v0.16.0
@ -98,6 +98,7 @@ require (
)
require (
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 // indirect
dario.cat/mergo v1.0.0 // indirect
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
@ -126,11 +127,11 @@ require (
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/cloudflare/circl v1.3.7 // indirect
github.com/cockroachdb/apd/v2 v2.0.2 // indirect
github.com/cockroachdb/apd/v3 v3.2.1 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/creack/pty v1.1.18 // indirect
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/docker/cli v24.0.0+incompatible // indirect
@ -169,7 +170,6 @@ require (
github.com/gobuffalo/flect v0.3.0 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/glog v1.0.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/btree v1.0.1 // indirect
@ -180,9 +180,8 @@ require (
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
@ -224,11 +223,10 @@ require (
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
github.com/opencontainers/image-spec v1.1.0 // indirect
github.com/openshift/library-go v0.0.0-20230327085348-8477ec72b725 // indirect
github.com/perimeterx/marshmallow v1.1.4 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
@ -236,9 +234,10 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.10.1 // indirect
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b // indirect
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/rubenv/sql-migrate v1.3.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
@ -271,11 +270,9 @@ require (
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/automaxprocs v1.5.3 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.25.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
google.golang.org/grpc v1.53.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
@ -303,6 +300,7 @@ replace (
cloud.google.com/go => cloud.google.com/go v0.100.2
github.com/docker/cli => github.com/docker/cli v20.10.9+incompatible
github.com/docker/docker => github.com/moby/moby v20.10.24+incompatible
github.com/kubevela/workflow => github.com/FogDong/workflow v0.0.0-20240723124017-5de159eb484c
github.com/wercker/stern => github.com/oam-dev/stern v1.13.2
sigs.k8s.io/apiserver-network-proxy/konnectivity-client => sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.36
)

52
go.sum
View File

@ -1,14 +1,15 @@
cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/compute v1.19.3 h1:DcTwsFgGev/wV5+q8o2fzgcHOaac+DKGC91ZlvpsQds=
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cuelang.org/go v0.5.0 h1:D6N0UgTGJCOxFKU8RU+qYvavKNsVc/+ZobmifStVJzU=
cuelang.org/go v0.5.0/go.mod h1:okjJBHFQFer+a41sAe2SaGm1glWS8oEb6CmJvn5Zdws=
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2 h1:BnG6pr9TTr6CYlrJznYUDj6V7xldD1W+1iXPum0wT/w=
cuelabs.dev/go/oci/ociregistry v0.0.0-20240404174027-a39bec0462d2/go.mod h1:pK23AUVXuNzzTpfMCA06sxZGeVQ/75FdVtW249de9Uo=
cuelang.org/go v0.9.2 h1:pfNiry2PdRBr02G/aKm5k2vhzmqbAOoaB4WurmEbWvs=
cuelang.org/go v0.9.2/go.mod h1:qpAYsLOf7gTM1YdEg6cxh553uZ4q9ZDWlPbtZr9q1Wk=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
@ -35,6 +36,8 @@ github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20O
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/FogDong/uitable v0.0.5 h1:1bJo/uvhGUC6i8JPHZCr8XKMHiDExE7mQkOCmDl0ryQ=
github.com/FogDong/uitable v0.0.5/go.mod h1:1yEaP13SkkBUj3HvqKIUWnsb42XigyZbNle84mc5kLM=
github.com/FogDong/workflow v0.0.0-20240723124017-5de159eb484c h1:uj3GVjWUzGJ+aOuLrYo4/GTFHQhCjbyYrf4zzeFDGrM=
github.com/FogDong/workflow v0.0.0-20240723124017-5de159eb484c/go.mod h1:/tWZOtO+bp/EUQCJZjL8t3O5YDx5QXnKVllQkDTKKuw=
github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ=
github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
@ -171,8 +174,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E=
github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw=
github.com/cockroachdb/apd/v3 v3.2.1 h1:U+8j7t0axsIgvQUqthuNm82HIrYXodOV2iWLWtEaIwg=
github.com/cockroachdb/apd/v3 v3.2.1/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc=
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo=
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
@ -198,8 +201,9 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
@ -365,6 +369,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI=
github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow=
github.com/go-resty/resty/v2 v2.8.0 h1:J29d0JFWwSWrDCysnOK/YjsPMLQTx0TvgJEHVGvf2L8=
github.com/go-resty/resty/v2 v2.8.0/go.mod h1:UCui0cMHekLrSntoMyofdSTaPpinlRHFtPpizuyDW2w=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
@ -475,8 +481,9 @@ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
@ -627,8 +634,6 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kubevela/pkg v1.9.2 h1:K6pGoJikf6l8vlfehewmb36hyToX0KpUaQP4NVET/S8=
github.com/kubevela/pkg v1.9.2/go.mod h1:u/MGuFXVSECxvIWdTKS4AQs1H+USfAMQgi30BUrOb04=
github.com/kubevela/workflow v0.6.0 h1:fYXviOYD5zqHs3J61tNbM4HZ85EcZlPm7Fyz8Q5o9Fk=
github.com/kubevela/workflow v0.6.0/go.mod h1:sjLcYqKHKeCQ+w77gijoNILwIShJKnCU+e3q7ETtZGI=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
@ -744,8 +749,6 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de h1:D5x39vF5KCwKQaw+OC9ZPiLVHXz3UFw2+psEX+gYcto=
github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de/go.mod h1:kJun4WP5gFuHZgRjZUWWuH1DTxCtxbHDOIJsudS8jzY=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
@ -806,8 +809,8 @@ github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8=
github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
github.com/openkruise/kruise-api v1.4.0 h1:MDDXQIYvaCh0ioIJSRniF4kCKby9JI3/ec6pZHHw/Ao=
github.com/openkruise/kruise-api v1.4.0/go.mod h1:HyRlDV0MfW5Zm+3g36bx7u4CcWHcKBxL8g/c/2bjcd4=
github.com/openkruise/rollouts v0.3.0 h1:T02r9BxHJ02MRkbc7C4F12qMGgrziZVjgmukwz6k60s=
@ -888,8 +891,8 @@ github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0ua
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b h1:zd/2RNzIRkoGGMjE+YIsZ85CnDIz672JK2F3Zl4vux4=
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b/go.mod h1:KjY0wibdYKc4DYkerHSbguaf3JeIPGhNJBp2BNiFH78=
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0 h1:sadMIsgmHpEOGbUs6VtHBXRR1OHevnj7hLx9ZcdNGW4=
github.com/protocolbuffers/txtpbfmt v0.0.0-20230328191034-3462fbc510c0/go.mod h1:jgxiZysxFPM+iWKwQwPR+y+Jvo54ARd4EisXxKYpB5c=
github.com/rivo/tview v0.0.0-20221128165837-db36428c92d9 h1:ccTgRxA37ypj3q8zB8G4k3xGPfBbIaMwrf3Yw6k50NY=
github.com/rivo/tview v0.0.0-20221128165837-db36428c92d9/go.mod h1:YX2wUZOcJGOIycErz2s9KvDaP0jnWwRCirQMPLPpQ+Y=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@ -902,8 +905,8 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/rubenv/sql-migrate v1.3.1 h1:Vx+n4Du8X8VTYuXbhNxdEUoh6wiJERA0GlWocR5FrbA=
github.com/rubenv/sql-migrate v1.3.1/go.mod h1:YzG/Vh82CwyhTFXy+Mf5ahAiiEOpAlHurg+23VEzcsk=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@ -947,8 +950,8 @@ github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSW
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@ -1252,8 +1255,8 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -1432,7 +1435,6 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=

View File

@ -32,10 +32,11 @@ import (
"sync"
"time"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"github.com/Masterminds/semver/v3"
"github.com/google/go-github/v32/github"
"github.com/imdario/mergo"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/pkg/errors"
"github.com/xanzy/go-gitlab"
"go.uber.org/multierr"
@ -63,11 +64,11 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/config"
"github.com/oam-dev/kubevela/pkg/cue/script"
"github.com/oam-dev/kubevela/pkg/definition"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/schema"
"github.com/oam-dev/kubevela/pkg/utils"
addonutil "github.com/oam-dev/kubevela/pkg/utils/addon"
"github.com/oam-dev/kubevela/pkg/utils/apply"
@ -589,12 +590,11 @@ func unmarshalToContent(content []byte) (fileContent *github.RepositoryContent,
}
func genAddonAPISchema(addonRes *UIData) error {
cueScript := script.CUE(addonRes.Parameters)
schema, err := cueScript.ParsePropertiesToSchema()
s, err := schema.ParsePropertiesToSchema(context.Background(), addonRes.Parameters)
if err != nil {
return err
}
addonRes.APISchema = schema
addonRes.APISchema = s
return nil
}
@ -700,12 +700,12 @@ func RenderDefinitions(addon *InstallPackage, config *rest.Config) ([]*unstructu
}
// RenderConfigTemplates render the config template
func RenderConfigTemplates(addon *InstallPackage, cli client.Client) ([]*unstructured.Unstructured, error) {
func RenderConfigTemplates(ctx context.Context, addon *InstallPackage, cli client.Client) ([]*unstructured.Unstructured, error) {
templates := make([]*unstructured.Unstructured, 0)
factory := config.NewConfigFactory(cli)
for _, templateFile := range addon.ConfigTemplates {
t, err := factory.ParseTemplate("", []byte(templateFile.Data))
t, err := factory.ParseTemplate(ctx, "", []byte(templateFile.Data))
if err != nil {
return nil, err
}
@ -738,7 +738,7 @@ func RenderDefinitionSchema(addon *InstallPackage) ([]*unstructured.Unstructured
}
// RenderViews will render views in addons.
func RenderViews(addon *InstallPackage) ([]*unstructured.Unstructured, error) {
func RenderViews(ctx context.Context, addon *InstallPackage) ([]*unstructured.Unstructured, error) {
views := make([]*unstructured.Unstructured, 0)
for _, view := range addon.YAMLViews {
obj, err := renderObject(view)
@ -748,7 +748,7 @@ func RenderViews(addon *InstallPackage) ([]*unstructured.Unstructured, error) {
views = append(views, obj)
}
for _, view := range addon.CUEViews {
obj, err := renderCUEView(view)
obj, err := renderCUEView(ctx, view)
if err != nil {
return nil, errors.Wrapf(err, "render velaQL view file %s", view.Name)
}
@ -811,13 +811,13 @@ func renderSchemaConfigmap(elem ElementFile) (*unstructured.Unstructured, error)
return util.Object2Unstructured(cm)
}
func renderCUEView(elem ElementFile) (*unstructured.Unstructured, error) {
func renderCUEView(ctx context.Context, elem ElementFile) (*unstructured.Unstructured, error) {
name, err := utils.GetFilenameFromLocalOrRemote(elem.Name)
if err != nil {
return nil, err
}
cm, err := velaql.ParseViewIntoConfigMap(elem.Data, name)
cm, err := velaql.ParseViewIntoConfigMap(ctx, elem.Data, name)
if err != nil {
return nil, err
}
@ -935,7 +935,7 @@ func NewAddonInstaller(ctx context.Context, cli client.Client, discoveryClient *
return i
}
func (h *Installer) enableAddon(addon *InstallPackage) (string, error) {
func (h *Installer) enableAddon(ctx context.Context, addon *InstallPackage) (string, error) {
var err error
h.addon = addon
if !h.skipVersionValidate {
@ -946,10 +946,10 @@ func (h *Installer) enableAddon(addon *InstallPackage) (string, error) {
}
}
if err = h.installDependency(addon); err != nil {
if err = h.installDependency(ctx, addon); err != nil {
return "", err
}
if err = h.dispatchAddonResource(addon); err != nil {
if err = h.dispatchAddonResource(ctx, addon); err != nil {
return "", err
}
// we shouldn't put continue func into dispatchAddonResource, because the re-apply app maybe already update app and
@ -1015,7 +1015,7 @@ func (h *Installer) getAddonMeta() (map[string]SourceMeta, error) {
}
// installDependency checks if addon's dependency and install it
func (h *Installer) installDependency(addon *InstallPackage) error {
func (h *Installer) installDependency(ctx context.Context, addon *InstallPackage) error {
installedAddons, err := listInstalledAddons(h.ctx, h.cli)
if err != nil {
return err
@ -1069,7 +1069,7 @@ func (h *Installer) installDependency(addon *InstallPackage) error {
// try to install the dependent addon from the same registry with the current addon
depAddon, err = h.loadInstallPackage(dep.Name, depVersion)
if err == nil {
additionalInfo, err := depHandler.enableAddon(depAddon)
additionalInfo, err := depHandler.enableAddon(ctx, depAddon)
if err != nil {
return errors.Wrap(err, "fail to dispatch dependent addon resource")
}
@ -1096,7 +1096,7 @@ func (h *Installer) installDependency(addon *InstallPackage) error {
return err
}
if err == nil {
additionalInfo, err := depHandler.enableAddon(depAddon)
additionalInfo, err := depHandler.enableAddon(ctx, depAddon)
if err != nil {
return errors.Wrap(err, "fail to dispatch dependent addon resource")
}
@ -1491,7 +1491,7 @@ func (h *Installer) createOrUpdate(app *v1beta1.Application) (bool, error) {
return true, nil
}
func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
func (h *Installer) dispatchAddonResource(ctx context.Context, addon *InstallPackage) error {
app, auxiliaryOutputs, err := RenderApp(h.ctx, addon, h.cli, h.args)
if err != nil {
return errors.Wrap(err, "render addon application fail")
@ -1521,7 +1521,7 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
}
// Step2: Render the config templates
templates, err := RenderConfigTemplates(addon, h.cli)
templates, err := RenderConfigTemplates(ctx, addon, h.cli)
if err != nil {
return errors.Wrap(err, "render the config template fail")
}
@ -1533,7 +1533,7 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
}
// Step4: Render the velaQL views
views, err := RenderViews(addon)
views, err := RenderViews(ctx, addon)
if err != nil {
return errors.Wrap(err, "render addon views fail")
}
@ -1625,15 +1625,15 @@ func (h *Installer) renderNotes(addon *InstallPackage) (string, error) {
return "", err
}
notesFile := contextFile + "\n" + addon.Notes.Data
val, err := value.NewValue(notesFile, nil, "")
if err != nil {
val := cuecontext.New().CompileString(notesFile)
if val.Err() != nil {
return "", errors.Wrap(err, "build values for NOTES.cue")
}
notes, err := val.LookupValue(KeyWordNotes)
if err != nil {
return "", errors.Wrap(err, "look up notes in NOTES.cue")
notes := val.LookupPath(cue.ParsePath(KeyWordNotes))
if !notes.Exists() {
return "", errors.New("notes not found")
}
notesStr, err := notes.CueValue().String()
notesStr, err := notes.String()
if err != nil {
return "", errors.Wrap(err, "convert notes to string")
}

View File

@ -441,7 +441,7 @@ var _ = Describe("func addon update ", func() {
pkg := &InstallPackage{Meta: Meta{Name: "test-update", Version: "1.3.0"}}
h := NewAddonInstaller(context.Background(), k8sClient, nil, nil, nil, &Registry{Name: "test"}, nil, nil, nil)
h.addon = pkg
Expect(h.dispatchAddonResource(pkg)).Should(BeNil())
Expect(h.dispatchAddonResource(context.Background(), pkg)).Should(BeNil())
Eventually(func() error {
var err error
@ -504,7 +504,7 @@ var _ = Describe("test dry-run addon from local dir", func() {
h := NewAddonInstaller(ctx, k8sClient, dc, apply.NewAPIApplicator(k8sClient), cfg, &Registry{Name: LocalAddonRegistryName}, map[string]interface{}{"example": "test-dry-run"}, nil, nil, DryRunAddon)
_, err = h.enableAddon(pkg)
_, err = h.enableAddon(context.Background(), pkg)
Expect(err).Should(BeNil())
decoder := yaml3.NewDecoder(h.dryRunBuff)

View File

@ -267,7 +267,7 @@ func TestRenderViews(t *testing.T) {
DisableControlPlane: false,
RuntimeCluster: false,
}
views, err := RenderViews(&addonDeployToRuntime)
views, err := RenderViews(context.Background(), &addonDeployToRuntime)
assert.NoError(t, err)
assert.Equal(t, len(views), 2)
@ -1107,7 +1107,7 @@ func TestCheckEnableAddonErrorWhenMissMatch(t *testing.T) {
version2.VelaVersion = "v1.3.0"
i := InstallPackage{Meta: Meta{SystemRequirements: &SystemRequirements{VelaVersion: ">=1.4.0"}}}
installer := &Installer{}
_, err := installer.enableAddon(&i)
_, err := installer.enableAddon(context.Background(), &i)
assert.Equal(t, errors.As(err, &VersionUnMatchError{}), true)
}

View File

@ -61,7 +61,7 @@ func EnableAddon(ctx context.Context, name string, version string, cli client.Cl
if err := validateAddonPackage(pkg); err != nil {
return "", errors.Wrap(err, fmt.Sprintf("failed to enable addon: %s", name))
}
return h.enableAddon(pkg)
return h.enableAddon(ctx, pkg)
}
// DisableAddon will disable addon from cluster.
@ -117,7 +117,7 @@ func EnableAddonByLocalDir(ctx context.Context, name string, dir string, cli cli
if len(needEnableAddonNames) > 0 {
return "", fmt.Errorf("you must first enable dependencies: %v", needEnableAddonNames)
}
return h.enableAddon(pkg)
return h.enableAddon(ctx, pkg)
}
// GetAddonStatus is general func for cli and apiServer get addon status

View File

@ -24,8 +24,10 @@ import (
"strconv"
"strings"
"cuelang.org/go/cue"
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/parser"
"github.com/cue-exp/kubevelafix"
"github.com/pkg/errors"
@ -36,7 +38,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/kubevela/workflow/pkg/cue/packages"
workflowerrors "github.com/kubevela/workflow/pkg/errors"
common2 "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
@ -47,7 +50,6 @@ import (
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
addonutil "github.com/oam-dev/kubevela/pkg/utils/addon"
verrors "github.com/oam-dev/kubevela/pkg/utils/errors"
)
const (
@ -105,19 +107,16 @@ func (a addonCueTemplateRender) toObject(cueTemplate string, path string, object
if err != nil {
return err
}
v, err := value.NewValue(contextFile, nil, "")
v := cuecontext.New().CompileString(contextFile)
out, err := value.LookupValueByScript(v, cueTemplate)
if err != nil {
return err
}
out, err := v.LookupByScript(cueTemplate)
if err != nil {
return err
outputContent := out.LookupPath(cue.ParsePath(path))
if !outputContent.Exists() {
return workflowerrors.LookUpNotFoundErr(path)
}
outputContent, err := out.LookupValue(path)
if err != nil {
return err
}
return outputContent.UnmarshalTo(object)
return value.UnmarshalTo(outputContent, object)
}
// renderApp will render Application from CUE files
@ -144,32 +143,29 @@ func (a addonCueTemplateRender) renderApp() (*v1beta1.Application, []*unstructur
}
// TODO(wonderflow): add package discover to support vela own packages if needed
v, err := newValueWithMainAndFiles(a.addon.AppCueTemplate.Data, files, nil, "")
v, err := newValueWithMainAndFiles(a.addon.AppCueTemplate.Data, files, "")
if err != nil {
return nil, nil, errors.Wrap(err, "load app template with CUE files")
}
if v.Error() != nil {
return nil, nil, errors.Wrap(v.Error(), "load app template with CUE files")
if v.Err() != nil {
return nil, nil, errors.Wrap(v.Err(), "load app template with CUE files")
}
outputContent, err := v.LookupValue(renderOutputCuePath)
if err != nil {
return nil, nil, errors.Wrap(err, "render app from output field from CUE")
outputContent := v.LookupPath(cue.ParsePath(renderOutputCuePath))
if !outputContent.Exists() {
return nil, nil, errors.Wrap(workflowerrors.LookUpNotFoundErr(renderOutputCuePath), "render app from output field from CUE")
}
err = outputContent.UnmarshalTo(&app)
err = value.UnmarshalTo(outputContent, &app)
if err != nil {
return nil, nil, errors.Wrap(err, "decode app from CUE")
}
auxiliaryContent, err := v.LookupValue(renderAuxiliaryOutputsPath)
if err != nil {
auxiliaryContent := v.LookupPath(cue.ParsePath(renderAuxiliaryOutputsPath))
if !auxiliaryContent.Exists() {
// no outputs defined in app template, return normal data
if verrors.IsCuePathNotFound(err) {
return &app, res, nil
}
return nil, nil, errors.Wrap(err, "render app from output field from CUE")
return &app, res, nil
}
err = auxiliaryContent.UnmarshalTo(&outputs)
err = value.UnmarshalTo(auxiliaryContent, &outputs)
if err != nil {
return nil, nil, errors.Wrap(err, "decode app from CUE")
}
@ -184,49 +180,49 @@ func (a addonCueTemplateRender) renderApp() (*v1beta1.Application, []*unstructur
}
// newValueWithMainAndFiles new a value from main and appendix files
func newValueWithMainAndFiles(main string, slaveFiles []string, pd *packages.PackageDiscover, tagTempl string, opts ...func(*ast.File) error) (*value.Value, error) {
func newValueWithMainAndFiles(main string, slaveFiles []string, _ string, opts ...func(*ast.File) error) (cue.Value, error) {
builder := &build.Instance{}
mainFile, err := parser.ParseFile("main.cue", main, parser.ParseComments)
mainFile = kubevelafix.Fix(mainFile).(*ast.File)
if err != nil {
return nil, errors.Wrap(err, "parse main file")
return cue.Value{}, errors.Wrap(err, "parse main file")
}
if mainFile.PackageName() == "" {
// add a default package main if not exist
mainFile, err = parser.ParseFile("main.cue", defaultPackageHeader+main, parser.ParseComments)
if err != nil {
return nil, errors.Wrap(err, "parse main file with added package main header")
return cue.Value{}, errors.Wrap(err, "parse main file with added package main header")
}
}
for _, opt := range opts {
if err := opt(mainFile); err != nil {
return nil, errors.Wrap(err, "run option func for main file")
return cue.Value{}, errors.Wrap(err, "run option func for main file")
}
}
if err := builder.AddSyntax(mainFile); err != nil {
return nil, errors.Wrap(err, "add main file to CUE builder")
return cue.Value{}, errors.Wrap(err, "add main file to CUE builder")
}
for idx, sf := range slaveFiles {
cueSF, err := parser.ParseFile("sf-"+strconv.Itoa(idx)+".cue", sf, parser.ParseComments)
cueSF = kubevelafix.Fix(cueSF).(*ast.File)
if err != nil {
return nil, errors.Wrap(err, "parse added file "+strconv.Itoa(idx)+" \n"+sf)
return cue.Value{}, errors.Wrap(err, "parse added file "+strconv.Itoa(idx)+" \n"+sf)
}
if cueSF.PackageName() != mainFile.PackageName() {
continue
}
for _, opt := range opts {
if err := opt(cueSF); err != nil {
return nil, errors.Wrap(err, "run option func for files")
return cue.Value{}, errors.Wrap(err, "run option func for files")
}
}
if err := builder.AddSyntax(cueSF); err != nil {
return nil, errors.Wrap(err, "add slave files to CUE builder")
return cue.Value{}, errors.Wrap(err, "add slave files to CUE builder")
}
}
return value.NewValueWithInstance(builder, pd, tagTempl)
return cuecontext.New().BuildInstance(builder), nil
}
// generateAppFramework generate application from yaml defined by template.yaml or cue file from template.cue

View File

@ -39,8 +39,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log/zap"
coreoam "github.com/oam-dev/kubevela/apis/core.oam.dev"
"github.com/kubevela/workflow/pkg/cue/packages"
// +kubebuilder:scaffold:imports
)
@ -48,7 +46,6 @@ var cfg *rest.Config
var scheme *runtime.Scheme
var k8sClient client.Client
var testEnv *envtest.Environment
var pd *packages.PackageDiscover
var testns string
var dc *discovery.DiscoveryClient
@ -87,9 +84,6 @@ var _ = BeforeSuite(func() {
Expect(err).ToNot(HaveOccurred())
Expect(dc).ShouldNot(BeNil())
pd, err = packages.NewPackageDiscover(cfg)
Expect(err).ToNot(HaveOccurred())
Expect(pd).ToNot(BeNil())
testns = "vela-system"
Expect(k8sClient.Create(context.Background(),
&v12.Namespace{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Namespace"}, ObjectMeta: metav1.ObjectMeta{

View File

@ -23,6 +23,7 @@ import (
"reflect"
"strings"
"cuelang.org/go/cue"
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
"github.com/kubevela/pkg/util/slices"
terraformapi "github.com/oam-dev/terraform-controller/api/v1beta2"
@ -85,7 +86,7 @@ type Component struct {
Traits []*Trait
FullTemplate *Template
Ctx process.Context
Patch *value.Value
Patch *cue.Value
engine definition.AbstractEngine
SkipApplyWorkload bool
}
@ -533,14 +534,14 @@ func baseGenerateComponent(pCtx process.Context, comp *Component, appName, ns st
}
if patcher := comp.Patch; patcher != nil {
workload, auxiliaries := pCtx.Output()
if p, err := patcher.LookupValue("workload"); err == nil {
if err := workload.Unify(p.CueValue()); err != nil {
if p := patcher.LookupPath(cue.ParsePath("workload")); p.Exists() {
if err := workload.Unify(p); err != nil {
return nil, errors.WithMessage(err, "patch workload")
}
}
for _, aux := range auxiliaries {
if p, err := patcher.LookupByScript(fmt.Sprintf("traits[\"%s\"]", aux.Name)); err == nil && p.CueValue().Err() == nil {
if err := aux.Ins.Unify(p.CueValue()); err != nil {
if p, err := value.LookupValueByScript(*patcher, fmt.Sprintf("traits[\"%s\"]", aux.Name)); err == nil && p.Err() == nil {
if err := aux.Ins.Unify(p); err != nil {
return nil, errors.WithMessagef(err, "patch outputs.%s", aux.Name)
}
}

View File

@ -386,7 +386,7 @@ variable "password" {
},
},
CapabilityCategory: oamtypes.TerraformCategory,
engine: definition.NewWorkloadAbstractEngine(compName, pd),
engine: definition.NewWorkloadAbstractEngine(compName),
Params: map[string]interface{}{
"variable": map[string]interface{}{
"account_name": "oamtest",
@ -716,7 +716,7 @@ func TestBaseGenerateComponent(t *testing.T) {
assert.NoError(t, err)
tr := &Trait{
Name: traitName,
engine: definition.NewTraitAbstractEngine(traitName, nil),
engine: definition.NewTraitAbstractEngine(traitName),
Template: `outputs:mytrait:{
if context.componentType == "stateless" {
kind: "Deployment"
@ -759,7 +759,7 @@ var _ = Describe("Test use context.appLabels& context.appAnnotations in componen
"image": "busybox",
"cmd": []interface{}{"sleep", "1000"},
},
engine: definition.NewWorkloadAbstractEngine("myweb", pd),
engine: definition.NewWorkloadAbstractEngine("myweb"),
FullTemplate: &Template{
TemplateStr: `
output: {

View File

@ -30,7 +30,6 @@ import (
"sigs.k8s.io/yaml"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
@ -41,9 +40,9 @@ import (
)
// NewLiveDiffOption creates a live-diff option
func NewLiveDiffOption(c client.Client, cfg *rest.Config, pd *packages.PackageDiscover, as []*unstructured.Unstructured) *LiveDiffOption {
parser := appfile.NewApplicationParser(c, pd)
return &LiveDiffOption{DryRun: NewDryRunOption(c, cfg, pd, as, false), Parser: parser}
func NewLiveDiffOption(c client.Client, cfg *rest.Config, as []*unstructured.Unstructured) *LiveDiffOption {
parser := appfile.NewApplicationParser(c)
return &LiveDiffOption{DryRun: NewDryRunOption(c, cfg, as, false), Parser: parser}
}
// ManifestKind enums the kind of OAM objects

View File

@ -153,8 +153,8 @@ var _ = Describe("Test Live-Diff", func() {
It("Test renderless diff", func() {
liveDiffOpt := LiveDiffOption{
DryRun: NewDryRunOption(k8sClient, cfg, pd, nil, false),
Parser: appfile.NewApplicationParser(k8sClient, pd),
DryRun: NewDryRunOption(k8sClient, cfg, nil, false),
Parser: appfile.NewApplicationParser(k8sClient),
}
applyFile := func(filename string, ns string) {
bs, err := os.ReadFile("./testdata/" + filename)

View File

@ -35,8 +35,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
@ -56,9 +54,9 @@ type DryRun interface {
}
// NewDryRunOption creates a dry-run option
func NewDryRunOption(c client.Client, cfg *rest.Config, pd *packages.PackageDiscover, as []*unstructured.Unstructured, serverSideDryRun bool) *Option {
parser := appfile.NewDryRunApplicationParser(c, pd, as)
return &Option{c, pd, parser, parser.GenerateAppFileFromApp, cfg, as, serverSideDryRun}
func NewDryRunOption(c client.Client, cfg *rest.Config, as []*unstructured.Unstructured, serverSideDryRun bool) *Option {
parser := appfile.NewDryRunApplicationParser(c, as)
return &Option{c, parser, parser.GenerateAppFileFromApp, cfg, as, serverSideDryRun}
}
// GenerateAppFileFunc generate the app file model from an application
@ -67,7 +65,6 @@ type GenerateAppFileFunc func(ctx context.Context, app *v1beta1.Application) (*a
// Option contains options to execute dry-run
type Option struct {
Client client.Client
PackageDiscover *packages.PackageDiscover
Parser *appfile.Parser
GenerateAppFile GenerateAppFileFunc
cfg *rest.Config
@ -227,7 +224,7 @@ func (d *Option) ExecuteDryRunWithPolicies(ctx context.Context, application *v1b
app.Namespace = appNs.(string)
}
ctx = oamutil.SetNamespaceInCtx(ctx, app.Namespace)
parser := appfile.NewDryRunApplicationParser(d.Client, d.PackageDiscover, d.Auxiliaries)
parser := appfile.NewDryRunApplicationParser(d.Client, d.Auxiliaries)
af, err := parser.GenerateAppFileFromApp(ctx, app)
if err != nil {
return err

View File

@ -43,8 +43,6 @@ import (
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"github.com/kubevela/workflow/pkg/cue/packages"
coreoam "github.com/oam-dev/kubevela/apis/core.oam.dev"
"github.com/oam-dev/kubevela/pkg/appfile"
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
@ -54,7 +52,6 @@ var cfg *rest.Config
var scheme *runtime.Scheme
var k8sClient client.Client
var testEnv *envtest.Environment
var pd *packages.PackageDiscover
var dryrunOpt *Option
var diffOpt *LiveDiffOption
@ -85,9 +82,6 @@ var _ = BeforeSuite(func() {
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme})
Expect(err).ToNot(HaveOccurred())
Expect(k8sClient).ToNot(BeNil())
pd, err = packages.NewPackageDiscover(cfg)
Expect(err).ToNot(HaveOccurred())
Expect(pd).ToNot(BeNil())
By("Prepare capability definitions")
myingressYAML := readDataFromFile("./testdata/td-myingress.yaml")
@ -113,8 +107,8 @@ var _ = BeforeSuite(func() {
wfsd.SetNamespace(types.DefaultKubeVelaNS)
Expect(k8sClient.Create(context.TODO(), &wfsd)).Should(BeNil())
dryrunOpt = NewDryRunOption(k8sClient, cfg, pd, []*unstructured.Unstructured{cdMyWorker, tdMyIngress}, false)
diffOpt = &LiveDiffOption{DryRun: dryrunOpt, Parser: appfile.NewApplicationParser(k8sClient, pd)}
dryrunOpt = NewDryRunOption(k8sClient, cfg, []*unstructured.Unstructured{cdMyWorker, tdMyIngress}, false)
diffOpt = &LiveDiffOption{DryRun: dryrunOpt, Parser: appfile.NewApplicationParser(k8sClient)}
})
var _ = AfterSuite(func() {

View File

@ -33,7 +33,6 @@ import (
monitorContext "github.com/kubevela/pkg/monitor/context"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
@ -63,24 +62,21 @@ func (fn TemplateLoaderFn) LoadTemplate(ctx context.Context, c client.Client, ca
// Parser is an application parser
type Parser struct {
client client.Client
pd *packages.PackageDiscover
tmplLoader TemplateLoaderFn
}
// NewApplicationParser create appfile parser
func NewApplicationParser(cli client.Client, pd *packages.PackageDiscover) *Parser {
func NewApplicationParser(cli client.Client) *Parser {
return &Parser{
client: cli,
pd: pd,
tmplLoader: LoadTemplate,
}
}
// NewDryRunApplicationParser create an appfile parser for DryRun
func NewDryRunApplicationParser(cli client.Client, pd *packages.PackageDiscover, defs []*unstructured.Unstructured) *Parser {
func NewDryRunApplicationParser(cli client.Client, defs []*unstructured.Unstructured) *Parser {
return &Parser{
client: cli,
pd: pd,
tmplLoader: DryRunTemplateLoader(defs),
}
}
@ -515,7 +511,7 @@ func (p *Parser) convertTemplate2Component(name, typ string, props *runtime.RawE
CapabilityCategory: templ.CapabilityCategory,
FullTemplate: templ,
Params: settings,
engine: definition.NewWorkloadAbstractEngine(name, p.pd),
engine: definition.NewWorkloadAbstractEngine(name),
}, nil
}
@ -710,7 +706,7 @@ func (p *Parser) convertTemplate2Trait(name string, properties map[string]interf
HealthCheckPolicy: templ.Health,
CustomStatusFormat: templ.CustomStatus,
FullTemplate: templ,
engine: definition.NewTraitAbstractEngine(traitName, p.pd),
engine: definition.NewTraitAbstractEngine(traitName),
}, nil
}

View File

@ -265,21 +265,21 @@ var _ = Describe("Test application parser", func() {
},
}
appfile, err := NewApplicationParser(&tclient, pd).GenerateAppFile(context.TODO(), &o)
appfile, err := NewApplicationParser(&tclient).GenerateAppFile(context.TODO(), &o)
Expect(err).ShouldNot(HaveOccurred())
Expect(equal(expectedExceptApp, appfile)).Should(BeTrue())
notfound := v1beta1.Application{}
err = yaml.Unmarshal([]byte(appfileYaml2), &notfound)
Expect(err).ShouldNot(HaveOccurred())
_, err = NewApplicationParser(&tclient, pd).GenerateAppFile(context.TODO(), &notfound)
_, err = NewApplicationParser(&tclient).GenerateAppFile(context.TODO(), &notfound)
Expect(err).Should(HaveOccurred())
By("app with empty policy")
emptyPolicy := v1beta1.Application{}
err = yaml.Unmarshal([]byte(appfileYamlEmptyPolicy), &emptyPolicy)
Expect(err).ShouldNot(HaveOccurred())
_, err = NewApplicationParser(&tclient, pd).GenerateAppFile(context.TODO(), &emptyPolicy)
_, err = NewApplicationParser(&tclient).GenerateAppFile(context.TODO(), &emptyPolicy)
Expect(err).Should(HaveOccurred())
Expect(err.Error()).Should(ContainSubstring("have empty properties"))
})
@ -439,7 +439,7 @@ patch: spec: replicas: parameter.replicas
It("Test we can parse an application revision to an appFile 1", func() {
appfile, err := NewApplicationParser(&mockClient, pd).GenerateAppFile(context.TODO(), &app)
appfile, err := NewApplicationParser(&mockClient).GenerateAppFile(context.TODO(), &app)
Expect(err).ShouldNot(HaveOccurred())
Expect(equal(expectedExceptAppfile, appfile)).Should(BeTrue())
Expect(len(appfile.WorkflowSteps) > 0 &&
@ -469,7 +469,7 @@ patch: spec: replicas: parameter.replicas
It("Test we can parse an application revision to an appFile 2", func() {
appfile, err := NewApplicationParser(&mockClient, pd).GenerateAppFile(context.TODO(), &app)
appfile, err := NewApplicationParser(&mockClient).GenerateAppFile(context.TODO(), &app)
Expect(err).ShouldNot(HaveOccurred())
Expect(equal(expectedExceptAppfile, appfile)).Should(BeTrue())
Expect(len(appfile.WorkflowSteps) > 0 &&
@ -500,7 +500,7 @@ patch: spec: replicas: parameter.replicas
It("Test we can parse an application revision to an appFile 3", func() {
_, err := NewApplicationParser(&mockClient, pd).GenerateAppFile(context.TODO(), &app)
_, err := NewApplicationParser(&mockClient).GenerateAppFile(context.TODO(), &app)
Expect(err).Should(HaveOccurred())
Expect(err.Error()).Should(SatisfyAll(
ContainSubstring("failed to get workflow step definition apply-application-unknown: not found"),
@ -594,7 +594,7 @@ func TestParser_parseTraits(t *testing.T) {
},
}
p := NewApplicationParser(nil, pd)
p := NewApplicationParser(nil)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p.tmplLoader = tt.mockTemplateLoaderFn
@ -696,7 +696,7 @@ func TestParser_parseTraitsFromRevision(t *testing.T) {
},
},
}
p := NewApplicationParser(fake.NewClientBuilder().Build(), pd)
p := NewApplicationParser(fake.NewClientBuilder().Build())
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.wantErr(t, p.parseTraitsFromRevision(tt.args.comp, tt.args.appRev, tt.args.workload), fmt.Sprintf("parseTraitsFromRevision(%v, %v, %v)", tt.args.comp, tt.args.appRev, tt.args.workload))

View File

@ -32,8 +32,6 @@ import (
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"github.com/kubevela/workflow/pkg/cue/packages"
coreoam "github.com/oam-dev/kubevela/apis/core.oam.dev"
// +kubebuilder:scaffold:imports
)
@ -42,7 +40,6 @@ var cfg *rest.Config
var scheme *runtime.Scheme
var k8sClient client.Client
var testEnv *envtest.Environment
var pd *packages.PackageDiscover
func TestAppFile(t *testing.T) {
RegisterFailHandler(Fail)
@ -71,9 +68,6 @@ var _ = BeforeSuite(func() {
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme})
Expect(err).ToNot(HaveOccurred())
Expect(k8sClient).ToNot(BeNil())
pd, err = packages.NewPackageDiscover(cfg)
Expect(err).ToNot(HaveOccurred())
Expect(pd).ToNot(BeNil())
})
var _ = AfterSuite(func() {

View File

@ -43,19 +43,19 @@ var _ = Describe("Test validate CUE schematic Appfile", func() {
Name: "myscaler",
CapabilityCategory: types.CUECategory,
Template: tc.traitDefTmpl1,
engine: definition.NewTraitAbstractEngine("myscaler", pd),
engine: definition.NewTraitAbstractEngine("myscaler"),
},
{
Name: "myingress",
CapabilityCategory: types.CUECategory,
Template: tc.traitDefTmpl2,
engine: definition.NewTraitAbstractEngine("myingress", pd),
engine: definition.NewTraitAbstractEngine("myingress"),
},
},
FullTemplate: &Template{
TemplateStr: tc.compDefTmpl,
},
engine: definition.NewWorkloadAbstractEngine("myweb", pd),
engine: definition.NewWorkloadAbstractEngine("myweb"),
}
ctxData := GenerateContextDataFromAppFile(&Appfile{

View File

@ -33,8 +33,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
ctrlutils "github.com/oam-dev/kubevela/pkg/controller/utils"
"github.com/oam-dev/kubevela/pkg/features"
"github.com/oam-dev/kubevela/pkg/utils/apply"
)
var (
@ -104,7 +104,7 @@ func (in *ObjectCache[T]) DeleteRef(hash string, ref string) {
// Remap relocate the object ptr with given ref
func (in *ObjectCache[T]) Remap(m map[string]*T, ref string) {
for key, o := range m {
if hash, err := ctrlutils.ComputeSpecHash(o); err == nil {
if hash, err := apply.ComputeSpecHash(o); err == nil {
m[key] = in.Add(hash, o, ref)
}
}
@ -113,7 +113,7 @@ func (in *ObjectCache[T]) Remap(m map[string]*T, ref string) {
// Unmap drop all the hash object from the map
func (in *ObjectCache[T]) Unmap(m map[string]*T, ref string) {
for _, o := range m {
if hash, err := ctrlutils.ComputeSpecHash(o); err == nil {
if hash, err := apply.ComputeSpecHash(o); err == nil {
in.DeleteRef(hash, ref)
}
}

View File

@ -214,7 +214,7 @@ func (e *Validation) Error() string {
// Factory handle the config
type Factory interface {
ParseTemplate(defaultName string, content []byte) (*Template, error)
ParseTemplate(ctx context.Context, defaultName string, content []byte) (*Template, error)
ParseConfig(ctx context.Context, template NamespacedName, meta Metadata) (*Config, error)
LoadTemplate(ctx context.Context, name, ns string) (*Template, error)
@ -269,9 +269,9 @@ type kubeConfigFactory struct {
}
// ParseTemplate parse a config template instance form the cue script
func (k *kubeConfigFactory) ParseTemplate(defaultName string, content []byte) (*Template, error) {
func (k *kubeConfigFactory) ParseTemplate(ctx context.Context, defaultName string, content []byte) (*Template, error) {
cueScript := script.BuildCUEScriptWithDefaultContext(icontext.DefaultContext, content)
value, err := cueScript.ParseToTemplateValueWithCueX()
value, err := cueScript.ParseToTemplateValueWithCueX(ctx)
if err != nil {
return nil, fmt.Errorf("the cue script is invalid:%w", err)
}
@ -292,7 +292,7 @@ func (k *kubeConfigFactory) ParseTemplate(defaultName string, content []byte) (*
if !templateValue.Exists() {
return nil, fmt.Errorf("failed to lookup value: var(path=template) not exist")
}
schema, err := cueScript.ParsePropertiesToSchemaWithCueX("template")
schema, err := cueScript.ParsePropertiesToSchemaWithCueX(ctx, "template")
if err != nil {
return nil, fmt.Errorf("the properties of the cue script is invalid:%w", err)
}

View File

@ -34,7 +34,7 @@ func TestParseConfigTemplate(t *testing.T) {
content, err := os.ReadFile("testdata/helm-repo.cue")
r.Equal(err, nil)
var inf = &kubeConfigFactory{}
template, err := inf.ParseTemplate("default", content)
template, err := inf.ParseTemplate(context.Background(), "default", content)
r.Equal(err, nil)
r.NotEqual(template, nil)
r.Equal(template.Name, "default")
@ -52,7 +52,7 @@ var _ = Describe("test config factory", func() {
It("apply the nacos server template", func() {
data, err := os.ReadFile("./testdata/nacos-server.cue")
Expect(err).Should(BeNil())
t, err := fac.ParseTemplate("", data)
t, err := fac.ParseTemplate(context.Background(), "", data)
Expect(err).Should(BeNil())
Expect(fac.CreateOrUpdateConfigTemplate(context.TODO(), "default", t)).Should(BeNil())
})
@ -78,7 +78,7 @@ var _ = Describe("test config factory", func() {
By("apply a template that with the nacos writer")
data, err := os.ReadFile("./testdata/mysql-db-nacos.cue")
Expect(err).Should(BeNil())
t, err := fac.ParseTemplate("", data)
t, err := fac.ParseTemplate(context.Background(), "", data)
Expect(err).Should(BeNil())
Expect(t.ExpandedWriter.Nacos).ShouldNot(BeNil())
Expect(t.ExpandedWriter.Nacos.Endpoint.Name).Should(Equal("nacos"))

View File

@ -1,147 +0,0 @@
/*
Copyright 2023 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package provider
import (
"errors"
"strings"
"sigs.k8s.io/controller-runtime/pkg/client"
monitorContext "github.com/kubevela/pkg/monitor/context"
wfContext "github.com/kubevela/workflow/pkg/context"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/kubevela/workflow/pkg/types"
"github.com/oam-dev/kubevela/pkg/config"
)
const (
// ProviderName is provider name
ProviderName = "config"
)
// ErrRequestInvalid means the request is invalid
var ErrRequestInvalid = errors.New("the request is in valid")
type provider struct {
factory config.Factory
}
// CreateConfigProperties the request body for creating a config
type CreateConfigProperties struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Template string `json:"template,omitempty"`
Config map[string]interface{} `json:"config"`
}
// Response the response body
type Response struct {
Status string `json:"status"`
Message string `json:"message"`
}
func (p *provider) Create(ctx monitorContext.Context, _ wfContext.Context, v *value.Value, _ types.Action) error {
var ccp CreateConfigProperties
if err := v.UnmarshalTo(&ccp); err != nil {
return ErrRequestInvalid
}
name := ccp.Template
namespace := "vela-system"
if strings.Contains(ccp.Template, "/") {
namespacedName := strings.SplitN(ccp.Template, "/", 2)
namespace = namespacedName[0]
name = namespacedName[1]
}
configItem, err := p.factory.ParseConfig(ctx.GetContext(), config.NamespacedName{
Name: name,
Namespace: namespace,
}, config.Metadata{
NamespacedName: config.NamespacedName{
Name: ccp.Name,
Namespace: ccp.Namespace,
},
Properties: ccp.Config,
})
if err != nil {
return err
}
return p.factory.CreateOrUpdateConfig(ctx.GetContext(), configItem, ccp.Namespace)
}
func (p *provider) Read(ctx monitorContext.Context, _ wfContext.Context, v *value.Value, _ types.Action) error {
var nn config.NamespacedName
if err := v.UnmarshalTo(&nn); err != nil {
return ErrRequestInvalid
}
content, err := p.factory.ReadConfig(ctx.GetContext(), nn.Namespace, nn.Name)
if err != nil {
return err
}
return v.FillObject(content, "config")
}
func (p *provider) List(ctx monitorContext.Context, _ wfContext.Context, v *value.Value, _ types.Action) error {
template, err := v.GetString("template")
if err != nil {
return ErrRequestInvalid
}
namespace, err := v.GetString("namespace")
if err != nil {
return ErrRequestInvalid
}
if strings.Contains(template, "/") {
namespacedName := strings.SplitN(template, "/", 2)
template = namespacedName[1]
}
configs, err := p.factory.ListConfigs(ctx.GetContext(), namespace, template, "", false)
if err != nil {
return err
}
var contents = []map[string]interface{}{}
for _, c := range configs {
contents = append(contents, map[string]interface{}{
"name": c.Name,
"alias": c.Alias,
"description": c.Description,
"config": c.Properties,
})
}
return v.FillObject(contents, "configs")
}
func (p *provider) Delete(ctx monitorContext.Context, _ wfContext.Context, v *value.Value, _ types.Action) error {
var nn config.NamespacedName
if err := v.UnmarshalTo(&nn); err != nil {
return errors.New("the request is in valid")
}
return p.factory.DeleteConfig(ctx.GetContext(), nn.Namespace, nn.Name)
}
// Install register handlers to provider discover.
func Install(p types.Providers, cli client.Client, apply config.Dispatcher) {
prd := &provider{
factory: config.NewConfigFactoryWithDispatcher(cli, apply),
}
p.Register(ProviderName, map[string]types.Handler{
"create": prd.Create,
"read": prd.Read,
"list": prd.List,
"delete": prd.Delete,
})
}

View File

@ -22,6 +22,7 @@ import (
"runtime/debug"
"strings"
"cuelang.org/go/cue"
"github.com/nacos-group/nacos-sdk-go/v2/clients"
"github.com/nacos-group/nacos-sdk-go/v2/clients/config_client"
"github.com/nacos-group/nacos-sdk-go/v2/common/constant"
@ -32,7 +33,6 @@ import (
"github.com/oam-dev/kubevela/apis/types"
icontext "github.com/oam-dev/kubevela/pkg/config/context"
"github.com/oam-dev/kubevela/pkg/cue"
"github.com/oam-dev/kubevela/pkg/cue/script"
)
@ -62,15 +62,17 @@ type NacosData struct {
}
// parseNacosConfig parse the nacos server config
func parseNacosConfig(templateField *value.Value, wc *ExpandedWriterConfig) {
nacos, _ := templateField.LookupValue("nacos")
if nacos != nil {
format, err := nacos.GetString("format")
if err != nil && !cue.IsFieldNotExist(err) {
func parseNacosConfig(templateField cue.Value, wc *ExpandedWriterConfig) {
nacos := templateField.LookupPath(cue.ParsePath("nacos"))
if nacos.Err() == nil {
formatValue := nacos.LookupPath(cue.ParsePath("format"))
format, err := formatValue.String()
if err != nil {
klog.Warningf("fail to get the format from the nacos config: %s", err.Error())
}
endpoint, err := nacos.GetString("endpoint", "name")
if err != nil && !cue.IsFieldNotExist(err) {
endpointValue := nacos.LookupPath(value.FieldPath("endpoint", "name"))
endpoint, err := endpointValue.String()
if err != nil {
klog.Warningf("fail to get the endpoint name from the nacos config: %s", err.Error())
}
wc.Nacos = &NacosConfig{
@ -87,17 +89,18 @@ func renderNacos(config *NacosConfig, template script.CUE, context icontext.Conf
if err != nil {
return nil, err
}
format, err := nacos.GetString("format")
formatValue := nacos.LookupPath(cue.ParsePath("format"))
format, err := formatValue.String()
if err != nil {
format = config.Format
}
var nacosData NacosData
if err := nacos.UnmarshalTo(&nacosData); err != nil {
if err := value.UnmarshalTo(nacos, &nacosData); err != nil {
return nil, err
}
content, err := nacos.LookupValue("content")
if err != nil {
return nil, err
content := nacos.LookupPath(cue.ParsePath("content"))
if content.Err() != nil {
return nil, content.Err()
}
out, err := encodingOutput(content, format)

View File

@ -25,7 +25,7 @@ import (
"github.com/nacos-group/nacos-sdk-go/v2/vo"
"github.com/stretchr/testify/require"
"github.com/kubevela/workflow/pkg/cue/model/value"
"cuelang.org/go/cue/cuecontext"
configcontext "github.com/oam-dev/kubevela/pkg/config/context"
"github.com/oam-dev/kubevela/pkg/cue/script"
@ -34,15 +34,15 @@ import (
func TestNacosWriter(t *testing.T) {
r := require.New(t)
v, err := value.NewValue(`
v := cuecontext.New().CompileString(`
nacos: {
endpoint: {
name: "test-nacos-server"
}
format: "json"
}
`, nil, "")
r.Equal(err, nil)
`)
r.Equal(v.Err(), nil)
ewc := &ExpandedWriterConfig{}
parseNacosConfig(v, ewc)
r.Equal(ewc.Nacos.Endpoint.Name, "test-nacos-server")

View File

@ -25,13 +25,12 @@ import (
"cuelang.org/go/cue"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/magiconair/properties"
"github.com/pelletier/go-toml"
"gopkg.in/yaml.v3"
"k8s.io/klog/v2"
"github.com/kubevela/workflow/pkg/cue/model/value"
icontext "github.com/oam-dev/kubevela/pkg/config/context"
"github.com/oam-dev/kubevela/pkg/cue/script"
)
@ -94,9 +93,9 @@ func Write(ctx context.Context, ewd *ExpandedWriterData, ri icontext.ReadConfigP
}
// encodingOutput support the json、toml、xml、properties and yaml formats.
func encodingOutput(input *value.Value, format string) ([]byte, error) {
func encodingOutput(input cue.Value, format string) ([]byte, error) {
var data = make(map[string]interface{})
if err := input.UnmarshalTo(&data); err != nil {
if err := value.UnmarshalTo(input, &data); err != nil {
return nil, err
}
switch strings.ToLower(format) {

View File

@ -19,7 +19,7 @@ package writer
import (
"testing"
"github.com/kubevela/workflow/pkg/cue/model/value"
"cuelang.org/go/cue/cuecontext"
"github.com/stretchr/testify/require"
)
@ -70,10 +70,10 @@ func TestEncodingOutput(t *testing.T) {
key9: {key10: [{"wang": true}]}
}
`
v, err := value.NewValue(testValue, nil, "")
r.Equal(err, nil)
v := cuecontext.New().CompileString(testValue)
r.Equal(v.Err(), nil)
_, err = encodingOutput(v, "yaml")
_, err := encodingOutput(v, "yaml")
r.Equal(err, nil)
_, err = encodingOutput(v, "properties")

View File

@ -18,8 +18,6 @@ package core_oam_dev
import (
"github.com/spf13/pflag"
"github.com/kubevela/workflow/pkg/cue/packages"
)
// Args args used by controller
@ -37,9 +35,6 @@ type Args struct {
// The default value is 20.
DefRevisionLimit int
// PackageDiscover used for CRD discovery in CUE packages, a K8s client is contained in it.
PackageDiscover *packages.PackageDiscover
// ConcurrentReconciles is the concurrent reconcile number of the controller
ConcurrentReconciles int

View File

@ -45,7 +45,6 @@ import (
monitorContext "github.com/kubevela/pkg/monitor/context"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
wfContext "github.com/kubevela/workflow/pkg/context"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/kubevela/workflow/pkg/executor"
wffeatures "github.com/kubevela/workflow/pkg/features"
@ -86,7 +85,6 @@ var (
// Reconciler reconciles an Application object
type Reconciler struct {
client.Client
pd *packages.PackageDiscover
Scheme *runtime.Scheme
Recorder event.Recorder
options
@ -139,7 +137,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
setVelaVersion(app)
logCtx.AddTag("publish_version", app.GetAnnotations()[oam.AnnotationPublishVersion])
appParser := appfile.NewApplicationParser(r.Client, r.pd)
appParser := appfile.NewApplicationParser(r.Client)
handler, err := NewAppHandler(logCtx, r, app)
if err != nil {
return r.endWithNegativeCondition(logCtx, app, condition.ReconcileError(err), common.ApplicationStarting)
@ -203,7 +201,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
app.Status.SetConditions(condition.ReadyCondition(common.RenderCondition.String()))
r.Recorder.Event(app, event.Normal(velatypes.ReasonRendered, velatypes.MessageRendered))
workflowExecutor := executor.New(workflowInstance, r.Client, nil)
workflowExecutor := executor.New(workflowInstance)
authCtx := logCtx.Fork("execute application workflow")
defer authCtx.Commit("finish execute application workflow")
authCtx = auth.MonitorContextWithUserInfo(authCtx, app)
@ -600,7 +598,6 @@ func Setup(mgr ctrl.Manager, args core.Args) error {
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Recorder: event.NewAPIRecorder(mgr.GetEventRecorderFor("Application")),
pd: args.PackageDiscover,
options: parseOptions(args),
}
return reconciler.SetupWithManager(mgr)

View File

@ -20,7 +20,6 @@ import (
"context"
"sync"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
@ -47,7 +46,6 @@ import (
// AppHandler handles application reconcile
type AppHandler struct {
client.Client
pd *packages.PackageDiscover
app *v1beta1.Application
currentAppRev *v1beta1.ApplicationRevision
@ -78,14 +76,13 @@ func NewAppHandler(ctx context.Context, r *Reconciler, app *v1beta1.Application)
}
return &AppHandler{
Client: r.Client,
pd: r.pd,
app: app,
resourceKeeper: resourceHandler,
}, nil
}
// Dispatch apply manifests into k8s.
func (h *AppHandler) Dispatch(ctx context.Context, cluster string, owner string, manifests ...*unstructured.Unstructured) error {
func (h *AppHandler) Dispatch(ctx context.Context, _ client.Client, cluster string, owner string, manifests ...*unstructured.Unstructured) error {
manifests = multicluster.ResourcesWithClusterName(cluster, manifests...)
if err := h.resourceKeeper.Dispatch(ctx, manifests, nil); err != nil {
return err
@ -113,7 +110,7 @@ func (h *AppHandler) Dispatch(ctx context.Context, cluster string, owner string,
}
// Delete delete manifests from k8s.
func (h *AppHandler) Delete(ctx context.Context, cluster string, owner string, manifest *unstructured.Unstructured) error {
func (h *AppHandler) Delete(ctx context.Context, _ client.Client, cluster string, owner string, manifest *unstructured.Unstructured) error {
manifests := multicluster.ResourcesWithClusterName(cluster, manifest)
if err := h.resourceKeeper.Delete(ctx, manifests); err != nil {
return err
@ -224,11 +221,11 @@ func (h *AppHandler) addServiceStatus(cover bool, svcs ...common.ApplicationComp
}
// collectTraitHealthStatus collect trait health status
func (h *AppHandler) collectTraitHealthStatus(comp *appfile.Component, tr *appfile.Trait, appRev *v1beta1.ApplicationRevision, overrideNamespace string) (common.ApplicationTraitStatus, []*unstructured.Unstructured, error) {
func (h *AppHandler) collectTraitHealthStatus(comp *appfile.Component, tr *appfile.Trait, overrideNamespace string) (common.ApplicationTraitStatus, []*unstructured.Unstructured, error) {
defer func(clusterName string) {
comp.Ctx.SetCtx(pkgmulticluster.WithCluster(comp.Ctx.GetCtx(), clusterName))
}(multicluster.ClusterNameInContext(comp.Ctx.GetCtx()))
appRev := h.currentAppRev
var (
pCtx = comp.Ctx
appName = appRev.Spec.Application.Name
@ -259,10 +256,11 @@ func (h *AppHandler) collectTraitHealthStatus(comp *appfile.Component, tr *appfi
}
// collectWorkloadHealthStatus collect workload health status
func (h *AppHandler) collectWorkloadHealthStatus(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision, status *common.ApplicationComponentStatus, accessor util.NamespaceAccessor) (bool, *unstructured.Unstructured, []*unstructured.Unstructured, error) {
func (h *AppHandler) collectWorkloadHealthStatus(ctx context.Context, comp *appfile.Component, status *common.ApplicationComponentStatus, accessor util.NamespaceAccessor) (bool, *unstructured.Unstructured, []*unstructured.Unstructured, error) {
var output *unstructured.Unstructured
var outputs []*unstructured.Unstructured
var (
appRev = h.currentAppRev
appName = appRev.Spec.Application.Name
isHealth = true
)
@ -303,7 +301,7 @@ func (h *AppHandler) collectWorkloadHealthStatus(ctx context.Context, comp *appf
// nolint
// collectHealthStatus will collect health status of component, including component itself and traits.
func (h *AppHandler) collectHealthStatus(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision, overrideNamespace string, skipWorkload bool, traitFilters ...TraitFilter) (*common.ApplicationComponentStatus, *unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
func (h *AppHandler) collectHealthStatus(ctx context.Context, comp *appfile.Component, overrideNamespace string, skipWorkload bool, traitFilters ...TraitFilter) (*common.ApplicationComponentStatus, *unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
output := new(unstructured.Unstructured)
outputs := make([]*unstructured.Unstructured, 0)
accessor := util.NewApplicationResourceNamespaceAccessor(h.app.Namespace, overrideNamespace)
@ -321,7 +319,7 @@ func (h *AppHandler) collectHealthStatus(ctx context.Context, comp *appfile.Comp
status = h.getServiceStatus(status)
if !skipWorkload {
isHealth, output, outputs, err = h.collectWorkloadHealthStatus(ctx, comp, appRev, &status, accessor)
isHealth, output, outputs, err = h.collectWorkloadHealthStatus(ctx, comp, &status, accessor)
if err != nil {
return nil, nil, nil, false, err
}
@ -337,7 +335,7 @@ collectNext:
}
}
traitStatus, _outputs, err := h.collectTraitHealthStatus(comp, tr, appRev, overrideNamespace)
traitStatus, _outputs, err := h.collectTraitHealthStatus(comp, tr, overrideNamespace)
if err != nil {
return nil, nil, nil, false, err
}
@ -405,7 +403,7 @@ func (h *AppHandler) ApplyPolicies(ctx context.Context, af *appfile.Appfile) err
oam.LabelAppNamespace: h.app.GetNamespace(),
})
}
if err = h.Dispatch(ctx, "", common.PolicyResourceCreator, policyManifests...); err != nil {
if err = h.Dispatch(ctx, h.Client, "", common.PolicyResourceCreator, policyManifests...); err != nil {
return errors.Wrapf(err, "failed to dispatch policy manifests")
}
}

View File

@ -227,7 +227,7 @@ var _ = Describe("Test deleter resource", func() {
h, err := NewAppHandler(ctx, reconciler, &v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Name: "example", Namespace: "default"}})
Expect(err).Should(Succeed())
h.appliedResources = appliedRsc
Expect(h.Delete(ctx, "", common.WorkflowResourceCreator, &u))
Expect(h.Delete(ctx, h.Client, "", common.WorkflowResourceCreator, &u))
checkDeploy := unstructured.Unstructured{}
checkDeploy.SetAPIVersion("apps/v1")
checkDeploy.SetKind("Deployment")

View File

@ -36,8 +36,6 @@ import (
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/appfile"
// +kubebuilder:scaffold:imports
@ -89,10 +87,8 @@ var _ = BeforeSuite(func() {
k8sClient, err = client.New(cfg, client.Options{Scheme: testScheme})
Expect(err).ToNot(HaveOccurred())
Expect(k8sClient).ToNot(BeNil())
pd, err := packages.NewPackageDiscover(cfg)
Expect(err).To(BeNil())
appParser = appfile.NewApplicationParser(k8sClient, pd)
appParser = appfile.NewApplicationParser(k8sClient)
})
var _ = AfterSuite(func() {

View File

@ -129,7 +129,7 @@ func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, rea
if !h.resourceKeeper.ContainsResources(manifests) {
return false, nil
}
_, _, _, isHealth, err := h.collectHealthStatus(ctx, comp, appRev, options.OverrideNamespace, skipWorkload,
_, _, _, isHealth, err := h.collectHealthStatus(ctx, comp, options.OverrideNamespace, skipWorkload,
ByTraitType(readyTraits, options.Traits))
if err != nil {
return false, err
@ -139,10 +139,10 @@ func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, rea
dispatcher.run = func(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision, clusterName string) (bool, error) {
skipWorkload, dispatchManifests := assembleManifestFn(comp.SkipApplyWorkload)
if isHealth, err := dispatcher.healthCheck(ctx, comp, appRev); !isHealth || err != nil {
if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, dispatchManifests...); err != nil {
if err := h.Dispatch(ctx, h.Client, clusterName, common.WorkflowResourceCreator, dispatchManifests...); err != nil {
return false, errors.WithMessage(err, "Dispatch")
}
status, _, _, isHealth, err := h.collectHealthStatus(ctx, comp, appRev, options.OverrideNamespace, skipWorkload,
status, _, _, isHealth, err := h.collectHealthStatus(ctx, comp, options.OverrideNamespace, skipWorkload,
ByTraitType(readyTraits, options.Traits))
if err != nil {
return false, errors.WithMessage(err, "CollectHealthStatus")

View File

@ -545,7 +545,7 @@ var _ = Describe("Test Application with GC options", func() {
return errors.New("app is not in running status")
}
return nil
}, 3*time.Second, 300*time.Second).Should(BeNil())
}, 3*time.Second, time.Second).Should(BeNil())
By("check the resourceTrackers number")
listOpts := []client.ListOption{

View File

@ -18,15 +18,15 @@ package application
import (
"context"
"encoding/json"
"os"
"strings"
"time"
"cuelang.org/go/cue"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/klog/v2"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"
@ -34,11 +34,9 @@ import (
pkgmulticluster "github.com/kubevela/pkg/multicluster"
"github.com/kubevela/pkg/util/slices"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/kubevela/workflow/pkg/executor"
"github.com/kubevela/workflow/pkg/generator"
"github.com/kubevela/workflow/pkg/providers"
"github.com/kubevela/workflow/pkg/providers/kube"
providertypes "github.com/kubevela/workflow/pkg/providers/types"
wfTypes "github.com/kubevela/workflow/pkg/types"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
@ -47,7 +45,7 @@ import (
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/auth"
configprovider "github.com/oam-dev/kubevela/pkg/config/provider"
"github.com/oam-dev/kubevela/pkg/config"
"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1/application/assemble"
ctrlutil "github.com/oam-dev/kubevela/pkg/controller/utils"
velaprocess "github.com/oam-dev/kubevela/pkg/cue/process"
@ -56,22 +54,12 @@ import (
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/stdlib"
"github.com/oam-dev/kubevela/pkg/utils/apply"
"github.com/oam-dev/kubevela/pkg/velaql/providers/query"
multiclusterProvider "github.com/oam-dev/kubevela/pkg/workflow/providers/multicluster"
oamProvider "github.com/oam-dev/kubevela/pkg/workflow/providers/oam"
terraformProvider "github.com/oam-dev/kubevela/pkg/workflow/providers/terraform"
"github.com/oam-dev/kubevela/pkg/workflow/providers"
oamprovidertypes "github.com/oam-dev/kubevela/pkg/workflow/providers/legacy/types"
"github.com/oam-dev/kubevela/pkg/workflow/template"
)
func init() {
if err := stdlib.SetupBuiltinImports(); err != nil {
klog.ErrorS(err, "Unable to set up builtin imports on package initialization")
os.Exit(1)
}
}
var (
// DisableResourceApplyDoubleCheck optimize applyComponentFunc by disable post resource existing check after dispatch
DisableResourceApplyDoubleCheck = false
@ -94,40 +82,36 @@ func (h *AppHandler) GenerateApplicationSteps(ctx monitorContext.Context,
oam.LabelAppName: app.Name,
oam.LabelAppNamespace: app.Namespace,
}
handlerProviders := providers.NewProviders()
kube.Install(handlerProviders, h.Client, appLabels, &kube.Handlers{
Apply: h.Dispatch,
Delete: h.Delete,
})
configprovider.Install(handlerProviders, h.Client, func(ctx context.Context, resources []*unstructured.Unstructured, applyOptions []apply.ApplyOption) error {
for _, res := range resources {
res.SetLabels(util.MergeMapOverrideWithDst(res.GetLabels(), appLabels))
}
return h.resourceKeeper.Dispatch(ctx, resources, applyOptions)
})
oamProvider.Install(handlerProviders, app, af, h.Client,
h.applyComponentFunc(appParser, appRev, af),
h.renderComponentFunc(appParser, appRev, af),
)
pCtx := velaprocess.NewContext(generateContextDataFromApp(app, appRev.Name))
renderer := func(ctx context.Context, comp common.ApplicationComponent) (*appfile.Component, error) {
return appParser.ParseComponentFromRevisionAndClient(ctx, comp, appRev)
}
multiclusterProvider.Install(handlerProviders, h.Client, app, af,
h.applyComponentFunc(appParser, appRev, af),
h.checkComponentHealth(appParser, appRev, af),
renderer)
terraformProvider.Install(handlerProviders, app, renderer)
query.Install(handlerProviders, h.Client, nil)
ctxWithRuntimeParams := oamprovidertypes.WithRuntimeParams(ctx.GetContext(), oamprovidertypes.RuntimeParams{
ComponentApply: h.applyComponentFunc(appParser, af),
ComponentRender: h.renderComponentFunc(appParser, af),
ComponentHealthCheck: h.checkComponentHealth(appParser, af),
WorkloadRender: func(ctx context.Context, comp common.ApplicationComponent) (*appfile.Component, error) {
return appParser.ParseComponentFromRevisionAndClient(ctx, comp, appRev)
},
App: app,
AppLabels: appLabels,
Appfile: af,
KubeHandlers: &providertypes.KubeHandlers{
Apply: h.Dispatch,
Delete: h.Delete,
},
ConfigFactory: config.NewConfigFactoryWithDispatcher(h.Client, func(ctx context.Context, resources []*unstructured.Unstructured, applyOptions []apply.ApplyOption) error {
for _, res := range resources {
res.SetLabels(util.MergeMapOverrideWithDst(res.GetLabels(), appLabels))
}
return h.resourceKeeper.Dispatch(ctx, resources, applyOptions)
}),
KubeClient: h.Client,
})
ctx.SetContext(ctxWithRuntimeParams)
instance := generateWorkflowInstance(af, app)
executor.InitializeWorkflowInstance(instance)
runners, err := generator.GenerateRunners(ctx, instance, wfTypes.StepGeneratorOptions{
Providers: handlerProviders,
PackageDiscover: h.pd,
ProcessCtx: pCtx,
TemplateLoader: template.NewWorkflowStepTemplateRevisionLoader(appRev, h.Client.RESTMapper()),
Client: h.Client,
Compiler: providers.Compiler.Get(),
ProcessCtx: pCtx,
TemplateLoader: template.NewWorkflowStepTemplateRevisionLoader(appRev, h.Client.RESTMapper()),
StepConvertor: map[string]func(step workflowv1alpha1.WorkflowStep) (workflowv1alpha1.WorkflowStep, error){
wfTypes.WorkflowStepTypeApplyComponent: func(lstep workflowv1alpha1.WorkflowStep) (workflowv1alpha1.WorkflowStep, error) {
copierStep := lstep.DeepCopy()
@ -317,31 +301,31 @@ func checkDependsOnValidComponent(dependsOnComponentNames, allComponentNames []s
return "", true
}
func (h *AppHandler) renderComponentFunc(appParser *appfile.Parser, appRev *v1beta1.ApplicationRevision, af *appfile.Appfile) oamProvider.ComponentRender {
return func(baseCtx context.Context, comp common.ApplicationComponent, patcher *value.Value, clusterName string, overrideNamespace string) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
func (h *AppHandler) renderComponentFunc(appParser *appfile.Parser, af *appfile.Appfile) oamprovidertypes.ComponentRender {
return func(baseCtx context.Context, comp common.ApplicationComponent, patcher *cue.Value, clusterName string, overrideNamespace string) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
ctx := multicluster.ContextWithClusterName(baseCtx, clusterName)
_, manifest, err := h.prepareWorkloadAndManifests(ctx, appParser, comp, appRev, patcher, af)
_, manifest, err := h.prepareWorkloadAndManifests(ctx, appParser, comp, patcher, af)
if err != nil {
return nil, nil, err
}
return renderComponentsAndTraits(manifest, appRev, clusterName, overrideNamespace)
return renderComponentsAndTraits(manifest, h.currentAppRev, clusterName, overrideNamespace)
}
}
func (h *AppHandler) checkComponentHealth(appParser *appfile.Parser, appRev *v1beta1.ApplicationRevision, af *appfile.Appfile) oamProvider.ComponentHealthCheck {
return func(baseCtx context.Context, comp common.ApplicationComponent, patcher *value.Value, clusterName string, overrideNamespace string) (bool, *unstructured.Unstructured, []*unstructured.Unstructured, error) {
func (h *AppHandler) checkComponentHealth(appParser *appfile.Parser, af *appfile.Appfile) oamprovidertypes.ComponentHealthCheck {
return func(baseCtx context.Context, comp common.ApplicationComponent, patcher *cue.Value, clusterName string, overrideNamespace string) (bool, *unstructured.Unstructured, []*unstructured.Unstructured, error) {
ctx := multicluster.ContextWithClusterName(baseCtx, clusterName)
ctx = contextWithComponentNamespace(ctx, overrideNamespace)
ctx = contextWithReplicaKey(ctx, comp.ReplicaKey)
wl, manifest, err := h.prepareWorkloadAndManifests(ctx, appParser, comp, appRev, patcher, af)
wl, manifest, err := h.prepareWorkloadAndManifests(ctx, appParser, comp, patcher, af)
if err != nil {
return false, nil, nil, err
}
wl.Ctx.SetCtx(auth.ContextWithUserInfo(ctx, h.app))
readyWorkload, readyTraits, err := renderComponentsAndTraits(manifest, appRev, clusterName, overrideNamespace)
readyWorkload, readyTraits, err := renderComponentsAndTraits(manifest, h.currentAppRev, clusterName, overrideNamespace)
if err != nil {
return false, nil, nil, err
}
@ -355,7 +339,7 @@ func (h *AppHandler) checkComponentHealth(appParser *appfile.Parser, appRev *v1b
return false, nil, nil, err
}
_, output, outputs, isHealth, err := h.collectHealthStatus(auth.ContextWithUserInfo(ctx, h.app), wl, appRev, overrideNamespace, false)
_, output, outputs, isHealth, err := h.collectHealthStatus(auth.ContextWithUserInfo(ctx, h.app), wl, overrideNamespace, false)
if err != nil {
return false, nil, nil, err
}
@ -364,16 +348,17 @@ func (h *AppHandler) checkComponentHealth(appParser *appfile.Parser, appRev *v1b
}
}
func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1beta1.ApplicationRevision, af *appfile.Appfile) oamProvider.ComponentApply {
return func(baseCtx context.Context, comp common.ApplicationComponent, patcher *value.Value, clusterName string, overrideNamespace string) (*unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, af *appfile.Appfile) oamprovidertypes.ComponentApply {
return func(baseCtx context.Context, comp common.ApplicationComponent, patcher *cue.Value, clusterName string, overrideNamespace string) (*unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
t := time.Now()
appRev := h.currentAppRev
defer func() { metrics.ApplyComponentTimeHistogram.WithLabelValues("-").Observe(time.Since(t).Seconds()) }()
ctx := multicluster.ContextWithClusterName(baseCtx, clusterName)
ctx = contextWithComponentNamespace(ctx, overrideNamespace)
ctx = contextWithReplicaKey(ctx, comp.ReplicaKey)
wl, manifest, err := h.prepareWorkloadAndManifests(ctx, appParser, comp, appRev, patcher, af)
wl, manifest, err := h.prepareWorkloadAndManifests(ctx, appParser, comp, patcher, af)
if err != nil {
return nil, nil, false, err
}
@ -403,10 +388,10 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
dispatchResources = append([]*unstructured.Unstructured{readyWorkload}, readyTraits...)
}
if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, dispatchResources...); err != nil {
if err := h.Dispatch(ctx, h.Client, clusterName, common.WorkflowResourceCreator, dispatchResources...); err != nil {
return nil, nil, false, errors.WithMessage(err, "Dispatch")
}
_, _, _, isHealth, err = h.collectHealthStatus(ctx, wl, appRev, overrideNamespace, false)
_, _, _, isHealth, err = h.collectHealthStatus(ctx, wl, overrideNamespace, false)
if err != nil {
return nil, nil, false, errors.WithMessage(err, "CollectHealthStatus")
}
@ -438,10 +423,9 @@ func redirectTraitToLocalIfNeed(appRev *v1beta1.ApplicationRevision, readyTraits
func (h *AppHandler) prepareWorkloadAndManifests(ctx context.Context,
appParser *appfile.Parser,
comp common.ApplicationComponent,
appRev *v1beta1.ApplicationRevision,
patcher *value.Value,
patcher *cue.Value,
af *appfile.Appfile) (*appfile.Component, *types.ComponentManifest, error) {
wl, err := appParser.ParseComponentFromRevisionAndClient(ctx, comp, appRev)
wl, err := appParser.ParseComponentFromRevisionAndClient(ctx, comp, h.currentAppRev)
if err != nil {
return nil, nil, errors.WithMessage(err, "ParseWorkload")
}

View File

@ -165,7 +165,7 @@ var _ = Describe("test generate revision ", func() {
It("Test application revision compare", func() {
By("Apply the application")
appParser := appfile.NewApplicationParser(reconciler.Client, reconciler.pd)
appParser := appfile.NewApplicationParser(reconciler.Client)
ctx = util.SetNamespaceInCtx(ctx, app.Namespace)
generatedAppfile, err := appParser.GenerateAppFile(ctx, &app)
Expect(err).Should(Succeed())
@ -186,7 +186,7 @@ var _ = Describe("test generate revision ", func() {
It("Test apply success for none rollout case", func() {
By("Apply the application")
appParser := appfile.NewApplicationParser(reconciler.Client, reconciler.pd)
appParser := appfile.NewApplicationParser(reconciler.Client)
ctx = util.SetNamespaceInCtx(ctx, app.Namespace)
annoKey1 := "testKey1"
app.SetAnnotations(map[string]string{annoKey1: "true"})
@ -337,7 +337,7 @@ var _ = Describe("test generate revision ", func() {
It("Test apply passes all label and annotation from app to appRevision", func() {
By("Apply the application")
appParser := appfile.NewApplicationParser(reconciler.Client, reconciler.pd)
appParser := appfile.NewApplicationParser(reconciler.Client)
ctx = util.SetNamespaceInCtx(ctx, app.Namespace)
labelKey1 := "labelKey1"
app.SetLabels(map[string]string{labelKey1: "true"})
@ -723,7 +723,7 @@ status: {}
It("Test currentAppRevIsNew func", func() {
By("Backport 1.2 version that WorkflowStepDefinitions are not patched to application revision")
// generate appfile
appfile, err := appfile.NewApplicationParser(reconciler.Client, reconciler.pd).GenerateAppFile(ctx, &app)
appfile, err := appfile.NewApplicationParser(reconciler.Client).GenerateAppFile(ctx, &app)
ctx = util.SetNamespaceInCtx(ctx, app.Namespace)
Expect(err).To(Succeed())
Expect(handler.PrepareCurrentAppRevision(ctx, appfile)).Should(Succeed())

View File

@ -27,6 +27,7 @@ import (
"time"
"github.com/crossplane/crossplane-runtime/pkg/event"
"github.com/kubevela/pkg/util/singleton"
terraformv1beta2 "github.com/oam-dev/terraform-controller/api/v1beta2"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@ -45,8 +46,6 @@ import (
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/multicluster"
@ -109,15 +108,12 @@ var _ = BeforeSuite(func() {
k8sClient, err = client.New(cfg, client.Options{Scheme: testScheme})
Expect(err).ToNot(HaveOccurred())
Expect(k8sClient).ToNot(BeNil())
pd, err := packages.NewPackageDiscover(cfg)
Expect(err).To(BeNil())
appParser = appfile.NewApplicationParser(k8sClient, pd)
singleton.KubeClient.Set(k8sClient)
appParser = appfile.NewApplicationParser(k8sClient)
reconciler = &Reconciler{
Client: k8sClient,
Scheme: testScheme,
pd: pd,
Recorder: event.NewAPIRecorder(recorder),
}

View File

@ -381,6 +381,8 @@ var _ = Describe("Test Workflow", func() {
},
}
b, _ := json.Marshal(appwithInputOutput)
fmt.Println("app", string(b))
Expect(k8sClient.Create(context.Background(), appwithInputOutput)).Should(BeNil())
appKey := types.NamespacedName{Namespace: ns.Name, Name: appwithInputOutput.Name}
testutil.ReconcileOnceAfterFinalizer(reconciler, reconcile.Request{NamespacedName: appKey})
@ -824,8 +826,12 @@ spec:
}
}
// wait until workload.status equal "Running"
w: *false | bool
if apply.value.spec != _|_ if apply.value.spec.key != "" {
w: true
}
wait: op.#ConditionalWait & {
continue: apply.value.spec.key != ""
continue: w
}
`
)

View File

@ -23,6 +23,7 @@ import (
"testing"
"time"
"github.com/kubevela/pkg/util/singleton"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
@ -71,6 +72,7 @@ var _ = BeforeSuite(func() {
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
Expect(err).ToNot(HaveOccurred())
Expect(k8sClient).ToNot(BeNil())
singleton.KubeClient.Set(k8sClient)
By("Starting the controller in the background")
mgr, err := ctrl.NewManager(cfg, ctrl.Options{

View File

@ -40,8 +40,8 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/cue/script"
"github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/schema"
"github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/oam-dev/kubevela/pkg/utils/terraform"
)
@ -121,12 +121,12 @@ func NewCapabilityComponentDef(componentDefinition *v1beta1.ComponentDefinition)
}
// GetOpenAPISchema gets OpenAPI v3 schema by WorkloadDefinition name
func (def *CapabilityComponentDefinition) GetOpenAPISchema(name string) ([]byte, error) {
func (def *CapabilityComponentDefinition) GetOpenAPISchema(ctx context.Context, name string) ([]byte, error) {
capability, err := appfile.ConvertTemplateJSON2Object(name, def.ComponentDefinition.Spec.Extension, def.ComponentDefinition.Spec.Schematic)
if err != nil {
return nil, fmt.Errorf("failed to convert ComponentDefinition to Capability Object")
}
return getOpenAPISchema(capability)
return getOpenAPISchema(ctx, capability)
}
// GetOpenAPISchemaFromTerraformComponentDefinition gets OpenAPI v3 schema by WorkloadDefinition name
@ -383,7 +383,7 @@ func (def *CapabilityComponentDefinition) StoreOpenAPISchema(ctx context.Context
}
jsonSchema, err = GetOpenAPISchemaFromTerraformComponentDefinition(configuration)
default:
jsonSchema, err = def.GetOpenAPISchema(name)
jsonSchema, err = def.GetOpenAPISchema(ctx, name)
}
if err != nil {
return "", fmt.Errorf("failed to generate OpenAPI v3 JSON schema for capability %s: %w", def.Name, err)
@ -441,17 +441,17 @@ func NewCapabilityTraitDef(traitdefinition *v1beta1.TraitDefinition) CapabilityT
}
// GetOpenAPISchema gets OpenAPI v3 schema by TraitDefinition name
func (def *CapabilityTraitDefinition) GetOpenAPISchema(name string) ([]byte, error) {
func (def *CapabilityTraitDefinition) GetOpenAPISchema(ctx context.Context, name string) ([]byte, error) {
capability, err := appfile.ConvertTemplateJSON2Object(name, def.TraitDefinition.Spec.Extension, def.TraitDefinition.Spec.Schematic)
if err != nil {
return nil, fmt.Errorf("failed to convert WorkloadDefinition to Capability Object")
}
return getOpenAPISchema(capability)
return getOpenAPISchema(ctx, capability)
}
// StoreOpenAPISchema stores OpenAPI v3 schema from TraitDefinition in ConfigMap
func (def *CapabilityTraitDefinition) StoreOpenAPISchema(ctx context.Context, k8sClient client.Client, namespace, name string, revName string) (string, error) {
jsonSchema, err := def.GetOpenAPISchema(name)
jsonSchema, err := def.GetOpenAPISchema(ctx, name)
if err != nil {
return "", fmt.Errorf("failed to generate OpenAPI v3 JSON schema for capability %s: %w", def.Name, err)
}
@ -507,12 +507,12 @@ func NewCapabilityStepDef(stepdefinition *v1beta1.WorkflowStepDefinition) Capabi
}
// GetOpenAPISchema gets OpenAPI v3 schema by StepDefinition name
func (def *CapabilityStepDefinition) GetOpenAPISchema(name string) ([]byte, error) {
func (def *CapabilityStepDefinition) GetOpenAPISchema(ctx context.Context, name string) ([]byte, error) {
capability, err := appfile.ConvertTemplateJSON2Object(name, nil, def.StepDefinition.Spec.Schematic)
if err != nil {
return nil, fmt.Errorf("failed to convert WorkflowStepDefinition to Capability Object")
}
return getOpenAPISchema(capability)
return getOpenAPISchema(ctx, capability)
}
// StoreOpenAPISchema stores OpenAPI v3 schema from StepDefinition in ConfigMap
@ -520,7 +520,7 @@ func (def *CapabilityStepDefinition) StoreOpenAPISchema(ctx context.Context, k8s
var jsonSchema []byte
var err error
jsonSchema, err = def.GetOpenAPISchema(name)
jsonSchema, err = def.GetOpenAPISchema(ctx, name)
if err != nil {
return "", fmt.Errorf("failed to generate OpenAPI v3 JSON schema for capability %s: %w", def.Name, err)
}
@ -576,12 +576,12 @@ func NewCapabilityPolicyDef(policydefinition *v1beta1.PolicyDefinition) Capabili
}
// GetOpenAPISchema gets OpenAPI v3 schema by StepDefinition name
func (def *CapabilityPolicyDefinition) GetOpenAPISchema(name string) ([]byte, error) {
func (def *CapabilityPolicyDefinition) GetOpenAPISchema(ctx context.Context, name string) ([]byte, error) {
capability, err := appfile.ConvertTemplateJSON2Object(name, nil, def.PolicyDefinition.Spec.Schematic)
if err != nil {
return nil, fmt.Errorf("failed to convert WorkflowStepDefinition to Capability Object")
}
return getOpenAPISchema(capability)
return getOpenAPISchema(ctx, capability)
}
// StoreOpenAPISchema stores OpenAPI v3 schema from StepDefinition in ConfigMap
@ -589,7 +589,7 @@ func (def *CapabilityPolicyDefinition) StoreOpenAPISchema(ctx context.Context, k
var jsonSchema []byte
var err error
jsonSchema, err = def.GetOpenAPISchema(name)
jsonSchema, err = def.GetOpenAPISchema(ctx, name)
if err != nil {
return "", fmt.Errorf("failed to generate OpenAPI v3 JSON schema for capability %s: %w", def.Name, err)
}
@ -687,14 +687,13 @@ func (def *CapabilityBaseDefinition) CreateOrUpdateConfigMap(ctx context.Context
}
// getOpenAPISchema is the main function for GetDefinition API
func getOpenAPISchema(capability types.Capability) ([]byte, error) {
cueTemplate := script.CUE(capability.CueTemplate)
schema, err := cueTemplate.ParsePropertiesToSchema()
func getOpenAPISchema(ctx context.Context, capability types.Capability) ([]byte, error) {
s, err := schema.ParsePropertiesToSchema(ctx, capability.CueTemplate)
if err != nil {
return nil, err
}
klog.Infof("parsed %d properties by %s/%s", len(schema.Properties), capability.Type, capability.Name)
parameter, err := schema.MarshalJSON()
klog.Infof("parsed %d properties by %s/%s", len(s.Properties), capability.Type, capability.Name)
parameter, err := s.MarshalJSON()
if err != nil {
return nil, err
}

View File

@ -111,7 +111,7 @@ spec:
def := &CapabilityComponentDefinition{Name: componentDefinitionName, ComponentDefinition: *componentDefinition.DeepCopy()}
By("Test GetOpenAPISchema")
schema, err := def.GetOpenAPISchema(namespace)
schema, err := def.GetOpenAPISchema(context.Background(), namespace)
Expect(err).Should(BeNil())
Expect(schema).Should(Not(BeNil()))
})

View File

@ -29,15 +29,12 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"github.com/kubevela/workflow/pkg/cue/packages"
oamCore "github.com/oam-dev/kubevela/apis/core.oam.dev"
)
var cfg *rest.Config
var k8sClient client.Client
var testEnv *envtest.Environment
var pd *packages.PackageDiscover
func TestCapability(t *testing.T) {
RegisterFailHandler(Fail)
@ -67,9 +64,6 @@ var _ = BeforeSuite(func() {
k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
Expect(err).ToNot(HaveOccurred())
Expect(k8sClient).ToNot(BeNil())
pd, err = packages.NewPackageDiscover(cfg)
Expect(err).ToNot(HaveOccurred())
})
var _ = AfterSuite(func() {

View File

@ -187,7 +187,7 @@ parameter: [string]: string
},
}
capability, _ := appfile.ConvertTemplateJSON2Object(tc.name, nil, schematic)
schema, err := getOpenAPISchema(capability)
schema, err := getOpenAPISchema(context.Background(), capability)
if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" {
t.Errorf("\n%s\ngetOpenAPISchema(...): -want error, +got error:\n%s", tc.reason, diff)
}

View File

@ -18,13 +18,10 @@ package cue
import (
"errors"
"fmt"
"strings"
"cuelang.org/go/cue"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/kubevela/workflow/pkg/cue/packages"
"cuelang.org/go/cue/cuecontext"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/cue/process"
@ -34,16 +31,13 @@ import (
var ErrParameterNotExist = errors.New("parameter not exist")
// GetParameters get parameter from cue template
func GetParameters(templateStr string, pd *packages.PackageDiscover) ([]types.Parameter, error) {
template, err := value.NewValue(templateStr+BaseTemplate, pd, "")
if err != nil {
return nil, fmt.Errorf("error in template: %w", err)
}
paramVal, err := template.LookupValue(process.ParameterFieldName)
if err != nil || !paramVal.CueValue().Exists() {
func GetParameters(templateStr string) ([]types.Parameter, error) {
template := cuecontext.New().CompileString(templateStr + BaseTemplate)
paramVal := template.LookupPath(cue.ParsePath(process.ParameterFieldName))
if !paramVal.Exists() {
return nil, ErrParameterNotExist
}
iter, err := paramVal.CueValue().Fields(cue.Definitions(true), cue.Hidden(true), cue.All())
iter, err := paramVal.Fields(cue.Definitions(true), cue.Hidden(true), cue.All())
if err != nil {
return nil, err
}

View File

@ -28,7 +28,7 @@ import (
func TestGetParameter(t *testing.T) {
data, _ := os.ReadFile("testdata/workloads/metrics.cue")
params, err := GetParameters(string(data), nil)
params, err := GetParameters(string(data))
assert.NoError(t, err)
assert.Equal(t, params, []types.Parameter{
{Name: "format", Required: false, Default: "prometheus", Usage: "format of the metrics, " +
@ -38,7 +38,7 @@ func TestGetParameter(t *testing.T) {
{Name: "selector", Required: false, Usage: "the label selector for the pods, default is the workload labels", Type: cue.StructKind},
})
data, _ = os.ReadFile("testdata/workloads/deployment.cue")
params, err = GetParameters(string(data), nil)
params, err = GetParameters(string(data))
assert.NoError(t, err)
assert.Equal(t, []types.Parameter{
{Name: "name", Required: true, Default: "", Type: cue.StringKind},
@ -50,7 +50,7 @@ func TestGetParameter(t *testing.T) {
params)
data, _ = os.ReadFile("testdata/workloads/test-param.cue")
params, err = GetParameters(string(data), nil)
params, err = GetParameters(string(data))
assert.NoError(t, err)
assert.Equal(t, []types.Parameter{
{Name: "name", Required: true, Default: "", Type: cue.StringKind},
@ -61,13 +61,13 @@ func TestGetParameter(t *testing.T) {
{Name: "fval", Default: 64.3, Type: cue.FloatKind},
{Name: "nval", Default: float64(0), Required: true, Type: cue.NumberKind}}, params)
data, _ = os.ReadFile("testdata/workloads/empty.cue")
params, err = GetParameters(string(data), nil)
params, err = GetParameters(string(data))
assert.NoError(t, err)
var exp []types.Parameter
assert.Equal(t, exp, params)
data, _ = os.ReadFile("testdata/workloads/webservice.cue") // test cue parameter with "// +ignore" annotation
params, err = GetParameters(string(data), nil) // Only test for func RetrieveComments
params, err = GetParameters(string(data)) // Only test for func RetrieveComments
assert.NoError(t, err)
var flag bool
for _, para := range params {

View File

@ -23,8 +23,8 @@ import (
"github.com/oam-dev/kubevela/pkg/cue/cuex/providers/config"
)
// KubeVelaDefaultCompiler compiler for cuex to compile
var KubeVelaDefaultCompiler = singleton.NewSingleton[*cuex.Compiler](func() *cuex.Compiler {
// ConfigCompiler ...
var ConfigCompiler = singleton.NewSingleton[*cuex.Compiler](func() *cuex.Compiler {
compiler := cuex.NewCompilerWithInternalPackages(
config.Package,
)

View File

@ -20,9 +20,9 @@ import (
"context"
"encoding/json"
"fmt"
"strings"
"cuelang.org/go/cue"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/cuecontext"
"github.com/kubevela/pkg/multicluster"
@ -33,7 +33,6 @@ import (
"github.com/kubevela/workflow/pkg/cue/model"
"github.com/kubevela/workflow/pkg/cue/model/sets"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/kubevela/workflow/pkg/cue/process"
velaprocess "github.com/oam-dev/kubevela/pkg/cue/process"
@ -75,7 +74,6 @@ type AbstractEngine interface {
type def struct {
name string
pd *packages.PackageDiscover
}
type workloadDef struct {
@ -83,21 +81,16 @@ type workloadDef struct {
}
// NewWorkloadAbstractEngine create Workload Definition AbstractEngine
func NewWorkloadAbstractEngine(name string, pd *packages.PackageDiscover) AbstractEngine {
func NewWorkloadAbstractEngine(name string) AbstractEngine {
return &workloadDef{
def: def{
name: name,
pd: pd,
},
}
}
// Complete do workload definition's rendering
func (wd *workloadDef) Complete(ctx process.Context, abstractTemplate string, params interface{}) error {
bi := build.NewContext().NewInstance("", nil)
if err := value.AddFile(bi, "-", renderTemplate(abstractTemplate)); err != nil {
return errors.WithMessagef(err, "invalid cue template of workload %s", wd.name)
}
var paramFile = velaprocess.ParameterFieldName + ": {}"
if params != nil {
bt, err := json.Marshal(params)
@ -108,22 +101,15 @@ func (wd *workloadDef) Complete(ctx process.Context, abstractTemplate string, pa
paramFile = fmt.Sprintf("%s: %s", velaprocess.ParameterFieldName, string(bt))
}
}
if err := value.AddFile(bi, velaprocess.ParameterFieldName, paramFile); err != nil {
return errors.WithMessagef(err, "invalid parameter of workload %s", wd.name)
}
c, err := ctx.BaseContextFile()
if err != nil {
return err
}
if err := value.AddFile(bi, "context", c); err != nil {
return err
}
val, err := wd.pd.ImportPackagesAndBuildValue(bi)
if err != nil {
return err
}
val := cuecontext.New().CompileString(strings.Join([]string{
renderTemplate(abstractTemplate), paramFile, c,
}, "\n"))
if err := val.Validate(); err != nil {
return errors.WithMessagef(err, "invalid cue template of workload %s after merge parameter and context", wd.name)
@ -260,10 +246,10 @@ func checkHealth(templateContext map[string]interface{}, healthPolicyTemplate st
// Status get workload status by customStatusTemplate
func (wd *workloadDef) Status(templateContext map[string]interface{}, customStatusTemplate string, parameter interface{}) (string, error) {
return getStatusMessage(wd.pd, templateContext, customStatusTemplate, parameter)
return getStatusMessage(templateContext, customStatusTemplate, parameter)
}
func getStatusMessage(pd *packages.PackageDiscover, templateContext map[string]interface{}, customStatusTemplate string, parameter interface{}) (string, error) {
func getStatusMessage(templateContext map[string]interface{}, customStatusTemplate string, parameter interface{}) (string, error) {
if customStatusTemplate == "" {
return "", nil
}
@ -273,11 +259,11 @@ func getStatusMessage(pd *packages.PackageDiscover, templateContext map[string]i
}
var buff = customStatusTemplate + "\n" + runtimeContextBuff
val, err := value.NewValue(buff, pd, "")
if err != nil {
return "", errors.WithMessage(err, "compile status template")
val := cuecontext.New().CompileString(buff)
if val.Err() != nil {
return "", errors.WithMessage(val.Err(), "compile status template")
}
message, err := val.CueValue().LookupPath(value.FieldPath(CustomMessage)).String()
message, err := val.LookupPath(value.FieldPath(CustomMessage)).String()
if err != nil {
return "", errors.WithMessage(err, "evaluate customStatus.message")
}
@ -293,11 +279,10 @@ type traitDef struct {
}
// NewTraitAbstractEngine create Trait Definition AbstractEngine
func NewTraitAbstractEngine(name string, pd *packages.PackageDiscover) AbstractEngine {
func NewTraitAbstractEngine(name string) AbstractEngine {
return &traitDef{
def: def{
name: name,
pd: pd,
},
}
}
@ -305,7 +290,6 @@ func NewTraitAbstractEngine(name string, pd *packages.PackageDiscover) AbstractE
// Complete do trait definition's rendering
// nolint:gocyclo
func (td *traitDef) Complete(ctx process.Context, abstractTemplate string, params interface{}) error {
bi := build.NewContext().NewInstance("", nil)
buff := abstractTemplate + "\n"
if params != nil {
bt, err := json.Marshal(params)
@ -321,15 +305,8 @@ func (td *traitDef) Complete(ctx process.Context, abstractTemplate string, param
return err
}
buff += c
if err := value.AddFile(bi, "-", buff); err != nil {
return errors.WithMessagef(err, "invalid context of trait %s", td.name)
}
val, err := td.pd.ImportPackagesAndBuildValue(bi)
if err != nil {
return err
}
val := cuecontext.New().CompileString(buff)
if err := val.Validate(); err != nil {
return errors.WithMessagef(err, "invalid template of trait %s after merge with parameter and context", td.name)
}
@ -479,7 +456,7 @@ func (td *traitDef) getTemplateContext(ctx process.Context, cli client.Reader, a
// Status get trait status by customStatusTemplate
func (td *traitDef) Status(templateContext map[string]interface{}, customStatusTemplate string, parameter interface{}) (string, error) {
return getStatusMessage(td.pd, templateContext, customStatusTemplate, parameter)
return getStatusMessage(templateContext, customStatusTemplate, parameter)
}
// HealthCheck address health check for trait

View File

@ -24,7 +24,6 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"github.com/kubevela/workflow/pkg/cue/packages"
wfprocess "github.com/kubevela/workflow/pkg/cue/process"
"github.com/oam-dev/kubevela/apis/types"
@ -245,7 +244,7 @@ output:{
AppRevisionName: "myapp-v1",
ClusterVersion: types.ClusterVersion{Minor: "19+"},
})
wt := NewWorkloadAbstractEngine("testWorkload", &packages.PackageDiscover{})
wt := NewWorkloadAbstractEngine("testWorkload")
err := wt.Complete(ctx, v.workloadTemplate, v.params)
hasError := err != nil
assert.Equal(t, v.hasCompileErr, hasError)
@ -1081,7 +1080,7 @@ parameter: { errs: [...string] }`,
Namespace: "default",
AppRevisionName: "myapp-v1",
})
wt := NewWorkloadAbstractEngine("-", &packages.PackageDiscover{})
wt := NewWorkloadAbstractEngine("-")
if err := wt.Complete(ctx, baseTemplate, map[string]interface{}{
"replicas": 2,
"enemies": "enemies-data",
@ -1091,7 +1090,7 @@ parameter: { errs: [...string] }`,
t.Error(err)
return
}
td := NewTraitAbstractEngine(v.traitName, &packages.PackageDiscover{})
td := NewTraitAbstractEngine(v.traitName)
r := require.New(t)
err := td.Complete(ctx, v.traitTemplate, v.params)
if v.hasCompileErr {
@ -1179,7 +1178,7 @@ outputs: service :{
},
}
for k, v := range testcases {
wd := NewWorkloadAbstractEngine(k, &packages.PackageDiscover{})
wd := NewWorkloadAbstractEngine(k)
ctx := process.NewContext(process.ContextData{
AppName: "myapp",
CompName: k,
@ -1264,7 +1263,7 @@ outputs: abc :{
},
}
for k, v := range testcases {
td := NewTraitAbstractEngine(k, &packages.PackageDiscover{})
td := NewTraitAbstractEngine(k)
ctx := process.NewContext(process.ContextData{
AppName: "myapp",
CompName: k,
@ -1476,7 +1475,7 @@ if len(context.outputs.ingress.status.loadBalancer.ingress) == 0 {
},
}
for message, ca := range cases {
gotMessage, err := getStatusMessage(&packages.PackageDiscover{}, ca.tpContext, ca.statusTemp, ca.parameter)
gotMessage, err := getStatusMessage(ca.tpContext, ca.statusTemp, ca.parameter)
assert.NoError(t, err, message)
assert.Equal(t, ca.expMessage, gotMessage, message)
}
@ -1516,12 +1515,12 @@ func TestTraitPatchSingleOutput(t *testing.T) {
Namespace: "default",
AppRevisionName: "myapp-v1",
})
wt := NewWorkloadAbstractEngine("-", &packages.PackageDiscover{})
wt := NewWorkloadAbstractEngine("-")
if err := wt.Complete(ctx, baseTemplate, map[string]interface{}{}); err != nil {
t.Error(err)
return
}
td := NewTraitAbstractEngine("single-patch", &packages.PackageDiscover{})
td := NewTraitAbstractEngine("single-patch")
r := require.New(t)
err := td.Complete(ctx, traitTemplate, map[string]string{})
r.NoError(err)
@ -1560,7 +1559,7 @@ parameter: {
},
}
for k, v := range cases {
td := NewTraitAbstractEngine(k, &packages.PackageDiscover{})
td := NewTraitAbstractEngine(k)
err := td.Complete(v.ctx, v.template, v.params)
assert.Error(t, err)
assert.Contains(t, err.Error(), v.err)

View File

@ -22,14 +22,21 @@ import (
"fmt"
"strings"
"github.com/getkin/kin-openapi/openapi3"
"github.com/kubevela/pkg/cue/cuex"
cuelang "cuelang.org/go/cue"
"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/errors"
"github.com/kubevela/workflow/pkg/cue/model/sets"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/oam-dev/kubevela/pkg/cue"
"github.com/oam-dev/kubevela/pkg/appfile"
velacuex "github.com/oam-dev/kubevela/pkg/cue/cuex"
"github.com/oam-dev/kubevela/pkg/cue/process"
"github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/utils/common"
)
// CUE the cue script with the template format
@ -45,68 +52,74 @@ import (
// ------------
type CUE string
// BaseTemplate include base info provided by KubeVela for CUE template
const BaseTemplate = `
context: {
name: string
config?: [...{
name: string
value: string
}]
...
}
`
// BuildCUEScriptWithDefaultContext build a cue script instance from a byte array.
func BuildCUEScriptWithDefaultContext(defaultContext []byte, content []byte) CUE {
return CUE(content) + "\n" + CUE(defaultContext)
}
// ParseToValue parse the cue script to cue.Value
func (c CUE) ParseToValue() (*value.Value, error) {
func (c CUE) ParseToValue() (cue.Value, error) {
// the cue script must be first, it could include the imports
template := string(c) + "\n" + cue.BaseTemplate
v, err := value.NewValue(template, nil, "")
if err != nil {
return nil, fmt.Errorf("fail to parse the template:%w", err)
}
return v, nil
template := string(c) + "\n" + BaseTemplate
v := cuecontext.New().CompileString(template)
return v, v.Err()
}
// ParseToValueWithCueX parse the cue script to cue.Value
func (c CUE) ParseToValueWithCueX() (cuelang.Value, error) {
func (c CUE) ParseToValueWithCueX(ctx context.Context) (cue.Value, error) {
// the cue script must be first, it could include the imports
template := string(c) + "\n" + cue.BaseTemplate
val, err := velacuex.KubeVelaDefaultCompiler.Get().CompileStringWithOptions(context.Background(), template, cuex.DisableResolveProviderFunctions{})
template := string(c) + "\n" + BaseTemplate
val, err := velacuex.ConfigCompiler.Get().CompileStringWithOptions(ctx, template, cuex.DisableResolveProviderFunctions{})
if err != nil {
return cuelang.Value{}, fmt.Errorf("failed to compile config template: %w", err)
return cue.Value{}, fmt.Errorf("failed to compile config template: %w", err)
}
return val, nil
}
// ParseToTemplateValue parse the cue script to cue.Value. It must include a valid template.
func (c CUE) ParseToTemplateValue() (*value.Value, error) {
func (c CUE) ParseToTemplateValue() (cue.Value, error) {
// the cue script must be first, it could include the imports
template := string(c) + "\n" + cue.BaseTemplate
v, err := value.NewValue(template, nil, "")
if err != nil {
return nil, fmt.Errorf("fail to parse the template:%w", err)
template := string(c) + "\n" + BaseTemplate
v := cuecontext.New().CompileString(template)
if v.Err() != nil {
return cue.Value{}, fmt.Errorf("fail to parse the template:%w", v.Err())
}
_, err = v.LookupValue("template")
if err != nil {
if v.Error() != nil {
return nil, fmt.Errorf("the template cue is invalid:%w", v.Error())
}
return nil, fmt.Errorf("the template cue must include the template field:%w", err)
res := v.LookupPath(value.FieldPath("template"))
if res.Err() != nil {
return cue.Value{}, fmt.Errorf("the template cue is invalid:%w", res.Err())
}
_, err = v.LookupValue("template", "parameter")
if err != nil {
return nil, fmt.Errorf("the template cue must include the template.parameter field")
parameter := v.LookupPath(value.FieldPath("template", "parameter"))
if parameter.Err() != nil {
return cue.Value{}, fmt.Errorf("the template cue must include the template.parameter field")
}
return v, nil
}
// ParseToTemplateValueWithCueX parse the cue script to cue.Value. It must include a valid template.
func (c CUE) ParseToTemplateValueWithCueX() (cuelang.Value, error) {
val, err := c.ParseToValueWithCueX()
func (c CUE) ParseToTemplateValueWithCueX(ctx context.Context) (cue.Value, error) {
val, err := c.ParseToValueWithCueX(ctx)
if err != nil {
return cuelang.Value{}, err
return cue.Value{}, err
}
templateValue := val.LookupPath(cuelang.ParsePath("template"))
templateValue := val.LookupPath(cue.ParsePath("template"))
if !templateValue.Exists() {
return cuelang.Value{}, fmt.Errorf("the template cue must include the template field")
return cue.Value{}, fmt.Errorf("the template cue must include the template field")
}
tmplParamValue := val.LookupPath(cuelang.ParsePath("template.parameter"))
tmplParamValue := val.LookupPath(cue.ParsePath("template.parameter"))
if !tmplParamValue.Exists() {
return cuelang.Value{}, fmt.Errorf("the template cue must include the template.parameter field")
return cue.Value{}, fmt.Errorf("the template cue must include the template.parameter field")
}
return val, nil
}
@ -114,87 +127,88 @@ func (c CUE) ParseToTemplateValueWithCueX() (cuelang.Value, error) {
// MergeValues merge the input values to the cue script
// The context variables could be referenced in all fields.
// The parameter only could be referenced in the template area.
func (c CUE) MergeValues(context interface{}, properties map[string]interface{}) (*value.Value, error) {
func (c CUE) MergeValues(context interface{}, properties map[string]interface{}) (cue.Value, error) {
parameterByte, err := json.Marshal(properties)
if err != nil {
return nil, fmt.Errorf("the parameter is invalid %w", err)
return cue.Value{}, fmt.Errorf("the parameter is invalid %w", err)
}
contextByte, err := json.Marshal(context)
if err != nil {
return nil, fmt.Errorf("the context is invalid %w", err)
return cue.Value{}, fmt.Errorf("the context is invalid %w", err)
}
var script = strings.Builder{}
_, err = script.WriteString(string(c) + "\n")
if err != nil {
return nil, err
return cue.Value{}, err
}
if properties != nil {
_, err = script.WriteString(fmt.Sprintf("template: parameter: %s \n", string(parameterByte)))
if err != nil {
return nil, err
return cue.Value{}, err
}
}
if context != nil {
_, err = script.WriteString(fmt.Sprintf("context: %s \n", string(contextByte)))
if err != nil {
return nil, err
return cue.Value{}, err
}
}
mergeValue, err := value.NewValue(script.String(), nil, "")
if err != nil {
return nil, err
mergeValue := cuecontext.New().CompileString(script.String())
if mergeValue.Err() != nil {
return cue.Value{}, mergeValue.Err()
}
if err := mergeValue.CueValue().Validate(); err != nil {
return nil, fmt.Errorf("fail to validate the merged value %w", err)
if err := mergeValue.Validate(); err != nil {
return cue.Value{}, fmt.Errorf("fail to validate the merged value %w", err)
}
return mergeValue, nil
}
// RunAndOutput run the cue script and return the values of the specified field.
// The output field must be under the template field.
func (c CUE) RunAndOutput(context interface{}, properties map[string]interface{}, outputField ...string) (*value.Value, error) {
func (c CUE) RunAndOutput(context interface{}, properties map[string]interface{}, outputField ...string) (cue.Value, error) {
// Validate the properties
if err := c.ValidateProperties(properties); err != nil {
return nil, err
return cue.Value{}, err
}
render, err := c.MergeValues(context, properties)
if err != nil {
return nil, fmt.Errorf("fail to merge the properties to template %w", err)
return cue.Value{}, fmt.Errorf("fail to merge the properties to template %w", err)
}
if render.Error() != nil {
return nil, fmt.Errorf("fail to merge the properties to template %w", render.Error())
if render.Err() != nil {
return cue.Value{}, fmt.Errorf("fail to merge the properties to template %w", render.Err())
}
if len(outputField) == 0 {
outputField = []string{"template", "output"}
}
return render.LookupValue(outputField...)
lookup := render.LookupPath(value.FieldPath(outputField...))
return lookup, lookup.Err()
}
// RunAndOutputWithCueX run the cue script and return the values of the specified field.
// The output field must be under the template field.
func (c CUE) RunAndOutputWithCueX(ctx context.Context, context interface{}, properties map[string]interface{}, outputField ...string) (cuelang.Value, error) {
func (c CUE) RunAndOutputWithCueX(ctx context.Context, context interface{}, properties map[string]interface{}, outputField ...string) (cue.Value, error) {
// Validate the properties
if err := c.ValidatePropertiesWithCueX(properties); err != nil {
return cuelang.Value{}, err
if err := c.ValidatePropertiesWithCueX(ctx, properties); err != nil {
return cue.Value{}, err
}
contextOption := cuex.WithExtraData("context", context)
parameterOption := cuex.WithExtraData("template.parameter", properties)
val, err := velacuex.KubeVelaDefaultCompiler.Get().CompileStringWithOptions(ctx, string(c), contextOption, parameterOption)
val, err := velacuex.ConfigCompiler.Get().CompileStringWithOptions(ctx, string(c), contextOption, parameterOption)
if !val.Exists() {
return cuelang.Value{}, fmt.Errorf("failed to compile config template")
return cue.Value{}, fmt.Errorf("failed to compile config template")
}
if err != nil {
return cuelang.Value{}, fmt.Errorf("failed to compile config template: %w", err)
return cue.Value{}, fmt.Errorf("failed to compile config template: %w", err)
}
if Error(val) != nil {
return cuelang.Value{}, fmt.Errorf("failed to compile config template: %w", Error(val))
return cue.Value{}, fmt.Errorf("failed to compile config template: %w", Error(val))
}
if len(outputField) == 0 {
return val, nil
}
outputFieldVal := val.LookupPath(cuelang.ParsePath(strings.Join(outputField, ".")))
outputFieldVal := val.LookupPath(cue.ParsePath(strings.Join(outputField, ".")))
if !outputFieldVal.Exists() {
return cuelang.Value{}, fmt.Errorf("failed to lookup value: var(path=%s) not exist", strings.Join(outputField, "."))
return cue.Value{}, fmt.Errorf("failed to lookup value: var(path=%s) not exist", strings.Join(outputField, "."))
}
return outputFieldVal, nil
}
@ -205,11 +219,11 @@ func (c CUE) ValidateProperties(properties map[string]interface{}) error {
if err != nil {
return err
}
parameter, err := template.LookupValue("template", "parameter")
if err != nil {
return err
parameter := template.LookupPath(value.FieldPath("template", "parameter"))
if parameter.Err() != nil {
return parameter.Err()
}
parameterStr, err := parameter.String()
parameterStr, err := sets.ToString(parameter)
if err != nil {
return fmt.Errorf("the parameter is invalid %w", err)
}
@ -220,14 +234,14 @@ func (c CUE) ValidateProperties(properties map[string]interface{}) error {
newCue := strings.Builder{}
newCue.WriteString(parameterStr + "\n")
newCue.WriteString(string(propertiesByte) + "\n")
newValue, err := value.NewValue(newCue.String(), nil, "")
if err != nil {
newValue := cuecontext.New().CompileString(newCue.String())
if newValue.Err() != nil {
return ConvertFieldError(newValue.Err())
}
if err := newValue.Validate(); err != nil {
return ConvertFieldError(err)
}
if err := newValue.CueValue().Validate(); err != nil {
return ConvertFieldError(err)
}
_, err = newValue.CueValue().MarshalJSON()
_, err = newValue.MarshalJSON()
if err != nil {
return ConvertFieldError(err)
}
@ -235,17 +249,17 @@ func (c CUE) ValidateProperties(properties map[string]interface{}) error {
}
// ValidatePropertiesWithCueX validate the input properties by the template
func (c CUE) ValidatePropertiesWithCueX(properties map[string]interface{}) error {
template, err := c.ParseToTemplateValueWithCueX()
func (c CUE) ValidatePropertiesWithCueX(ctx context.Context, properties map[string]interface{}) error {
template, err := c.ParseToTemplateValueWithCueX(ctx)
if err != nil {
return err
}
paramPath := cuelang.ParsePath("template.parameter")
paramPath := cue.ParsePath("template.parameter")
parameter := template.LookupPath(paramPath)
if !parameter.Exists() {
return fmt.Errorf("failed to lookup value: var(path=template.parameter) not exist")
}
props := parameter.FillPath(cuelang.ParsePath(""), properties)
props := parameter.FillPath(cue.ParsePath(""), properties)
if props.Err() != nil {
return ConvertFieldError(props.Err())
}
@ -290,7 +304,7 @@ func ConvertFieldError(err error) error {
}
// Error return value's error information.
func Error(val cuelang.Value) error {
func Error(val cue.Value) error {
if !val.Exists() {
return errors.New("empty value")
}
@ -298,7 +312,7 @@ func Error(val cuelang.Value) error {
return err
}
var gerr error
val.Walk(func(value cuelang.Value) bool {
val.Walk(func(value cue.Value) bool {
if err := value.Eval().Err(); err != nil {
gerr = err
return false
@ -307,3 +321,76 @@ func Error(val cuelang.Value) error {
}, nil)
return gerr
}
// ParsePropertiesToSchemaWithCueX parse the properties in cue script to the openapi schema
// Read the template.parameter field
func (c CUE) ParsePropertiesToSchemaWithCueX(ctx context.Context, templateFieldPath string) (*openapi3.Schema, error) {
val, err := c.ParseToValueWithCueX(ctx)
if err != nil {
return nil, err
}
var template cue.Value
if len(templateFieldPath) == 0 {
template = val
} else {
template = val.LookupPath(cue.ParsePath(templateFieldPath))
if !template.Exists() {
return nil, fmt.Errorf("failed to lookup value: var(path=%s) not exist, cue script: %s", templateFieldPath, c)
}
}
data, err := common.GenOpenAPIWithCueX(template)
if err != nil {
return nil, err
}
schema, err := ConvertOpenAPISchema2SwaggerObject(data)
if err != nil {
return nil, err
}
FixOpenAPISchema("", schema)
return schema, nil
}
// FIXME: double code with pkg/schema/schema.go to avoid import cycle
// FixOpenAPISchema fixes tainted `description` filed, missing of title `field`.
func FixOpenAPISchema(name string, schema *openapi3.Schema) {
t := schema.Type
switch t {
case "object":
for k, v := range schema.Properties {
s := v.Value
FixOpenAPISchema(k, s)
}
case "array":
if schema.Items != nil {
FixOpenAPISchema("", schema.Items.Value)
}
}
if name != "" {
schema.Title = name
}
description := schema.Description
if strings.Contains(description, appfile.UsageTag) {
description = strings.Split(description, appfile.UsageTag)[1]
}
if strings.Contains(description, appfile.ShortTag) {
description = strings.Split(description, appfile.ShortTag)[0]
description = strings.TrimSpace(description)
}
schema.Description = description
}
// ConvertOpenAPISchema2SwaggerObject converts OpenAPI v2 JSON schema to Swagger Object
func ConvertOpenAPISchema2SwaggerObject(data []byte) (*openapi3.Schema, error) {
swagger, err := openapi3.NewLoader().LoadFromData(data)
if err != nil {
return nil, err
}
schemaRef, ok := swagger.Components.Schemas[process.ParameterFieldName]
if !ok {
return nil, errors.New(util.ErrGenerateOpenAPIV2JSONSchemaForCapability)
}
return schemaRef.Value, nil
}

View File

@ -22,6 +22,8 @@ import (
"strings"
"testing"
"cuelang.org/go/cue"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/stretchr/testify/assert"
)
@ -127,22 +129,6 @@ parameter: {
}
`
var withImport = `
import (
"vela/op"
)
apply: op.#Apply & {
value: parameter.value
cluster: parameter.cluster
}
parameter: {
// +usage=Specify the value of the object
value: {...}
// +usage=Specify the cluster of the object
cluster: *"" | string
}`
var withTemplate = `
metadata: {
name: "xxx"
@ -164,15 +150,15 @@ template: {
func TestMergeValues(t *testing.T) {
var cueScript = CUE(templateScript)
value, err := cueScript.MergeValues(nil, map[string]interface{}{
v, err := cueScript.MergeValues(nil, map[string]interface{}{
"url": "hub.docker.com",
"username": "name",
})
assert.Equal(t, err, nil)
output, err := value.LookupValue("template", "output")
assert.Equal(t, err, nil)
output := v.LookupPath(cue.ParsePath("template.output"))
assert.Equal(t, output.Err(), nil)
var data = map[string]interface{}{}
err = output.UnmarshalTo(&data)
err = value.UnmarshalTo(output, &data)
assert.Equal(t, err, nil)
assert.Equal(t, data["url"], "hub.docker.com")
}
@ -190,7 +176,7 @@ func TestRunAndOutput(t *testing.T) {
})
assert.Equal(t, err, nil)
var data = map[string]interface{}{}
err = output.UnmarshalTo(&data)
err = value.UnmarshalTo(output, &data)
assert.Equal(t, err, nil)
assert.Equal(t, data["name"], "nnn")
assert.Equal(t, data["namespace"], "ns")
@ -254,14 +240,15 @@ func TestValidateProperties(t *testing.T) {
func TestValidatePropertiesWithCueX(t *testing.T) {
var cueScript = CUE(templateScript)
ctx := context.Background()
// miss the required parameter
err := cueScript.ValidatePropertiesWithCueX(map[string]interface{}{
err := cueScript.ValidatePropertiesWithCueX(ctx, map[string]interface{}{
"url": "hub.docker.com",
})
assert.Equal(t, err.(*ParameterError).Message, "This parameter is required")
// wrong the parameter value type
err = cueScript.ValidatePropertiesWithCueX(map[string]interface{}{
err = cueScript.ValidatePropertiesWithCueX(ctx, map[string]interface{}{
"url": 1,
"username": "ddd",
})
@ -269,7 +256,7 @@ func TestValidatePropertiesWithCueX(t *testing.T) {
assert.Equal(t, strings.Contains(err.(*ParameterError).Name, "url"), true)
// wrong the parameter value
err = cueScript.ValidatePropertiesWithCueX(map[string]interface{}{
err = cueScript.ValidatePropertiesWithCueX(ctx, map[string]interface{}{
"url": "ddd",
"username": "ddd",
})
@ -277,7 +264,7 @@ func TestValidatePropertiesWithCueX(t *testing.T) {
assert.Equal(t, strings.Contains(err.(*ParameterError).Name, "options"), true)
// wrong the parameter value and no required value
err = cueScript.ValidatePropertiesWithCueX(map[string]interface{}{
err = cueScript.ValidatePropertiesWithCueX(ctx, map[string]interface{}{
"url": "ddd",
"username": "ddd",
"options": "o3",
@ -287,31 +274,15 @@ func TestValidatePropertiesWithCueX(t *testing.T) {
assert.Equal(t, strings.Contains(err.(*ParameterError).Message, "2 errors in empty disjunction"), true)
}
func TestParsePropertiesToSchema(t *testing.T) {
cue := CUE(withPackage)
schema, err := cue.ParsePropertiesToSchema()
assert.Equal(t, err, nil)
assert.Equal(t, len(schema.Properties), 10)
cue = CUE(withImport)
schema, err = cue.ParsePropertiesToSchema()
assert.Equal(t, err, nil)
assert.Equal(t, len(schema.Properties), 2)
cue = CUE([]byte(withTemplate))
schema, err = cue.ParsePropertiesToSchema("template")
assert.Equal(t, err, nil)
assert.Equal(t, len(schema.Properties), 2)
}
func TestParsePropertiesToSchemaWithCueX(t *testing.T) {
cue := CUE([]byte(withPackage))
schema, err := cue.ParsePropertiesToSchemaWithCueX("")
ctx := context.Background()
schema, err := cue.ParsePropertiesToSchemaWithCueX(ctx, "")
assert.Equal(t, err, nil)
assert.Equal(t, len(schema.Properties), 10)
cue = CUE([]byte(withTemplate))
schema, err = cue.ParsePropertiesToSchemaWithCueX("template")
schema, err = cue.ParsePropertiesToSchemaWithCueX(ctx, "template")
assert.Equal(t, err, nil)
assert.Equal(t, len(schema.Properties), 2)
}

View File

@ -40,9 +40,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
"github.com/kubevela/pkg/cue/cuex"
"github.com/kubevela/workflow/pkg/cue/model/sets"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/kubevela/workflow/pkg/cue/packages"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
@ -50,6 +49,7 @@ import (
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/filters"
"github.com/oam-dev/kubevela/pkg/workflow/providers"
)
const (
@ -379,8 +379,8 @@ func (def *Definition) FromYAML(data []byte) error {
}
// FromCUEString converts cue string into Definition
func (def *Definition) FromCUEString(cueString string, config *rest.Config) error {
cuectx := cuecontext.New()
func (def *Definition) FromCUEString(cueString string, _ *rest.Config) error {
// cuectx := cuecontext.New()
f, err := parser.ParseFile("-", cueString, parser.ParseComments)
if err != nil {
return err
@ -430,23 +430,15 @@ func (def *Definition) FromCUEString(cueString string, config *rest.Config) erro
return errors.Wrapf(err, "failed to encode template decls to string")
}
inst := cuectx.CompileString(metadataString)
if inst.Err() != nil {
return inst.Err()
inst, err := providers.Compiler.Get().CompileStringWithOptions(context.Background(), metadataString, cuex.DisableResolveProviderFunctions{})
if err != nil {
return err
}
templateString, err = formatCUEString(importString + templateString)
if err != nil {
return err
}
var pd *packages.PackageDiscover
// validate template
if config != nil {
pd, err = packages.NewPackageDiscover(config)
if err != nil {
return err
}
}
if _, err = value.NewValue(templateString+"\n"+velacue.BaseTemplate, pd, ""); err != nil {
if _, err := providers.Compiler.Get().CompileStringWithOptions(context.Background(), templateString+"\n"+velacue.BaseTemplate, cuex.DisableResolveProviderFunctions{}); err != nil {
return err
}
return def.FromCUE(&inst, templateString)

View File

@ -18,6 +18,7 @@ package gen_sdk
import (
"bytes"
"context"
"fmt"
"io"
"io/fs"
@ -33,8 +34,8 @@ import (
"cuelang.org/go/cue"
"cuelang.org/go/encoding/openapi"
"github.com/getkin/kin-openapi/openapi3"
"github.com/kubevela/pkg/cue/cuex"
"github.com/kubevela/pkg/util/slices"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/rest"
@ -42,9 +43,9 @@ import (
velacue "github.com/oam-dev/kubevela/pkg/cue"
"github.com/oam-dev/kubevela/pkg/definition"
"github.com/oam-dev/kubevela/pkg/stdlib"
"github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/oam-dev/kubevela/pkg/utils/system"
"github.com/oam-dev/kubevela/pkg/workflow/providers"
)
type byteHandler func([]byte) []byte
@ -126,7 +127,6 @@ func NewLanguageArgs(lang string, langArgs []string) (LanguageArgs, error) {
if len(parts) != 2 {
return nil, errors.Errorf("argument %s is not in the format of key=value", arg)
}
fmt.Println("====availableArgs", availableArgs, langArgKey(parts[0]))
if _, ok := availableArgs[langArgKey(parts[0])]; !ok {
return nil, errors.Errorf("argument %s is not supported for language %s", parts[0], lang)
}
@ -163,10 +163,6 @@ func (meta *GenMeta) Init(c common.Args, langArgs []string) (err error) {
if err != nil {
klog.Info("No kubeconfig found, skipping")
}
err = stdlib.SetupBuiltinImports()
if err != nil {
return err
}
if _, ok := SupportedLangs[meta.Lang]; !ok {
return fmt.Errorf("language %s is not supported", meta.Lang)
}
@ -320,7 +316,7 @@ func (meta *GenMeta) PrepareGeneratorAndTemplate() error {
// Run will generally do two thing:
// 1. Generate OpenAPI schema from cue files
// 2. Generate code from OpenAPI schema
func (meta *GenMeta) Run() error {
func (meta *GenMeta) Run(ctx context.Context) error {
g := NewModifiableGenerator(meta)
if len(meta.cuePaths) == 0 {
return nil
@ -333,7 +329,7 @@ func (meta *GenMeta) Run() error {
if err != nil {
return errors.Wrapf(err, "failed to read %s", cuePath)
}
template, defName, defKind, err := g.GetDefinitionValue(cueBytes)
template, defName, defKind, err := g.GetDefinitionValue(ctx, cueBytes)
if err != nil {
return err
}
@ -375,28 +371,29 @@ func (meta *GenMeta) SetDefinition(defName, defKind string) {
}
// GetDefinitionValue returns a value.Value definition name, definition kind from cue bytes
func (g *Generator) GetDefinitionValue(cueBytes []byte) (*value.Value, string, string, error) {
func (g *Generator) GetDefinitionValue(ctx context.Context, cueBytes []byte) (cue.Value, string, string, error) {
g.def = definition.Definition{Unstructured: unstructured.Unstructured{}}
if err := g.def.FromCUEString(string(cueBytes), g.meta.config); err != nil {
return nil, "", "", errors.Wrapf(err, "failed to parse CUE")
return cue.Value{}, "", "", errors.Wrapf(err, "failed to parse CUE")
}
templateString, _, err := unstructured.NestedString(g.def.Object, definition.DefinitionTemplateKeys...)
if err != nil {
return nil, "", "", err
return cue.Value{}, "", "", err
}
if templateString == "" {
return nil, "", "", errors.New("definition doesn't include cue schematic")
return cue.Value{}, "", "", errors.New("definition doesn't include cue schematic")
}
template, err := value.NewValue(templateString+velacue.BaseTemplate, nil, "")
template, err := providers.Compiler.Get().CompileStringWithOptions(ctx, templateString+velacue.BaseTemplate, cuex.DisableResolveProviderFunctions{})
if err != nil {
return nil, "", "", err
return cue.Value{}, "", "", err
}
return template, g.def.GetName(), g.def.GetKind(), nil
}
// GenOpenAPISchema generates OpenAPI json schema from cue.Instance
func (g *Generator) GenOpenAPISchema(val *value.Value) error {
func (g *Generator) GenOpenAPISchema(val cue.Value) error {
var err error
defer func() {
if r := recover(); r != nil {
@ -405,8 +402,8 @@ func (g *Generator) GenOpenAPISchema(val *value.Value) error {
return
}
}()
if val.CueValue().Err() != nil {
return val.CueValue().Err()
if val.Err() != nil {
return val.Err()
}
paramOnlyVal, err := common.RefineParameterValue(val)
if err != nil {

View File

@ -17,6 +17,7 @@ limitations under the License.
package gen_sdk
import (
"context"
"os"
"path/filepath"
@ -60,7 +61,7 @@ var _ = Describe("Test Generating SDK", func() {
Expect(err).Should(BeNil())
err = meta.PrepareGeneratorAndTemplate()
Expect(err).Should(BeNil())
err = meta.Run()
err = meta.Run(context.Background())
Expect(err).Should(BeNil())
}
It("Test generating SDK and init the scaffold", func() {

View File

@ -156,7 +156,7 @@ func listApplicationResourceTrackers(ctx context.Context, cli client.Client, app
}
rtError := err
if !kerrors.IsForbidden(err) && !kerrors.IsUnauthorized(err) {
return nil, err
return nil, errors.WithMessage(err, "failed to list ResourceTrackers")
}
appRts := &unstructured.UnstructuredList{}
appRts.SetGroupVersionKind(applicationResourceTrackerGroupVersionKind)
@ -188,7 +188,7 @@ func ListApplicationResourceTrackers(ctx context.Context, cli client.Client, app
metrics.ListResourceTrackerCounter.WithLabelValues("application").Inc()
rts, err := listApplicationResourceTrackers(ctx, cli, app)
if err != nil {
return nil, nil, nil, nil, err
return nil, nil, nil, nil, errors.WithMessage(err, "failed to list ResourceTrackers")
}
for _, _rt := range rts {
rt := _rt.DeepCopy()

View File

@ -43,8 +43,6 @@ import (
kruisev1alpha1 "github.com/openkruise/rollouts/api/v1alpha1"
"github.com/kubevela/workflow/pkg/cue/packages"
coreoam "github.com/oam-dev/kubevela/apis/core.oam.dev"
// +kubebuilder:scaffold:imports
)
@ -53,7 +51,6 @@ var cfg *rest.Config
var scheme *runtime.Scheme
var k8sClient client.Client
var testEnv *envtest.Environment
var pd *packages.PackageDiscover
var testns string
var dc *discovery.DiscoveryClient
@ -93,9 +90,6 @@ var _ = BeforeSuite(func() {
Expect(err).ToNot(HaveOccurred())
Expect(dc).ShouldNot(BeNil())
pd, err = packages.NewPackageDiscover(cfg)
Expect(err).ToNot(HaveOccurred())
Expect(pd).ToNot(BeNil())
testns = "vela-system"
Expect(k8sClient.Create(context.Background(),
&v12.Namespace{TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Namespace"}, ObjectMeta: metav1.ObjectMeta{

View File

@ -1,5 +1,5 @@
/*
Copyright 2022 The KubeVela Authors.
Copyright 2024 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -14,39 +14,54 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package script
package schema
import (
"context"
"errors"
"fmt"
"strings"
"cuelang.org/go/cue"
"github.com/getkin/kin-openapi/openapi3"
"github.com/kubevela/pkg/cue/cuex"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/cue/process"
"github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/oam-dev/kubevela/pkg/workflow/providers"
)
// BaseTemplate include base info provided by KubeVela for CUE template
const BaseTemplate = `
context: {
name: string
config?: [...{
name: string
value: string
}]
...
}
`
// ErrGenerateOpenAPIV2JSONSchemaForCapability is the error while generating OpenAPI v3 schema
const ErrGenerateOpenAPIV2JSONSchemaForCapability = "cannot generate OpenAPI v3 JSON schema for capability %s: %v"
// ParsePropertiesToSchema parse the properties in cue script to the openapi schema
// Read the template.parameter field
func (c CUE) ParsePropertiesToSchema(templateFieldPath ...string) (*openapi3.Schema, error) {
val, err := c.ParseToValue()
func ParsePropertiesToSchema(ctx context.Context, s string, templateFieldPath ...string) (*openapi3.Schema, error) {
t := s + "\n" + BaseTemplate
val, err := providers.Compiler.Get().CompileStringWithOptions(ctx, t, cuex.DisableResolveProviderFunctions{})
if err != nil {
return nil, err
}
var template *value.Value
var template cue.Value
if len(templateFieldPath) == 0 {
template = val
} else {
template, err = val.LookupValue(templateFieldPath...)
if err != nil {
return nil, fmt.Errorf("%w cue script: %s", err, c)
template = val.LookupPath(value.FieldPath(templateFieldPath...))
if template.Err() != nil {
return nil, fmt.Errorf("%w cue script: %s", template.Err(), s)
}
}
data, err := common.GenOpenAPI(template)
@ -61,32 +76,18 @@ func (c CUE) ParsePropertiesToSchema(templateFieldPath ...string) (*openapi3.Sch
return schema, nil
}
// ParsePropertiesToSchemaWithCueX parse the properties in cue script to the openapi schema
// Read the template.parameter field
func (c CUE) ParsePropertiesToSchemaWithCueX(templateFieldPath string) (*openapi3.Schema, error) {
val, err := c.ParseToValueWithCueX()
// ConvertOpenAPISchema2SwaggerObject converts OpenAPI v2 JSON schema to Swagger Object
func ConvertOpenAPISchema2SwaggerObject(data []byte) (*openapi3.Schema, error) {
swagger, err := openapi3.NewLoader().LoadFromData(data)
if err != nil {
return nil, err
}
var template cue.Value
if len(templateFieldPath) == 0 {
template = val
} else {
template = val.LookupPath(cue.ParsePath(templateFieldPath))
if !template.Exists() {
return nil, fmt.Errorf("failed to lookup value: var(path=%s) not exist, cue script: %s", templateFieldPath, c)
}
schemaRef, ok := swagger.Components.Schemas["parameter"]
if !ok {
return nil, errors.New(util.ErrGenerateOpenAPIV2JSONSchemaForCapability)
}
data, err := common.GenOpenAPIWithCueX(template)
if err != nil {
return nil, err
}
schema, err := ConvertOpenAPISchema2SwaggerObject(data)
if err != nil {
return nil, err
}
FixOpenAPISchema("", schema)
return schema, nil
return schemaRef.Value, nil
}
// FixOpenAPISchema fixes tainted `description` filed, missing of title `field`.
@ -117,17 +118,3 @@ func FixOpenAPISchema(name string, schema *openapi3.Schema) {
}
schema.Description = description
}
// ConvertOpenAPISchema2SwaggerObject converts OpenAPI v2 JSON schema to Swagger Object
func ConvertOpenAPISchema2SwaggerObject(data []byte) (*openapi3.Schema, error) {
swagger, err := openapi3.NewLoader().LoadFromData(data)
if err != nil {
return nil, err
}
schemaRef, ok := swagger.Components.Schemas[process.ParameterFieldName]
if !ok {
return nil, errors.New(util.ErrGenerateOpenAPIV2JSONSchemaForCapability)
}
return schemaRef.Value, nil
}

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package script
package schema
import (
"os"

View File

@ -1,93 +0,0 @@
#GetPlacementsFromTopologyPolicies: multicluster.#GetPlacementsFromTopologyPolicies
#Deploy: multicluster.#Deploy
#ApplyApplication: #Steps & {
load: oam.#LoadComponetsInOrder @step(1)
components: #Steps & {
for name, c in load.value {
"\(name)": oam.#ApplyComponent & {
value: c
}
}
} @step(2)
}
// This operator will dispatch all the components in parallel when applying an application.
// Currently it works for Addon Observability to speed up the installation. It can also works for other applications, which
// needs to skip health check for components.
#ApplyApplicationInParallel: #Steps & {
load: oam.#LoadComponetsInOrder @step(1)
components: #Steps & {
for name, c in load.value {
"\(name)": oam.#ApplyComponent & {
value: c
waitHealthy: false
}
}
} @step(2)
}
#ApplyComponent: oam.#ApplyComponent
#RenderComponent: oam.#RenderComponent
#ApplyComponentRemaining: #Steps & {
// exceptions specify the resources not to apply.
exceptions: [...string]
exceptions_: {for c in exceptions {"\(c)": true}}
component: string
load: oam.#LoadComponets @step(1)
render: #Steps & {
rendered: oam.#RenderComponent & {
value: load.value[component]
}
comp: kube.#Apply & {
value: rendered.output
}
for name, c in rendered.outputs {
if exceptions_[name] == _|_ {
"\(name)": kube.#Apply & {
value: c
}
}
}
} @step(2)
}
#ApplyRemaining: #Steps & {
// exceptions specify the resources not to apply.
exceptions: [...string]
exceptions_: {for c in exceptions {"\(c)": true}}
load: oam.#LoadComponets @step(1)
components: #Steps & {
for name, c in load.value {
if exceptions_[name] == _|_ {
"\(name)": oam.#ApplyComponent & {
value: c
}
}
}
} @step(2)
}
#ApplyEnvBindApp: multicluster.#ApplyEnvBindApp
#DeployCloudResource: terraform.#DeployCloudResource
#ShareCloudResource: terraform.#ShareCloudResource
#LoadPolicies: oam.#LoadPolicies
#ListClusters: multicluster.#ListClusters
#MakePlacementDecisions: multicluster.#MakePlacementDecisions
#PatchApplication: multicluster.#PatchApplication
#Load: oam.#LoadComponets
#LoadInOrder: oam.#LoadComponetsInOrder

View File

@ -1,76 +0,0 @@
/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package stdlib
import (
"embed"
"fmt"
"strings"
"github.com/kubevela/workflow/pkg/stdlib"
)
var (
//go:embed pkgs op.cue ql.cue
fs embed.FS
)
// SetupBuiltinImports set up builtin imports
func SetupBuiltinImports() error {
pkgs, err := getPackages()
if err != nil {
return err
}
return stdlib.SetupBuiltinImports(pkgs)
}
// getPackages get stdlib packages
func getPackages() (map[string]string, error) {
files, err := fs.ReadDir("pkgs")
if err != nil {
return nil, err
}
opBytes, err := fs.ReadFile("op.cue")
if err != nil {
return nil, err
}
qlBytes, err := fs.ReadFile("ql.cue")
if err != nil {
return nil, err
}
opContent := string(opBytes) + "\n"
qlContent := string(qlBytes) + "\n"
for _, file := range files {
body, err := fs.ReadFile("pkgs/" + file.Name())
if err != nil {
return nil, err
}
pkgContent := fmt.Sprintf("%s: {\n%s\n}\n", strings.TrimSuffix(file.Name(), ".cue"), string(body))
opContent += pkgContent
if file.Name() == "kube.cue" || file.Name() == "query.cue" {
qlContent += pkgContent
}
}
return map[string]string{
"vela/op": opContent,
"vela/ql": qlContent,
}, nil
}

View File

@ -1,55 +0,0 @@
/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package stdlib
import (
"testing"
"cuelang.org/go/cue"
"cuelang.org/go/cue/build"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/parser"
"github.com/stretchr/testify/assert"
"github.com/kubevela/workflow/pkg/stdlib"
)
func TestGetPackages(t *testing.T) {
pkgs, err := getPackages()
assert.NoError(t, err)
cuectx := cuecontext.New()
for path, content := range pkgs {
file, err := parser.ParseFile(path, content)
assert.NoError(t, err)
_ = cuectx.BuildFile(file)
}
file, err := parser.ParseFile("-", `
import "vela/custom"
out: custom.context`)
assert.NoError(t, err)
builder := &build.Instance{}
err = builder.AddSyntax(file)
assert.NoError(t, err)
err = stdlib.AddImportsFor(builder, "context: id: \"xxx\"")
assert.NoError(t, err)
inst := cuectx.BuildInstance(builder)
str, err := inst.LookupPath(cue.ParsePath("out.id")).String()
assert.NoError(t, err)
assert.Equal(t, str, "xxx")
}

View File

@ -1,55 +0,0 @@
#ApplyComponent: {
#provider: "oam"
#do: "component-apply"
// +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?: {...}
...
}
#RenderComponent: {
#provider: "oam"
#do: "component-render"
cluster: *"" | string
env: *"" | string
namespace: *"" | string
value: {...}
patch?: {...}
output?: {...}
outputs?: {...}
...
}
#LoadComponets: {
#provider: "oam"
#do: "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?: {...}
...
}
#LoadPolicies: {
#provider: "oam"
#do: "load-policies"
value?: {...}
...
}
#LoadComponetsInOrder: {
#provider: "oam"
#do: "load-comps-in-order"
...
}

View File

@ -1,81 +0,0 @@
#Read: {
#do: "read"
#provider: "kube"
// +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?: {...}
...
}
#List: {
#do: "list"
#provider: "kube"
// +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?: {...}
...
}
#Delete: {
#do: "delete"
#provider: "kube"
// +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?: {...}
}
...
}
#ListResourcesInApp: query.#ListResourcesInApp
#ListAppliedResources: query.#ListAppliedResources
#CollectPods: query.#CollectPods
#CollectServices: query.#CollectServices
#SearchEvents: query.#SearchEvents
#CollectLogsInPod: query.#CollectLogsInPod
#CollectServiceEndpoints: query.#CollectServiceEndpoints
#GetApplicationTree: query.#GetApplicationTree

View File

@ -21,8 +21,10 @@ import (
"encoding/json"
"fmt"
"reflect"
"strconv"
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
"github.com/mitchellh/hashstructure/v2"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@ -38,7 +40,6 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/controller/utils"
"github.com/oam-dev/kubevela/pkg/features"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
@ -259,11 +260,22 @@ func (a *APIApplicator) Apply(ctx context.Context, desired client.Object, ao ...
}
}
// ComputeSpecHash computes the hash value of a k8s resource spec
func ComputeSpecHash(spec interface{}) (string, error) {
// compute a hash value of any resource spec
specHash, err := hashstructure.Hash(spec, hashstructure.FormatV2, nil)
if err != nil {
return "", err
}
specHashLabel := strconv.FormatUint(specHash, 16)
return specHashLabel, nil
}
func generateRenderHash(desired client.Object) (string, error) {
if desired == nil {
return "", nil
}
desiredHash, err := utils.ComputeSpecHash(desired)
desiredHash, err := ComputeSpecHash(desired)
if err != nil {
return "", errors.Wrap(err, "compute desired hash")
}

View File

@ -17,8 +17,6 @@ limitations under the License.
package common
import (
"fmt"
pkgmulticluster "github.com/kubevela/pkg/multicluster"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
@ -30,8 +28,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"github.com/kubevela/workflow/pkg/cue/packages"
)
// Args is args for controller-runtime client
@ -40,7 +36,6 @@ type Args struct {
rawConfig *api.Config
Schema *runtime.Scheme
client client.Client
pd *packages.PackageDiscover
dc *discovery.DiscoveryClient
}
@ -139,24 +134,6 @@ func (a *Args) GetFakeClient(defs []*unstructured.Unstructured) (client.Client,
return fake.NewClientBuilder().WithObjects(objs...).WithScheme(a.Schema).Build(), nil
}
// GetPackageDiscover get PackageDiscover client if exist, create if not exist.
func (a *Args) GetPackageDiscover() (*packages.PackageDiscover, error) {
if a.config == nil {
if err := a.SetConfig(nil); err != nil {
return nil, err
}
}
if a.pd != nil {
return a.pd, nil
}
pd, err := packages.NewPackageDiscover(a.config)
if err != nil {
return nil, fmt.Errorf("failed to create CRD discovery for CUE package client %w", err)
}
a.pd = pd
return pd, nil
}
// GetDiscoveryClient return a discovery client from cli args
func (a *Args) GetDiscoveryClient() (*discovery.DiscoveryClient, error) {
if a.dc != nil {

View File

@ -57,8 +57,6 @@ import (
gatewayv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1"
"sigs.k8s.io/yaml"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/kubevela/workflow/pkg/cue/packages"
clustergatewayapi "github.com/oam-dev/cluster-gateway/pkg/apis/cluster/v1alpha1"
terraformapiv1 "github.com/oam-dev/terraform-controller/api/v1beta1"
terraformapi "github.com/oam-dev/terraform-controller/api/v1beta2"
@ -202,21 +200,18 @@ func HTTPGetKubernetesObjects(ctx context.Context, url string) ([]*unstructured.
}
// GetCUEParameterValue converts definitions to cue format
func GetCUEParameterValue(cueStr string, pd *packages.PackageDiscover) (cue.Value, error) {
template, err := value.NewValue(cueStr+velacue.BaseTemplate, pd, "")
if err != nil {
return cue.Value{}, err
}
val, err := template.LookupValue(process.ParameterFieldName)
if err != nil || !val.CueValue().Exists() {
func GetCUEParameterValue(cueStr string) (cue.Value, error) {
template := cuecontext.New().CompileString(cueStr + velacue.BaseTemplate)
val := template.LookupPath(cue.ParsePath(process.ParameterFieldName))
if !val.Exists() {
return cue.Value{}, velacue.ErrParameterNotExist
}
return val.CueValue(), nil
return val, nil
}
// GenOpenAPI generates OpenAPI json schema from cue.Instance
func GenOpenAPI(val *value.Value) (b []byte, err error) {
func GenOpenAPI(val cue.Value) (b []byte, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("invalid cue definition to generate open api: %v", r)
@ -224,8 +219,8 @@ func GenOpenAPI(val *value.Value) (b []byte, err error) {
return
}
}()
if val.CueValue().Err() != nil {
return nil, val.CueValue().Err()
if val.Err() != nil {
return nil, val.Err()
}
paramOnlyVal, err := RefineParameterValue(val)
if err != nil {
@ -265,23 +260,17 @@ func GenOpenAPIWithCueX(val cue.Value) (b []byte, err error) {
}
// RefineParameterValue refines cue value to merely include `parameter` identifier
func RefineParameterValue(val *value.Value) (cue.Value, error) {
defaultValue := cuecontext.New().CompileString("#parameter: {}")
func RefineParameterValue(val cue.Value) (cue.Value, error) {
cuectx := val.Context()
defaultValue := cuectx.CompileString("#parameter: {}")
parameterPath := cue.MakePath(cue.Def(process.ParameterFieldName))
v, err := val.MakeValue("{}")
if err != nil {
return defaultValue, err
}
paramVal, err := val.LookupValue(process.ParameterFieldName)
if err != nil {
// nolint:nilerr
return defaultValue, nil
}
switch k := paramVal.CueValue().IncompleteKind(); k {
v := cuectx.CompileString("{}")
paramVal := val.LookupPath(cue.ParsePath(process.ParameterFieldName))
switch k := paramVal.IncompleteKind(); k {
case cue.BottomKind:
return defaultValue, nil
default:
paramOnlyVal := v.CueValue().FillPath(parameterPath, paramVal.CueValue())
paramOnlyVal := v.FillPath(parameterPath, paramVal)
return paramOnlyVal, nil
}
}

View File

@ -33,7 +33,6 @@ import (
"cuelang.org/go/cue/load"
"github.com/crossplane/crossplane-runtime/pkg/test"
"github.com/google/go-cmp/cmp"
"github.com/kubevela/workflow/pkg/cue/model/value"
"github.com/stretchr/testify/assert"
)
@ -252,7 +251,7 @@ output: {
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
_, err := GetCUEParameterValue(tc.cueStr, nil)
_, err := GetCUEParameterValue(tc.cueStr)
if tc.want.err != nil {
if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" {
t.Errorf("\n%s\nGenOpenAPIFromFile(...): -want error, +got error:\n%s", tc.reason, diff)
@ -291,7 +290,7 @@ func TestGetCUEParameterValue4RareCases(t *testing.T) {
for name, tc := range cases {
t.Run(name, func(t *testing.T) {
_, err := GetCUEParameterValue(tc.cueStr, nil)
_, err := GetCUEParameterValue(tc.cueStr)
if diff := cmp.Diff(tc.want.errMsg, err.Error(), test.EquateConditions()); diff != "" {
t.Errorf("\n%s\nGenOpenAPIFromFile(...): -want error, +got error:\n%s", tc.reason, diff)
}
@ -334,8 +333,7 @@ func TestGenOpenAPI(t *testing.T) {
instances := load.Instances([]string{filepath.FromSlash(tc.fileName)}, &load.Config{
Dir: "testdata",
})
val, err := value.NewValueWithInstance(instances[0], nil, "")
assert.NoError(t, err)
val := cuecontext.New().BuildInstance(instances[0])
got, err := GenOpenAPI(val)
if tc.want.err != nil {
if diff := cmp.Diff(tc.want.err, errors.New(err.Error()), test.EquateErrors()); diff != "" {
@ -509,10 +507,10 @@ patch: {
label: parameter.x
}
}`
val, err := value.NewValue(s, nil, "")
assert.NoError(t, err)
assert.NoError(t, val.CueValue().Err())
_, err = RefineParameterValue(val)
cuectx := cuecontext.New()
val := cuectx.CompileString(s)
assert.NoError(t, val.Err())
_, err := RefineParameterValue(val)
assert.NoError(t, err)
// test #parameter not exist but parameter exists
s = `parameter: {
@ -521,18 +519,17 @@ patch: {
y: string
}
}`
val, err = value.NewValue(s, nil, "")
assert.NoError(t, err)
assert.NoError(t, val.CueValue().Err())
val = cuectx.CompileString(s)
assert.NoError(t, val.Err())
assert.NoError(t, err)
_, err = RefineParameterValue(val)
assert.NoError(t, err)
// test #parameter as int
s = `parameter: #parameter
#parameter: int`
val, err = value.NewValue(s, nil, "")
val = cuectx.CompileString(s)
assert.NoError(t, err)
assert.NoError(t, val.CueValue().Err())
assert.NoError(t, val.Err())
_, err = RefineParameterValue(val)
assert.NoError(t, err)
}

View File

@ -50,7 +50,7 @@ import (
"github.com/oam-dev/kubevela/pkg/oam/util"
velaerr "github.com/oam-dev/kubevela/pkg/utils/errors"
querytypes "github.com/oam-dev/kubevela/pkg/velaql/providers/query/types"
querytypes "github.com/oam-dev/kubevela/pkg/utils/types"
)
// MutateOption defines the function pattern for mutate

Some files were not shown because too many files have changed in this diff Show More