Compare commits

..

21 Commits

Author SHA1 Message Date
github-actions[bot]
1c2df10299 Fix: swagger DateType (#5570)
Signed-off-by: yueyongyue <yueyongyue@sina.cn>
(cherry picked from commit a4a4d64729)

Co-authored-by: yueyongyue <yueyongyue@sina.cn>
2023-02-27 09:53:52 +08:00
github-actions[bot]
918ed9727b [Backport release-1.7] Fix: delete the secret of the cluster (#5517)
* Fix: delete the secret of the cluster

Signed-off-by: suwanliang_yewu <suwanliang_yewu@cmss.chinamobile.com>
(cherry picked from commit ec466ab67e)

* Fix: add test

Signed-off-by: suwanliang_yewu <suwanliang_yewu@cmss.chinamobile.com>
(cherry picked from commit 63c44fdc39)

* Fix: modify error

Signed-off-by: suwanliang_yewu <suwanliang_yewu@cmss.chinamobile.com>
(cherry picked from commit e580597367)

* Fix: solve check-diff

Signed-off-by: suwanliang_yewu <suwanliang_yewu@cmss.chinamobile.com>
(cherry picked from commit c2316e10e8)

* Fix: modify test

Signed-off-by: suwanliang_yewu <suwanliang_yewu@cmss.chinamobile.com>
(cherry picked from commit afca7e6027)

---------

Co-authored-by: suwanliang_yewu <suwanliang_yewu@cmss.chinamobile.com>
2023-02-16 14:04:41 +08:00
github-actions[bot]
fa78cb7632 [Backport release-1.7] Fix: removes default parameter name for terraform provider (#5516)
* removes default name for terraform provider

Signed-off-by: afzalbin64 <afzal442@gmail.com>
(cherry picked from commit 92e7bf8263)

* fixes minor typos

Signed-off-by: afzalbin64 <afzal442@gmail.com>

undo the changes to typo

fixes minor typos in go_test files

updates config_test to support name as required param

(cherry picked from commit 51c2650a95)

---------

Co-authored-by: afzalbin64 <afzal442@gmail.com>
2023-02-16 14:02:10 +08:00
github-actions[bot]
f3cdbcf203 [Backport release-1.7] Feat: The vela-apiserver supports displaying chart values stored in the OCI registry (#5509)
* support helm chart values

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

rebase

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

no lint

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

fix lint error

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

add test and deprecated API

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

fix url bug

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

fix tests panic

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

fix tests

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit fc1d8c248d)

* fix golint

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit 6c462b7850)

* return values.yaml

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit 70d8cc5d52)

* fix test

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit ef4574a188)

* fix return values

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit c1488eee77)

* add multiple valeus yaml in

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit 04436188ff)

* add old interface back

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit ae0ac9f50f)

* fix golint

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

fix test

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit 00957744c0)

---------

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2023-02-15 14:00:16 +08:00
github-actions[bot]
7bd2cf4dbc [Backport release-1.7] Fix: read-only definition in cue spec (#5508)
* Fix: ref-object and take-over definition in cue spec

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit 23723af9af)

* rollback ref-objects

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit 1af2c3934f)

---------

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-02-15 13:59:48 +08:00
github-actions[bot]
969babdd9e Fix: apply-terraform-provider and container-image definition (#5486)
Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit 978feccf91)

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-02-13 11:21:52 +08:00
github-actions[bot]
94c46a179b Fix: use correct helm value when setting apprev compression (#5478)
Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>
(cherry picked from commit 17c36206bc)

Co-authored-by: Charlie Chiang <charlie_c_0129@outlook.com>
2023-02-10 19:18:14 +08:00
Tianxin Dong
bec288c6b4 Chore: update cue version to v0.5.0-beta.5 to fix certain bugs in the old version (#5475)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2023-02-10 19:17:51 +08:00
github-actions[bot]
9a44be9788 Fix: pod view invalid cue for special pod output (#5474)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit ece0396425)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-02-10 13:07:21 +08:00
github-actions[bot]
9c7f4b7e03 Feat: enhance expose trait and adopt (#5473)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit a05e4c8643)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-02-10 11:30:20 +08:00
github-actions[bot]
539f1ed02b Fix: expose trait load balance cue check bug (#5461)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 9dccfcea1e)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-02-08 23:25:11 +08:00
github-actions[bot]
9e95122387 Chore: fix krew release with new binary format for .exe (#5462)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit a4ea6ccb04)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2023-02-08 23:24:37 +08:00
github-actions[bot]
f49f11dd72 Fix: suppress klog logs output for vela top (#5452)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 55662b645a)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-02-08 16:26:44 +08:00
github-actions[bot]
191d9038f1 [Backport release-1.7] Fix: use get before create or update (#5450)
* Fix: use get before create or update

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 93c1881663)

* Fix: ignore resource not found error when manage privileges for target

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit dd4864c6d1)

---------

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-02-08 14:50:38 +08:00
github-actions[bot]
e10e43b6c8 [Backport release-1.7] Fix: simplify notification parameters (#5446)
* Fix: simplify notification parameters

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit a9a8a18529)

* remove close

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit 123c3f51b2)

* format

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit e2eee58a4b)

---------

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-02-08 14:05:13 +08:00
github-actions[bot]
b9cc523267 [Backport release-1.7] Fix: Add confirmation prompt for vela adopt --apply with existing app name (#5419)
* Add confirmation prompt for vela adopt --apply with existing app name

Signed-off-by: Karanjot Singh <drquark@duck.com>
(cherry picked from commit 5278e1b350)

* Added changes according to the review

Signed-off-by: Karanjot Singh <drquark@duck.com>
(cherry picked from commit 0a437e336f)

* Fixed Userinput and used loadremoteApplication

Signed-off-by: Karanjot Singh <drquark@duck.com>

minor fixes

Signed-off-by: Karanjot Singh <drquark@duck.com>

used loadRemoteApplication

Signed-off-by: Karanjot Singh <drquark@duck.com>

Minor Fix

Signed-off-by: Karanjot Singh <drquark@duck.com>

Minor Fix

Signed-off-by: Karanjot Singh <drquark@duck.com>

Minor Fix

Signed-off-by: Karanjot Singh <drquark@duck.com>

Minor Fix

Signed-off-by: Karanjot Singh <drquark@duck.com>

Minor Fix

Signed-off-by: Karanjot Singh <drquark@duck.com>

Minor fix

Signed-off-by: Karanjot Singh <drquark@duck.com>

Minor fix

Signed-off-by: Karanjot Singh <drquark@duck.com>
(cherry picked from commit 4e92eaf73e)

* Used f.Client().Get method

Signed-off-by: Karanjot Singh <drquark@duck.com>

minor fix

Signed-off-by: Karanjot Singh <drquark@duck.com>

minor fix

Signed-off-by: Karanjot Singh <drquark@duck.com>
(cherry picked from commit 96a2ae8fb7)

* Changed bool to False

Signed-off-by: Karanjot Singh <drquark@duck.com>
(cherry picked from commit 17a1131b90)

---------

Co-authored-by: Karanjot Singh <drquark@duck.com>
2023-02-03 18:03:42 +08:00
github-actions[bot]
7f1743ef58 [Backport release-1.7] Fix: sync project from app crd to velaux (#5410)
* Fix: sync project from app crd to velaux

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
(cherry picked from commit 3c613d7358)

* Fix: sync project from app crd to velaux

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
(cherry picked from commit 2492e3725c)

* Fix: sync project from app crd to velaux

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
(cherry picked from commit db3c7ea0a5)

* Fix: sync project from app crd to velaux

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
(cherry picked from commit 1a364e0737)

* Fix: sync project from app crd to velaux

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
(cherry picked from commit 363f56ac2a)

* Fix: sync project from app crd to velaux

Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
(cherry picked from commit 279517c142)

---------

Co-authored-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
2023-02-02 15:31:25 +08:00
github-actions[bot]
dd39c38cf1 fix bugs of specified addonName (#5407)
Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit 3a9df79b3a)

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2023-02-01 16:44:30 +08:00
github-actions[bot]
0851454c6f Fix: ignore validation webhook for ref-objects typed component (#5406)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 0fb1ab497b)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-02-01 16:10:16 +08:00
github-actions[bot]
cd3577db53 Fix: skip last-applied-configuration error for threewaymergepatch (#5405)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 6bf79461d4)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-02-01 16:00:44 +08:00
github-actions[bot]
d578adfe6e Fix: longer releaser timeout (#5400)
Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit 4ca1acdc22)

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-02-01 14:01:07 +08:00
47 changed files with 544 additions and 166 deletions

View File

@@ -43,7 +43,7 @@ jobs:
with:
distribution: goreleaser
version: 1.14.1
args: release --rm-dist
args: release --rm-dist --timeout 60m
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Since goreleaser haven't supported aliyun OSS, we need to upload the release manually

View File

@@ -33,8 +33,8 @@ spec:
arch: amd64
{{addURIAndSha "https://github.com/oam-dev/kubevela/releases/download/{{ .TagName }}/kubectl-vela-{{ .TagName }}-windows-amd64.zip" .TagName }}
files:
- from: "*/kubectl-vela"
to: "kubectl-vela.exe"
- from: "*/kubectl-vela.exe"
to: "."
- from: "*/LICENSE"
to: "."
bin: "kubectl-vela.exe"

View File

@@ -116,7 +116,7 @@ spec:
#ECProvider: {
type: "ec"
apiKey: *"" | string
name: "ec-provider" | string
name: *"ec-provider" | string
}
#GCPProvider: {
credentials: string

View File

@@ -72,7 +72,7 @@ spec:
}]
}
}
parameter: *#PatchParams | close({
parameter: #PatchParams | close({
// +usage=Specify the container image for multiple containers
containers: [...#PatchParams]
})

View File

@@ -53,7 +53,10 @@ spec:
}
if service.spec.type == "LoadBalancer" {
status: service.status
isHealth: status != _|_ && status.loadBalancer != _|_ && status.loadBalancer.ingress != _|_ && len(status.loadBalancer.ingress) > 0
isHealth: *false | bool
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
isHealth: true
}
if !isHealth {
message: "ExternalIP: Pending"
}
@@ -62,10 +65,15 @@ spec:
}
}
healthPolicy: |-
isHealth: *true | bool
service: context.outputs.service
if service.spec.type == "LoadBalancer" {
status: service.status
isHealth: status != _|_ && status.loadBalancer != _|_ && status.loadBalancer.ingress != _|_ && len(status.loadBalancer.ingress) > 0
isHealth: *false | bool
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
isHealth: true
}
}
if service.spec.type != "LoadBalancer" {
isHealth: true
}

