Compare commits

...

47 Commits

Author SHA1 Message Date
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
github-actions[bot]
4b88cd201e [Backport release-1.7] Fix: replace homemade release script with goreleaser (#5398)
* Replace homemade release script with goreleaser

refactor release.yml

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

* wrap files in a directory

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

---------

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-01-31 20:55:06 +08:00
github-actions[bot]
492e7d7f0d [Backport release-1.7] Fix: use the namespace specified in the resource if -n is not s… (#5396)
* fix #5368, use the namespace specified in the resource if -n is not specified

Signed-off-by: Basuotian <basuoluomiu@gmail.com>
(cherry picked from commit 47c9b4457b)

* add default namespace for the case missing namespace in resourceRef

Signed-off-by: Basuotian <basuoluomiu@gmail.com>
(cherry picked from commit 3ae0657796)

* add test case

Signed-off-by: Basuotian <basuoluomiu@gmail.com>
(cherry picked from commit 4ba5eb88eb)

---------

Co-authored-by: Basuotian <basuoluomiu@gmail.com>
2023-01-31 20:16:18 +08:00
Jianbo Sun
0742ca9ee5 Fix: aligin config create to be managed by apps with Dispatch function (#5384) (#5394)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2023-01-31 18:04:36 +08:00
github-actions[bot]
1cf4ae3fc3 [Backport release-1.7] Feat: add the updating the application trigger API (#5395)
* Feat: add the updating the application trigger API

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 05bc42bc50)

* Fix: change the test case

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit d6f3e0e90b)

* Fix: imported more than once

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 37f7af0beb)

---------

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2023-01-31 17:14:03 +08:00
qiaozp
444d315143 Fix: rework on apisrever e2e test covergae (#5390)
Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-01-31 15:04:24 +08:00
github-actions[bot]
2e3a89f6b1 Chore: update workflow version to fix panic (#5386)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 4ae1fe044e)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2023-01-31 10:57:40 +08:00
github-actions[bot]
d94293ac59 Fix: failed to create the record when rollbacking the application (#5381)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 57d85ecb7c)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2023-01-30 20:51:04 +08:00
github-actions[bot]
cc604cfadb Feat: upgrade cluster gateway to 1.7.0 (#5356)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 3245ea148c)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-01-19 11:21:38 +08:00
github-actions[bot]
8ef2513b2e fix: fix --cluster when addon enable (#5343)
Signed-off-by: zhaowei.wang <zhaowei.wang@metabit-trading.com>
(cherry picked from commit 021ca69cfd)

Co-authored-by: zhaowei.wang <zhaowei.wang@metabit-trading.com>
2023-01-13 17:09:26 +08:00
github-actions[bot]
657e3b1bde Fix: optimize skip reconcile and expose error if the traits patch an invalid workload like terraform (#5342)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 3730291eff)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2023-01-13 17:08:52 +08:00
github-actions[bot]
004e2a814d Feat: upgrade the workflow version to v0.4.0 (#5337)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit e0b8c9e4c9)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2023-01-13 16:57:03 +08:00
github-actions[bot]
6dcba5ef11 [Backport release-1.7] Fix: conflict while using gc policy and shared-resource policy concurrently (#5333)
* Fix: conflict while using gc policy and shared-resource policy concurrently

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

* Fix: github ci

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

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-01-13 15:55:05 +08:00
github-actions[bot]
fd39804dc9 Fix: maintain compatibility with old project data (#5331)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit fef55b9b1b)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2023-01-13 13:59:35 +08:00
github-actions[bot]
ce57fbb752 Feat: need one Trait to set Rollout strategy of Workload (#5327)
Signed-off-by: StevenLeiZhang <zhangleiic@163.com>
(cherry picked from commit 5d00b2ac73)

Co-authored-by: StevenLeiZhang <zhangleiic@163.com>
2023-01-12 17:19:17 +08:00
github-actions[bot]
80b2b2c2d3 velaql support indexing into exported array field (#5323)
Signed-off-by: hnd4r7 <307365651@qq.com>
(cherry picked from commit 441d8f0a66)

Co-authored-by: hnd4r7 <307365651@qq.com>
2023-01-12 10:13:57 +08:00
github-actions[bot]
49d97e5c2b Fix typo in the long cli description of vela system command (#5322)
Signed-off-by: Girish Ramnani <girishramnani95@gmail.com>
(cherry picked from commit 273b91c41f)

Co-authored-by: Girish <girishramnani95@gmail.com>
2023-01-12 10:10:15 +08:00
github-actions[bot]
1ee5915546 Fix: the developer user can't load the definition (#5319)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 78c9a1a370)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2023-01-11 18:28:36 +08:00
github-actions[bot]
3f6b38cc7f small optimzie for addon (#5318)
Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

name the compoennt

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2023-01-11 16:33:16 +08:00
Jianbo Sun
c2c7ab91f9 Feat: vela dry-run render results should be affected by override policy and deploy workflowstep (#4815) (#5314)
* [Feature] vela dry-run render results should be affected by override policy and deploy workflowstep

Signed-off-by: cezhang <c1zhang.dev@gmail.com>

* multiple input files support; policy,workflow support; new flag: merge orphan policy or workflow

Signed-off-by: cezhang <c1zhang.dev@gmail.com>

* add more tests

Signed-off-by: cezhang <c1zhang.dev@gmail.com>

* fix comment issues

Signed-off-by: cezhang <c1zhang.dev@gmail.com>

* add tests

Signed-off-by: cezhang <c1zhang.dev@gmail.com>

* fix e2e

Signed-off-by: cezhang <c1zhang.dev@gmail.com>

* fix tests

Signed-off-by: cezhang <c1zhang.dev@gmail.com>

Signed-off-by: cezhang <c1zhang.dev@gmail.com>

Signed-off-by: cezhang <c1zhang.dev@gmail.com>
Co-authored-by: cezhang <c1zhang.dev@gmail.com>
2023-01-11 15:39:45 +08:00
github-actions[bot]
866ffb9689 Chore: vela delete doc (#5315)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit ce79ab1691)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2023-01-11 15:08:08 +08:00
github-actions[bot]
61afb366ee Fix: fix vela debug cli to find id for step (#5313)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 2f77353cbe)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2023-01-11 14:57:02 +08:00
github-actions[bot]
a2a8d73a58 Fix: don't return err if subresource type is not found when listing application resources (#5312)
Signed-off-by: hnd4r7 <307365651@qq.com>
(cherry picked from commit 58a150d1d4)

Co-authored-by: hnd4r7 <307365651@qq.com>
2023-01-11 14:56:22 +08:00
github-actions[bot]
fc3b428788 fix: errorMsg when uninstall vela (#5310)
Signed-off-by: bitliu <bitliu@tencent.com>
(cherry picked from commit 771e0b5429)

Co-authored-by: bitliu <bitliu@tencent.com>
2023-01-11 14:49:14 +08:00
github-actions[bot]
500dc52b34 [Backport release-1.7] Fix: create a config with the same name reported an incorrect error (#5307)
* Fix: create a config with the same name reported an incorrect error

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

* Fix: create a config with the same name reported an incorrect error

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

Co-authored-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
2023-01-11 14:25:13 +08:00
github-actions[bot]
789aa38476 [Backport release-1.7] Feat: enhance the application synchronizer (#5305)
* Feat: enhance the application synchronizer

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit e5d112b04a)

* Fix: e2e test case

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 940ffb30f5)

* Fix: the unit test case

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit c3e896fbc1)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2023-01-11 14:24:25 +08:00
github-actions[bot]
17adf35717 Fix: Index structure map[string]string,Mongo resulting in inconsistent results obtained by filtering non-string type by index. (#5303)
Signed-off-by: old.prince <di7zhang@gmail.com>
(cherry picked from commit a763d3da54)

Co-authored-by: old.prince <di7zhang@gmail.com>
2023-01-11 13:06:15 +08:00
github-actions[bot]
586f266798 [Backport release-1.7] Fix: more explicit error when addon package hasn't a metadata.yaml (#5302)
* more explicit error when addon package hasn't a metadata.yaml

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

fix checkdiff

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

* fix commets

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

* fix test

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2023-01-11 11:53:00 +08:00
github-actions[bot]
b8dcbe4964 Fix: Delete appplication fails if status.workflow.endTime not specified. (#5297)
Error Details:
E0106 08:12:02.807341       1 controller.go:317] controller/application "msg"="Reconciler error" "error"="Application.core.oam.dev \"test\" is invalid: status.workflow.endTime: Invalid value: \"null\": status.workflow.endTime in body must be of type string: \"null\"" "name"="test" "namespace"="test" "reconciler group"="core.oam.dev" "reconciler kind"="Application"

If the workflow is not completed, the endtime should be null, and the deletion of the application will fail

Signed-off-by: old.prince <di7zhang@gmail.com>
(cherry picked from commit 16b6a02018)

Co-authored-by: old.prince <di7zhang@gmail.com>
2023-01-10 15:16:26 +08:00
github-actions[bot]
778579c79b Test: let addon helper tests use local helm server (#5290)
Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>
(cherry picked from commit 44eaa1d004)

Co-authored-by: Charlie Chiang <charlie_c_0129@outlook.com>
2023-01-09 13:30:04 +08:00
165 changed files with 3527 additions and 788 deletions

View File

@@ -64,6 +64,8 @@ jobs:
- name: Install ginkgo
run: |
sudo sed -i 's/azure\.//' /etc/apt/sources.list
sudo apt-get update
sudo apt-get install -y golang-ginkgo-dev
- name: Start MongoDB
@@ -184,7 +186,7 @@ jobs:
uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70
with:
token: ${{ secrets.CODECOV_TOKEN }}
files: /tmp/e2e_apiserver_test.out
files: /tmp/e2e-profile.out, /tmp/e2e_apiserver_test.out
flags: apiserver-e2etests
name: codecov-umbrella

View File

@@ -7,7 +7,6 @@ on:
workflow_dispatch: { }
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUCKET: ${{ secrets.CLI_OSS_BUCKET }}
ENDPOINT: ${{ secrets.CLI_OSS_ENDPOINT }}
ACCESS_KEY: ${{ secrets.CLI_OSS_ACCESS_KEY }}
@@ -28,105 +27,36 @@ jobs:
repository-projects: read
statuses: read
runs-on: ubuntu-latest
name: build
strategy:
matrix:
TARGETS: [ linux/amd64, darwin/amd64, windows/amd64, linux/arm64, darwin/arm64 ]
env:
VELA_VERSION_KEY: github.com/oam-dev/kubevela/version.VelaVersion
VELA_GITVERSION_KEY: github.com/oam-dev/kubevela/version.GitRevision
GO_BUILD_ENV: GO111MODULE=on CGO_ENABLED=0
DIST_DIRS: find * -type d -exec
name: goreleaser
steps:
- name: Checkout
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b
with:
fetch-depth: 0
- run: git fetch --force --tags
- name: Set up Go
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568
with:
go-version: 1.19
- name: Get release
id: get_release
uses: bruceadams/get-release@74c3d60f5a28f358ccf241a00c9021ea16f0569f # v1.3.2
cache: true
- uses: goreleaser/goreleaser-action@9754a253a8673b0ea869c2e863b4e975497efd0c # v4.1.1
with:
distribution: goreleaser
version: 1.14.1
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
- name: Get version
run: echo "VELA_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- name: Get matrix
id: get_matrix
run: |
TARGETS=${{matrix.TARGETS}}
echo "OS=${TARGETS%/*}" >> $GITHUB_OUTPUT
echo "ARCH=${TARGETS#*/}" >> $GITHUB_OUTPUT
- name: Get ldflags
id: get_ldflags
run: |
LDFLAGS="-s -w -X ${{ env.VELA_VERSION_KEY }}=${{ env.VELA_VERSION }} -X ${{ env.VELA_GITVERSION_KEY }}=git-$(git rev-parse --short HEAD)"
echo "LDFLAGS=${LDFLAGS}" >> $GITHUB_ENV
- name: Build
run: |
${{ env.GO_BUILD_ENV }} GOOS=${{ steps.get_matrix.outputs.OS }} GOARCH=${{ steps.get_matrix.outputs.ARCH }} \
go build -ldflags "${{ env.LDFLAGS }}" \
-o _bin/vela/${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}/vela -v \
./references/cmd/cli/main.go
${{ env.GO_BUILD_ENV }} GOOS=${{ steps.get_matrix.outputs.OS }} GOARCH=${{ steps.get_matrix.outputs.ARCH }} \
go build -ldflags "${{ env.LDFLAGS }}" \
-o _bin/kubectl-vela/${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}/kubectl-vela -v \
./cmd/plugin/main.go
- name: Compress
run: |
echo "\n## Release Info\nVERSION: ${{ env.VELA_VERSION }}" >> README.md && \
echo "GIT_COMMIT: ${GITHUB_SHA}\n" >> README.md && \
cd _bin/vela && \
${{ env.DIST_DIRS }} cp ../../LICENSE {} \; && \
${{ env.DIST_DIRS }} cp ../../README.md {} \; && \
${{ env.DIST_DIRS }} tar -zcf vela-{}.tar.gz {} \; && \
${{ env.DIST_DIRS }} zip -r vela-{}.zip {} \; && \
cd ../kubectl-vela && \
${{ env.DIST_DIRS }} cp ../../LICENSE {} \; && \
${{ env.DIST_DIRS }} cp ../../README.md {} \; && \
${{ env.DIST_DIRS }} tar -zcf kubectl-vela-{}.tar.gz {} \; && \
${{ env.DIST_DIRS }} zip -r kubectl-vela-{}.zip {} \; && \
cd .. && \
sha256sum vela/vela-* kubectl-vela/kubectl-vela-* >> sha256-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.txt \
- name: Upload Vela tar.gz
uses: kubevela/vela-upload-release-asset@9b3858e67d3205e056d6220e5972abb32fc47289 # v1.0.0
with:
release_id: ${{ steps.get_release.outputs.id }}
asset_path: ./_bin/vela/vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
asset_name: vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
- name: Upload Vela zip
uses: kubevela/vela-upload-release-asset@9b3858e67d3205e056d6220e5972abb32fc47289 # v1.0.0
with:
release_id: ${{ steps.get_release.outputs.id }}
asset_path: ./_bin/vela/vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
asset_name: vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
- name: Upload Kubectl-Vela tar.gz
uses: kubevela/vela-upload-release-asset@9b3858e67d3205e056d6220e5972abb32fc47289 # v1.0.0
with:
release_id: ${{ steps.get_release.outputs.id }}
asset_path: ./_bin/kubectl-vela/kubectl-vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
asset_name: kubectl-vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
- name: Upload Kubectl-Vela zip
uses: kubevela/vela-upload-release-asset@9b3858e67d3205e056d6220e5972abb32fc47289 # v1.0.0
with:
release_id: ${{ steps.get_release.outputs.id }}
asset_path: ./_bin/kubectl-vela/kubectl-vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
asset_name: kubectl-vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
- name: Post sha256
uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
with:
name: sha256sums
path: ./_bin/sha256-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.txt
retention-days: 1
- name: clear the asset
run: |
rm -rf ./_bin/vela/${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}
mv ./_bin/vela/vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz ./_bin/vela/vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
mv ./_bin/vela/vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip ./_bin/vela/vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
- name: Install ossutil
run: wget http://gosspublic.alicdn.com/ossutil/1.7.0/ossutil64 && chmod +x ossutil64 && mv ossutil64 ossutil
- name: Configure Alibaba Cloud OSSUTIL
run: ./ossutil --config-file .ossutilconfig config -i ${ACCESS_KEY} -k ${ACCESS_KEY_SECRET} -e ${ENDPOINT} -c .ossutilconfig
run: ./ossutil --config-file .ossutilconfig config -i ${ACCESS_KEY} -k ${ACCESS_KEY_SECRET} -e ${ENDPOINT}
- name: split files to be upload
run: mkdir -p ./dist/files_upload && mv ./dist/*.tar.gz ./dist/files_upload && mv ./dist/*.zip ./dist/files_upload
- name: sync local to cloud
run: ./ossutil --config-file .ossutilconfig sync ./_bin/vela oss://$BUCKET/binary/vela/${{ env.VELA_VERSION }}
run: ./ossutil --config-file .ossutilconfig sync ./dist/files_upload oss://$BUCKET/binary/vela/${{ env.VELA_VERSION }}
- name: sync the latest version file
if: ${{ !contains(env.VELA_VERSION,'alpha') && !contains(env.VELA_VERSION,'beta') }}
run: |
@@ -137,7 +67,6 @@ jobs:
verlte ${{ env.VELA_VERSION }} $LATEST_VERSION && echo "${{ env.VELA_VERSION }} <= $LATEST_VERSION, skip update" && exit 0
echo ${{ env.VELA_VERSION }} > ./latest_version
./ossutil --config-file .ossutilconfig cp -u ./latest_version oss://$BUCKET/binary/vela/latest_version
upload-plugin-homebrew:
permissions:
contents: write
@@ -154,34 +83,6 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b
- name: Get release
id: get_release
uses: bruceadams/get-release@74c3d60f5a28f358ccf241a00c9021ea16f0569f # v1.3.2
- name: Download sha256sums
uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3.0.1
with:
name: sha256sums
path: cli-artifacts
- name: Display structure of downloaded files
run: ls -R
working-directory: cli-artifacts
- name: Get version
run: echo "VELA_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
- shell: bash
working-directory: cli-artifacts
run: |
for file in *
do
sed -i "s/\/vela/-${{ env.VELA_VERSION }}/g" ${file}
sed -i "s/\/kubectl-vela/-${{ env.VELA_VERSION }}/g" ${file}
cat ${file} >> sha256sums.txt
done
- name: Upload Checksums
uses: kubevela/vela-upload-release-asset@9b3858e67d3205e056d6220e5972abb32fc47289 # v1.0.0
with:
release_id: ${{ steps.get_release.outputs.id }}
asset_path: cli-artifacts/sha256sums.txt
asset_name: sha256sums.txt
- name: Update kubectl plugin version in krew-index
uses: rajatjindal/krew-release-bot@3320c0b546b5d2320613c46762bd3f73e2801bdc # v0.0.38
- name: Update Homebrew formula

View File

@@ -61,6 +61,8 @@ jobs:
- name: Install ginkgo
run: |
sudo sed -i 's/azure\.//' /etc/apt/sources.list
sudo apt-get update
sudo apt-get install -y golang-ginkgo-dev
- name: Setup K3d

2
.gitignore vendored
View File

@@ -53,3 +53,5 @@ git-page/
# e2e rollout runtime image build
runtime/rollout/e2e/tmp
vela.json
dist/

76
.goreleaser.yaml Normal file
View File

@@ -0,0 +1,76 @@
# This is an example .goreleaser.yml file with some sensible defaults.
# Make sure to check the documentation at https://goreleaser.com
builds:
- id: vela-cli
binary: vela
goos:
- linux
- windows
- darwin
goarch:
- amd64
- arm64
main: ./references/cmd/cli/main.go
ldflags:
- -s -w -X github.com/oam-dev/kubevela/version.VelaVersion={{ .Version }} -X github.com/oam-dev/kubevela/version.GitRevision=git-{{.ShortCommit}}
env:
- CGO_ENABLED=0
- id: kubectl-vela
binary: kubectl-vela
env:
- CGO_ENABLED=0
goos:
- linux
- windows
- darwin
goarch:
- amd64
- arm64
main: ./cmd/plugin/main.go
ldflags:
- -s -w -X github.com/oam-dev/kubevela/version.VelaVersion={{ .Version }} -X github.com/oam-dev/kubevela/version.GitRevision=git-{{.ShortCommit}}
archives:
- format: tar.gz
id: vela-cli-tgz
wrap_in_directory: '{{ .Os }}-{{ .Arch }}'
builds:
- vela-cli
name_template: '{{ trimsuffix .ArtifactName ".exe" }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}'
files: [ LICENSE, README.md ]
- format: zip
id: vela-cli-zip
builds:
- vela-cli
wrap_in_directory: '{{ .Os }}-{{ .Arch }}'
name_template: '{{ trimsuffix .ArtifactName ".exe" }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}'
files: [ LICENSE, README.md ]
- format: tar.gz
id: plugin-tgz
builds:
- kubectl-vela
wrap_in_directory: '{{ .Os }}-{{ .Arch }}'
name_template: '{{ trimsuffix .ArtifactName ".exe" }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}'
files: [ LICENSE, README.md ]
- format: zip
id: plugin-zip
builds:
- kubectl-vela
wrap_in_directory: '{{ .Os }}-{{ .Arch }}'
name_template: '{{ trimsuffix .ArtifactName ".exe" }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}'
files: [ LICENSE, README.md ]
checksum:
name_template: 'sha256sums.txt'
changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
# The lines beneath this are called `modelines`. See `:help modeline`
# Feel free to remove those if you don't want/use them.
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
# vim: set ts=2 sw=2 tw=0 fo=cnqoj

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

@@ -336,7 +336,8 @@ type WorkflowStatus struct {
Steps []workflowv1alpha1.WorkflowStepStatus `json:"steps,omitempty"`
StartTime metav1.Time `json:"startTime,omitempty"`
EndTime metav1.Time `json:"endTime,omitempty"`
// +nullable
EndTime metav1.Time `json:"endTime,omitempty"`
}
// DefinitionType describes the type of DefinitionRevision.

View File

@@ -111,7 +111,7 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
| `multicluster.clusterGateway.replicaCount` | ClusterGateway replica count | `1` |
| `multicluster.clusterGateway.port` | ClusterGateway port | `9443` |
| `multicluster.clusterGateway.image.repository` | ClusterGateway image repository | `oamdev/cluster-gateway` |
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.7.0-alpha.3` |
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.7.0` |
| `multicluster.clusterGateway.image.pullPolicy` | ClusterGateway image pull policy | `IfNotPresent` |
| `multicluster.clusterGateway.resources.limits.cpu` | ClusterGateway cpu limit | `100m` |
| `multicluster.clusterGateway.resources.limits.memory` | ClusterGateway memory limit | `200Mi` |

View File

@@ -848,6 +848,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean
@@ -2806,6 +2807,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean
@@ -4942,6 +4944,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean

View File

@@ -774,6 +774,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean
@@ -1535,6 +1536,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean

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

@@ -0,0 +1,77 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/k8s-update-strategy.cue
apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/alias: ""
definition.oam.dev/description: Set k8s update strategy for Deployment/DaemonSet/StatefulSet
name: k8s-update-strategy
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
conflictsWith: []
podDisruptive: false
schematic:
cue:
template: |
patch: spec: {
if parameter.targetKind == "Deployment" && parameter.strategy.type != "OnDelete" {
// +patchStrategy=retainKeys
strategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
maxSurge: parameter.strategy.rollingStrategy.maxSurge
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
}
}
}
}
if parameter.targetKind == "StatefulSet" && parameter.strategy.type != "Recreate" {
// +patchStrategy=retainKeys
updateStrategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: partition: parameter.strategy.rollingStrategy.partition
}
}
}
if parameter.targetKind == "DaemonSet" && parameter.strategy.type != "Recreate" {
// +patchStrategy=retainKeys
updateStrategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
maxSurge: parameter.strategy.rollingStrategy.maxSurge
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
}
}
}
}
}
parameter: {
// +usage=Specify the apiVersion of target
targetAPIVersion: *"apps/v1" | string
// +usage=Specify the kind of target
targetKind: *"Deployment" | "StatefulSet" | "DaemonSet"
// +usage=Specify the strategy of update
strategy: {
// +usage=Specify the strategy type
type: *"RollingUpdate" | "Recreate" | "OnDelete"
// +usage=Specify the parameters of rollong update strategy
rollingStrategy?: {
maxSurge: *"25%" | string
maxUnavailable: *"25%" | string
partition: *0 | int
}
}
}
workloadRefPath: ""

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

@@ -148,7 +148,7 @@ multicluster:
port: 9443
image:
repository: oamdev/cluster-gateway
tag: v1.7.0-alpha.3
tag: v1.7.0
pullPolicy: IfNotPresent
resources:
limits:

View File

@@ -105,7 +105,7 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-minimal --
| `multicluster.clusterGateway.replicaCount` | ClusterGateway replica count | `1` |
| `multicluster.clusterGateway.port` | ClusterGateway port | `9443` |
| `multicluster.clusterGateway.image.repository` | ClusterGateway image repository | `oamdev/cluster-gateway` |
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.4.0` |
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.7.0` |
| `multicluster.clusterGateway.image.pullPolicy` | ClusterGateway image pull policy | `IfNotPresent` |
| `multicluster.clusterGateway.resources.limits.cpu` | ClusterGateway cpu limit | `100m` |
| `multicluster.clusterGateway.resources.limits.memory` | ClusterGateway memory limit | `200Mi` |

View File

@@ -848,6 +848,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean
@@ -2806,6 +2807,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean
@@ -4942,6 +4944,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean

View File

@@ -774,6 +774,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean
@@ -1535,6 +1536,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean

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

@@ -0,0 +1,77 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/k8s-update-strategy.cue
apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/alias: ""
definition.oam.dev/description: Set k8s update strategy for Deployment/DaemonSet/StatefulSet
name: k8s-update-strategy
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
conflictsWith: []
podDisruptive: false
schematic:
cue:
template: |
patch: spec: {
if parameter.targetKind == "Deployment" && parameter.strategy.type != "OnDelete" {
// +patchStrategy=retainKeys
strategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
maxSurge: parameter.strategy.rollingStrategy.maxSurge
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
}
}
}
}
if parameter.targetKind == "StatefulSet" && parameter.strategy.type != "Recreate" {
// +patchStrategy=retainKeys
updateStrategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: partition: parameter.strategy.rollingStrategy.partition
}
}
}
if parameter.targetKind == "DaemonSet" && parameter.strategy.type != "Recreate" {
// +patchStrategy=retainKeys
updateStrategy: {
type: parameter.strategy.type
if parameter.strategy.type == "RollingUpdate" {
rollingUpdate: {
maxSurge: parameter.strategy.rollingStrategy.maxSurge
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
}
}
}
}
}
parameter: {
// +usage=Specify the apiVersion of target
targetAPIVersion: *"apps/v1" | string
// +usage=Specify the kind of target
targetKind: *"Deployment" | "StatefulSet" | "DaemonSet"
// +usage=Specify the strategy of update
strategy: {
// +usage=Specify the strategy type
type: *"RollingUpdate" | "Recreate" | "OnDelete"
// +usage=Specify the parameters of rollong update strategy
rollingStrategy?: {
maxSurge: *"25%" | string
maxUnavailable: *"25%" | string
partition: *0 | int
}
}
}
workloadRefPath: ""

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

@@ -106,7 +106,7 @@ multicluster:
port: 9443
image:
repository: oamdev/cluster-gateway
tag: v1.4.0
tag: v1.7.0
pullPolicy: IfNotPresent
resources:
limits:

View File

@@ -21,6 +21,7 @@ import (
"strconv"
"time"
pkgclient "github.com/kubevela/pkg/controller/client"
ctrlrec "github.com/kubevela/pkg/controller/reconciler"
pkgmulticluster "github.com/kubevela/pkg/multicluster"
wfTypes "github.com/kubevela/workflow/pkg/types"
@@ -171,6 +172,7 @@ func (s *CoreOptions) Flags() cliflag.NamedFlagSets {
local := flag.NewFlagSet("klog", flag.ExitOnError)
klog.InitFlags(local)
kfs.AddGoFlagSet(local)
pkgclient.AddTimeoutControllerClientFlags(fss.FlagSet("controllerclient"))
if s.LogDebug {
_ = kfs.Set("v", strconv.Itoa(int(commonconfig.LogDebug)))

View File

@@ -2086,7 +2086,7 @@
"tags": [
"application"
],
"summary": "list application triggers",
"summary": "List the application triggers",
"operationId": "listApplicationTriggers",
"parameters": [
{
@@ -2124,7 +2124,7 @@
"tags": [
"application"
],
"summary": "create one application trigger",
"summary": "Create an application trigger",
"operationId": "createApplicationTrigger",
"parameters": [
{
@@ -2160,6 +2160,51 @@
}
},
"/api/v1/applications/{appName}/triggers/{token}": {
"put": {
"consumes": [
"application/xml",
"application/json"
],
"produces": [
"application/json",
"application/xml"
],
"tags": [
"application"
],
"summary": "Update an application trigger",
"operationId": "updateApplicationTrigger",
"parameters": [
{
"type": "string",
"description": "identifier of the application ",
"name": "appName",
"in": "path",
"required": true
},
{
"type": "string",
"description": "identifier of the trigger",
"name": "token",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/v1.ApplicationTriggerBase"
}
},
"400": {
"description": "Bad Request",
"schema": {
"$ref": "#/definitions/bcode.Bcode"
}
}
}
},
"delete": {
"consumes": [
"application/xml",
@@ -2172,7 +2217,7 @@
"tags": [
"application"
],
"summary": "delete one application trigger",
"summary": "Delete an application trigger",
"operationId": "deleteApplicationTrigger",
"parameters": [
{
@@ -8964,8 +9009,8 @@
},
"model.ApplicationRevision": {
"required": [
"createTime",
"updateTime",
"createTime",
"appPrimaryKey",
"version",
"revisionCRName",
@@ -9347,11 +9392,11 @@
},
"model.WorkflowStep": {
"required": [
"alias",
"name",
"dependsOn",
"description",
"orderIndex",
"dependsOn",
"name",
"alias",
"type"
],
"properties": {
@@ -9469,9 +9514,9 @@
},
"model.WorkflowStepStatus": {
"required": [
"id",
"name",
"alias"
"alias",
"id"
],
"properties": {
"alias": {
@@ -10055,11 +10100,11 @@
"v1.ApplicationDeployResponse": {
"required": [
"version",
"status",
"triggerType",
"createTime",
"status",
"note",
"envName",
"triggerType",
"record"
],
"properties": {
@@ -10338,6 +10383,7 @@
"type",
"payloadType",
"token",
"registry",
"createTime",
"updateTime"
],
@@ -10361,6 +10407,9 @@
"payloadType": {
"type": "string"
},
"registry": {
"type": "string"
},
"token": {
"type": "string"
},
@@ -10833,13 +10882,13 @@
},
"v1.ConfigTemplateDetail": {
"required": [
"sensitive",
"createTime",
"alias",
"name",
"namespace",
"description",
"scope",
"sensitive",
"createTime",
"alias",
"schema",
"uiSchema"
],
@@ -11669,11 +11718,11 @@
},
"v1.DetailAddonResponse": {
"required": [
"invisible",
"name",
"version",
"description",
"icon",
"invisible",
"description",
"schema",
"uiSchema",
"definitions",
@@ -11753,12 +11802,12 @@
},
"v1.DetailApplicationResponse": {
"required": [
"project",
"createTime",
"updateTime",
"name",
"alias",
"project",
"description",
"createTime",
"updateTime",
"icon",
"policies",
"envBindings",
@@ -11816,20 +11865,20 @@
},
"v1.DetailClusterResponse": {
"required": [
"status",
"provider",
"dashboardURL",
"description",
"icon",
"labels",
"reason",
"apiServerURL",
"kubeConfigSecret",
"alias",
"status",
"dashboardURL",
"icon",
"description",
"reason",
"createTime",
"updateTime",
"name",
"kubeConfig",
"labels",
"provider",
"apiServerURL",
"createTime",
"resourceInfo"
],
"properties": {
@@ -11887,13 +11936,13 @@
},
"v1.DetailComponentResponse": {
"required": [
"name",
"main",
"alias",
"createTime",
"updateTime",
"appPrimaryKey",
"creator",
"name",
"main",
"createTime",
"updateTime",
"alias",
"type",
"definition"
],
@@ -11982,12 +12031,12 @@
},
"v1.DetailDefinitionResponse": {
"required": [
"alias",
"labels",
"ownerAddon",
"name",
"alias",
"icon",
"labels",
"description",
"icon",
"status",
"schema",
"uiSchema"
@@ -12045,15 +12094,15 @@
},
"v1.DetailPolicyResponse": {
"required": [
"description",
"creator",
"envName",
"name",
"alias",
"type",
"description",
"createTime",
"updateTime",
"type",
"properties"
"alias",
"creator",
"properties",
"envName"
],
"properties": {
"alias": {
@@ -12095,18 +12144,18 @@
},
"v1.DetailRevisionResponse": {
"required": [
"appPrimaryKey",
"revisionCRName",
"triggerType",
"workflowName",
"version",
"status",
"deployUser",
"note",
"createTime",
"appPrimaryKey",
"deployUser",
"triggerType",
"updateTime",
"revisionCRName",
"reason",
"envName"
"envName",
"version",
"workflowName",
"createTime"
],
"properties": {
"appPrimaryKey": {
@@ -12163,10 +12212,10 @@
},
"v1.DetailTargetResponse": {
"required": [
"updateTime",
"name",
"project",
"createTime",
"updateTime"
"project"
],
"properties": {
"alias": {
@@ -12206,11 +12255,11 @@
},
"v1.DetailUserResponse": {
"required": [
"email",
"disabled",
"createTime",
"lastLoginTime",
"name",
"email",
"projects",
"roles"
],
@@ -12252,12 +12301,12 @@
"v1.DetailWorkflowRecordResponse": {
"required": [
"status",
"mode",
"workflowAlias",
"applicationRevision",
"namespace",
"message",
"mode",
"name",
"namespace",
"workflowName",
"deployTime",
"deployUser",
@@ -12321,15 +12370,15 @@
"v1.DetailWorkflowResponse": {
"required": [
"name",
"enable",
"envName",
"alias",
"description",
"default",
"createTime",
"updateTime",
"subMode",
"alias",
"enable",
"default",
"envName",
"mode"
"mode",
"subMode"
],
"properties": {
"alias": {
@@ -12537,8 +12586,8 @@
},
"v1.EnvBindingTarget": {
"required": [
"name",
"alias"
"alias",
"name"
],
"properties": {
"alias": {
@@ -12565,11 +12614,11 @@
"v1.GetPipelineResponse": {
"required": [
"spec",
"description",
"createTime",
"name",
"alias",
"project",
"description",
"info"
],
"properties": {
@@ -12612,10 +12661,10 @@
},
"v1.GetPipelineRunLogResponse": {
"required": [
"phase",
"id",
"name",
"type",
"phase",
"source",
"log"
],
@@ -13269,11 +13318,11 @@
},
"v1.LoginUserInfoResponse": {
"required": [
"createTime",
"lastLoginTime",
"name",
"email",
"disabled",
"createTime",
"lastLoginTime",
"projects",
"platformPermissions",
"projectPermissions"
@@ -13475,11 +13524,11 @@
},
"v1.PipelineBase": {
"required": [
"description",
"createTime",
"name",
"alias",
"project",
"description",
"spec"
],
"properties": {
@@ -13578,11 +13627,11 @@
},
"v1.PipelineMetaResponse": {
"required": [
"name",
"alias",
"project",
"description",
"createTime",
"name",
"alias"
"createTime"
],
"properties": {
"alias": {
@@ -13605,13 +13654,13 @@
},
"v1.PipelineRun": {
"required": [
"contextName",
"contextValues",
"spec",
"pipelineName",
"project",
"pipelineRunName",
"record",
"contextName",
"contextValues",
"spec",
"status"
],
"properties": {
@@ -14208,9 +14257,9 @@
},
"v1.SystemInfoResponse": {
"required": [
"loginType",
"platformID",
"enableCollection",
"loginType",
"systemVersion"
],
"properties": {
@@ -14734,14 +14783,14 @@
},
"v1.WorkflowRecord": {
"required": [
"namespace",
"message",
"status",
"mode",
"name",
"namespace",
"workflowName",
"workflowAlias",
"applicationRevision"
"applicationRevision",
"mode",
"message"
],
"properties": {
"applicationRevision": {
@@ -14832,8 +14881,8 @@
},
"v1.WorkflowStep": {
"required": [
"type",
"name"
"name",
"type"
],
"properties": {
"alias": {

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())

5
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
@@ -57,7 +57,7 @@ require (
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
github.com/kubevela/pkg v0.0.0-20230105054759-263dc191bf51
github.com/kubevela/prism v1.7.0-alpha.1
github.com/kubevela/workflow v0.3.6-0.20221230102636-6ae0c5cbc40f
github.com/kubevela/workflow v0.4.1
github.com/kyokomi/emoji v2.2.4+incompatible
github.com/mitchellh/hashstructure/v2 v2.0.1
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
@@ -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

8
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,14 +1285,12 @@ 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=
github.com/kubevela/prism v1.7.0-alpha.1/go.mod h1:AJSDfdA+RkRSnWx3xEcogbmOTpX+l7RSIwqVHxwUtaI=
github.com/kubevela/workflow v0.3.6-0.20221230102636-6ae0c5cbc40f h1:7EZWIfcTOgMlLgHkdDlf++hSjBTulfr4DYhZjeQbiJI=
github.com/kubevela/workflow v0.3.6-0.20221230102636-6ae0c5cbc40f/go.mod h1:AX/WL3G/YBkpmNpA/SKKm9M3Y0T9y95gZA8mFWylkyM=
github.com/kubevela/workflow v0.4.1 h1:lYeWE9KgSSkb368u8G7cGfyzCz41Am8MdxgViRFJxXE=
github.com/kubevela/workflow v0.4.1/go.mod h1:AX/WL3G/YBkpmNpA/SKKm9M3Y0T9y95gZA8mFWylkyM=
github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U=
github.com/kunwardeep/paralleltest v1.0.3/go.mod h1:vLydzomDFpk7yu5UX02RmP0H8QfRPOV/oFhWN85Mjb4=
github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=

View File

@@ -848,6 +848,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean
@@ -2806,6 +2807,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean
@@ -4942,6 +4944,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean

View File

@@ -774,6 +774,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean
@@ -1535,6 +1536,7 @@ spec:
x-kubernetes-map-type: atomic
endTime:
format: date-time
nullable: true
type: string
finished:
type: boolean

View File

@@ -911,7 +911,6 @@ func NewAddonInstaller(ctx context.Context, cli client.Client, discoveryClient *
func (h *Installer) enableAddon(addon *InstallPackage) (string, error) {
var err error
h.addon = addon
if !h.skipVersionValidate {
err = checkAddonVersionMeetRequired(h.ctx, addon.SystemRequirements, h.cli, h.dc)
if err != nil {
@@ -1076,6 +1075,8 @@ func (h *Installer) checkDependency(addon *InstallPackage) ([]string, error) {
// createOrUpdate will return true if updated
func (h *Installer) createOrUpdate(app *v1beta1.Application) (bool, error) {
// Set the publish version for the addon application
oam.SetPublishVersion(app, apiutils.GenerateVersion("addon"))
var existApp v1beta1.Application
err := h.cli.Get(h.ctx, client.ObjectKey{Name: app.Name, Namespace: app.Namespace}, &existApp)
if apierrors.IsNotFound(err) {
@@ -1087,8 +1088,6 @@ func (h *Installer) createOrUpdate(app *v1beta1.Application) (bool, error) {
existApp.Spec = app.Spec
existApp.Labels = app.Labels
existApp.Annotations = app.Annotations
// Set the publish version for the addon application
oam.SetPublishVersion(&existApp, apiutils.GenerateVersion("addon"))
err = h.cli.Update(h.ctx, &existApp)
if err != nil {
klog.Errorf("fail to create application: %v", err)
@@ -1211,6 +1210,9 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
}
func (h *Installer) renderNotes(addon *InstallPackage) (string, error) {
if len(addon.Notes.Data) == 0 {
return "", nil
}
r := addonCueTemplateRender{
addon: addon,
inputArgs: h.args,

View File

@@ -58,6 +58,9 @@ func EnableAddon(ctx context.Context, name string, version string, cli client.Cl
if err != nil {
return "", err
}
if err := validateAddonPackage(pkg); err != nil {
return "", errors.Wrap(err, fmt.Sprintf("failed to enable addon: %s", name))
}
return h.enableAddon(pkg)
}
@@ -106,6 +109,9 @@ func EnableAddonByLocalDir(ctx context.Context, name string, dir string, cli cli
if err != nil {
return "", err
}
if err := validateAddonPackage(pkg); err != nil {
return "", errors.Wrap(err, fmt.Sprintf("failed to enable addon by local dir: %s", dir))
}
h := NewAddonInstaller(ctx, cli, dc, applicator, config, &Registry{Name: LocalAddonRegistryName}, args, nil, nil, opts...)
needEnableAddonNames, err := h.checkDependency(pkg)
if err != nil {

View File

@@ -17,9 +17,12 @@ limitations under the License.
package addon
import (
"bytes"
"context"
"errors"
"net/http"
"net/http/httptest"
"os"
"strings"
v1 "k8s.io/api/core/v1"
@@ -29,6 +32,38 @@ import (
. "github.com/onsi/gomega"
)
func setupMockServer() *httptest.Server {
var listenURL string
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
fileList := []string{
"index.yaml",
"fluxcd-test-version-1.0.0.tgz",
"fluxcd-test-version-2.0.0.tgz",
"vela-workflow-v0.3.5.tgz",
"foo-v1.0.0.tgz",
"bar-v1.0.0.tgz",
"bar-v2.0.0.tgz",
"mock-be-dep-addon-v1.0.0.tgz",
}
for _, f := range fileList {
if strings.Contains(req.URL.Path, f) {
file, err := os.ReadFile("../../e2e/addon/mock/testrepo/helm-repo/" + f)
if err != nil {
_, _ = w.Write([]byte(err.Error()))
}
if f == "index.yaml" {
// in index.yaml, url is hardcoded to 127.0.0.1:9098,
// so we need to replace it with the real random listen url
file = bytes.ReplaceAll(file, []byte("http://127.0.0.1:9098"), []byte(listenURL))
}
_, _ = w.Write(file)
}
}
}))
listenURL = s.URL
return s
}
var _ = Describe("test FindAddonPackagesDetailFromRegistry", func() {
Describe("when no registry is added, no matter what you do, it will just return error", func() {
Context("when empty addonNames and registryNames is supplied", func() {
@@ -50,12 +85,15 @@ var _ = Describe("test FindAddonPackagesDetailFromRegistry", func() {
})
Describe("one versioned registry is added", func() {
var s *httptest.Server
BeforeEach(func() {
// Prepare KubeVela registry
s = setupMockServer()
// Prepare registry
reg := &Registry{
Name: "KubeVela",
Name: "addon_helper_test",
Helm: &HelmSource{
URL: "https://addons.kubevela.net",
URL: s.URL,
},
}
ds := NewRegistryDataStore(k8sClient)
@@ -63,38 +101,36 @@ var _ = Describe("test FindAddonPackagesDetailFromRegistry", func() {
})
AfterEach(func() {
// Clean up KubeVela registry
// Clean up registry
ds := NewRegistryDataStore(k8sClient)
Expect(ds.DeleteRegistry(context.Background(), "KubeVela")).To(Succeed())
Expect(ds.DeleteRegistry(context.Background(), "addon_helper_test")).To(Succeed())
s.Close()
})
Context("when empty addonNames and registryNames is supplied", func() {
It("should return error, empty addonNames are not allowed", func() {
_, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{}, []string{"KubeVela"})
_, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{}, []string{"addon_helper_test"})
Expect(err).To(HaveOccurred())
})
It("should return error, empty addonNames are not allowed", func() {
_, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, nil, []string{"KubeVela"})
_, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, nil, []string{"addon_helper_test"})
Expect(err).To(HaveOccurred())
})
})
Context("one existing addon name provided", func() {
It("should return one valid result, matching all registries", func() {
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"velaux"}, nil)
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"foo"}, nil)
Expect(err).To(Succeed())
Expect(res).To(HaveLen(1))
Expect(res[0].Name).To(Equal("velaux"))
Expect(res[0].InstallPackage).ToNot(BeNil())
Expect(res[0].APISchema).ToNot(BeNil())
Expect(res[0].Name).To(Equal("foo"))
})
It("should return one valid result, matching one registry", func() {
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"velaux"}, []string{"KubeVela"})
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"foo"}, []string{"addon_helper_test"})
Expect(err).To(Succeed())
Expect(res).To(HaveLen(1))
Expect(res[0].Name).To(Equal("velaux"))
Expect(res[0].InstallPackage).ToNot(BeNil())
Expect(res[0].APISchema).ToNot(BeNil())
Expect(res[0].Name).To(Equal("foo"))
})
})
@@ -108,26 +144,20 @@ var _ = Describe("test FindAddonPackagesDetailFromRegistry", func() {
Context("two existing addon names provided", func() {
It("should return two valid result", func() {
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"velaux", "traefik"}, nil)
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"foo", "bar"}, nil)
Expect(err).To(Succeed())
Expect(res).To(HaveLen(2))
Expect(res[0].Name).To(Equal("velaux"))
Expect(res[0].InstallPackage).ToNot(BeNil())
Expect(res[0].APISchema).ToNot(BeNil())
Expect(res[1].Name).To(Equal("traefik"))
Expect(res[1].InstallPackage).ToNot(BeNil())
Expect(res[1].APISchema).ToNot(BeNil())
Expect(res[0].Name).To(Equal("foo"))
Expect(res[1].Name).To(Equal("bar"))
})
})
Context("one existing addon name and one non-existent addon name provided", func() {
It("should return only one valid result", func() {
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"velaux", "non-existent-addon"}, nil)
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"foo", "non-existent-addon"}, nil)
Expect(err).To(Succeed())
Expect(res).To(HaveLen(1))
Expect(res[0].Name).To(Equal("velaux"))
Expect(res[0].InstallPackage).ToNot(BeNil())
Expect(res[0].APISchema).ToNot(BeNil())
Expect(res[0].Name).To(Equal("foo"))
})
})
})

View File

@@ -196,9 +196,13 @@ func (cmd *InitCmd) createHelmComponent() error {
tmpl := helmComponentTmpl{}
tmpl.Type = "helm"
tmpl.Properties.RepoType = "helm"
if strings.HasPrefix(cmd.HelmRepoURL, "oci") {
tmpl.Properties.RepoType = "oci"
}
tmpl.Properties.URL = cmd.HelmRepoURL
tmpl.Properties.Chart = cmd.HelmChartName
tmpl.Properties.Version = cmd.HelmChartVersion
tmpl.Name = "addon-" + cmd.AddonName
str, err := toCUEResourceString(tmpl)
if err != nil {
@@ -383,6 +387,7 @@ func (cmd *InitCmd) writeFiles() error {
// helmComponentTmpl is a template for a helm component .cue in an addon
type helmComponentTmpl struct {
Name string `json:"name"`
Type string `json:"type"`
Properties struct {
RepoType string `json:"repoType"`

View File

@@ -21,6 +21,7 @@ import (
"fmt"
"os"
"path/filepath"
"reflect"
"strings"
"github.com/pkg/errors"
@@ -503,6 +504,19 @@ func checkBondComponentExist(u unstructured.Unstructured, app v1beta1.Applicatio
return false
}
func validateAddonPackage(addonPkg *InstallPackage) error {
if reflect.DeepEqual(addonPkg.Meta, Meta{}) {
return fmt.Errorf("the addon package doesn't have `metadata.yaml`")
}
if addonPkg.Name == "" {
return fmt.Errorf("`matadata.yaml` must define the name of addon")
}
if addonPkg.Version == "" {
return fmt.Errorf("`matadata.yaml` must define the version of addon")
}
return nil
}
// FilterDependencyRegistries will return all registries besides the target registry itself
func FilterDependencyRegistries(i int, rs []Registry) []Registry {
if i >= len(rs) {

View File

@@ -17,9 +17,11 @@ limitations under the License.
package addon
import (
"fmt"
"net/http/httptest"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
@@ -402,6 +404,30 @@ func TestFilterDependencyRegistries(t *testing.T) {
}
}
func TestCheckAddonPackageValid(t *testing.T) {
testCases := []struct {
testCase Meta
err error
}{{
testCase: Meta{},
err: fmt.Errorf("the addon package doesn't have `metadata.yaml`"),
}, {
testCase: Meta{Version: "v1.4.0"},
err: fmt.Errorf("`matadata.yaml` must define the name of addon"),
}, {
testCase: Meta{Name: "test-addon"},
err: fmt.Errorf("`matadata.yaml` must define the version of addon"),
}, {
testCase: Meta{Name: "test-addon", Version: "1.4.5"},
err: nil,
},
}
for _, testCase := range testCases {
err := validateAddonPackage(&InstallPackage{Meta: testCase.testCase})
assert.Equal(t, reflect.DeepEqual(err, testCase.err), true)
}
}
const (
compDefYaml = `
apiVersion: core.oam.dev/v1beta1

View File

@@ -59,8 +59,8 @@ func (a *Application) PrimaryKey() string {
}
// Index return custom index
func (a *Application) Index() map[string]string {
index := make(map[string]string)
func (a *Application) Index() map[string]interface{} {
index := make(map[string]interface{})
if a.Name != "" {
index["name"] = a.Name
}
@@ -154,8 +154,8 @@ func (a *ApplicationComponent) PrimaryKey() string {
}
// Index return custom index
func (a *ApplicationComponent) Index() map[string]string {
index := make(map[string]string)
func (a *ApplicationComponent) Index() map[string]interface{} {
index := make(map[string]interface{})
if a.Name != "" {
index["name"] = a.Name
}
@@ -202,8 +202,8 @@ func (a *ApplicationPolicy) PrimaryKey() string {
}
// Index return custom index
func (a *ApplicationPolicy) Index() map[string]string {
index := make(map[string]string)
func (a *ApplicationPolicy) Index() map[string]interface{} {
index := make(map[string]interface{})
if a.Name != "" {
index["name"] = a.Name
}
@@ -348,8 +348,8 @@ func (a *ApplicationRevision) PrimaryKey() string {
}
// Index return custom index
func (a *ApplicationRevision) Index() map[string]string {
index := make(map[string]string)
func (a *ApplicationRevision) Index() map[string]interface{} {
index := make(map[string]interface{})
if a.Version != "" {
index["version"] = a.Version
}
@@ -434,8 +434,8 @@ func (w *ApplicationTrigger) PrimaryKey() string {
}
// Index return custom index
func (w *ApplicationTrigger) Index() map[string]string {
index := make(map[string]string)
func (w *ApplicationTrigger) Index() map[string]interface{} {
index := make(map[string]interface{})
if w.AppPrimaryKey != "" {
index["appPrimaryKey"] = w.AppPrimaryKey
}

View File

@@ -93,8 +93,8 @@ func (c *Cluster) PrimaryKey() string {
}
// Index set to nil for list
func (c *Cluster) Index() map[string]string {
index := make(map[string]string)
func (c *Cluster) Index() map[string]interface{} {
index := make(map[string]interface{})
if c.Name != "" {
index["name"] = c.Name
}

View File

@@ -53,8 +53,8 @@ func (p *Env) PrimaryKey() string {
}
// Index return custom index
func (p *Env) Index() map[string]string {
index := make(map[string]string)
func (p *Env) Index() map[string]interface{} {
index := make(map[string]interface{})
if p.Name != "" {
index["name"] = p.Name
}

View File

@@ -62,8 +62,8 @@ func (e *EnvBinding) PrimaryKey() string {
}
// Index return custom index
func (e *EnvBinding) Index() map[string]string {
index := make(map[string]string)
func (e *EnvBinding) Index() map[string]interface{} {
index := make(map[string]interface{})
if e.Name != "" {
index["name"] = e.Name
}

View File

@@ -61,8 +61,8 @@ func (p Pipeline) ShortTableName() string {
}
// Index return custom index
func (p Pipeline) Index() map[string]string {
var index = make(map[string]string)
func (p Pipeline) Index() map[string]interface{} {
var index = make(map[string]interface{})
if p.Project != "" {
index["project"] = p.Project
}
@@ -102,8 +102,8 @@ func (c *PipelineContext) PrimaryKey() string {
}
// Index return custom index
func (c *PipelineContext) Index() map[string]string {
index := make(map[string]string)
func (c *PipelineContext) Index() map[string]interface{} {
index := make(map[string]interface{})
if c.ProjectName != "" {
index["project_name"] = c.ProjectName
}

View File

@@ -54,8 +54,8 @@ func (p *Project) PrimaryKey() string {
}
// Index return custom index
func (p *Project) Index() map[string]string {
index := make(map[string]string)
func (p *Project) Index() map[string]interface{} {
index := make(map[string]interface{})
if p.Name != "" {
index["name"] = p.Name
}

View File

@@ -146,8 +146,8 @@ func (u *SystemInfo) PrimaryKey() string {
}
// Index return custom index
func (u *SystemInfo) Index() map[string]string {
index := make(map[string]string)
func (u *SystemInfo) Index() map[string]interface{} {
index := make(map[string]interface{})
if u.InstallID != "" {
index["installID"] = u.InstallID
}

View File

@@ -48,8 +48,8 @@ func (d *Target) PrimaryKey() string {
}
// Index return custom index
func (d *Target) Index() map[string]string {
index := make(map[string]string)
func (d *Target) Index() map[string]interface{} {
index := make(map[string]interface{})
if d.Name != "" {
index["name"] = d.Name
}

View File

@@ -67,8 +67,8 @@ func (u *User) PrimaryKey() string {
}
// Index return custom index
func (u *User) Index() map[string]string {
index := make(map[string]string)
func (u *User) Index() map[string]interface{} {
index := make(map[string]interface{})
if u.Name != "" {
index["name"] = u.Name
}
@@ -106,8 +106,8 @@ func (u *ProjectUser) PrimaryKey() string {
}
// Index return custom index
func (u *ProjectUser) Index() map[string]string {
index := make(map[string]string)
func (u *ProjectUser) Index() map[string]interface{} {
index := make(map[string]interface{})
if u.Username != "" {
index["username"] = u.Username
}
@@ -177,8 +177,8 @@ func (r *Role) PrimaryKey() string {
}
// Index return custom index
func (r *Role) Index() map[string]string {
index := make(map[string]string)
func (r *Role) Index() map[string]interface{} {
index := make(map[string]interface{})
if r.Name != "" {
index["name"] = r.Name
}
@@ -207,8 +207,8 @@ func (p *Permission) PrimaryKey() string {
}
// Index return custom index
func (p *Permission) Index() map[string]string {
index := make(map[string]string)
func (p *Permission) Index() map[string]interface{} {
index := make(map[string]interface{})
if p.Name != "" {
index["name"] = p.Name
}
@@ -250,8 +250,8 @@ func (p *PermissionTemplate) PrimaryKey() string {
}
// Index return custom index
func (p *PermissionTemplate) Index() map[string]string {
index := make(map[string]string)
func (p *PermissionTemplate) Index() map[string]interface{} {
index := make(map[string]interface{})
if p.Name != "" {
index["name"] = p.Name
}

View File

@@ -38,6 +38,8 @@ const (
// LabelSyncGeneration describes the generation synced from
LabelSyncGeneration = "ux.oam.dev/synced-generation"
// LabelSyncRevision describes the revision name synced from
LabelSyncRevision = "ux.oam.dev/synced-revision"
// LabelSyncNamespace describes the namespace synced from
LabelSyncNamespace = "ux.oam.dev/from-namespace"
)

View File

@@ -18,7 +18,6 @@ package model
import (
"fmt"
"strconv"
"time"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
@@ -88,8 +87,8 @@ func (w *Workflow) PrimaryKey() string {
}
// Index return custom primary key
func (w *Workflow) Index() map[string]string {
index := make(map[string]string)
func (w *Workflow) Index() map[string]interface{} {
index := make(map[string]interface{})
if w.Name != "" {
index["name"] = w.Name
}
@@ -100,7 +99,7 @@ func (w *Workflow) Index() map[string]string {
index["envName"] = w.EnvName
}
if w.Default != nil {
index["default"] = strconv.FormatBool(*w.Default)
index["default"] = *w.Default
}
return index
@@ -161,8 +160,8 @@ func (w *WorkflowRecord) PrimaryKey() string {
}
// Index return custom primary key
func (w *WorkflowRecord) Index() map[string]string {
index := make(map[string]string)
func (w *WorkflowRecord) Index() map[string]interface{} {
index := make(map[string]interface{})
if w.Name != "" {
index["name"] = w.Name
}

View File

@@ -106,7 +106,7 @@ func NewDatastore(cfg datastore.Config) (ds datastore.DataStore, err error) {
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
}
case "kubeapi":
ds, err = kubeapi.New(context.Background(), cfg)
ds, err = kubeapi.New(context.Background(), cfg, k8sClient)
if err != nil {
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
}

View File

@@ -99,6 +99,7 @@ type ApplicationService interface {
CreateApplicationTrigger(ctx context.Context, app *model.Application, req apisv1.CreateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error)
ListApplicationTriggers(ctx context.Context, app *model.Application) ([]*apisv1.ApplicationTriggerBase, error)
DeleteApplicationTrigger(ctx context.Context, app *model.Application, triggerName string) error
UpdateApplicationTrigger(ctx context.Context, app *model.Application, token string, req apisv1.UpdateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error)
}
type applicationServiceImpl struct {
@@ -410,6 +411,18 @@ func (c *applicationServiceImpl) CreateApplication(ctx context.Context, req apis
// CreateApplicationTrigger create application trigger
func (c *applicationServiceImpl) CreateApplicationTrigger(ctx context.Context, app *model.Application, req apisv1.CreateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error) {
// checking the workflow
_, err := c.WorkflowService.GetWorkflow(ctx, app, req.WorkflowName)
if err != nil {
return nil, err
}
if req.ComponentName != "" {
_, err := c.GetApplicationComponent(ctx, app, req.ComponentName)
if err != nil {
return nil, err
}
}
trigger := &model.ApplicationTrigger{
AppPrimaryKey: app.Name,
WorkflowName: req.WorkflowName,
@@ -427,18 +440,7 @@ func (c *applicationServiceImpl) CreateApplicationTrigger(ctx context.Context, a
return nil, err
}
return &apisv1.ApplicationTriggerBase{
WorkflowName: req.WorkflowName,
Name: req.Name,
Alias: req.Alias,
Description: req.Description,
Type: req.Type,
PayloadType: req.PayloadType,
Token: trigger.Token,
ComponentName: trigger.ComponentName,
CreateTime: trigger.CreateTime,
UpdateTime: trigger.UpdateTime,
}, nil
return assembler.ConvertTrigger2DTO(*trigger), nil
}
// DeleteApplicationTrigger delete application trigger
@@ -457,6 +459,42 @@ func (c *applicationServiceImpl) DeleteApplicationTrigger(ctx context.Context, a
return nil
}
// UpdateApplicationTrigger update application trigger
func (c *applicationServiceImpl) UpdateApplicationTrigger(ctx context.Context, app *model.Application, token string, req apisv1.UpdateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error) {
trigger := model.ApplicationTrigger{
AppPrimaryKey: app.PrimaryKey(),
Token: token,
}
if err := c.Store.Get(ctx, &trigger); err != nil {
if errors.Is(err, datastore.ErrRecordNotExist) {
return nil, bcode.ErrApplicationTriggerNotExist
}
klog.Warningf("get app trigger failure %s", err.Error())
return nil, err
}
// checking the workflow
_, err := c.WorkflowService.GetWorkflow(ctx, app, req.WorkflowName)
if err != nil {
return nil, err
}
if req.ComponentName != "" {
_, err := c.GetApplicationComponent(ctx, app, req.ComponentName)
if err != nil {
return nil, err
}
}
trigger.Alias = req.Alias
trigger.ComponentName = req.ComponentName
trigger.Description = req.Description
trigger.WorkflowName = req.WorkflowName
trigger.Registry = req.Registry
trigger.PayloadType = req.PayloadType
if err := c.Store.Put(ctx, &trigger); err != nil {
return nil, err
}
return assembler.ConvertTrigger2DTO(trigger), nil
}
// ListApplicationTrigger list application triggers
func (c *applicationServiceImpl) ListApplicationTriggers(ctx context.Context, app *model.Application) ([]*apisv1.ApplicationTriggerBase, error) {
trigger := &model.ApplicationTrigger{
@@ -607,7 +645,8 @@ func (c *applicationServiceImpl) DetailComponent(ctx context.Context, app *model
return nil, err
}
var cd v1beta1.ComponentDefinition
if err := c.KubeClient.Get(ctx, types.NamespacedName{Name: component.Type, Namespace: velatypes.DefaultKubeVelaNS}, &cd); err != nil {
loadCtx := utils.WithProject(ctx, "")
if err := c.KubeClient.Get(loadCtx, types.NamespacedName{Name: component.Type, Namespace: velatypes.DefaultKubeVelaNS}, &cd); err != nil {
klog.Warningf("component definition %s get failure. %s", pkgUtils.Sanitize(component.Type), err.Error())
}
@@ -1072,7 +1111,8 @@ func (c *applicationServiceImpl) UpdateComponent(ctx context.Context, app *model
func (c *applicationServiceImpl) createComponent(ctx context.Context, app *model.Application, com apisv1.CreateComponentRequest, main bool) (*apisv1.ComponentBase, error) {
var cd v1beta1.ComponentDefinition
if err := c.KubeClient.Get(ctx, types.NamespacedName{Name: com.ComponentType, Namespace: velatypes.DefaultKubeVelaNS}, &cd); err != nil {
loadCtx := utils.WithProject(ctx, "")
if err := c.KubeClient.Get(loadCtx, types.NamespacedName{Name: com.ComponentType, Namespace: velatypes.DefaultKubeVelaNS}, &cd); err != nil {
klog.Warningf("component definition %s get failure. %s", pkgUtils.Sanitize(com.ComponentType), err.Error())
return nil, bcode.ErrComponentTypeNotSupport
}
@@ -1713,6 +1753,10 @@ func (c *applicationServiceImpl) RollbackWithRevision(ctx context.Context, appli
if err != nil {
return nil, err
}
// The deploy version is the primary key of the revision
if rollbackApplication.Annotations[oam.AnnotationDeployVersion] == "" {
rollbackApplication.Annotations[oam.AnnotationDeployVersion] = publishVersion
}
record, err := c.WorkflowService.CreateWorkflowRecord(ctx, application, rollbackApplication, &work)
if err != nil {
return nil, fmt.Errorf("create workflow record failure %w", err)

View File

@@ -208,15 +208,17 @@ var _ = Describe("Test application service function", func() {
appModel, err := appService.GetApplication(context.TODO(), testApp)
Expect(err).Should(BeNil())
_, err = appService.CreateApplicationTrigger(context.TODO(), appModel, v1.CreateApplicationTriggerRequest{
Name: "trigger-name",
Name: "trigger-name",
WorkflowName: repository.ConvertWorkflowName("app-dev"),
})
Expect(err).Should(BeNil())
base, err := appService.CreateApplicationTrigger(context.TODO(), appModel, v1.CreateApplicationTriggerRequest{
Name: "trigger-name-2",
ComponentName: "trigger-component",
ComponentName: "component-name",
WorkflowName: repository.ConvertWorkflowName("app-dev"),
})
Expect(err).Should(BeNil())
Expect(base.ComponentName).Should(Equal("trigger-component"))
Expect(base.ComponentName).Should(Equal("component-name"))
})
It("Test ListTriggers function", func() {
@@ -299,6 +301,33 @@ var _ = Describe("Test application service function", func() {
Expect(cmp.Diff(len(detailResponse.Traits), 2)).Should(BeEmpty())
})
It("Test UpdateTrigger function", func() {
appModel, err := appService.GetApplication(context.TODO(), testApp)
Expect(err).Should(BeNil())
triggers, err := appService.ListApplicationTriggers(context.TODO(), appModel)
Expect(err).Should(BeNil())
Expect(len(triggers)).Should(Equal(2))
_, err = appService.UpdateApplicationTrigger(context.TODO(), appModel, triggers[1].Token, v1.UpdateApplicationTriggerRequest{
ComponentName: "notfound",
WorkflowName: repository.ConvertWorkflowName("app-dev"),
})
Expect(err).Should(Equal(bcode.ErrApplicationComponentNotExist))
_, err = appService.UpdateApplicationTrigger(context.TODO(), appModel, triggers[1].Token, v1.UpdateApplicationTriggerRequest{
WorkflowName: "notfound",
})
Expect(err).Should(Equal(bcode.ErrWorkflowNotExist))
base, err := appService.UpdateApplicationTrigger(context.TODO(), appModel, triggers[1].Token, v1.UpdateApplicationTriggerRequest{
Alias: triggers[1].Alias,
Description: triggers[1].Description,
ComponentName: "test2",
WorkflowName: repository.ConvertWorkflowName("app-dev"),
PayloadType: triggers[1].PayloadType,
Registry: triggers[1].Registry,
})
Expect(err).Should(BeNil())
Expect(cmp.Diff(base.ComponentName, "test2")).Should(BeEmpty())
})
It("Test DetailComponent function", func() {
appModel, err := appService.GetApplication(context.TODO(), testApp)
Expect(err).Should(BeNil())

View File

@@ -135,6 +135,14 @@ func (u *configServiceImpl) CreateConfig(ctx context.Context, project string, re
}
ns = pro.GetNamespace()
}
exist, err := u.Factory.IsExist(ctx, ns, req.Name)
if err != nil {
klog.Errorf("check config name is exist failure %s", err.Error())
return nil, bcode.ErrConfigExist
}
if exist {
return nil, bcode.ErrConfigExist
}
var properties = make(map[string]interface{})
if err := json.Unmarshal([]byte(req.Properties), &properties); err != nil {
return nil, err
@@ -154,9 +162,6 @@ func (u *configServiceImpl) CreateConfig(ctx context.Context, project string, re
return nil, err
}
if err := u.Factory.CreateOrUpdateConfig(ctx, configItem, ns); err != nil {
if errors.Is(err, config.ErrConfigExist) {
return nil, bcode.ErrConfigExist
}
return nil, err
}
return convertConfig(project, *configItem), nil
@@ -194,9 +199,12 @@ func (u *configServiceImpl) UpdateConfig(ctx context.Context, project string, na
return nil, err
}
if err := u.Factory.CreateOrUpdateConfig(ctx, configItem, ns); err != nil {
if errors.Is(err, config.ErrConfigExist) {
if errors.Is(err, config.ErrChangeTemplate) {
return nil, bcode.ErrChangeTemplate
}
if errors.Is(err, config.ErrChangeSecretType) {
return nil, bcode.ErrChangeSecretType
}
return nil, err
}
return convertConfig(project, *configItem), nil

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

@@ -104,7 +104,7 @@ func NewDatastore(cfg datastore.Config) (ds datastore.DataStore, err error) {
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
}
case "kubeapi":
ds, err = kubeapi.New(context.Background(), cfg)
ds, err = kubeapi.New(context.Background(), cfg, k8sClient)
if err != nil {
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
}

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

@@ -29,6 +29,7 @@ import (
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/repository"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
@@ -168,6 +169,7 @@ var _ = Describe("Test application service function", func() {
Name: "test-acr",
PayloadType: "acr",
Type: "webhook",
WorkflowName: repository.ConvertWorkflowName("webhook-dev"),
ComponentName: "component-name-webhook",
})
Expect(err).Should(BeNil())
@@ -202,6 +204,7 @@ var _ = Describe("Test application service function", func() {
PayloadType: "acr",
Type: "webhook",
ComponentName: "component-name-webhook",
WorkflowName: repository.ConvertWorkflowName("webhook-dev"),
Registry: "test-enterprise-registry.test-region.cr.aliyuncs.com",
})
Expect(err).Should(BeNil())
@@ -236,6 +239,7 @@ var _ = Describe("Test application service function", func() {
PayloadType: "harbor",
Type: "webhook",
ComponentName: "component-name-webhook",
WorkflowName: repository.ConvertWorkflowName("webhook-dev"),
})
Expect(err).Should(BeNil())
@@ -274,6 +278,7 @@ var _ = Describe("Test application service function", func() {
PayloadType: "dockerhub",
Type: "webhook",
ComponentName: "component-name-webhook",
WorkflowName: repository.ConvertWorkflowName("webhook-dev"),
})
Expect(err).Should(BeNil())
@@ -306,6 +311,7 @@ var _ = Describe("Test application service function", func() {
PayloadType: "jfrog",
Type: "webhook",
ComponentName: "component-name-webhook",
WorkflowName: repository.ConvertWorkflowName("webhook-dev"),
})
Expect(err).Should(BeNil())
jfrogBody := apisv1.HandleApplicationTriggerJFrogRequest{

View File

@@ -550,10 +550,10 @@ func (w *workflowServiceImpl) syncWorkflowStatus(ctx context.Context,
record.Message = status.Message
record.Mode = status.Mode
if cb := app.Status.Workflow.ContextBackend; cb != nil && workflowContext == nil {
if cb := app.Status.Workflow.ContextBackend; cb != nil && workflowContext == nil && cb.Namespace != "" && cb.Name != "" {
var cm corev1.ConfigMap
if err := w.KubeClient.Get(ctx, types.NamespacedName{Namespace: cb.Namespace, Name: cb.Name}, &cm); err != nil {
klog.Error(err, "failed to load the context values", "Application", app.Name)
klog.Errorf("failed to load the context values of the application %s:%s", app.Name, err.Error())
}
record.ContextValue = cm.Data
}
@@ -866,8 +866,8 @@ func (w *workflowServiceImpl) RollbackRecord(ctx context.Context, appModel *mode
if len(revisions) == 0 {
return nil, bcode.ErrApplicationNoReadyRevision
}
revisionVersion = revisions[0].Index()["version"]
klog.Infof("select lastest complete revision %s", revisions[0].Index()["version"])
revisionVersion = pkgUtils.ToString(revisions[0].Index()["version"])
klog.Infof("select lastest complete revision %s", revisionVersion)
}
var record = &model.WorkflowRecord{

View File

@@ -48,6 +48,7 @@ var _ = Describe("Test workflow service functions", func() {
projectService *projectServiceImpl
envService *envServiceImpl
envBinding *envBindingServiceImpl
targetService *targetServiceImpl
testProject = "workflow-project"
ds datastore.DataStore
)
@@ -60,6 +61,7 @@ var _ = Describe("Test workflow service functions", func() {
rbacService := &rbacServiceImpl{Store: ds}
projectService = &projectServiceImpl{Store: ds, RbacService: rbacService, K8sClient: k8sClient}
envService = &envServiceImpl{Store: ds, KubeClient: k8sClient, ProjectService: projectService}
targetService = &targetServiceImpl{Store: ds, K8sClient: k8sClient}
envBinding = &envBindingServiceImpl{
Store: ds,
WorkflowService: workflowService,
@@ -77,11 +79,20 @@ var _ = Describe("Test workflow service functions", func() {
ProjectService: projectService,
EnvService: envService,
EnvBindingService: envBinding,
WorkflowService: workflowService,
}
})
It("Test CreateWorkflow function", func() {
_, err := projectService.CreateProject(context.TODO(), apisv1.CreateProjectRequest{Name: testProject})
Expect(err).Should(BeNil())
_, err = targetService.CreateTarget(context.TODO(), apisv1.CreateTargetRequest{
Name: "dev-1", Project: testProject, Cluster: &apisv1.ClusterTarget{ClusterName: "local", Namespace: "dev-1"}})
Expect(err).Should(BeNil())
_, err = envService.CreateEnv(context.TODO(), apisv1.CreateEnvRequest{Name: "dev", Namespace: "dev-1", Targets: []string{"dev-1"}, Project: testProject})
Expect(err).Should(BeNil())
reqApp := apisv1.CreateApplicationRequest{
Name: appName,
Project: testProject,

View File

@@ -89,7 +89,7 @@ func NewDatastore(cfg datastore.Config) (ds datastore.DataStore, err error) {
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
}
case "kubeapi":
ds, err = kubeapi.New(context.Background(), cfg)
ds, err = kubeapi.New(context.Background(), cfg, k8sClient)
if err != nil {
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
}

View File

@@ -21,14 +21,13 @@ import (
"sort"
"time"
client2 "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/clients"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
@@ -56,8 +55,9 @@ var waitBackOff = wait.Backoff{
// InfoCalculateCronJob is the cronJob to calculate the system info store in db
type InfoCalculateCronJob struct {
Store datastore.DataStore `inject:"datastore"`
cron *cron.Cron
KubeClient client.Client `inject:"kubeClient"`
Store datastore.DataStore `inject:"datastore"`
cron *cron.Cron
}
// Start start the worker
@@ -230,12 +230,8 @@ func (i InfoCalculateCronJob) calculateAppInfo(ctx context.Context) (int, []stri
}
func (i InfoCalculateCronJob) calculateAddonInfo(ctx context.Context) (map[string]string, error) {
client, err := clients.GetKubeClient()
if err != nil {
return nil, err
}
apps := &v1beta1.ApplicationList{}
if err := client.List(ctx, apps, client2.InNamespace(types.DefaultKubeVelaNS), client2.HasLabels{oam.LabelAddonName}); err != nil {
if err := i.KubeClient.List(ctx, apps, client.InNamespace(types.DefaultKubeVelaNS), client.HasLabels{oam.LabelAddonName}); err != nil {
return nil, err
}
res := map[string]string{}
@@ -257,11 +253,7 @@ func (i InfoCalculateCronJob) calculateAddonInfo(ctx context.Context) (map[strin
}
func (i InfoCalculateCronJob) calculateClusterInfo(ctx context.Context) (int, error) {
client, err := clients.GetKubeClient()
if err != nil {
return 0, err
}
cs, err := multicluster.ListVirtualClusters(ctx, client)
cs, err := multicluster.ListVirtualClusters(ctx, i.KubeClient)
if err != nil {
return 0, err
}

View File

@@ -83,7 +83,8 @@ var _ = Describe("Test calculate cronJob", func() {
testProject = "test-cronjob-project"
mockDataInDs()
i = InfoCalculateCronJob{
Store: ds,
Store: ds,
KubeClient: k8sClient,
}
systemInfo := model.SystemInfo{InstallID: "test-id", EnableCollection: true}
Expect(ds.Add(ctx, &systemInfo)).Should(SatisfyAny(BeNil(), DataExistMatcher{}))

View File

@@ -30,8 +30,8 @@ import (
)
type cached struct {
resourceVersion string
targets int64
revision string
targets int64
}
// initCache will initialize the cache
@@ -48,9 +48,8 @@ func (c *CR2UX) initCache(ctx context.Context) error {
if !ok {
continue
}
// Change the generation to resource version
gen, ok := app.Labels[model.LabelSyncGeneration]
if !ok || gen == "" {
revision, ok := app.Labels[model.LabelSyncRevision]
if !ok {
continue
}
namespace := app.Labels[model.LabelSyncNamespace]
@@ -60,7 +59,7 @@ func (c *CR2UX) initCache(ctx context.Context) error {
}
// we should check targets if we synced from app status
c.syncCache(key, gen, 0)
c.syncCache(key, revision, 0)
}
return nil
}
@@ -78,8 +77,10 @@ func (c *CR2UX) shouldSync(ctx context.Context, targetApp *v1beta1.Application,
}
// if no LabelSourceOfTruth label, it means the app is existing ones, check the existing labels and annotations
if _, appName := targetApp.Annotations[oam.AnnotationAppName]; appName {
return false
if targetApp.Annotations != nil {
if _, exist := targetApp.Annotations[oam.AnnotationAppName]; exist {
return false
}
}
key := formatAppComposedName(targetApp.Name, targetApp.Namespace)
@@ -90,16 +91,15 @@ func (c *CR2UX) shouldSync(ctx context.Context, targetApp *v1beta1.Application,
_, _, err := c.getApp(ctx, targetApp.Name, targetApp.Namespace)
if del || err != nil {
c.cache.Delete(key)
} else if cd.resourceVersion == targetApp.ResourceVersion {
klog.Infof("app %s/%s with resource version(%v) hasn't updated, ignore the sync event..", targetApp.Name, targetApp.Namespace, targetApp.ResourceVersion)
} else if cd.revision == getRevision(*targetApp) {
klog.V(5).Infof("app %s/%s with resource revision(%v) hasn't updated, ignore the sync event..", targetApp.Name, targetApp.Namespace, targetApp.ResourceVersion)
return false
}
}
return true
}
func (c *CR2UX) syncCache(key string, resourceVersion string, targets int64) {
func (c *CR2UX) syncCache(key string, revision string, targets int64) {
// update cache
c.cache.Store(key, &cached{resourceVersion: resourceVersion, targets: targets})
c.cache.Store(key, &cached{revision: revision, targets: targets})
}

View File

@@ -68,14 +68,18 @@ var _ = Describe("Test Cache", func() {
app1 := &v1beta1.Application{}
app1.Name = "app1"
app1.Namespace = "app1-ns"
app1.ResourceVersion = "1"
Expect(cr2ux.shouldSync(ctx, app1, false)).Should(BeEquivalentTo(true))
app2 := &v1beta1.Application{}
app2.Name = "app2"
app2.Namespace = "app2-ns"
app2.ResourceVersion = "1"
app2.Generation = 1
app2.Status.LatestRevision = &common.Revision{Name: "v1"}
Expect(cr2ux.shouldSync(ctx, app2, false)).Should(BeEquivalentTo(true))
// Only need to sync once.
cr2ux.syncCache(formatAppComposedName(app2.Name, app2.Namespace), "v1", 1)
Expect(cr2ux.shouldSync(ctx, app2, false)).Should(BeEquivalentTo(false))
app3 := &v1beta1.Application{}
@@ -83,18 +87,17 @@ var _ = Describe("Test Cache", func() {
app3.Namespace = "app3-ns"
app3.ResourceVersion = "3"
app3.Labels = map[string]string{
model.LabelSyncGeneration: "1",
model.LabelSyncNamespace: "app3-ns",
model.LabelSourceOfTruth: model.FromUX,
model.LabelSourceOfTruth: model.FromUX,
}
Expect(cr2ux.shouldSync(ctx, app3, false)).Should(BeEquivalentTo(false))
Expect(ds.Put(ctx, &model.Application{Name: "app1", Labels: map[string]string{
model.LabelSyncGeneration: "1",
model.LabelSyncNamespace: "app1-ns",
model.LabelSyncRevision: "v1",
model.LabelSyncNamespace: "app1-ns",
}})).Should(BeNil())
cr2ux.syncCache(formatAppComposedName(app1.Name, app1.Namespace), "1", 0)
cr2ux.syncCache(formatAppComposedName(app1.Name, app1.Namespace), "v1", 0)
app1.Status.LatestRevision = &common.Revision{Name: "v1"}
Expect(cr2ux.shouldSync(ctx, app1, false)).Should(BeEquivalentTo(false))
Expect(cr2ux.shouldSync(ctx, app1, true)).Should(BeEquivalentTo(true))
Expect(ds.Delete(ctx, &model.Application{Name: "app1"})).Should(BeNil())

View File

@@ -46,11 +46,7 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
}
sourceOfTruth := model.FromCR
if _, ok := targetApp.Labels[oam.LabelAddonName]; ok && strings.HasPrefix(targetApp.Name, "addon-") && targetApp.Namespace == apitypes.DefaultKubeVelaNS {
project = v1.CreateProjectRequest{
Name: model.DefaultSystemProject,
Alias: model.DefaultSystemProjectAlias,
Namespace: targetApp.Namespace,
}
project = c.generateSystemProject(ctx, targetApp.Namespace)
sourceOfTruth = model.FromInner
}
@@ -62,6 +58,7 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
Labels: map[string]string{
model.LabelSyncNamespace: targetApp.Namespace,
model.LabelSyncGeneration: strconv.FormatInt(targetApp.Generation, 10),
model.LabelSyncRevision: getRevision(*targetApp),
model.LabelSourceOfTruth: sourceOfTruth,
},
}
@@ -87,7 +84,7 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
if err != nil {
return nil, err
}
klog.Infof("generate the environment %s for the application %s", env.Name, targetApp.Name)
klog.V(5).Infof("generate the environment %s for the application %s", env.Name, targetApp.Name)
dsApp.Env = env
if newProject != "" {
project = v1.CreateProjectRequest{
@@ -149,6 +146,8 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
// 7. convert the revision
if revision := convert.FromCRApplicationRevision(ctx, cli, targetApp, *dsApp.Workflow, dsApp.Env.Name); revision != nil {
dsApp.Revision = revision
} else {
klog.Warningf("can't generate the application revision(%s) for the app %s", getRevision(*targetApp), targetApp.Name)
}
// 8. convert the workflow record
if record := convert.FromCRWorkflowRecord(targetApp, *dsApp.Workflow, dsApp.Revision); record != nil {
@@ -157,6 +156,27 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
return dsApp, nil
}
// In order to maintain compatibility with old data,
// if there is a project named addons, continue to use it, but change the alias to System.
func (c *CR2UX) generateSystemProject(ctx context.Context, ns string) v1.CreateProjectRequest {
var pro = model.Project{Name: "addons"}
if err := c.ds.Get(ctx, &pro); err == nil {
if pro.Alias == "Addons" {
pro.Alias = model.DefaultSystemProjectAlias
pro.Namespace = ns
if err := c.ds.Put(ctx, &pro); err != nil {
klog.Warningf("failed to update the project alias to System:%s", err.Error())
}
}
return v1.CreateProjectRequest{Name: pro.Name, Alias: pro.Alias, Namespace: pro.Namespace}
}
return v1.CreateProjectRequest{
Name: model.DefaultSystemProject,
Alias: model.DefaultSystemProjectAlias,
Namespace: ns,
}
}
func (c *CR2UX) generateEnv(ctx context.Context, defaultProject string, envNamespace string, envTargetNames map[string]string) (*model.Env, string, error) {
existEnv := &model.Env{Namespace: envNamespace}
existEnvs, err := c.ds.List(ctx, existEnv, nil)
@@ -170,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
@@ -212,3 +232,17 @@ func (c *CR2UX) generateEnv(ctx context.Context, defaultProject string, envNames
}
return env, "", nil
}
func getRevision(app v1beta1.Application) string {
if app.Status.LatestRevision == nil {
return ""
}
return app.Status.LatestRevision.Name
}
func getSyncedRevision(rev *model.ApplicationRevision) string {
if rev == nil {
return ""
}
return rev.Version
}

View File

@@ -133,7 +133,10 @@ func (c *CR2UX) AddOrUpdate(ctx context.Context, targetApp *v1beta1.Application)
}
// update cache
c.syncCache(dsApp.AppMeta.PrimaryKey(), targetApp.ResourceVersion, int64(len(dsApp.Targets)))
key := formatAppComposedName(targetApp.Name, targetApp.Namespace)
syncedVersion := getSyncedRevision(dsApp.Revision)
c.syncCache(key, syncedVersion, int64(len(dsApp.Targets)))
klog.Infof("application %s/%s revision %s synced successful", targetApp.Name, targetApp.Namespace, syncedVersion)
return nil
}

View File

@@ -26,6 +26,7 @@ import (
corev1 "k8s.io/api/core/v1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/service"
@@ -138,7 +139,7 @@ var _ = Describe("Test CR convert to ux", func() {
app2 := &v1beta1.Application{}
Expect(common2.ReadYamlToObject("testdata/test-app2.yaml", app2)).Should(BeNil())
app1.Namespace = appNS1
app1.Generation = 2
app1.Status.LatestRevision = &common.Revision{Name: "v2"}
app1.Spec = app2.Spec
Expect(cr2ux.AddOrUpdate(context.Background(), app1)).Should(BeNil())
comp3 := model.ApplicationComponent{AppPrimaryKey: apName1, Name: "blog"}
@@ -216,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

@@ -87,7 +87,7 @@ func NewDatastore(cfg datastore.Config) (ds datastore.DataStore, err error) {
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
}
case "kubeapi":
ds, err = kubeapi.New(context.Background(), cfg)
ds, err = kubeapi.New(context.Background(), cfg, k8sClient)
if err != nil {
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
}

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

@@ -101,7 +101,7 @@ func (a *ApplicationSync) Start(ctx context.Context, errorChan chan error) {
app := getApp(obj)
if app.DeletionTimestamp == nil {
a.Queue.Add(app)
klog.Infof("watched update/add app event, namespace: %s, name: %s", app.Namespace, app.Name)
klog.V(4).Infof("watched update/add app event, namespace: %s, name: %s", app.Namespace, app.Name)
}
}
@@ -114,7 +114,7 @@ func (a *ApplicationSync) Start(ctx context.Context, errorChan chan error) {
},
DeleteFunc: func(obj interface{}) {
app := getApp(obj)
klog.Infof("watched delete app event, namespace: %s, name: %s", app.Namespace, app.Name)
klog.V(4).Infof("watched delete app event, namespace: %s, name: %s", app.Namespace, app.Name)
a.Queue.Forget(app)
a.Queue.Done(app)
err = cu.DeleteApp(ctx, app)

View File

@@ -26,6 +26,7 @@ import (
corev1 "k8s.io/api/core/v1"
"k8s.io/client-go/util/workqueue"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/repository"
@@ -133,6 +134,9 @@ var _ = Describe("Test Worker CR sync to datastore", func() {
app2.Spec = newapp2.Spec
Expect(k8sClient.Update(context.TODO(), app2)).Should(BeNil())
app2.Status.LatestRevision = &common.Revision{Name: "v3"}
Expect(k8sClient.Status().Update(context.TODO(), app2)).Should(BeNil())
Eventually(func() error {
appm := model.ApplicationComponent{AppPrimaryKey: formatAppComposedName(app2.Name, app2.Namespace), Name: "nginx2"}
return ds.Get(ctx, &appm)

View File

@@ -74,7 +74,7 @@ type Entity interface {
PrimaryKey() string
TableName() string
ShortTableName() string
Index() map[string]string
Index() map[string]interface{}
}
// NewEntity Create a new object based on the input type

View File

@@ -35,8 +35,8 @@ import (
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/clients"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
pkgUtils "github.com/oam-dev/kubevela/pkg/utils"
)
type kubeapi struct {
@@ -46,17 +46,13 @@ type kubeapi struct {
// New new kubeapi datastore instance
// Data is stored using ConfigMap.
func New(ctx context.Context, cfg datastore.Config) (datastore.DataStore, error) {
kubeClient, err := clients.GetKubeClient()
if err != nil {
return nil, err
}
func New(ctx context.Context, cfg datastore.Config, client client.Client) (datastore.DataStore, error) {
if cfg.Database == "" {
cfg.Database = "kubevela_store"
}
var namespace corev1.Namespace
if err := kubeClient.Get(ctx, types.NamespacedName{Name: cfg.Database}, &namespace); apierrors.IsNotFound(err) {
if err := kubeClient.Create(ctx, &corev1.Namespace{
if err := client.Get(ctx, types.NamespacedName{Name: cfg.Database}, &namespace); apierrors.IsNotFound(err) {
if err := client.Create(ctx, &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: cfg.Database,
Annotations: map[string]string{"description": "For KubeVela API Server metadata storage."},
@@ -64,9 +60,9 @@ func New(ctx context.Context, cfg datastore.Config) (datastore.DataStore, error)
return nil, fmt.Errorf("create namespace failure %w", err)
}
}
migrate(cfg.Database)
migrate(cfg.Database, client)
return &kubeapi{
kubeClient: kubeClient,
kubeClient: client,
namespace: cfg.Database,
}, nil
}
@@ -81,7 +77,7 @@ func generateName(entity datastore.Entity) string {
func (m *kubeapi) generateConfigMap(entity datastore.Entity) *corev1.ConfigMap {
data, _ := json.Marshal(entity)
labels := entity.Index()
labels := convertIndex2Labels(entity.Index())
if labels == nil {
labels = make(map[string]string)
}
@@ -176,7 +172,7 @@ func (m *kubeapi) Put(ctx context.Context, entity datastore.Entity) error {
return datastore.ErrTableNameEmpty
}
// update labels
labels := entity.Index()
labels := convertIndex2Labels(entity.Index())
if labels == nil {
labels = make(map[string]string)
}
@@ -350,8 +346,8 @@ func (m *kubeapi) List(ctx context.Context, entity datastore.Entity, op *datasto
rq, _ := labels.NewRequirement(MigrateKey, selection.DoesNotExist, []string{"ok"})
selector = selector.Add(*rq)
for k, v := range entity.Index() {
metedataLabels := convertIndex2Labels(entity.Index())
for k, v := range metedataLabels {
rq, err := labels.NewRequirement(k, selection.Equals, []string{verifyValue(v)})
if err != nil {
return nil, datastore.ErrIndexInvalid
@@ -441,7 +437,8 @@ func (m *kubeapi) Count(ctx context.Context, entity datastore.Entity, filterOpti
if err != nil {
return 0, datastore.NewDBError(err)
}
for k, v := range entity.Index() {
metedataLabels := convertIndex2Labels(entity.Index())
for k, v := range metedataLabels {
rq, err := labels.NewRequirement(k, selection.Equals, []string{verifyValue(v)})
if err != nil {
return 0, datastore.ErrIndexInvalid
@@ -494,3 +491,19 @@ func verifyValue(v string) string {
s = strings.ReplaceAll(s, " ", "-")
return strings.ToLower(s)
}
func convertIndex2Labels(index map[string]interface{}) map[string]string {
if index == nil {
return nil
}
ret := make(map[string]string, len(index))
for k, v := range index {
value := pkgUtils.ToString(v)
if value == "" {
klog.Warningf("unable to cast %#v of type %T to string", v, v)
continue
}
ret[k] = pkgUtils.ToString(v)
}
return ret
}

View File

@@ -73,7 +73,7 @@ var _ = BeforeSuite(func(done Done) {
By("new kube client success")
clients.SetKubeClient(k8sClient)
kubeStore, err = New(context.TODO(), datastore.Config{Database: "test"})
kubeStore, err = New(context.TODO(), datastore.Config{Database: "test"}, k8sClient)
Expect(err).Should(BeNil())
Expect(kubeStore).ToNot(BeNil())
close(done)

View File

@@ -72,20 +72,38 @@ var _ = Describe("Test kubeapi datastore driver", func() {
err := kubeStore.Put(context.TODO(), &model.Application{Name: "kubevela-app", Description: "this is demo"})
Expect(err).ToNot(HaveOccurred())
})
It("Test index", func() {
It("Test application index", func() {
var app = model.Application{
Name: "test",
}
selector, err := labels.Parse(fmt.Sprintf("table=%s", app.TableName()))
Expect(err).ToNot(HaveOccurred())
Expect(cmp.Diff(app.Index()["name"], "test")).Should(BeEmpty())
for k, v := range app.Index() {
index := convertIndex2Labels(app.Index())
for k, v := range index {
rq, err := labels.NewRequirement(k, selection.Equals, []string{v})
Expect(err).ToNot(HaveOccurred())
selector = selector.Add(*rq)
}
Expect(cmp.Diff(selector.String(), "name=test,table=vela_application")).Should(BeEmpty())
})
It("Test workflow index", func() {
defaultPtr := false
var workflow = model.Workflow{
Name: "test",
Default: &defaultPtr,
}
selector, err := labels.Parse(fmt.Sprintf("table=%s", workflow.TableName()))
Expect(err).ToNot(HaveOccurred())
Expect(cmp.Diff(workflow.Index()["name"], "test")).Should(BeEmpty())
index := convertIndex2Labels(workflow.Index())
for k, v := range index {
rq, err := labels.NewRequirement(k, selection.Equals, []string{v})
Expect(err).ToNot(HaveOccurred())
selector = selector.Add(*rq)
}
Expect(cmp.Diff(selector.String(), "default=false,name=test,table=vela_workflow")).Should(BeEmpty())
})
It("Test list function", func() {
var app model.Application
list, err := kubeStore.List(context.TODO(), &app, &datastore.ListOptions{Page: -1})

View File

@@ -27,7 +27,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/clients"
)
// MigrateKey marks the label key of the migrated data
@@ -36,17 +35,13 @@ const MigrateKey = "db.oam.dev/migrated"
// migrate will migrate the configmap to new short table name, it won't delete the configmaps:
// users can delete by the following commands:
// kubectl -n kubevela delete cm -l db.oam.dev/migrated=ok
func migrate(dbns string) {
kubeClient, err := clients.GetKubeClient()
if err != nil {
panic(err)
}
func migrate(dbns string, c client.Client) {
models := model.GetRegisterModels()
for _, k := range models {
var configMaps corev1.ConfigMapList
table := k.TableName()
selector, _ := labels.Parse(fmt.Sprintf("table=%s", table))
if err = kubeClient.List(context.Background(), &configMaps, &client.ListOptions{Namespace: dbns, LabelSelector: selector}); err != nil {
if err := c.List(context.Background(), &configMaps, &client.ListOptions{Namespace: dbns, LabelSelector: selector}); err != nil {
err = client.IgnoreNotFound(err)
if err != nil {
klog.Errorf("migrate db for kubeapi storage err: %v", err)
@@ -72,14 +67,14 @@ func migrate(dbns string) {
}
cm.Labels[MigrateKey] = "ok"
err = kubeClient.Update(context.Background(), &cm)
err := c.Update(context.Background(), &cm)
if err != nil {
klog.Errorf("update migrated record %s for kubeapi storage err: %v", cm.Name, err)
}
cm.Name = strings.ReplaceAll(k.ShortTableName()+strings.TrimPrefix(cm.Name, checkprefix), "_", "-")
cm.ResourceVersion = ""
delete(cm.Labels, MigrateKey)
err = kubeClient.Create(context.Background(), &cm)
err = c.Create(context.Background(), &cm)
if err != nil {
klog.Errorf("migrate record %s for kubeapi storage err: %v", cm.Name, err)
}

View File

@@ -47,7 +47,7 @@ var _ = Describe("Test Migrate", func() {
cm.Namespace = nsName
Expect(ds.kubeClient.Create(context.Background(), cm)).Should(BeNil())
migrate(nsName)
migrate(nsName, k8sClient)
cmList := v1.ConfigMapList{}
Expect(k8sClient.List(context.Background(), &cmList, client.InNamespace(nsName))).Should(BeNil())
Expect(len(cmList.Items)).Should(BeEquivalentTo(2))

View File

@@ -90,7 +90,7 @@ func NewDatastore(cfg datastore.Config) (ds datastore.DataStore, err error) {
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
}
case "kubeapi":
ds, err = kubeapi.New(context.Background(), cfg)
ds, err = kubeapi.New(context.Background(), cfg, k8sClient)
if err != nil {
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
}

View File

@@ -118,7 +118,7 @@ func (c *application) GetWebServiceRoute() *restful.WebService {
Writes(apis.ApplicationStatisticsResponse{}))
ws.Route(ws.POST("/{appName}/triggers").To(c.createApplicationTrigger).
Doc("create one application trigger").
Doc("Create an application trigger").
Metadata(restfulspec.KeyOpenAPITags, tags).
Filter(c.RbacService.CheckPerm("trigger", "create")).
Filter(c.appCheckFilter).
@@ -129,7 +129,7 @@ func (c *application) GetWebServiceRoute() *restful.WebService {
Writes(apis.ApplicationTriggerBase{}))
ws.Route(ws.DELETE("/{appName}/triggers/{token}").To(c.deleteApplicationTrigger).
Doc("delete one application trigger").
Doc("Delete an application trigger").
Metadata(restfulspec.KeyOpenAPITags, tags).
Filter(c.RbacService.CheckPerm("trigger", "delete")).
Filter(c.appCheckFilter).
@@ -139,8 +139,19 @@ func (c *application) GetWebServiceRoute() *restful.WebService {
Returns(400, "Bad Request", bcode.Bcode{}).
Writes([]*apis.EmptyResponse{}))
ws.Route(ws.PUT("/{appName}/triggers/{token}").To(c.updateApplicationTrigger).
Doc("Update an application trigger").
Metadata(restfulspec.KeyOpenAPITags, tags).
Filter(c.RbacService.CheckPerm("trigger", "update")).
Filter(c.appCheckFilter).
Param(ws.PathParameter("appName", "identifier of the application ").DataType("string")).
Param(ws.PathParameter("token", "identifier of the trigger").DataType("string")).
Returns(200, "OK", apis.ApplicationTriggerBase{}).
Returns(400, "Bad Request", bcode.Bcode{}).
Writes([]*apis.ApplicationTriggerBase{}))
ws.Route(ws.GET("/{appName}/triggers").To(c.listApplicationTriggers).
Doc("list application triggers").
Doc("List the application triggers").
Metadata(restfulspec.KeyOpenAPITags, tags).
Filter(c.RbacService.CheckPerm("trigger", "list")).
Filter(c.appCheckFilter).
@@ -747,6 +758,24 @@ func (c *application) deleteApplicationTrigger(req *restful.Request, res *restfu
}
}
func (c *application) updateApplicationTrigger(req *restful.Request, res *restful.Response) {
var updateReq apis.UpdateApplicationTriggerRequest
if err := req.ReadEntity(&updateReq); err != nil {
bcode.ReturnError(req, res, err)
return
}
app := req.Request.Context().Value(&apis.CtxKeyApplication).(*model.Application)
trigger, err := c.ApplicationService.UpdateApplicationTrigger(req.Request.Context(), app, req.PathParameter("token"), updateReq)
if err != nil {
bcode.ReturnError(req, res, err)
return
}
if err := res.WriteEntity(trigger); err != nil {
bcode.ReturnError(req, res, err)
return
}
}
func (c *application) publishApplicationTemplate(req *restful.Request, res *restful.Response) {
app := req.Request.Context().Value(&apis.CtxKeyApplication).(*model.Application)
base, err := c.ApplicationService.PublishApplicationTemplate(req.Request.Context(), app)

View File

@@ -274,6 +274,23 @@ func ConvertPermission2DTO(permission *model.Permission) *apisv1.PermissionBase
}
}
// ConvertTrigger2DTO convert trigger model to the DTO
func ConvertTrigger2DTO(trigger model.ApplicationTrigger) *apisv1.ApplicationTriggerBase {
return &apisv1.ApplicationTriggerBase{
WorkflowName: trigger.WorkflowName,
Name: trigger.Name,
Alias: trigger.Alias,
Description: trigger.Description,
Type: trigger.Type,
PayloadType: trigger.PayloadType,
Token: trigger.Token,
Registry: trigger.Registry,
ComponentName: trigger.ComponentName,
CreateTime: trigger.CreateTime,
UpdateTime: trigger.UpdateTime,
}
}
func convertBool(b *bool) bool {
if b == nil {
return false

View File

@@ -512,6 +512,16 @@ type CreateApplicationTriggerRequest struct {
Registry string `json:"registry,omitempty" optional:"true"`
}
// UpdateApplicationTriggerRequest update application trigger
type UpdateApplicationTriggerRequest struct {
Alias string `json:"alias" validate:"checkalias" optional:"true"`
Description string `json:"description" optional:"true"`
WorkflowName string `json:"workflowName"`
PayloadType string `json:"payloadType" validate:"checkpayloadtype"`
ComponentName string `json:"componentName,omitempty" optional:"true"`
Registry string `json:"registry,omitempty" optional:"true"`
}
// ApplicationTriggerBase application trigger base model
type ApplicationTriggerBase struct {
Name string `json:"name"`
@@ -522,6 +532,7 @@ type ApplicationTriggerBase struct {
PayloadType string `json:"payloadType"`
Token string `json:"token"`
ComponentName string `json:"componentName,omitempty"`
Registry string `json:"registry"`
CreateTime time.Time `json:"createTime"`
UpdateTime time.Time `json:"updateTime"`
}

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

@@ -121,7 +121,7 @@ func (dt *Target) createTarget(req *restful.Request, res *restful.Response) {
// Call the domain layer code
TargetDetail, err := dt.TargetService.CreateTarget(req.Request.Context(), createReq)
if err != nil {
klog.Errorf("create -target failure %s", err.Error())
klog.Errorf("create target failure %s", err.Error())
bcode.ReturnError(req, res, err)
return
}

View File

@@ -43,6 +43,7 @@ import (
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/container"
pkgconfig "github.com/oam-dev/kubevela/pkg/config"
"github.com/oam-dev/kubevela/pkg/features"
pkgUtils "github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/apply"
)
@@ -86,6 +87,8 @@ func (s *restServer) buildIoCContainer() error {
if err != nil {
return err
}
authClient := utils.NewAuthClient(kubeClient)
var ds datastore.DataStore
switch s.cfg.Datastore.Type {
case "mongodb":
@@ -94,7 +97,7 @@ func (s *restServer) buildIoCContainer() error {
return fmt.Errorf("create mongodb datastore instance failure %w", err)
}
case "kubeapi":
ds, err = kubeapi.New(context.Background(), s.cfg.Datastore)
ds, err = kubeapi.New(context.Background(), s.cfg.Datastore, kubeClient)
if err != nil {
return fmt.Errorf("create kubeapi datastore instance failure %w", err)
}
@@ -106,23 +109,22 @@ func (s *restServer) buildIoCContainer() error {
return fmt.Errorf("fail to provides the datastore bean to the container: %w", err)
}
kubeClient = utils.NewAuthClient(kubeClient)
if err := s.beanContainer.ProvideWithName("kubeClient", kubeClient); err != nil {
if err := s.beanContainer.ProvideWithName("kubeClient", authClient); err != nil {
return fmt.Errorf("fail to provides the kubeClient bean to the container: %w", err)
}
if err := s.beanContainer.ProvideWithName("kubeConfig", kubeConfig); err != nil {
return fmt.Errorf("fail to provides the kubeConfig bean to the container: %w", err)
}
if err := s.beanContainer.ProvideWithName("apply", apply.NewAPIApplicator(kubeClient)); err != nil {
if err := s.beanContainer.ProvideWithName("apply", apply.NewAPIApplicator(authClient)); err != nil {
return fmt.Errorf("fail to provides the apply bean to the container: %w", err)
}
factory := pkgconfig.NewConfigFactory(kubeClient)
factory := pkgconfig.NewConfigFactory(authClient)
if err := s.beanContainer.ProvideWithName("configFactory", factory); err != nil {
return fmt.Errorf("fail to provides the config factory bean to the container: %w", err)
}
addonStore := pkgaddon.NewRegistryDataStore(kubeClient)
addonStore := pkgaddon.NewRegistryDataStore(authClient)
if err := s.beanContainer.ProvideWithName("registryDatastore", addonStore); err != nil {
return fmt.Errorf("fail to provides the registry datastore bean to the container: %w", err)
}
@@ -149,6 +151,12 @@ func (s *restServer) buildIoCContainer() error {
func (s *restServer) Run(ctx context.Context, errChan chan error) error {
for feature := range features.APIServerMutableFeatureGate.GetAll() {
if features.APIServerFeatureGate.Enabled(feature) {
klog.Infof("The %s feature enabled", feature)
}
}
// build the Ioc Container
if err := s.buildIoCContainer(); err != nil {
return err

View File

@@ -86,6 +86,12 @@ func (c *authClient) Status() client.StatusWriter {
return &authAppStatusClient{StatusWriter: c.Client.Status()}
}
// Get .
func (c *authClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error {
ctx = ContextWithUserInfo(ctx)
return c.Client.Get(ctx, key, obj)
}
// List .
func (c *authClient) List(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error {
ctx = ContextWithUserInfo(ctx)

View File

@@ -37,4 +37,7 @@ var (
// ErrNotFoundDistribution means the distribution is not exist
ErrNotFoundDistribution = NewBcode(404, 16007, "the distribution is 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")
)

View File

@@ -23,8 +23,6 @@ import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/yaml"
@@ -167,7 +165,6 @@ var _ = Describe("Test Live-Diff", func() {
Expect(k8sClient.Create(context.Background(), un)).Should(Succeed())
}
ctx := context.Background()
Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "vela-system"}})).Should(Succeed())
applyFile("diff-input-app-with-externals.yaml", "default")
applyFile("diff-apprevision.yaml", "default")
app := &v1beta1.Application{}
@@ -190,7 +187,6 @@ var _ = Describe("Test Live-Diff", func() {
Expect(runDiff()).Should(ContainSubstring("\"myworker\" not found"))
applyFile("td-myingress.yaml", "vela-system")
applyFile("cd-myworker.yaml", "vela-system")
applyFile("wd-deploy.yaml", "vela-system")
applyFile("wd-ref-objects.yaml", "vela-system")
Expect(runDiff()).Should(ContainSubstring("\"deploy-livediff-demo\" not found"))
applyFile("external-workflow.yaml", "default")

View File

@@ -37,14 +37,19 @@ import (
"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"
apiutils "github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/cue/definition"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/policy/envbinding"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/apply"
"github.com/oam-dev/kubevela/pkg/workflow/step"
)
// DryRun executes dry-run on an application
@@ -136,13 +141,15 @@ func (d *Option) ExecuteDryRun(ctx context.Context, application *v1beta1.Applica
if app.Namespace != "" {
ctx = oamutil.SetNamespaceInCtx(ctx, app.Namespace)
}
appFile, err := parser.GenerateAppFileFromApp(ctx, app)
generateCtx := apiutils.WithProject(ctx, "")
appFile, err := parser.GenerateAppFileFromApp(generateCtx, app)
if err != nil {
return nil, nil, errors.WithMessage(err, "cannot generate appFile from application")
}
if appFile.Namespace == "" {
appFile.Namespace = corev1.NamespaceDefault
}
comps, err := appFile.GenerateComponentManifests()
if err != nil {
return nil, nil, errors.WithMessage(err, "cannot generate manifests from components and traits")
@@ -206,3 +213,120 @@ func (d *Option) PrintDryRun(buff *bytes.Buffer, appName string, comps []*types.
}
return nil
}
// ExecuteDryRunWithPolicies is similar to ExecuteDryRun func, but considers deploy workflow step and topology+override policies
func (d *Option) ExecuteDryRunWithPolicies(ctx context.Context, application *v1beta1.Application, buff *bytes.Buffer) error {
app := application.DeepCopy()
if app.Namespace == "" {
app.Namespace = corev1.NamespaceDefault
} else {
ctx = oamutil.SetNamespaceInCtx(ctx, app.Namespace)
}
parser := appfile.NewDryRunApplicationParser(d.Client, d.DiscoveryMapper, d.PackageDiscover, d.Auxiliaries)
af, err := parser.GenerateAppFileFromApp(ctx, app)
if err != nil {
return err
}
deployWorkflowCount := 0
for _, wfs := range af.WorkflowSteps {
if wfs.Type == step.DeployWorkflowStep {
deployWorkflowCount++
deployWorkflowStepSpec := &step.DeployWorkflowStepSpec{}
if err := utils.StrictUnmarshal(wfs.Properties.Raw, deployWorkflowStepSpec); err != nil {
return err
}
topologyPolicies, overridePolicies, err := filterPolicies(af.Policies, deployWorkflowStepSpec.Policies)
if err != nil {
return err
}
if len(topologyPolicies) > 0 {
for _, tp := range topologyPolicies {
patchedApp, err := patchApp(app, overridePolicies)
if err != nil {
return err
}
comps, pms, err := d.ExecuteDryRun(ctx, patchedApp)
if err != nil {
return err
}
err = d.PrintDryRun(buff, fmt.Sprintf("%s with topology %s", patchedApp.Name, tp.Name), comps, pms)
if err != nil {
return err
}
}
} else {
patchedApp, err := patchApp(app, overridePolicies)
if err != nil {
return err
}
comps, pms, err := d.ExecuteDryRun(ctx, patchedApp)
if err != nil {
return err
}
err = d.PrintDryRun(buff, fmt.Sprintf("%s only with override policies", patchedApp.Name), comps, pms)
if err != nil {
return err
}
}
}
}
if deployWorkflowCount == 0 {
comps, pms, err := d.ExecuteDryRun(ctx, app)
if err != nil {
return err
}
err = d.PrintDryRun(buff, app.Name, comps, pms)
if err != nil {
return err
}
}
return nil
}
func filterPolicies(policies []v1beta1.AppPolicy, policyNames []string) ([]v1beta1.AppPolicy, []v1beta1.AppPolicy, error) {
policyMap := make(map[string]v1beta1.AppPolicy)
for _, policy := range policies {
policyMap[policy.Name] = policy
}
var topologyPolicies []v1beta1.AppPolicy
var overridePolicies []v1beta1.AppPolicy
for _, policyName := range policyNames {
if policy, found := policyMap[policyName]; found {
switch policy.Type {
case v1alpha1.TopologyPolicyType:
topologyPolicies = append(topologyPolicies, policy)
case v1alpha1.OverridePolicyType:
overridePolicies = append(overridePolicies, policy)
}
} else {
return nil, nil, errors.Errorf("policy %s not found", policyName)
}
}
return topologyPolicies, overridePolicies, nil
}
func patchApp(application *v1beta1.Application, overridePolicies []v1beta1.AppPolicy) (*v1beta1.Application, error) {
app := application.DeepCopy()
for _, policy := range overridePolicies {
if policy.Properties == nil {
return nil, fmt.Errorf("override policy %s must not have empty properties", policy.Name)
}
overrideSpec := &v1alpha1.OverridePolicySpec{}
if err := utils.StrictUnmarshal(policy.Properties.Raw, overrideSpec); err != nil {
return nil, errors.Wrapf(err, "failed to parse override policy %s", policy.Name)
}
overrideComps, err := envbinding.PatchComponents(app.Spec.Components, overrideSpec.Components, overrideSpec.Selector)
if err != nil {
return nil, errors.Wrapf(err, "failed to apply override policy %s", policy.Name)
}
app.Spec.Components = overrideComps
}
return app, nil
}

View File

@@ -17,8 +17,11 @@ limitations under the License.
package dryrun
import (
"bytes"
"context"
"encoding/json"
"os"
"strings"
"github.com/oam-dev/kubevela/apis/types"
@@ -59,3 +62,108 @@ var _ = Describe("Test DryRun", func() {
Expect(diff).Should(BeEmpty())
})
})
var _ = Describe("Test dry run with policies", func() {
It("Test dry run with override policy", func() {
webservice, err := os.ReadFile("../../../charts/vela-core/templates/defwithtemplate/webservice.yaml")
Expect(err).Should(BeNil())
webserviceYAML := strings.Replace(string(webservice), "{{ include \"systemDefinitionNamespace\" . }}", types.DefaultKubeVelaNS, 1)
wwd := v1beta1.ComponentDefinition{}
Expect(yaml.Unmarshal([]byte(webserviceYAML), &wwd)).Should(BeNil())
Expect(k8sClient.Create(context.TODO(), &wwd)).Should(BeNil())
scaler, err := os.ReadFile("../../../charts/vela-core/templates/defwithtemplate/scaler.yaml")
Expect(err).Should(BeNil())
scalerYAML := strings.Replace(string(scaler), "{{ include \"systemDefinitionNamespace\" . }}", types.DefaultKubeVelaNS, 1)
var td v1beta1.TraitDefinition
Expect(yaml.Unmarshal([]byte(scalerYAML), &td)).Should(BeNil())
Expect(k8sClient.Create(context.TODO(), &td)).Should(BeNil())
appYAML := readDataFromFile("./testdata/testing-dry-run-1.yaml")
app := &v1beta1.Application{}
Expect(yaml.Unmarshal([]byte(appYAML), &app)).Should(BeNil())
var buff = bytes.Buffer{}
err = dryrunOpt.ExecuteDryRunWithPolicies(context.TODO(), app, &buff)
Expect(err).Should(BeNil())
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app with topology target-default)"))
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app with topology target-prod)"))
Expect(buff.String()).Should(ContainSubstring("name: testing-dryrun"))
Expect(buff.String()).Should(ContainSubstring("kind: Deployment"))
Expect(buff.String()).Should(ContainSubstring("replicas: 1"))
Expect(buff.String()).Should(ContainSubstring("replicas: 3"))
Expect(buff.String()).Should(ContainSubstring("kind: Service"))
})
It("Test dry run only with override policy", func() {
appYAML := readDataFromFile("./testdata/testing-dry-run-2.yaml")
app := &v1beta1.Application{}
Expect(yaml.Unmarshal([]byte(appYAML), &app)).Should(BeNil())
var buff = bytes.Buffer{}
err := dryrunOpt.ExecuteDryRunWithPolicies(context.TODO(), app, &buff)
Expect(err).Should(BeNil())
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app only with override policies)"))
Expect(buff.String()).Should(ContainSubstring("name: testing-dryrun"))
Expect(buff.String()).Should(ContainSubstring("kind: Deployment"))
Expect(buff.String()).Should(ContainSubstring("replicas: 3"))
Expect(buff.String()).Should(ContainSubstring("kind: Service"))
})
It("Test dry run without deploy workflow", func() {
appYAML := readDataFromFile("./testdata/testing-dry-run-3.yaml")
app := &v1beta1.Application{}
Expect(yaml.Unmarshal([]byte(appYAML), &app)).Should(BeNil())
var buff = bytes.Buffer{}
err := dryrunOpt.ExecuteDryRunWithPolicies(context.TODO(), app, &buff)
Expect(err).Should(BeNil())
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app)"))
Expect(buff.String()).Should(ContainSubstring("name: testing-dryrun"))
Expect(buff.String()).Should(ContainSubstring("kind: Deployment"))
})
It("Test dry run without custom policy", func() {
topo, err := os.ReadFile("./testdata/pd-mypolicy.yaml")
Expect(err).Should(BeNil())
var pd v1beta1.PolicyDefinition
Expect(yaml.Unmarshal([]byte(topo), &pd)).Should(BeNil())
Expect(k8sClient.Create(context.TODO(), &pd)).Should(BeNil())
appYAML := readDataFromFile("./testdata/testing-dry-run-4.yaml")
app := &v1beta1.Application{}
Expect(yaml.Unmarshal([]byte(appYAML), &app)).Should(BeNil())
var buff = bytes.Buffer{}
err = dryrunOpt.ExecuteDryRunWithPolicies(context.TODO(), app, &buff)
Expect(err).Should(BeNil())
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app) -- Component(testing-dryrun)"))
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app) -- Policy(mypolicy)"))
Expect(buff.String()).Should(ContainSubstring("name: my-policy"))
})
It("Test dry run with trait", func() {
nocalhost, err := os.ReadFile("../../../charts/vela-core/templates/defwithtemplate/nocalhost.yaml")
Expect(err).Should(BeNil())
nocalhostYAML := strings.Replace(string(nocalhost), "{{ include \"systemDefinitionNamespace\" . }}", types.DefaultKubeVelaNS, 1)
var td v1beta1.TraitDefinition
Expect(yaml.Unmarshal([]byte(nocalhostYAML), &td)).Should(BeNil())
Expect(k8sClient.Create(context.TODO(), &td)).Should(BeNil())
appYAML := readDataFromFile("./testdata/testing-dry-run-5.yaml")
app := &v1beta1.Application{}
Expect(yaml.Unmarshal([]byte(appYAML), &app)).Should(BeNil())
var buff = bytes.Buffer{}
err = dryrunOpt.ExecuteDryRunWithPolicies(context.TODO(), app, &buff)
Expect(err).Should(BeNil())
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app) -- Component(testing-dryrun)"))
Expect(buff.String()).Should(ContainSubstring("## From the trait nocalhost"))
Expect(buff.String()).Should(ContainSubstring("trait.oam.dev/type: nocalhost"))
})
})

View File

@@ -17,11 +17,19 @@ limitations under the License.
package dryrun
import (
"context"
"os"
"path/filepath"
"testing"
"time"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@@ -103,6 +111,16 @@ var _ = BeforeSuite(func(done Done) {
tdMyIngress, err := oamutil.Object2Unstructured(myingressDef)
Expect(err).Should(BeNil())
// create vela-system ns
Expect(k8sClient.Create(context.TODO(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: types.DefaultKubeVelaNS}})).Should(Succeed())
// create deploy workflow step definition
deploy, err := os.ReadFile("./testdata/wd-deploy.yaml")
Expect(err).Should(BeNil())
var wfsd v1beta1.WorkflowStepDefinition
Expect(yaml.Unmarshal([]byte(deploy), &wfsd)).Should(BeNil())
wfsd.SetNamespace(types.DefaultKubeVelaNS)
Expect(k8sClient.Create(context.TODO(), &wfsd)).Should(BeNil())
dryrunOpt = NewDryRunOption(k8sClient, cfg, dm, pd, []oam.Object{cdMyWorker, tdMyIngress}, false)
diffOpt = &LiveDiffOption{DryRun: dryrunOpt, Parser: appfile.NewApplicationParser(k8sClient, dm, pd)}

View File

@@ -0,0 +1,22 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/topology.cue
apiVersion: core.oam.dev/v1beta1
kind: PolicyDefinition
metadata:
name: mypolicy
namespace: vela-system
spec:
schematic:
cue:
template: |
output: {
apiVersion: "testing/v1"
kind: "Policy"
policy: {
name: parameter.name
}
}
parameter: {
name: string
}

View File

@@ -0,0 +1,48 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: testing-app
namespace: default
spec:
components:
- name: testing-dryrun
type: webservice
properties:
image: oamdev/hello-world:v1
ports:
- port: 8000
expose: true
traits:
- type: scaler
properties:
replicas: 1
policies:
- name: target-default
type: topology
properties:
clusters: [ "local" ]
namespace: "default"
- name: target-prod
type: topology
properties:
clusters: [ "local" ]
namespace: "prod"
- name: deploy-ha
type: override
properties:
components:
- type: webservice
traits:
- type: scaler
properties:
replicas: 3
workflow:
steps:
- name: deploy2default
type: deploy
properties:
policies: [ "target-default" ]
- name: deploy2prod
type: deploy
properties:
policies: [ "target-prod", "deploy-ha" ]

View File

@@ -0,0 +1,27 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: testing-app
spec:
components:
- name: testing-dryrun
type: webservice
properties:
image: oamdev/hello-world:v1
ports:
- port: 8000
expose: true
traits:
- type: scaler
properties:
replicas: 1
policies:
- name: deploy-ha
type: override
properties:
components:
- type: webservice
traits:
- type: scaler
properties:
replicas: 3

View File

@@ -0,0 +1,15 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: testing-app
spec:
components:
- name: testing-dryrun
type: webservice
properties:
image: oamdev/hello-world:v1
workflow:
steps:
- name: suspend
type: suspend

View File

@@ -0,0 +1,16 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: testing-app
spec:
components:
- name: testing-dryrun
type: webservice
properties:
image: oamdev/hello-world:v1
policies:
- name: mypolicy
type: mypolicy
properties:
name: "my-policy"

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