View File

@@ -56,44 +56,41 @@ spec:
// +usage=Specify the message that you want to sent, refer to [dingtalk messaging](https://developers.dingtalk.com/document/robots/custom-robot-access/title-72m-8ag-pqw)
message: {
// +usage=Specify the message content of dingtalk notification
text?: *null | close({
text?: close({
content: string
})
// +usage=msgType can be text, link, mardown, actionCard, feedCard
msgtype: *"text" | "link" | "markdown" | "actionCard" | "feedCard"
link?: *null | close({
#link: {
text?: string
title?: string
messageUrl?: string
picUrl?: string
})
markdown?: *null | close({
}
link?: #link
markdown?: close({
text: string
title: string
})
at?: *null | close({
atMobiles?: *null | [...string]
isAtAll?: bool
at?: close({
atMobiles?: [...string]
isAtAll?: bool
})
actionCard?: *null | close({
actionCard?: close({
text: string
title: string
hideAvatar: string
btnOrientation: string
singleTitle: string
singleURL: string
btns: *null | close([...*null | close({
btns?: [...close({
title: string
actionURL: string
})])
})]
})
feedCard?: *null | close({
links: *null | close([...*null | close({
text?: string
title?: string
messageUrl?: string
picUrl?: string
})])
feedCard?: close({
links: [...#link]
})
}
}
@@ -114,11 +111,11 @@ spec:
// +usage=Specify the message that you want to sent, refer to [slack messaging](https://api.slack.com/reference/messaging/payload)
message: {
// +usage=Specify the message text for slack notification
text: string
blocks?: *null | close([...block])
attachments?: *null | close({
blocks?: *null | close([...block])
color?: string
text: string
blocks?: [...block]
attachments?: close({
blocks?: [...block]
color?: string
})
thread_ts?: string
// +usage=Specify the message text format in markdown for slack notification

View File

@@ -13,7 +13,7 @@ spec:
template: |
#PolicyRule: {
// +usage=Specify how to select the targets of the rule
selector: [...#RuleSelector]
selector: #RuleSelector
}
#RuleSelector: {
// +usage=Select resources by component names

View File

@@ -272,8 +272,8 @@ spec:
- "--feature-gates=ZstdResourceTracker={{- .Values.featureGates.zstdResourceTracker | toString -}}"
- "--feature-gates=ApplyOnce={{- .Values.featureGates.applyOnce | toString -}}"
- "--feature-gates=MultiStageComponentApply= {{- .Values.featureGates.multiStageComponentApply | toString -}}"
- "--feature-gates=GzipApplicationRevision={{- .Values.featureGates.gzipResourceTracker | toString -}}"
- "--feature-gates=ZstdApplicationRevision={{- .Values.featureGates.zstdResourceTracker | toString -}}"
- "--feature-gates=GzipApplicationRevision={{- .Values.featureGates.gzipApplicationRevision | toString -}}"
- "--feature-gates=ZstdApplicationRevision={{- .Values.featureGates.zstdApplicationRevision | toString -}}"
- "--feature-gates=PreDispatchDryRun={{- .Values.featureGates.preDispatchDryRun | toString -}}"
{{ if .Values.authentication.enabled }}
{{ if .Values.authentication.withUser }}

View File

@@ -2,7 +2,7 @@ apiVersion: v1
data:
template: |
import (
"vela/ql"
"vela/ql"
)
parameter: {
@@ -55,9 +55,15 @@ data:
phase: pod.object.status.phase
// refer to https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
if phase != "Pending" && phase != "Unknown" {
podIP: pod.object.status.podIP
hostIP: pod.object.status.hostIP
nodeName: pod.object.spec.nodeName
if pod.object.podIP != _|_ {
podIP: pod.object.status.podIP
}
if pod.object.hostIP != _|_ {
hostIP: pod.object.status.hostIP
}
if pod.object.nodeName != _|_ {
nodeName: pod.object.spec.nodeName
}
}
}
}]

View File

@@ -116,7 +116,7 @@ spec:
#ECProvider: {
type: "ec"
apiKey: *"" | string
name: "ec-provider" | string
name: *"ec-provider" | string
}
#GCPProvider: {
credentials: string

View File

@@ -72,7 +72,7 @@ spec:
}]
}
}
parameter: *#PatchParams | close({
parameter: #PatchParams | close({
// +usage=Specify the container image for multiple containers
containers: [...#PatchParams]
})

View File

@@ -53,7 +53,10 @@ spec:
}
if service.spec.type == "LoadBalancer" {
status: service.status
isHealth: status != _|_ && status.loadBalancer != _|_ && status.loadBalancer.ingress != _|_ && len(status.loadBalancer.ingress) > 0
isHealth: *false | bool
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
isHealth: true
}
if !isHealth {
message: "ExternalIP: Pending"
}
@@ -62,10 +65,15 @@ spec:
}
}
healthPolicy: |-
isHealth: *true | bool
service: context.outputs.service
if service.spec.type == "LoadBalancer" {
status: service.status
isHealth: status != _|_ && status.loadBalancer != _|_ && status.loadBalancer.ingress != _|_ && len(status.loadBalancer.ingress) > 0
isHealth: *false | bool
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
isHealth: true
}
}
if service.spec.type != "LoadBalancer" {
isHealth: true
}

View File

@@ -56,44 +56,41 @@ spec:
// +usage=Specify the message that you want to sent, refer to [dingtalk messaging](https://developers.dingtalk.com/document/robots/custom-robot-access/title-72m-8ag-pqw)
message: {
// +usage=Specify the message content of dingtalk notification
text?: *null | close({
text?: close({
content: string
})
// +usage=msgType can be text, link, mardown, actionCard, feedCard
msgtype: *"text" | "link" | "markdown" | "actionCard" | "feedCard"
link?: *null | close({
#link: {
text?: string
title?: string
messageUrl?: string
picUrl?: string
})
markdown?: *null | close({
}
link?: #link
markdown?: close({
text: string
title: string
})
at?: *null | close({
atMobiles?: *null | [...string]
isAtAll?: bool
at?: close({
atMobiles?: [...string]
isAtAll?: bool
})
actionCard?: *null | close({
actionCard?: close({
text: string
title: string
hideAvatar: string
btnOrientation: string
singleTitle: string
singleURL: string
btns: *null | close([...*null | close({
btns?: [...close({
title: string
actionURL: string
})])
})]
})
feedCard?: *null | close({
links: *null | close([...*null | close({
text?: string
title?: string
messageUrl?: string
picUrl?: string
})])
feedCard?: close({
links: [...#link]
})
}
}
@@ -114,11 +111,11 @@ spec:
// +usage=Specify the message that you want to sent, refer to [slack messaging](https://api.slack.com/reference/messaging/payload)
message: {
// +usage=Specify the message text for slack notification
text: string
blocks?: *null | close([...block])
attachments?: *null | close({
blocks?: *null | close([...block])
color?: string
text: string
blocks?: [...block]
attachments?: close({
blocks?: [...block]
color?: string
})
thread_ts?: string
// +usage=Specify the message text format in markdown for slack notification

View File

@@ -13,7 +13,7 @@ spec:
template: |
#PolicyRule: {
// +usage=Specify how to select the targets of the rule
selector: [...#RuleSelector]
selector: #RuleSelector
}
#RuleSelector: {
// +usage=Select resources by component names

View File

@@ -74,6 +74,12 @@ var _ = Describe("Addon Test", func() {
Expect(output).To(ContainSubstring("enabled successfully."))
})
It("Enable addon with specified registry ", func() {
output, err := e2e.LongTimeExec("vela addon enable KubeVela/test-addon", 300*time.Second)
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring("enabled successfully."))
})
It("Disable addon test-addon", func() {
output, err := e2e.LongTimeExec("vela addon disable test-addon", 600*time.Second)
Expect(err).NotTo(HaveOccurred())

3
go.mod
View File

@@ -3,7 +3,7 @@ module github.com/oam-dev/kubevela
go 1.19
require (
cuelang.org/go v0.5.0-alpha.1
cuelang.org/go v0.5.0-beta.5
github.com/AlecAivazis/survey/v2 v2.1.1
github.com/FogDong/uitable v0.0.5
github.com/Masterminds/semver/v3 v3.1.1
@@ -348,7 +348,6 @@ require (
replace (
cloud.google.com/go => cloud.google.com/go v0.100.2
cuelang.org/go => github.com/kubevela/cue v0.4.4-0.20221107123854-a976b0e340be
github.com/docker/cli => github.com/docker/cli v20.10.9+incompatible
github.com/docker/docker => github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible
github.com/wercker/stern => github.com/oam-dev/stern v1.13.2

4
go.sum
View File

@@ -34,6 +34,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
contrib.go.opencensus.io/exporter/ocagent v0.6.0/go.mod h1:zmKjrJcdo0aYcVS7bmEeSEBLPA9YJp5bjrofdU3pIXs=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
cuelang.org/go v0.5.0-beta.5 h1:TAV4ZjXw2M6xf6jI8XyAAXCqWJ82Y0oxhlf9w3l544A=
cuelang.org/go v0.5.0-beta.5/go.mod h1:okjJBHFQFer+a41sAe2SaGm1glWS8oEb6CmJvn5Zdws=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/AlecAivazis/survey/v2 v2.1.1 h1:LEMbHE0pLj75faaVEKClEX1TM4AJmmnOh9eimREzLWI=
github.com/AlecAivazis/survey/v2 v2.1.1/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
@@ -1283,8 +1285,6 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
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/cue v0.4.4-0.20221107123854-a976b0e340be h1:0xj/Rh4yVy54mUD2nLmAuN1AYgBkkHxBh4PoLGbIg5g=
github.com/kubevela/cue v0.4.4-0.20221107123854-a976b0e340be/go.mod h1:Ya12qn7FZc+LSN0qgEhzEpnzQsvnGHVgoDrqe9i3eNg=
github.com/kubevela/pkg v0.0.0-20230105054759-263dc191bf51 h1:xrcNNaAjqC6tr1leSYcjLFgrXKpZ8u87jpB5TolhUIc=
github.com/kubevela/pkg v0.0.0-20230105054759-263dc191bf51/go.mod h1:ZRnxY/gOcg/8FilZA+eYr+rtVXb1ijT5HFTe8zrv9zo=
github.com/kubevela/prism v1.7.0-alpha.1 h1:oeZFn1Oy6gxSSFzMTfsWjLOCKaaooMVm1JGNK4j4Mlo=

View File

@@ -387,7 +387,10 @@ func (c *clusterServiceImpl) DeleteKubeCluster(ctx context.Context, clusterName
cluster, err := c.getClusterFromDataStore(ctx, clusterName)
if err != nil {
if errors.Is(err, datastore.ErrRecordNotExist) {
return nil, bcode.ErrClusterNotFoundInDataStore
if err = multicluster.DetachCluster(ctx, c.K8sClient, clusterName); err != nil {
return nil, bcode.ErrClusterNotFoundInDataStore
}
return &apis.ClusterBase{Name: clusterName}, nil
}
return nil, errors.Wrapf(err, "failed to found cluster %s in data store", clusterName)
}

View File

@@ -98,6 +98,27 @@ var _ = Describe("Test cluster service function", func() {
Expect(err).Should(Equal(bcode.ErrClusterNotFoundInDataStore))
})
It("Test delete kube cluster", func() {
service := clusterServiceImpl{
Store: ds,
caches: cache,
K8sClient: k8sClient,
}
Expect(createClusterSecret("prism-cluster", "prism-alias")).Should(Succeed())
Expect(ds.Add(ctx, &model.Cluster{Name: "prism-cluster", Alias: "prism-alias", Icon: "prism-icon"})).Should(Succeed())
resp, err := service.DeleteKubeCluster(ctx, "prism-cluster")
Expect(err).Should(Succeed())
Expect(resp.Name).Should(Equal("prism-cluster"))
Expect(resp.Alias).Should(Equal("prism-alias"))
Expect(resp.Icon).Should(Equal("prism-icon"))
_, err = service.DeleteKubeCluster(ctx, "non-exist-cluster")
Expect(err).Should(Equal(bcode.ErrClusterNotFoundInDataStore))
Expect(createClusterSecret("secret-exist-cm-non-exist-cluster", "secret-exist-cm-non-exist-cluster")).Should(Succeed())
resp, err = service.DeleteKubeCluster(ctx, "secret-exist-cm-non-exist-cluster")
Expect(err).Should(Succeed())
Expect(resp.Name).Should(Equal("secret-exist-cm-non-exist-cluster"))
})
It("Test list kube clusters", func() {
service := clusterServiceImpl{
Store: ds,

View File

@@ -91,7 +91,7 @@ template: {
parameter: {
//+usage=The name of Terraform Provider for Alibaba Cloud
name: *"default" | string
name: string
//+usage=Get ALICLOUD_ACCESS_KEY per this guide https://help.aliyun.com/knowledge_detail/38738.html
ALICLOUD_ACCESS_KEY: string
//+usage=Get ALICLOUD_SECRET_KEY per this guide https://help.aliyun.com/knowledge_detail/38738.html
@@ -144,7 +144,7 @@ var _ = Describe("Test config service", func() {
Expect(err).ToNot(BeNil())
var paramErr = &script.ParameterError{}
Expect(errors.As(err, &paramErr)).To(Equal(true))
Expect(paramErr.Name).To(Equal("ALICLOUD_ACCESS_KEY"))
Expect(paramErr.Name).To(Equal("name"))
Expect(paramErr.Message).To(Equal("This parameter is required"))
config, err := configService.CreateConfig(context.TODO(), "", v1.CreateConfigRequest{

View File

@@ -45,8 +45,9 @@ func NewHelmService() HelmService {
type HelmService interface {
ListChartNames(ctx context.Context, url string, secretName string, skipCache bool) ([]string, error)
ListChartVersions(ctx context.Context, url string, chartName string, secretName string, skipCache bool) (repo.ChartVersions, error)
GetChartValues(ctx context.Context, url string, chartName string, version string, secretName string, skipCache bool) (map[string]interface{}, error)
ListChartValuesFiles(ctx context.Context, url string, chartName string, version string, secretName string, repoType string, skipCache bool) (map[string]string, error)
ListChartRepo(ctx context.Context, projectName string) (*v1.ChartRepoResponseList, error)
GetChartValues(ctx context.Context, repoURL string, chartName string, version string, secretName string, repoType string, skipCache bool) (map[string]interface{}, error)
}
type defaultHelmImpl struct {
@@ -99,7 +100,7 @@ func (d defaultHelmImpl) ListChartVersions(ctx context.Context, repoURL string,
return chartVersions, nil
}
func (d defaultHelmImpl) GetChartValues(ctx context.Context, repoURL string, chartName string, version string, secretName string, skipCache bool) (map[string]interface{}, error) {
func (d defaultHelmImpl) ListChartValuesFiles(ctx context.Context, repoURL string, chartName string, version string, secretName string, repoType string, skipCache bool) (map[string]string, error) {
if !utils.IsValidURL(repoURL) {
return nil, bcode.ErrRepoInvalidURL
}
@@ -111,13 +112,33 @@ func (d defaultHelmImpl) GetChartValues(ctx context.Context, repoURL string, cha
return nil, bcode.ErrRepoBasicAuth
}
}
v, err := d.helper.GetValuesFromChart(repoURL, chartName, version, skipCache, opts)
v, err := d.helper.GetValuesFromChart(repoURL, chartName, version, skipCache, repoType, opts)
if err != nil {
klog.Errorf("cannot fetch chart values repo: %s, chart: %s, version: %s, error: %s", utils.Sanitize(repoURL), utils.Sanitize(chartName), utils.Sanitize(version), err.Error())
return nil, bcode.ErrGetChartValues
}
res := make(map[string]interface{}, len(v))
flattenKey("", v, res)
return v.Data, nil
}
func (d defaultHelmImpl) GetChartValues(ctx context.Context, repoURL string, chartName string, version string, secretName string, repoType string, skipCache bool) (map[string]interface{}, error) {
if !utils.IsValidURL(repoURL) {
return nil, bcode.ErrRepoInvalidURL
}
var opts *common.HTTPOption
var err error
if len(secretName) != 0 {
opts, err = helm.SetHTTPOption(ctx, d.K8sClient, types2.NamespacedName{Namespace: types.DefaultKubeVelaNS, Name: secretName})
if err != nil {
return nil, bcode.ErrRepoBasicAuth
}
}
v, err := d.helper.GetValuesFromChart(repoURL, chartName, version, skipCache, repoType, opts)
if err != nil {
klog.Errorf("cannot fetch chart values repo: %s, chart: %s, version: %s, error: %s", utils.Sanitize(repoURL), utils.Sanitize(chartName), utils.Sanitize(version), err.Error())
return nil, bcode.ErrGetChartValues
}
res := make(map[string]interface{}, len(v.Values))
flattenKey("", v.Values, res)
return res, nil
}

View File

@@ -213,7 +213,7 @@ var _ = Describe("test helm usecasae", func() {
Expect(len(versions)).Should(BeEquivalentTo(1))
Expect(versions[0].Version).Should(BeEquivalentTo("8.8.23"))
values, err := u.GetChartValues(ctx, mockServer.URL, "mysql", "8.8.23", "repo-secret", false)
values, err := u.ListChartValuesFiles(ctx, mockServer.URL, "mysql", "8.8.23", "repo-secret", "helm", false)
Expect(err).Should(BeNil())
Expect(values).ShouldNot(BeNil())
Expect(len(values)).ShouldNot(BeEquivalentTo(0))
@@ -228,7 +228,7 @@ var _ = Describe("test helm usecasae", func() {
_, err = u.ListChartVersions(ctx, "http://127.0.0.1:8080", "mysql", "repo-secret-notExist", false)
Expect(err).ShouldNot(BeNil())
_, err = u.GetChartValues(ctx, "http://127.0.0.1:8080", "mysql", "8.8.23", "repo-secret-notExist", false)
_, err = u.ListChartValuesFiles(ctx, "http://127.0.0.1:8080", "mysql", "8.8.23", "repo-secret-notExist", "helm", false)
Expect(err).ShouldNot(BeNil())
})
})

View File

@@ -259,7 +259,9 @@ func managePrivilegesForTarget(ctx context.Context, cli client.Client, target *m
f, msg = auth.RevokePrivileges, "RevokePrivileges"
}
if err := f(ctx, cli, []auth.PrivilegeDescription{p}, identity, writer); err != nil {
return err
klog.Warningf("error encountered for %s: %s", msg, err.Error())
// for some cluster, authn/authz is not supported, ignore errors
return client.IgnoreNotFound(err)
}
klog.Infof("%s: %s", msg, writer.String())
return nil

View File

@@ -190,7 +190,7 @@ func (c *CR2UX) generateEnv(ctx context.Context, defaultProject string, envNames
env.Targets = append(env.Targets, name)
}
}
return env, "", nil
return env, env.Project, nil
}
// generate new environment

View File

@@ -217,6 +217,47 @@ var _ = Describe("Test CR convert to ux", func() {
Expect(count).Should(Equal(int64(2)))
})
It("Test to sync the project which existed env belongs", func() {
dbNamespace := "update-app-db-ns1-test"
ds, err := NewDatastore(datastore.Config{Type: "kubeapi", Database: dbNamespace})
Expect(err).Should(BeNil())
cr2ux := newCR2UX(ds)
projectName := "project-test"
_, err = cr2ux.projectService.CreateProject(context.TODO(), v1.CreateProjectRequest{
Name: projectName,
Owner: "admin",
})
Expect(err).Should(BeNil())
_, err = cr2ux.targetService.CreateTarget(context.TODO(), v1.CreateTargetRequest{
Name: "target-test1",
Project: projectName,
Cluster: &v1.ClusterTarget{
ClusterName: "local",
Namespace: "target-test1",
},
})
Expect(err).Should(BeNil())
_, err = cr2ux.envService.CreateEnv(context.TODO(), v1.CreateEnvRequest{
Name: "env-test1",
Project: projectName,
Namespace: "env-test1",
Targets: []string{"target-test1"},
})
Expect(err).Should(BeNil())
app5 := &v1beta1.Application{}
Expect(common2.ReadYamlToObject("testdata/test-app5.yaml", app5)).Should(BeNil())
app5.Namespace = "env-test1"
Expect(cr2ux.AddOrUpdate(context.Background(), app5)).Should(BeNil())
app, err := cr2ux.applicationService.GetApplication(context.TODO(), app5.Name)
Expect(err).Should(BeNil())
Expect(app.Project).Should(Equal("project-test"))
})
})
func newCR2UX(ds datastore.DataStore) *CR2UX {

View File

@@ -0,0 +1,16 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: example-sync-project
spec:
components:
- name: example-exist-env
type: webservice
properties:
image: wordpress
traits:
- type: gateway
properties:
domain: testsvc.example.com
http:
"/": 8000

View File

@@ -234,7 +234,7 @@ func (n *pipeline) GetWebServiceRoute() *restful.WebService {
Doc("list pipelines").
Param(ws.QueryParameter("query", "Fuzzy search based on name or description").DataType("string")).
Param(ws.QueryParameter("projectName", "query pipelines within a project").DataType("string")).
Param(ws.QueryParameter("detailed", "query pipelines with detail").DataType("bool").DefaultValue("true")).
Param(ws.QueryParameter("detailed", "query pipelines with detail").DataType("boolean").DefaultValue("true")).
Returns(200, "OK", apis.ListPipelineResponse{}).
Returns(400, "Bad Request", bcode.Bcode{}).
Writes(apis.ListPipelineResponse{}).Do(meta))

View File

@@ -69,9 +69,19 @@ func (h repository) GetWebServiceRoute() *restful.WebService {
Writes([]string{}))
// List available chart versions
ws.Route(ws.GET("/charts/{chart}/versions").To(h.listVersions).
ws.Route(ws.GET("/chart/versions").To(h.listVersionsFromQuery).
Doc("list versions").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(ws.QueryParameter("chart", "helm chart").DataType("string").Required(true)).
Param(ws.QueryParameter("repoUrl", "helm repository url").DataType("string").Required(true)).
Param(ws.QueryParameter("secretName", "secret of the repo").DataType("string")).
Returns(200, "OK", v1.ChartVersionListResponse{}).
Returns(400, "Bad Request", bcode.Bcode{}).
Writes([]string{}))
ws.Route(ws.GET("/charts/{chart}/versions").To(h.listChartVersions).
Doc("list versions").Deprecate().
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(ws.QueryParameter("repoUrl", "helm repository url").DataType("string")).
Param(ws.QueryParameter("secretName", "secret of the repo").DataType("string")).
Returns(200, "OK", v1.ChartVersionListResponse{}).
@@ -79,14 +89,26 @@ func (h repository) GetWebServiceRoute() *restful.WebService {
Writes([]string{}))
// List available chart versions
ws.Route(ws.GET("/charts/{chart}/versions/{version}/values").To(h.chartValues).
ws.Route(ws.GET("/chart/values").To(h.chartValues).
Doc("get chart value").
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(ws.QueryParameter("chart", "helm chart").DataType("string").Required(true)).
Param(ws.QueryParameter("version", "helm chart version").DataType("string").Required(true)).
Param(ws.QueryParameter("repoUrl", "helm repository url").DataType("string").Required(true)).
Param(ws.QueryParameter("repoType", "helm repository type").DataType("string").Required(true)).
Param(ws.QueryParameter("secretName", "secret of the repo").DataType("string")).
Returns(200, "OK", "").
Returns(400, "Bad Request", bcode.Bcode{}).
Writes(map[string]string{}))
ws.Route(ws.GET("/charts/{chart}/versions/{version}/values").To(h.getChartValues).
Doc("get chart value").Deprecate().
Metadata(restfulspec.KeyOpenAPITags, tags).
Param(ws.QueryParameter("repoUrl", "helm repository url").DataType("string")).
Param(ws.QueryParameter("secretName", "secret of the repo").DataType("string")).
Returns(200, "OK", map[string]interface{}{}).
Returns(400, "Bad Request", bcode.Bcode{}).
Writes([]string{}))
Writes(map[string]interface{}{}))
ws.Route(ws.GET("/image/repos").To(h.getImageRepos).
Doc("get the oci repos").
@@ -132,9 +154,9 @@ func (h repository) listCharts(req *restful.Request, res *restful.Response) {
}
}
func (h repository) listVersions(req *restful.Request, res *restful.Response) {
func (h repository) listVersionsFromQuery(req *restful.Request, res *restful.Response) {
url := req.QueryParameter("repoUrl")
chartName := req.PathParameter("chart")
chartName := req.QueryParameter("chart")
secName := req.QueryParameter("secretName")
skipCache, err := isSkipCache(req)
if err != nil {
@@ -154,7 +176,7 @@ func (h repository) listVersions(req *restful.Request, res *restful.Response) {
}
}
func (h repository) chartValues(req *restful.Request, res *restful.Response) {
func (h repository) getChartValues(req *restful.Request, res *restful.Response) {
url := req.QueryParameter("repoUrl")
secName := req.QueryParameter("secretName")
chartName := req.PathParameter("chart")
@@ -165,12 +187,57 @@ func (h repository) chartValues(req *restful.Request, res *restful.Response) {
return
}
versions, err := h.HelmService.GetChartValues(req.Request.Context(), url, chartName, version, secName, skipCache)
values, err := h.HelmService.GetChartValues(req.Request.Context(), url, chartName, version, secName, "helm", skipCache)
if err != nil {
bcode.ReturnError(req, res, err)
return
}
err = res.WriteEntity(versions)
err = res.WriteEntity(values)
if err != nil {
bcode.ReturnError(req, res, err)
return
}
}
func (h repository) listChartVersions(req *restful.Request, res *restful.Response) {
url := req.QueryParameter("repoUrl")
chartName := req.PathParameter("chart")
secName := req.QueryParameter("secretName")
skipCache, err := isSkipCache(req)
if err != nil {
bcode.ReturnError(req, res, bcode.ErrSkipCacheParameter)
return
}
versions, err := h.HelmService.ListChartVersions(req.Request.Context(), url, chartName, secName, skipCache)
if err != nil {
bcode.ReturnError(req, res, err)
return
}
err = res.WriteEntity(v1.ChartVersionListResponse{Versions: versions})
if err != nil {
bcode.ReturnError(req, res, err)
return
}
}
func (h repository) chartValues(req *restful.Request, res *restful.Response) {
url := req.QueryParameter("repoUrl")
secName := req.QueryParameter("secretName")
chartName := req.QueryParameter("chart")
version := req.QueryParameter("version")
repoType := req.QueryParameter("repoType")
skipCache, err := isSkipCache(req)
if err != nil {
bcode.ReturnError(req, res, bcode.ErrSkipCacheParameter)
return
}
values, err := h.HelmService.ListChartValuesFiles(req.Request.Context(), url, chartName, version, secName, repoType, skipCache)
if err != nil {
bcode.ReturnError(req, res, err)
return
}
err = res.WriteEntity(values)
if err != nil {
bcode.ReturnError(req, res, err)
return

View File

@@ -23,21 +23,21 @@ var (
// ErrNoConfigOrTarget means there is no target or config when creating the distribution.
ErrNoConfigOrTarget = NewBcode(400, 16002, "you must specify the config name and destination to distribute")
// ErrConfigExist means the config is exist
ErrConfigExist = NewBcode(400, 16003, "the config name is exist")
// ErrConfigExist means the config does exist
ErrConfigExist = NewBcode(400, 16003, "the config name does exist")
// ErrChangeTemplate the template of the config can not be change
ErrChangeTemplate = NewBcode(400, 16004, "the template of the config can not be change")
// ErrChangeTemplate the template of the config can not be changed
ErrChangeTemplate = NewBcode(400, 16004, "the template of the config can not be changed")
// ErrTemplateNotFound means the template is not exist
ErrTemplateNotFound = NewBcode(404, 16005, "the template is not exist")
// ErrTemplateNotFound means the template does not exist
ErrTemplateNotFound = NewBcode(404, 16005, "the template does not exist")
// ErrConfigNotFound means the config is not exist
ErrConfigNotFound = NewBcode(404, 16006, "the config is not exist")
// ErrConfigNotFound means the config does not exist
ErrConfigNotFound = NewBcode(404, 16006, "the config does not exist")
// ErrNotFoundDistribution means the distribution is not exist
ErrNotFoundDistribution = NewBcode(404, 16007, "the distribution is not exist")
// ErrNotFoundDistribution means the distribution does not exist
ErrNotFoundDistribution = NewBcode(404, 16007, "the distribution does not exist")
// ErrChangeSecretType the secret type of the config can not be change
ErrChangeSecretType = NewBcode(400, 16008, "the secret type of the config can not be change")
// ErrChangeSecretType the secret type of the config can not be changed
ErrChangeSecretType = NewBcode(400, 16008, "the secret type of the config can not be changed")
)

View File

@@ -23,6 +23,7 @@ import (
"github.com/kubevela/workflow/pkg/cue/process"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
"github.com/oam-dev/kubevela/apis/types"
velaprocess "github.com/oam-dev/kubevela/pkg/cue/process"
)
@@ -32,7 +33,7 @@ func (p *Parser) ValidateCUESchematicAppfile(a *Appfile) error {
for _, wl := range a.Workloads {
// because helm & kube schematic has no CUE template
// it only validates CUE schematic workload
if wl.CapabilityCategory != types.CUECategory {
if wl.CapabilityCategory != types.CUECategory || wl.Type == v1alpha1.RefObjectsComponentType {
continue
}
ctxData := GenerateContextDataFromAppFile(a, wl.Name)

View File

@@ -76,23 +76,23 @@ var ErrSensitiveConfig = errors.New("the config is sensitive")
// ErrNoConfigOrTarget means the config or the target is empty.
var ErrNoConfigOrTarget = errors.New("you must specify the config name and destination to distribute")
// ErrNotFoundDistribution means the app of the distribution is not exist.
var ErrNotFoundDistribution = errors.New("the distribution is not found")
// ErrNotFoundDistribution means the app of the distribution does not exist.
var ErrNotFoundDistribution = errors.New("the distribution does not found")
// ErrConfigExist means the config is exist.
var ErrConfigExist = errors.New("the config is exist")
// ErrConfigExist means the config does exist.
var ErrConfigExist = errors.New("the config does exist")
// ErrConfigNotFound means the config is not exist
var ErrConfigNotFound = errors.New("the config is not exist")
// ErrConfigNotFound means the config does not exist
var ErrConfigNotFound = errors.New("the config does not exist")
// ErrTemplateNotFound means the template is not exist
var ErrTemplateNotFound = errors.New("the template is not exist")
// ErrTemplateNotFound means the template does not exist
var ErrTemplateNotFound = errors.New("the template does not exist")
// ErrChangeTemplate means the template of the config can not be change
var ErrChangeTemplate = errors.New("the template of the config can not be change")
// ErrChangeTemplate means the template of the config can not be changed
var ErrChangeTemplate = errors.New("the template of the config can not be changed")
// ErrChangeSecretType means the secret type of the config can not be change
var ErrChangeSecretType = errors.New("the secret type of the config can not be change")
// ErrChangeSecretType means the secret type of the config can not be changed
var ErrChangeSecretType = errors.New("the secret type of the config can not be changed")
// NamespacedName the namespace and name model
type NamespacedName struct {

View File

@@ -94,7 +94,7 @@ var _ = Describe("Test the config provider", func() {
`, nil, "")
Expect(err).ToNot(HaveOccurred())
err = p.Create(mCtx, new(wfContext.WorkflowContext), v, nil)
Expect(strings.Contains(err.Error(), "the template is not exist")).Should(BeTrue())
Expect(strings.Contains(err.Error(), "the template does not exist")).Should(BeTrue())
template, err := p.factory.ParseTemplate("test-image-registry", []byte(templateContent))
Expect(err).ToNot(HaveOccurred())

View File

@@ -164,7 +164,7 @@ func getOriginalConfiguration(obj runtime.Object) ([]byte, error) {
return nil, nil
}
original, ok := annots[oam.AnnotationLastAppliedConfig]
if !ok {
if !ok || original == "-" || original == "skip" {
return nil, nil
}
return []byte(original), nil

View File

@@ -24,6 +24,7 @@ import (
"os"
"path"
"path/filepath"
"regexp"
"strings"
"time"
@@ -32,6 +33,9 @@ import (
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/chartutil"
"helm.sh/helm/v3/pkg/cli"
"helm.sh/helm/v3/pkg/downloader"
"helm.sh/helm/v3/pkg/getter"
"helm.sh/helm/v3/pkg/kube"
"helm.sh/helm/v3/pkg/release"
relutil "helm.sh/helm/v3/pkg/releaseutil"
@@ -56,6 +60,12 @@ const (
valuesPatten = "repoUrl: %s, chart: %s, version: %s"
)
// ChartValues contain all values files in chart and default chart values
type ChartValues struct {
Data map[string]string
Values map[string]interface{}
}
// Helper provides helper functions for common Helm operations
type Helper struct {
cache *utils2.MemoryCacheStore
@@ -309,12 +319,22 @@ func (h *Helper) ListChartsFromRepo(repoURL string, skipCache bool, opts *common
}
// GetValuesFromChart will extract the parameter from a helm chart
func (h *Helper) GetValuesFromChart(repoURL string, chartName string, version string, skipCache bool, opts *common.HTTPOption) (map[string]interface{}, error) {
func (h *Helper) GetValuesFromChart(repoURL string, chartName string, version string, skipCache bool, repoType string, opts *common.HTTPOption) (*ChartValues, error) {
if h.cache != nil && !skipCache {
if v := h.cache.Get(fmt.Sprintf(valuesPatten, repoURL, chartName, version)); v != nil {
return v.(map[string]interface{}), nil
return v.(*ChartValues), nil
}
}
if repoType == "oci" {
v, err := fetchChartValuesFromOciRepo(repoURL, chartName, version, opts)
if err != nil {
return nil, err
}
if h.cache != nil {
h.cache.Put(fmt.Sprintf(valuesPatten, repoURL, chartName, version), v, 20*time.Minute)
}
return v, nil
}
i, err := h.GetIndexInfo(repoURL, skipCache, opts)
if err != nil {
return nil, err
@@ -334,10 +354,17 @@ func (h *Helper) GetValuesFromChart(repoURL string, chartName string, version st
if err != nil {
continue
}
if h.cache != nil {
h.cache.Put(fmt.Sprintf(valuesPatten, repoURL, chartName, version), c.Values, calculateCacheTimeFromIndex(len(i.Entries)))
v := &ChartValues{
Data: loadValuesYamlFile(c),
Values: c.Values,
}
return c.Values, nil
if err != nil {
return nil, err
}
if h.cache != nil {
h.cache.Put(fmt.Sprintf(valuesPatten, repoURL, chartName, version), v, calculateCacheTimeFromIndex(len(i.Entries)))
}
return v, nil
}
return nil, fmt.Errorf("cannot load chart from chart repo")
}
@@ -351,3 +378,49 @@ func calculateCacheTimeFromIndex(length int) time.Duration {
}
return cacheTime
}
// nolint
func fetchChartValuesFromOciRepo(repoURL string, chartName string, version string, opts *common.HTTPOption) (*ChartValues, error) {
d := downloader.ChartDownloader{
Verify: downloader.VerifyNever,
Getters: getter.All(cli.New()),
}
if opts != nil {
d.Options = append(d.Options, getter.WithInsecureSkipVerifyTLS(opts.InsecureSkipTLS),
getter.WithTLSClientConfig(opts.CertFile, opts.KeyFile, opts.CaFile),
getter.WithBasicAuth(opts.Username, opts.Password))
}
var err error
dest, err := os.MkdirTemp("", "helm-")
if err != nil {
return nil, errors.Wrap(err, "failed to fetch values file")
}
defer os.RemoveAll(dest)
chartRef := fmt.Sprintf("%s/%s", repoURL, chartName)
saved, _, err := d.DownloadTo(chartRef, version, dest)
if err != nil {
return nil, err
}
c, err := loader.Load(saved)
if err != nil {
return nil, errors.Wrap(err, "failed to fetch values file")
}
return &ChartValues{
Data: loadValuesYamlFile(c),
Values: c.Values,
}, nil
}
func loadValuesYamlFile(chart *chart.Chart) map[string]string {
result := map[string]string{}
re := regexp.MustCompile(`.*yaml$`)
for _, f := range chart.Raw {
if re.MatchString(f.Name) && !strings.Contains(f.Name, "/") && f.Name != "Chart.yaml" {
result[f.Name] = string(f.Data)
}
}
return result
}

View File

@@ -114,9 +114,9 @@ var _ = Describe("Test helm helper", func() {
It("Test getValues from chart", func() {
helper := NewHelper()
values, err := helper.GetValuesFromChart("./testdata", "autoscalertrait", "0.2.0", true, nil)
values, err := helper.GetValuesFromChart("./testdata", "autoscalertrait", "0.2.0", true, "helm", nil)
Expect(err).Should(BeNil())
Expect(values).ShouldNot(BeEmpty())
Expect(values).ShouldNot(BeNil())
})
})

View File

@@ -92,12 +92,26 @@ func MergeNoConflictLabels(labels map[string]string) MutateOption {
// CreateOrUpdateNamespace will create a namespace if not exist, it will also update a namespace if exists
// It will report an error if the labels conflict while it will override the annotations
func CreateOrUpdateNamespace(ctx context.Context, kubeClient client.Client, name string, options ...MutateOption) error {
err := CreateNamespace(ctx, kubeClient, name, options...)
// only if namespace don't have the env label that we need to update it
if apierrors.IsAlreadyExists(err) {
return UpdateNamespace(ctx, kubeClient, name, options...)
ns, err := GetNamespace(ctx, kubeClient, name)
switch {
case err == nil:
return PatchNamespace(ctx, kubeClient, ns, options...)
case apierrors.IsNotFound(err):
return CreateNamespace(ctx, kubeClient, name, options...)
default:
return err
}
return err
}
// PatchNamespace will patch a namespace
func PatchNamespace(ctx context.Context, kubeClient client.Client, ns *corev1.Namespace, options ...MutateOption) error {
original := ns.DeepCopy()
for _, op := range options {
if err := op(ns); err != nil {
return err
}
}
return kubeClient.Patch(ctx, ns, client.MergeFrom(original))
}
// CreateNamespace will create a namespace with mutate option

View File

@@ -167,7 +167,7 @@ func NewAddonEnableCommand(c common.Args, ioStream cmdutil.IOStreams) *cobra.Com
addonArgs[pkgaddon.InstallerRuntimeOption] = map[string]interface{}{
"upgrade": false,
}
var addonName string
if file, err := os.Stat(addonOrDir); err == nil {
if !file.IsDir() {
return fmt.Errorf("%s is not addon dir", addonOrDir)
@@ -178,13 +178,13 @@ func NewAddonEnableCommand(c common.Args, ioStream cmdutil.IOStreams) *cobra.Com
if err != nil {
return errors.Wrapf(err, "directory %s is invalid", addonOrDir)
}
name = filepath.Base(abs)
addonName = filepath.Base(abs)
if !yes2all {
if err := checkUninstallFromClusters(ctx, k8sClient, name, addonArgs); err != nil {
if err := checkUninstallFromClusters(ctx, k8sClient, addonName, addonArgs); err != nil {
return err
}
}
additionalInfo, err = enableAddonByLocal(ctx, name, addonOrDir, k8sClient, dc, config, addonArgs)
additionalInfo, err = enableAddonByLocal(ctx, addonName, addonOrDir, k8sClient, dc, config, addonArgs)
if err != nil {
return err
}
@@ -192,8 +192,12 @@ func NewAddonEnableCommand(c common.Args, ioStream cmdutil.IOStreams) *cobra.Com
if filepath.IsAbs(addonOrDir) || strings.HasPrefix(addonOrDir, ".") || strings.HasSuffix(addonOrDir, "/") {
return fmt.Errorf("addon directory %s not found in local file system", addonOrDir)
}
_, addonName, err = splitSpecifyRegistry(name)
if err != nil {
return fmt.Errorf("failed to split addonName and addonRegistry: %w", err)
}
if !yes2all {
if err := checkUninstallFromClusters(ctx, k8sClient, name, addonArgs); err != nil {
if err := checkUninstallFromClusters(ctx, k8sClient, addonName, addonArgs); err != nil {
return err
}
}
@@ -205,8 +209,8 @@ func NewAddonEnableCommand(c common.Args, ioStream cmdutil.IOStreams) *cobra.Com
if dryRun {
return nil
}
fmt.Printf("Addon %s enabled successfully.\n", name)
AdditionalEndpointPrinter(ctx, c, k8sClient, name, additionalInfo, false)
fmt.Printf("Addon %s enabled successfully.\n", addonName)
AdditionalEndpointPrinter(ctx, c, k8sClient, addonName, additionalInfo, false)
return nil
},
}

View File

@@ -17,6 +17,7 @@ limitations under the License.
package cli
import (
"context"
_ "embed"
"encoding/json"
"fmt"
@@ -99,6 +100,7 @@ type AdoptOptions struct {
Apply bool
Recycle bool
Yes bool
AdoptTemplateFile string
AdoptTemplate string
@@ -195,6 +197,20 @@ func (opt *AdoptOptions) Complete(f velacmd.Factory, cmd *cobra.Command, args []
} else {
opt.AdoptTemplate = defaultAdoptTemplate
}
if opt.AppName != "" {
var ctx = context.Background()
app := &v1beta1.Application{}
err := f.Client().Get(ctx, apitypes.NamespacedName{Namespace: opt.AppNamespace, Name: opt.AppName}, app)
if err == nil && app != nil {
if !opt.Yes {
userInput := NewUserInput()
confirm := userInput.AskBool("Application '%s' already exists, apply will override the existing app with the adopted one, please confirm [Y/n]: "+opt.AppName, &UserInputOptions{AssumeYes: false})
if !confirm {
return nil
}
}
}
}
opt.AdoptTemplateCUEValue = cuecontext.New().CompileString(fmt.Sprintf("%s\n\n%s: %s", opt.AdoptTemplate, adoptCUETempVal, adoptCUETempFunc))
return nil
}
@@ -285,6 +301,12 @@ func (opt *AdoptOptions) render() (*v1beta1.Application, error) {
if err = json.Unmarshal(bs, app); err != nil {
return nil, fmt.Errorf("failed to parse template $returns into application: %w", err)
}
if app.Name == "" {
app.Name = opt.AppName
}
if app.Namespace == "" {
app.Namespace = opt.AppNamespace
}
return app, nil
}
@@ -457,6 +479,7 @@ func NewAdoptCommand(f velacmd.Factory, streams util.IOStreams) *cobra.Command {
cmd.Flags().StringVarP(&o.HelmDriver, "driver", "d", o.HelmDriver, "The storage backend of helm adoption. Only take effect when --type=helm.")
cmd.Flags().BoolVarP(&o.Apply, "apply", "", o.Apply, "If true, the application for adoption will be applied. Otherwise, it will only be printed.")
cmd.Flags().BoolVarP(&o.Recycle, "recycle", "", o.Recycle, "If true, when the adoption application is successfully applied, the old storage (like Helm secret) will be recycled.")
cmd.Flags().BoolVarP(&o.Yes, "yes", "y", o.Yes, "Skip confirmation prompt")
return velacmd.NewCommandBuilder(f, cmd).
WithNamespaceFlag().
WithResponsiveWriter().

View File

@@ -19,7 +19,10 @@ package cli
import (
"fmt"
"github.com/go-logr/logr"
"github.com/spf13/cobra"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/log"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/utils/common"
@@ -50,6 +53,7 @@ func NewTopCommand(c common.Args, order string, ioStreams cmdutil.IOStreams) *co
if AllNamespace {
namespace = ""
}
klog.SetLogger(logr.New(log.NullLogSink{}))
return launchUI(c, namespace)
},
Annotations: map[string]string{

View File

@@ -153,7 +153,7 @@ var _ = Describe("Test the rest api about the config", func() {
Expect(config.Secret).Should(BeNil())
Expect(config.Properties["registry"]).Should(Equal("kubevela.test.com"))
By("the config name is exist")
By("the config name does exist")
req = v1.CreateConfigRequest{
Name: "test-registry",
Alias: "Test Registry",
@@ -164,7 +164,7 @@ var _ = Describe("Test the rest api about the config", func() {
res = post("/configs", req)
Expect(res.StatusCode).Should(Equal(400))
By("the template is not exist")
By("the template does not exist")
req = v1.CreateConfigRequest{
Name: "test-registry2",
Alias: "Test Registry",

View File

@@ -0,0 +1,42 @@
/*
Copyright 2022 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 e2e_apiserver_test
import (
"io"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
var _ = Describe("Helm rest api test", func() {
Describe("helm repo api test", func() {
It("test fetching chart values in OCI registry", func() {
resp := getWithQuery("/repository/chart/values", map[string]string{
"repoUrl": "oci://ghcr.io",
"chart": "stefanprodan/charts/podinfo",
"repoType": "oci",
"version": "6.1.0",
})
defer resp.Body.Close()
values, err := io.ReadAll(resp.Body)
Expect(err).Should(BeNil())
Expect(len(values)).ShouldNot(BeEquivalentTo(0))
})
})
})

View File

@@ -191,6 +191,26 @@ func get(path string) *http.Response {
return response
}
func getWithQuery(path string, params map[string]string) *http.Response {
client := &http.Client{}
if !strings.HasPrefix(path, "/v1") {
path = baseURL + path
} else {
path = baseDomain + path
}
req, err := http.NewRequest(http.MethodGet, path, nil)
Expect(err).Should(BeNil())
req.Header.Add("Authorization", token)
query := req.URL.Query()
for k, v := range params {
query.Set(k, v)
}
req.URL.RawQuery = query.Encode()
response, err := client.Do(req)
Expect(err).Should(BeNil())
return response
}
func delete(path string) *http.Response {
client := &http.Client{}
if !strings.HasPrefix(path, "/v1") {

View File

@@ -9,7 +9,7 @@
template: {
#PolicyRule: {
// +usage=Specify how to select the targets of the rule
selector: [...#RuleSelector]
selector: #RuleSelector
}
#RuleSelector: {

View File

@@ -64,7 +64,7 @@ template: {
}
}
parameter: *#PatchParams | close({
parameter: #PatchParams | close({
// +usage=Specify the container image for multiple containers
containers: [...#PatchParams]
})

View File

@@ -18,7 +18,10 @@ expose: {
}
if service.spec.type == "LoadBalancer" {
status: service.status
isHealth: status != _|_ && status.loadBalancer != _|_ && status.loadBalancer.ingress != _|_ && len(status.loadBalancer.ingress) > 0
isHealth: *false | bool
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
isHealth: true
}
if !isHealth {
message: "ExternalIP: Pending"
}
@@ -28,11 +31,16 @@ expose: {
}
"""#
healthPolicy: #"""
isHealth: *true | bool
service: context.outputs.service
if service.spec.type == "LoadBalancer" {
status: service.status
isHealth: status != _|_ && status.loadBalancer != _|_ && status.loadBalancer.ingress != _|_ && len(status.loadBalancer.ingress) > 0
isHealth: *false | bool
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
isHealth: true
}
}
if service.spec.type != "LoadBalancer" {
isHealth: true
}
"""#
}

View File

@@ -113,7 +113,7 @@ template: {
#ECProvider: {
type: "ec"
apiKey: *"" | string
name: "ec-provider" | string
name: *"ec-provider" | string
}
#GCPProvider: {
credentials: string

View File

@@ -51,44 +51,41 @@ template: {
// +usage=Specify the message that you want to sent, refer to [dingtalk messaging](https://developers.dingtalk.com/document/robots/custom-robot-access/title-72m-8ag-pqw)
message: {
// +usage=Specify the message content of dingtalk notification
text?: *null | close({
text?: close({
content: string
})
// +usage=msgType can be text, link, mardown, actionCard, feedCard
msgtype: *"text" | "link" | "markdown" | "actionCard" | "feedCard"
link?: *null | close({
#link: {
text?: string
title?: string
messageUrl?: string
picUrl?: string
})
markdown?: *null | close({
}
link?: #link
markdown?: close({
text: string
title: string
})
at?: *null | close({
atMobiles?: *null | [...string]
isAtAll?: bool
at?: close({
atMobiles?: [...string]
isAtAll?: bool
})
actionCard?: *null | close({
actionCard?: close({
text: string
title: string
hideAvatar: string
btnOrientation: string
singleTitle: string
singleURL: string
btns: *null | close([...*null | close({
btns?: [...close({
title: string
actionURL: string
})])
})]
})
feedCard?: *null | close({
links: *null | close([...*null | close({
text?: string
title?: string
messageUrl?: string
picUrl?: string
})])
feedCard?: close({
links: [...#link]
})
}
}
@@ -109,11 +106,11 @@ template: {
// +usage=Specify the message that you want to sent, refer to [slack messaging](https://api.slack.com/reference/messaging/payload)
message: {
// +usage=Specify the message text for slack notification
text: string
blocks?: *null | close([...block])
attachments?: *null | close({
blocks?: *null | close([...block])
color?: string
text: string
blocks?: [...block]
attachments?: close({
blocks?: [...block]
color?: string
})
thread_ts?: string
// +usage=Specify the message text format in markdown for slack notification