Compare commits

...

63 Commits

Author SHA1 Message Date
github-actions[bot]
1a6b7244c8 Fix: can not logs from pod of subclusters (#5159)
Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit 7a17ee459d)

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-12-03 21:08:08 +08:00
github-actions[bot]
18a5b7c239 [Backport release-1.6] Feat: Introduce timeout mechanism into cache and update network request mechanism in vela top (#5156)
* Fix: update cache to lru cache with expire time

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit e54abd7a40)

* Fix: add auto refresh to topology view and fix the refresh bug in resource view
Signed-off-by: HanMengnan <1448189829@qq.com>

(cherry picked from commit f6dcc8f6ed)

Co-authored-by: HanMengnan <1448189829@qq.com>
2022-12-03 14:57:55 +08:00
github-actions[bot]
65e9b549e2 Feat: support huawei cloud terraform generation (#5155)
Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit e2bfb30f75)

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-12-03 14:57:08 +08:00
github-actions[bot]
b0a0d84030 Fix: addon upgrade command does not recognize the --clusters flag (#5154)
Signed-off-by: zhaohuihui <zhaohuihui_yewu@cmss.chinamobile.com>
(cherry picked from commit 4526400e3c)

Co-authored-by: zhaohuihui <zhaohuihui_yewu@cmss.chinamobile.com>
2022-12-03 14:56:30 +08:00
Jianbo Sun
773c4112d9 Chore: refine log and align using klog/v2 - cherry-pick #5145 (#5150)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>

Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-12-03 12:36:28 +08:00
github-actions[bot]
a5d68b2bea fix format error (#5147)
Signed-off-by: Ziqi Zhao <zhaoziqi9146@gmail.com>
(cherry picked from commit 0ad1517613)

Co-authored-by: Ziqi Zhao <zhaoziqi9146@gmail.com>
2022-12-01 16:06:50 +08:00
github-actions[bot]
353e592391 Fix: vela status --endpoint show no IP when only one master node (#5141)
Add fallback if no worker node

check app exist

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

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-11-30 10:47:19 +08:00
github-actions[bot]
c58e3dfea6 Fix: container image cue (#5135)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 447ece69e9)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-11-28 11:36:17 +08:00
github-actions[bot]
a783393ebd [Backport release-1.6] Fix: bug of filter registry func will modify origin data (#5120)
* fix filter registry func flaky

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

* fix comments

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-11-24 15:06:29 +08:00
github-actions[bot]
a19ed0b510 [Backport release-1.6] Chore: add definition example doc CI check (#5119)
* Chore: add definition example doc CI check

Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit 1afaaf047d)

* Fix: add example doc for trait

Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit 6c61643b8a)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-11-24 15:05:18 +08:00
github-actions[bot]
03223aa786 [Backport release-1.6] Fix: bug when addon dependent an addon in other registry (#5115)
* fix several bugs of addon

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

* fix golint error

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

* fix error and add tests

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

* fix comments and fix apiserver test

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

* fix typo

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

* fix tests

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

* small fix

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

* small fix

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

* add parameter in apiserver and test

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-11-24 09:46:54 +08:00
github-actions[bot]
55c8dad116 Fix: multicluster cluster scope ref (#5112)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 40a9a981d9)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-11-24 09:16:15 +08:00
github-actions[bot]
38c57c38c8 [Backport release-1.6] Fix: end test environments (#5107)
* Fix: end test environments

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

* fix

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

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-11-22 19:37:12 +08:00
github-actions[bot]
7f734e9479 Fix: patchOutputs bug for multiple outputs (#5104)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 4864ca3a27)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-11-22 11:40:20 +08:00
github-actions[bot]
7814232b7c Fix: fix acr webhook for enterprise registry (#5098)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit c0519d3fba)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-11-21 14:21:58 +08:00
github-actions[bot]
b1cc06b0f3 Feat: support dry-run with cue format definition (#5080)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit ce75a33633)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-11-16 18:11:58 +08:00
github-actions[bot]
ed9d53b448 Feat: add print message example (#5079)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit ee2b854c80)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-11-16 16:38:06 +08:00
github-actions[bot]
ad83e59865 [Backport release-1.6] Feat: add apply component definition for docs (#5076)
* Feat: add apply component definition for docs

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit d31dbecb76)

* Feat: add apply component definition for docs

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 454edb05ff)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-11-16 15:45:49 +08:00
github-actions[bot]
b62eeca3f9 [Backport release-1.6] Fix: code vulnerability (#5075)
* Fix: code vulnerability

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

* lint

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

* imports

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

* use space

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

* reuse sanitize function

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

Co-authored-by: qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-11-16 15:45:25 +08:00
github-actions[bot]
5d9757fcb8 Feat: support vela up --wait and --timeout (#5074)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit f81f26f66b)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-11-16 10:01:14 +08:00
github-actions[bot]
4d653951a1 add tests (#5068)
Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit 7080d7ae31)

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-11-15 13:17:06 +08:00
github-actions[bot]
bcda4976a9 [Backport release-1.6] Fix: Failed to get detail policy for application (#5049)
* Fix: Failed to get detail policy for application

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

* Fix: Failed to get detail policy for application

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

Co-authored-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
2022-11-10 21:50:22 +08:00
github-actions[bot]
a01d0e773a Fix: add debug for workflowrun and support debug sub steps (#5042)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 5749babe71)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-11-10 11:04:47 +08:00
github-actions[bot]
f0e3304c17 [Backport release-1.6] Fix: fix the stuck problem and use LRU cache to promote the speed of loading topology (#5036)
* Fix: fix the stuck problem and use lru cache to promote the speed of loading topology

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit 8395fe56b2)

* Fix: reuse existing lru golang library

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit d69018f71e)

Co-authored-by: HanMengnan <1448189829@qq.com>
2022-11-09 16:09:46 +08:00
github-actions[bot]
e9f1e21d55 Feat: support webservice containing duplicate port with different protocol (#5035)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit a8653e5d1c)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-11-09 13:15:17 +08:00
github-actions[bot]
de127b7311 Fix: higher version contraint in install command (#5033)
Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit a7b30ce104)

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-11-09 11:26:33 +08:00
github-actions[bot]
9f0558c62e Fix: temporary fix comments in comprehesions for env trait (#5025)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit b9d380142d)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-11-09 11:22:41 +08:00
github-actions[bot]
0f547fa158 Feat: add scope label in workflow step defs (#5023)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 2d02a7ac20)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-11-09 11:21:59 +08:00
github-actions[bot]
84155d06fb [Backport release-1.6] Fix: remove the reference of v1beta1 ingress (#5028)
* try to remove the v1beta1 ingress

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

* fix tests

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-11-09 11:20:14 +08:00
github-actions[bot]
bc7e31f979 use vi as ingress's target apiVersion (#5022)
Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

fix test

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

fix test

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

revert test

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

add tests

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-11-08 12:12:05 +08:00
github-actions[bot]
f406936dce Fix: vela status will always get external ip first (#5018)
Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit f1d81feece)

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-11-07 18:55:07 +08:00
github-actions[bot]
c2ecc71941 Fix: vela cluster join reports 'resource name may not be empty' error (#5015)
Signed-off-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
(cherry picked from commit ce4cad677d)

Co-authored-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
2022-11-07 16:14:47 +08:00
github-actions[bot]
c1efd3f056 Fix: fix problem of loading pods of cronjob (#5013)
Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit c074c558b6)

Co-authored-by: HanMengnan <1448189829@qq.com>
2022-11-07 16:12:52 +08:00
github-actions[bot]
7002182072 [Backport release-1.6] Fix: remove duplicate mock server in CI (#5012)
* Fix: not killing mock server process every time

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

* remove redundent mock server

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

Co-authored-by: qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-11-07 11:06:00 +08:00
github-actions[bot]
554a06e35e [Backport release-1.6] Fix: forbid 302 request to avoid SSRF (#5004)
* fix helm chart list endpoint SSRF CVE

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

* revert error log

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

* change with const value

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

fix ci

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-11-04 20:17:15 +08:00
github-actions[bot]
4ffb7e6707 Chore: update the API schema (#4997)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 64eb622f12)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-11-04 13:10:56 +08:00
github-actions[bot]
caeb334340 [Backport release-1.6] Fix: test ci windows (#4991)
* Fix: test ci windows

Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit f3dfa50514)

* Fix: rename add exe suffix for command

Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit 447e91c316)

* Fix: trim extra commands

Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit b23ce529d1)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-11-03 15:43:31 +08:00
github-actions[bot]
275b61d427 Fix: app contains app override the child app with parent app label (#4988)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit c39e6adc50)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-11-02 22:39:57 +08:00
github-actions[bot]
11904a6f60 [Backport release-1.6] Fix: fix filepath for windows (#4987)
* Fix: fix filepath for windows

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit ef5b4fbe38)

* test ci

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit fb367d3722)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-11-02 22:39:29 +08:00
github-actions[bot]
4b4e4f8530 [Backport release-1.6] Fix: enhance the default permissions (#4977)
* Fix: enhance the default permissions

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

* Fix: unit test error

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-11-01 20:51:33 +08:00
github-actions[bot]
0121e8b6ef Feat: allowing restart a compeleted workflow (#4976)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 74eea5bed2)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-11-01 20:35:36 +08:00
github-actions[bot]
382510aa67 [Backport release-1.6] Fix: mongodb can not decode runtime.Object (#4974)
* Fix: mongodb can not decode runtime.Object

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

* reuse struct

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

* fix no output when filter

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

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-11-01 17:25:55 +08:00
github-actions[bot]
7ae7d2a5ef [Backport release-1.6] Fix: grant the permission to read the ConfigMap in the vela-system namesapce (#4970)
* Fix: grant the permission to read the ConfigMap in the vela-system namespace

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

* Fix: change the test

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-11-01 10:00:04 +08:00
github-actions[bot]
0736e85e07 [Backport release-1.6] Feat: implement pipeline APIs (#4969)
* add context when run pipeline

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

* Feat: implement pipeline API

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

* Extract get log logic and implement getPipelineRunLog API

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

* Init and delete pipeline contexts

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

* fix panic

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

* Allow not specifying context

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

* change pipeline to path parameter

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

* Add permission check filter

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

* project -> projects in route

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

* fix route conflict

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

* Add project alias

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

* Feat: change the list pipeline API

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

* Feat: filter the project

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

* Fix: the error of the run APi

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

* fix log pipeline run API

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

* Fix lint, fix the error of log api

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

* fix error returning

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

* Fix: change the lable to annotation

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

* remove log config not found error

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

* fix pipeline list api return no context info

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

* Fix: create the namespace

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

* get pipeline lastrun info

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

* allow query single step output

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

* organize code in api layer

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

* fix project filter, add context value when get pp run, extend lastRun

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

* fix get output and implement get input api

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

* Fix: change the last run

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

* if query sub-step outout, return it directly

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

* Fix: change the run stats

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

* Fix: change the output

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

* flatten the input/output api

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

* more info for i/o vars

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

* fix nested i/o struct

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

* add fromStep in input api

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

* add e2e test skeleton

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

* add more e2e test

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

* use db to store pipeline

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

* keep the last 5k lines of log

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

* use stern param to keep last lines of logs

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

* filter, nil labels, spec check

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

* empty res, index, detail param

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

* Add e2e test

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

* fix e2e test and unit test

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

* add context e2e test

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

* goimports

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

* add more test

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

* review

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

* remove optional tag in returned value, unify the imports name

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

* fix e2e test

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

* add stop test

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

* more coverage

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

* single case selct

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

* optimize log color

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

* add default permission and role

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

* fix permission ut

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

* change the log api implementation

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

* add color, add container order

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

* lint

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

* fix filter nil will cut all log

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

* longer timeout and lint

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

Co-authored-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-11-01 00:13:37 +08:00
github-actions[bot]
f01e6d9723 Chore: stable the version of cue and workflow (#4964)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 0defa2d53d)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-10-31 15:12:35 +08:00
github-actions[bot]
2d7d4ef99d [Backport release-1.6] Fix: do not change the workflow after the env changed (#4962)
* Fix: do not change the workflow after the env changed

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

* Fix: change the test case

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

* Fix: check app when deleting the target from a env

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-10-31 11:19:49 +08:00
github-actions[bot]
6bbce07a21 Feat: add mode in workflow template (#4960)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 19a30371dd)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-10-31 11:09:54 +08:00
github-actions[bot]
12ba4631c1 [Backport release-1.6] Fix: bocde error override origin error message (#4955)
* fix bcode error

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

* small fix

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-10-29 17:05:25 +08:00
github-actions[bot]
d5b4f9ae5d [Backport release-1.6] Fix: update namespace only if it doesn't have the env label (#4953)
* Fix: update namespace only if it doesn't have the env label

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

* Fix: update namespace only if it doesn't have the env label

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

Co-authored-by: wuzhongjian <wuzhongjian_yewu@cmss.chinamobile.com>
2022-10-29 10:36:02 +08:00
github-actions[bot]
d62185315a It is unnecessary to judge that the index function is not null (#4952)
Signed-off-by: liutiangang <liutiangang@cmbchina.com>
(cherry picked from commit 2570df7e83)

Co-authored-by: liutiangang <liutiangang@cmbchina.com>
2022-10-29 09:13:48 +08:00
github-actions[bot]
12f0cebc6c more error info for apiservice and add tests (#4949)
Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

change the mock addon version

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-10-29 08:32:26 +08:00
github-actions[bot]
284a7d08b2 Feat: sync the model of api workflow with core (#4950)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 0bfa9f9143)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-10-29 08:31:13 +08:00
github-actions[bot]
c91850ce0d Fix: apiserver & vela status use multi-cluster client (#4946)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit a1a3996062)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-10-28 14:15:58 +08:00
github-actions[bot]
e13b31d00e [Backport release-1.6] Fix: can't obtain pods generated by Crontask component (patch of PR 4925) (#4945)
* Fix: get label selector from cronJob

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit 03be6b3f8f)

* Fix: small fix

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit b8c97411d5)

* Fix: use scheme create obj

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit fa00132e2d)

* Fix: update method of generating selector

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit d30010ec7a)

* Fix: update cron-task

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit 864c04eee6)

* Fix: add test case

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit c1cdf8f290)

* Fix: add test case

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit f977805810)

Co-authored-by: HanMengnan <1448189829@qq.com>
2022-10-28 11:34:28 +08:00
github-actions[bot]
71d0d7344f Fix: fix gen doc for container image (#4937)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 33f7c2539b)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-10-27 22:19:10 +08:00
github-actions[bot]
247845db0a fix gitlab addon registry (#4939)
Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit f3ee964734)

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-10-27 22:17:58 +08:00
github-actions[bot]
427809cea7 Fix: update export2config and export2secret example (#4940)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit b2de4020a4)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-10-27 19:07:39 +08:00
github-actions[bot]
6c29b7b088 Fix: get Application status using jsonpath filter expression (#4933)
Signed-off-by: yanghaojia <yanghaojia@coding.net>
(cherry picked from commit 16272cffaa)

Co-authored-by: yanghaojia <yanghaojia@coding.net>
2022-10-27 14:45:14 +08:00
github-actions[bot]
77e85472fa [Backport release-1.6] Fix: can't get pods of CronTask component (#4930)
* Fix: get label selector from cronJob

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit a9b2c3ac88)

* Fix: update cron-task yaml

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit 188b544db0)

* Fix: small fix

Signed-off-by: HanMengnan <1448189829@qq.com>
(cherry picked from commit 9d393df2fa)

Co-authored-by: HanMengnan <1448189829@qq.com>
2022-10-27 11:22:51 +08:00
github-actions[bot]
c60df945c3 [Backport release-1.6] Feat: support operations for workflow run (#4924)
* Feat: support operations for workflow run

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 5b721ad97b)

* fix test

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 9421eb4a78)

* fix lint

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 0b2f6b46c7)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-10-27 10:26:13 +08:00
github-actions[bot]
28488a4e9b [Backport release-1.6] Feat: enhance the apply-once capability (#4919)
* Feat: enhance the apply-once capability

Signed-off-by: 朱晓兵 <596908030@qq.com>
(cherry picked from commit 43eef883d0)

* Fix: add unit-test

Signed-off-by: 朱晓兵 <596908030@qq.com>
(cherry picked from commit 514c2bc8bd)

* Fix: adjustment variable name

Signed-off-by: 朱晓兵 <596908030@qq.com>
(cherry picked from commit 70b3621ac6)

* Fix: add doc

Signed-off-by: 朱晓兵 <596908030@qq.com>
(cherry picked from commit 5506fe9cda)

* Fix: adjustment variable name

Signed-off-by: 朱晓兵 <596908030@qq.com>
(cherry picked from commit 4e5f8d9443)

Co-authored-by: 朱晓兵 <596908030@qq.com>
2022-10-26 16:36:08 +08:00
github-actions[bot]
1ae7ba1e1e [Backport release-1.6] Fix: add sub step in vela workflow logs (#4918)
* Fix: add sub step in vela workflow logs

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 81616ffd89)

* fix lint

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit d491c6c8cf)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-10-25 16:58:02 +08:00
Somefive
2076c2f937 Feat: add feature docs and controller parameters for MultiStageComponentApply (#4873) (#4917)
Signed-off-by: ZhongsJie <zhongsjie@gmail.com>

Signed-off-by: ZhongsJie <zhongsjie@gmail.com>

Signed-off-by: ZhongsJie <zhongsjie@gmail.com>
Co-authored-by: ZhongsJie <62382570+ZhongsJie96@users.noreply.github.com>
2022-10-25 15:00:23 +08:00
283 changed files with 8359 additions and 3584 deletions

View File

@@ -176,10 +176,12 @@ jobs:
make e2e-cleanup
make e2e-setup-core
bin/vela addon enable fluxcd
bin/vela addon enable vela-workflow
timeout 600s bash -c -- 'while true; do kubectl get ns flux-system; if [ $? -eq 0 ] ; then break; else sleep 5; fi;done'
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=vela-core,app.kubernetes.io/instance=kubevela -n vela-system --timeout=600s
kubectl wait --for=condition=Ready pod -l app=source-controller -n flux-system --timeout=600s
kubectl wait --for=condition=Ready pod -l app=helm-controller -n flux-system --timeout=600s
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=vela-workflow -n vela-system --timeout=600s
- name: Run api server e2e test
run: |

44
.github/workflows/definition-lint.yml vendored Normal file
View File

@@ -0,0 +1,44 @@
name: Definition-Lint
on:
push:
branches:
- master
- release-*
workflow_dispatch: {}
pull_request:
branches:
- master
- release-*
env:
# Common versions
GO_VERSION: '1.19'
jobs:
definition-doc:
runs-on: ubuntu-latest
steps:
- name: Setup Go
uses: actions/setup-go@v3
with:
go-version: ${{ env.GO_VERSION }}
- name: Checkout
uses: actions/checkout@v3
with:
submodules: true
- name: Setup K3d
uses: nolar/setup-k3d-k3s@v1.0.9
with:
version: v1.20
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Definition Doc generate check
run: |
go build -o docgen hack/docgen/def/gen.go
./docgen --type=comp --force-example-doc --path=./comp-def-check.md
./docgen --type=trait --force-example-doc --path=./trait-def-check.md
./docgen --type=wf --force-example-doc --path=./wf-def-check.md
./docgen --type=policy --force-example-doc --path=./policy-def-check.md

View File

@@ -141,3 +141,35 @@ jobs:
- name: Cleanup binary
run: make build-cleanup
check-windows:
runs-on: windows-latest
needs: detect-noop
if: needs.detect-noop.outputs.noop != 'true'
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: true
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: ${{ env.GO_VERSION }}
- name: Cache Go Dependencies
uses: actions/cache@v2
with:
path: .work/pkg
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-pkg-
- name: Run Build CLI
run: make vela-cli
- name: Run CLI for version
shell: cmd
run: |
move .\bin\vela .\bin\vela.exe
.\bin\vela.exe version

View File

@@ -189,8 +189,6 @@ type Status struct {
type ApplicationPhase string
const (
// ApplicationRollingOut means the app is in the middle of rolling out
ApplicationRollingOut ApplicationPhase = "rollingOut"
// ApplicationStarting means the app is preparing for reconcile
ApplicationStarting ApplicationPhase = "starting"
// ApplicationRendering means the app is rendering
@@ -205,8 +203,6 @@ const (
ApplicationWorkflowTerminated ApplicationPhase = "workflowTerminated"
// ApplicationWorkflowFailed means the app's workflow is failed
ApplicationWorkflowFailed ApplicationPhase = "workflowFailed"
// ApplicationWorkflowFinished means the app's workflow is finished
ApplicationWorkflowFinished ApplicationPhase = "workflowFinished"
// ApplicationRunning means the app finished rendering and applied result to the cluster
ApplicationRunning ApplicationPhase = "running"
// ApplicationUnhealthy means the app finished rendering and applied result to the cluster, but still unhealthy

View File

@@ -23,8 +23,17 @@ import (
const (
// ApplyOncePolicyType refers to the type of configuration drift policy
ApplyOncePolicyType = "apply-once"
// ApplyOnceStrategyOnAppUpdate policy takes effect on application updating
ApplyOnceStrategyOnAppUpdate ApplyOnceAffectStrategy = "onUpdate"
// ApplyOnceStrategyOnAppStateKeep policy takes effect on application state keep
ApplyOnceStrategyOnAppStateKeep ApplyOnceAffectStrategy = "onStateKeep"
// ApplyOnceStrategyAlways policy takes effect always
ApplyOnceStrategyAlways ApplyOnceAffectStrategy = "always"
)
// ApplyOnceAffectStrategy is a string that mark the policy effective stage
type ApplyOnceAffectStrategy string
// ApplyOncePolicySpec defines the spec of preventing configuration drift
type ApplyOncePolicySpec struct {
Enable bool `json:"enable"`
@@ -45,6 +54,9 @@ type ApplyOnceStrategy struct {
// Path the specified path that allow configuration drift
// like 'spec.template.spec.containers[0].resources' and '*' means the whole target allow configuration drift
Path []string `json:"path"`
// ApplyOnceAffectStrategy Decide when the strategy will take effect
// like affect:onUpdate/onStateKeep/always
ApplyOnceAffectStrategy ApplyOnceAffectStrategy `json:"affect"`
}
// FindStrategy find apply-once strategy for target resource

View File

@@ -64,6 +64,8 @@ const (
LabelDefinitionDeprecated = "custom.definition.oam.dev/deprecated"
// LabelDefinitionHidden is the label which describe whether the capability is hidden by UI
LabelDefinitionHidden = "custom.definition.oam.dev/ui-hidden"
// LabelDefinitionScope is the label which describe whether the capability's scope
LabelDefinitionScope = "custom.definition.oam.dev/scope"
// LabelNodeRoleGateway gateway role of node
LabelNodeRoleGateway = "node-role.kubernetes.io/gateway"
// LabelNodeRoleWorker worker role of node

View File

@@ -97,6 +97,7 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
| `featureGates.gzipResourceTracker` | if enabled, resourceTracker will be compressed using gzip before being stored | `false` |
| `featureGates.zstdResourceTracker` | if enabled, resourceTracker will be compressed using zstd before being stored. It is much faster and more efficient than gzip. If both gzip and zstd are enabled, zstd will be used. | `false` |
| `featureGates.applyOnce` | if enabled, the apply-once feature will be applied to all applications, no state-keep and no resource data storage in ResourceTracker | `false` |
| `featureGates.multiStageComponentApply` | if enabled, the multiStageComponentApply feature will be combined with the stage field in TraitDefinition to complete the multi-stage apply. | `false` |
### MultiCluster parameters

View File

@@ -2209,10 +2209,11 @@ spec:
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
description: SubSteps is the mode of workflow sub
steps execution
type: string
type: object
ref:
@@ -4008,6 +4009,17 @@ spec:
namespace:
type: string
type: object
mode:
description: WorkflowExecuteMode defines the mode of workflow
execution
properties:
steps:
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: SubSteps is the mode of workflow sub steps execution
type: string
type: object
steps:
items:
description: WorkflowStep defines how to execute a workflow

View File

@@ -1020,10 +1020,10 @@ spec:
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
description: SubSteps is the mode of workflow sub steps execution
type: string
type: object
ref:

View File

@@ -1,10 +1,10 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
controller-gen.kubebuilder.io/version: v0.9.0
creationTimestamp: null
name: workflows.core.oam.dev
spec:
group: core.oam.dev
@@ -34,6 +34,16 @@ spec:
type: string
metadata:
type: object
mode:
description: WorkflowExecuteMode defines the mode of workflow execution
properties:
steps:
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: SubSteps is the mode of workflow sub steps execution
type: string
type: object
steps:
items:
description: WorkflowStep defines how to execute a workflow step.
@@ -161,153 +171,3 @@ spec:
type: object
served: true
storage: true
- name: v1beta1
schema:
openAPIV3Schema:
description: Workflow defines workflow steps and other attributes
properties:
mode:
description: WorkflowExecuteMode defines the mode of workflow execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
type: string
type: object
ref:
type: string
steps:
items:
description: WorkflowStep defines how to execute a workflow step.
properties:
dependsOn:
description: DependsOn is the dependency of the step
items:
type: string
type: array
if:
description: If is the if condition of the step
type: string
inputs:
description: Inputs is the inputs of the step
items:
properties:
from:
type: string
parameterKey:
type: string
required:
- from
- parameterKey
type: object
type: array
meta:
description: Meta is the meta data of the workflow step.
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
outputs:
description: Outputs is the outputs of the step
items:
properties:
name:
type: string
valueFrom:
type: string
required:
- name
- valueFrom
type: object
type: array
properties:
description: Properties is the properties of the step
type: object
x-kubernetes-preserve-unknown-fields: true
subSteps:
items:
description: WorkflowStepBase defines the workflow step base
properties:
dependsOn:
description: DependsOn is the dependency of the step
items:
type: string
type: array
if:
description: If is the if condition of the step
type: string
inputs:
description: Inputs is the inputs of the step
items:
properties:
from:
type: string
parameterKey:
type: string
required:
- from
- parameterKey
type: object
type: array
meta:
description: Meta is the meta data of the workflow step.
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
outputs:
description: Outputs is the outputs of the step
items:
properties:
name:
type: string
valueFrom:
type: string
required:
- name
- valueFrom
type: object
type: array
properties:
description: Properties is the properties of the step
type: object
x-kubernetes-preserve-unknown-fields: true
timeout:
description: Timeout is the timeout of the step
type: string
type:
description: Type is the type of the workflow step.
type: string
required:
- name
- type
type: object
type: array
timeout:
description: Timeout is the timeout of the step
type: string
type:
description: Type is the type of the workflow step.
type: string
required:
- name
- type
type: object
type: array
type: object
served: true
storage: false
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -7,6 +7,7 @@ metadata:
definition.oam.dev/description: Apply components of an application in parallel for your workflow steps
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: apply-application-in-parallel
namespace: {{ include "systemDefinitionNamespace" . }}

View File

@@ -7,6 +7,7 @@ metadata:
definition.oam.dev/description: Apply application for your workflow steps, it has no arguments, should be used for custom steps before or after application applied.
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: apply-application
namespace: {{ include "systemDefinitionNamespace" . }}

View File

@@ -0,0 +1,23 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/apply-component.cue
apiVersion: core.oam.dev/v1beta1
kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: Apply a specific component and its corresponding traits in application
labels:
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: apply-component
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
schematic:
cue:
template: |
parameter: {
// +usage=Specify the component name to apply
component: string
// +usage=Specify the cluster
cluster: *"" | string
}

View File

@@ -12,6 +12,8 @@ spec:
cue:
template: |
#ApplyOnceStrategy: {
// +usage=When the strategy takes effect,e.g. onUpdate、onStateKeep
affect?: string
// +usage=Specify the path of the resource that allow configuration drift
path: [...string]
}

View File

@@ -7,6 +7,7 @@ metadata:
definition.oam.dev/description: Apply remaining components and traits
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: apply-remaining
namespace: {{ include "systemDefinitionNamespace" . }}

View File

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

View File

@@ -5,6 +5,8 @@ kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: Deploy cloud resource and deliver secret to multi clusters.
labels:
custom.definition.oam.dev/scope: Application
name: deploy-cloud-resource
namespace: {{ include "systemDefinitionNamespace" . }}
spec:

View File

@@ -5,6 +5,8 @@ kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: A powerful and unified deploy step for components multi-cluster delivery with policies.
labels:
custom.definition.oam.dev/scope: Application
name: deploy
namespace: {{ include "systemDefinitionNamespace" . }}
spec:

View File

@@ -7,6 +7,7 @@ metadata:
definition.oam.dev/description: Deploy env binding component to target env
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: deploy2env
namespace: {{ include "systemDefinitionNamespace" . }}

View File

@@ -7,6 +7,7 @@ metadata:
definition.oam.dev/description: Deploy application to runtime clusters
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: deploy2runtime
namespace: {{ include "systemDefinitionNamespace" . }}

View File

@@ -4,7 +4,7 @@ apiVersion: core.oam.dev/v1beta1
kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: pring message in workflow status
definition.oam.dev/description: print message in workflow step status
labels:
custom.definition.oam.dev/ui-hidden: "true"
name: print-message-in-status

View File

@@ -5,6 +5,8 @@ kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: Sync secrets created by terraform component to runtime clusters so that runtime clusters can share the created cloud resource.
labels:
custom.definition.oam.dev/scope: Application
name: share-cloud-resource
namespace: {{ include "systemDefinitionNamespace" . }}
spec:

View File

@@ -13,6 +13,7 @@ spec:
template: |
import (
"strconv"
"strings"
)
mountsArray: [
@@ -167,7 +168,11 @@ spec:
name: v.name
}
if v.name == _|_ {
name: "port-" + strconv.FormatInt(v.port, 10)
_name: "port-" + strconv.FormatInt(v.port, 10)
name: *_name | string
if v.protocol != "TCP" {
name: _name + "-" + strings.ToLower(v.protocol)
}
}
}}]
}
@@ -283,11 +288,18 @@ spec:
name: v.name
}
if v.name == _|_ {
name: "port-" + strconv.FormatInt(v.port, 10)
_name: "port-" + strconv.FormatInt(v.port, 10)
name: *_name | string
if v.protocol != "TCP" {
name: _name + "-" + strings.ToLower(v.protocol)
}
}
if v.nodePort != _|_ && parameter.exposeType == "NodePort" {
nodePort: v.nodePort
}
if v.protocol != _|_ {
protocol: v.protocol
}
},
]
outputs: {

View File

@@ -116,6 +116,39 @@ subjects:
name: {{ include "kubevela.serviceAccountName" . }}
---
# permissions to read the view of VelaQL, schemas, and templates.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "kubevela.fullname" . }}:template-reader-role
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps/status
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "kubevela.fullname" . }}:template-reader-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "kubevela.fullname" . }}:template-reader-role
subjects:
- kind: Group
name: template-reader
---
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -221,6 +254,7 @@ spec:
- "--feature-gates=GzipResourceTracker={{- .Values.featureGates.gzipResourceTracker | toString -}}"
- "--feature-gates=ZstdResourceTracker={{- .Values.featureGates.zstdResourceTracker | toString -}}"
- "--feature-gates=ApplyOnce={{- .Values.featureGates.applyOnce | toString -}}"
- "--feature-gates=MultiStageComponentApply= {{- .Values.featureGates.multiStageComponentApply | toString -}}"
{{ if .Values.authentication.enabled }}
{{ if .Values.authentication.withUser }}
- "--authentication-with-user"

View File

@@ -113,11 +113,13 @@ optimize:
##@param featureGates.gzipResourceTracker if enabled, resourceTracker will be compressed using gzip before being stored
##@param featureGates.zstdResourceTracker if enabled, resourceTracker will be compressed using zstd before being stored. It is much faster and more efficient than gzip. If both gzip and zstd are enabled, zstd will be used.
##@param featureGates.applyOnce if enabled, the apply-once feature will be applied to all applications, no state-keep and no resource data storage in ResourceTracker
##@param featureGates.multiStageComponentApply if enabled, the multiStageComponentApply feature will be combined with the stage field in TraitDefinition to complete the multi-stage apply.
featureGates:
enableLegacyComponentRevision: false
gzipResourceTracker: false
zstdResourceTracker: false
applyOnce: false
multiStageComponentApply: false
## @section MultiCluster parameters

View File

@@ -2209,10 +2209,11 @@ spec:
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
description: SubSteps is the mode of workflow sub
steps execution
type: string
type: object
ref:
@@ -4008,6 +4009,17 @@ spec:
namespace:
type: string
type: object
mode:
description: WorkflowExecuteMode defines the mode of workflow
execution
properties:
steps:
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: SubSteps is the mode of workflow sub steps execution
type: string
type: object
steps:
items:
description: WorkflowStep defines how to execute a workflow

View File

@@ -1020,10 +1020,10 @@ spec:
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
description: SubSteps is the mode of workflow sub steps execution
type: string
type: object
ref:

View File

@@ -7,6 +7,7 @@ metadata:
definition.oam.dev/description: Apply components of an application in parallel for your workflow steps
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: apply-application-in-parallel
namespace: {{ include "systemDefinitionNamespace" . }}

View File

@@ -7,6 +7,7 @@ metadata:
definition.oam.dev/description: Apply application for your workflow steps, it has no arguments, should be used for custom steps before or after application applied.
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: apply-application
namespace: {{ include "systemDefinitionNamespace" . }}

View File

@@ -0,0 +1,23 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/apply-component.cue
apiVersion: core.oam.dev/v1beta1
kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: Apply a specific component and its corresponding traits in application
labels:
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: apply-component
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
schematic:
cue:
template: |
parameter: {
// +usage=Specify the component name to apply
component: string
// +usage=Specify the cluster
cluster: *"" | string
}

View File

@@ -12,6 +12,8 @@ spec:
cue:
template: |
#ApplyOnceStrategy: {
// +usage=When the strategy takes effect,e.g. onUpdate、onStateKeep
affect?: string
// +usage=Specify the path of the resource that allow configuration drift
path: [...string]
}

View File

@@ -7,6 +7,7 @@ metadata:
definition.oam.dev/description: Apply remaining components and traits
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: apply-remaining
namespace: {{ include "systemDefinitionNamespace" . }}

View File

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

View File

@@ -5,6 +5,8 @@ kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: Deploy cloud resource and deliver secret to multi clusters.
labels:
custom.definition.oam.dev/scope: Application
name: deploy-cloud-resource
namespace: {{ include "systemDefinitionNamespace" . }}
spec:

View File

@@ -5,6 +5,8 @@ kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: A powerful and unified deploy step for components multi-cluster delivery with policies.
labels:
custom.definition.oam.dev/scope: Application
name: deploy
namespace: {{ include "systemDefinitionNamespace" . }}
spec:

View File

@@ -7,6 +7,7 @@ metadata:
definition.oam.dev/description: Deploy application to runtime clusters
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/scope: Application
custom.definition.oam.dev/ui-hidden: "true"
name: deploy2runtime
namespace: {{ include "systemDefinitionNamespace" . }}

View File

@@ -4,7 +4,7 @@ apiVersion: core.oam.dev/v1beta1
kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: pring message in workflow status
definition.oam.dev/description: print message in workflow step status
labels:
custom.definition.oam.dev/ui-hidden: "true"
name: print-message-in-status

View File

@@ -5,6 +5,8 @@ kind: WorkflowStepDefinition
metadata:
annotations:
definition.oam.dev/description: Sync secrets created by terraform component to runtime clusters so that runtime clusters can share the created cloud resource.
labels:
custom.definition.oam.dev/scope: Application
name: share-cloud-resource
namespace: {{ include "systemDefinitionNamespace" . }}
spec:

View File

@@ -13,6 +13,7 @@ spec:
template: |
import (
"strconv"
"strings"
)
mountsArray: [
@@ -167,7 +168,11 @@ spec:
name: v.name
}
if v.name == _|_ {
name: "port-" + strconv.FormatInt(v.port, 10)
_name: "port-" + strconv.FormatInt(v.port, 10)
name: *_name | string
if v.protocol != "TCP" {
name: _name + "-" + strings.ToLower(v.protocol)
}
}
}}]
}
@@ -283,11 +288,18 @@ spec:
name: v.name
}
if v.name == _|_ {
name: "port-" + strconv.FormatInt(v.port, 10)
_name: "port-" + strconv.FormatInt(v.port, 10)
name: *_name | string
if v.protocol != "TCP" {
name: _name + "-" + strings.ToLower(v.protocol)
}
}
if v.nodePort != _|_ && parameter.exposeType == "NodePort" {
nodePort: v.nodePort
}
if v.protocol != _|_ {
protocol: v.protocol
}
},
]
outputs: {

View File

@@ -30,10 +30,10 @@ import (
"github.com/go-openapi/spec"
"github.com/google/uuid"
flag "github.com/spf13/pflag"
"k8s.io/klog/v2"
"github.com/oam-dev/kubevela/pkg/apiserver"
"github.com/oam-dev/kubevela/pkg/apiserver/config"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/features"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/version"
@@ -61,24 +61,24 @@ func main() {
func() {
swagger, err := s.buildSwagger()
if err != nil {
log.Logger.Fatal(err.Error())
klog.Fatal(err.Error())
}
outData, err := json.MarshalIndent(swagger, "", "\t")
if err != nil {
log.Logger.Fatal(err.Error())
klog.Fatal(err.Error())
}
swaggerFile, err := os.OpenFile(os.Args[2], os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
if err != nil {
log.Logger.Fatal(err.Error())
klog.Fatal(err.Error())
}
defer func() {
if err := swaggerFile.Close(); err != nil {
log.Logger.Errorf("close swagger file failure %s", err.Error())
klog.Errorf("close swagger file failure %s", err.Error())
}
}()
_, err = swaggerFile.Write(outData)
if err != nil {
log.Logger.Fatal(err.Error())
klog.Fatal(err.Error())
}
fmt.Println("build swagger config file success")
}()
@@ -107,11 +107,11 @@ func main() {
select {
case <-term:
log.Logger.Infof("Received SIGTERM, exiting gracefully...")
klog.Infof("Received SIGTERM, exiting gracefully...")
case err := <-errChan:
log.Logger.Errorf("Received an error: %s, exiting gracefully...", err.Error())
klog.Errorf("Received an error: %s, exiting gracefully...", err.Error())
}
log.Logger.Infof("See you next time!")
klog.Infof("See you next time!")
}
// Server apiserver
@@ -120,7 +120,7 @@ type Server struct {
}
func (s *Server) run(ctx context.Context, errChan chan error) error {
log.Logger.Infof("KubeVela information: version: %v, gitRevision: %v", version.VelaVersion, version.GitRevision)
klog.Infof("KubeVela information: version: %v, gitRevision: %v", version.VelaVersion, version.GitRevision)
server := apiserver.New(s.serverConfig)

File diff suppressed because it is too large Load Diff

View File

@@ -120,4 +120,61 @@ EOF
In the `apply-once-app-3` case, any changes of `hello-cosmos` deployment will not be brought back and any changes
of `hello-cosmos` service will be brought back in the next reconcile loop. In the same time, any changes
of `hello-world` component will be brought back in the next reconcile loop.
of `hello-world` component will be brought back in the next reconcile loop.
```shell
$ cat <<EOF | kubectl apply -f -
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: apply-once-app-4
spec:
components:
- name: hello-world
type: webservice
properties:
image: crccheck/hello-world
port: 8080
traits:
- type: scaler
properties:
replicas: 1
- name: hello-cosmos
type: webservice
properties:
image: crccheck/hello-world
port: 8080
traits:
- type: scaler
properties:
replicas: 1
policies:
- name: apply-once
type: apply-once
properties:
enable: true
rules:
- selector:
componentNames: [ "hello-cosmos" ]
resourceTypes: [ "Deployment" ]
strategy:
affect: onStateKeep
path: [ "spec.replicas"]
EOF
```
By default, KubeVela executes the apply-once policy in two phases: application update and cycle state maintenance,
allowing configuration drift depending on the policy configuration.
If you have special requirements, you can set the affect to determine the phase of policy execution .
affect supported configurations: onUpdate/onStateKeep/always (default)
When affect=always, or not set, the policy is executed in two phase.
When affect=onStateKeep, the policy is executed only during the stateKeep phase. In the case of `apply-once-app-4`, any
changes to the deployed copy of `hello-cosmos` will not be brought back to the next state keeping loop, but will be
brought back to the next application update.
When affect=onUpdate, the policy is only executed when the application is updated. In the case of `
apply-once-app-4`, if affect=onUpdate is set, any changes to the deployed copy of `hello-cosmos` will not be brought
back in the next application update, but will be brought back in the next state keeping loop.

View File

@@ -0,0 +1,43 @@
# MultiStageComponentApply
This example shows how to enable MultiStageComponentApply, the MultiStageComponentApply feature will be combined with the stage field in TraitDefinition to complete the multi-stage apply. Currently, the stage field in TraitDefinition is an optional parameter, which provides `PreDispatch` and `PostDispatch`.
## How to use multi-stage
> The future-gate is still in alpha stage, and it is recommended to use it only in short-term test clusters.
The `MultiStageComponentApply` is not enabled by default, you need some extra works to use it.
1. Add an args `--feature-gates=MultiStageComponentApply=ture` in KubeVela controller's deployment like:
```yaml
spec:
containers:
- args:
- --feature-gates=MultiStageComponentApply=true
...
```
2. Sometime, you have multi-stage apply requirements inside the component, and it is the `outputs` resource defined in the trait. In this case, you can use the `stage` with the value `PreDispatch` or `PostDispatch` like:
```yaml
apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/description: Add storages on K8s pod for your workload which follows the pod spec in path 'spec.template'.
name: storage
namespace: vela-system
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
stage: PreDispatch
schematic:
cue:
template: |
...
```

View File

@@ -0,0 +1,8 @@
name: mock-dep-addon
version: v1.0.0
description: Vela test addon named mock-dep-addon
icon: https://www.test.com/icon
url: https://www.test.com
dependencies:
- name: mock-be-dep-addon

View File

@@ -0,0 +1,19 @@
name: not-match-addon
version: 1.0.0
description: Extended workload to do continuous and progressive delivery
icon: https://raw.githubusercontent.com/fluxcd/flux/master/docs/_files/weave-flux.png
url: https://fluxcd.io
tags:
- mock
dependencies: []
#- name: addon_name
# set invisible means this won't be list and will be enabled when depended on
# for example, terraform-alibaba depends on terraform which is invisible,
# when terraform-alibaba is enabled, terraform will be enabled automatically
# default: false
invisible: false
system:
kubernetes: "<=v1.3.0"

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -23,4 +23,50 @@ entries:
annotations:
system.vela: ">=1.5.0"
system.kubernetes: ">=1.30.0"
vela-workflow:
- annotations:
system.vela: '>=v1.6.0-beta.1'
created: "2022-10-29T09:11:16.865230605Z"
description: vela-workflow provides the capability to run a standalone workflow
home: https://github.com/kubevela/workflow
icon: https://static.kubevela.net/images/logos/KubeVela%20-03.png
name: vela-workflow
urls:
- http://127.0.0.1:9098/helm/vela-workflow-v0.3.1.tgz
version: v0.3.1
foo:
- created: "2022-10-29T09:11:16.865230605Z"
description: Vela test addon named foo
home: https://www.foo.com/icon
icon: https://www.foo.com
name: foo
urls:
- http://127.0.0.1:9098/helm/foo-v1.0.0.tgz
version: v1.0.0
bar:
- created: "2022-10-29T09:11:16.865230605Z"
description: Vela test addon named bar
home: https://www.bar.com/icon
icon: https://www.bar.com
name: foo
urls:
- http://127.0.0.1:9098/helm/bar-v1.0.0.tgz
version: v1.0.0
- created: "2022-10-29T09:11:16.865230605Z"
description: Vela test addon named bar
home: https://www.bar.com/icon
icon: https://www.bar.com
name: foo
urls:
- http://127.0.0.1:9098/helm/bar-v2.0.0.tgz
version: v2.0.0
mock-be-dep-addon:
- created: "2022-10-29T09:11:16.865230605Z"
description: Vela test addon named mock-be-dep-addon
home: https://www.test.com/icon
icon: https://www.test.com
name: mock-be-dep-addon
urls:
- http://127.0.0.1:9098/helm/mock-be-dep-addon-v1.0.0.tgz
version: v1.0.0
generated: "2022-06-15T13:17:04.733573+08:00"

View File

@@ -22,9 +22,9 @@ import (
"fmt"
"html/template"
"io/fs"
"io/ioutil"
"log"
"net/http"
"os"
"path"
"strings"
@@ -108,24 +108,55 @@ var ossHandler http.HandlerFunc = func(rw http.ResponseWriter, req *http.Request
var helmHandler http.HandlerFunc = func(rw http.ResponseWriter, req *http.Request) {
switch {
case strings.Contains(req.URL.Path, "index.yaml"):
file, err := ioutil.ReadFile("./e2e/addon/mock/testrepo/helm-repo/index.yaml")
file, err := os.ReadFile("./e2e/addon/mock/testrepo/helm-repo/index.yaml")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
case strings.Contains(req.URL.Path, "fluxcd-test-version-1.0.0.tgz"):
file, err := ioutil.ReadFile("./e2e/addon/mock/testrepo/helm-repo/fluxcd-test-version-1.0.0.tgz")
file, err := os.ReadFile("./e2e/addon/mock/testrepo/helm-repo/fluxcd-test-version-1.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
case strings.Contains(req.URL.Path, "fluxcd-test-version-2.0.0.tgz"):
file, err := ioutil.ReadFile("./e2e/addon/mock/testrepo/helm-repo/fluxcd-test-version-2.0.0.tgz")
file, err := os.ReadFile("./e2e/addon/mock/testrepo/helm-repo/fluxcd-test-version-2.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
case strings.Contains(req.URL.Path, "vela-workflow-v0.3.1.tgz"):
file, err := os.ReadFile("./e2e/addon/mock/testrepo/helm-repo/vela-workflow-v0.3.1.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
case strings.Contains(req.URL.Path, "foo-v1.0.0.tgz"):
file, err := os.ReadFile("./e2e/addon/mock/testrepo/helm-repo/foo-v1.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
case strings.Contains(req.URL.Path, "bar-v1.0.0.tgz"):
file, err := os.ReadFile("./e2e/addon/mock/testrepo/helm-repo/bar-v1.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
case strings.Contains(req.URL.Path, "bar-v2.0.0.tgz"):
file, err := os.ReadFile("./e2e/addon/mock/testrepo/helm-repo/bar-v2.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
case strings.Contains(req.URL.Path, "mock-be-dep-addon-v1.0.0.tgz"):
file, err := os.ReadFile("./e2e/addon/mock/testrepo/helm-repo/mock-be-dep-addon-v1.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
}
}
func init() {

View File

@@ -47,6 +47,9 @@ var (
appbasicJsonAppFile = `{"name":"app-basic","services":{"app-basic":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}]}}}`
appbasicAddTraitJsonAppFile = `{"name":"app-basic","services":{"app-basic":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}],"scaler":{"replicas":2}}}}`
velaQL = "test-component-pod-view{appNs=default,appName=nginx-vela,name=nginx}"
waitAppfileToSuccess = `{"name":"app-wait-success","services":{"app-basic1":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}]}}}`
waitAppfileToFail = `{"name":"app-wait-fail","services":{"app-basic2":{"type":"webservice","image":"nginx:fail","ports":[{port: 80, expose: true}]}}}`
)
var _ = ginkgo.Describe("Test Vela Application", func() {
@@ -75,6 +78,9 @@ var _ = ginkgo.Describe("Test Vela Application", func() {
e2e.JsonAppFileContext("json appfile apply", testDeleteJsonAppFile)
VelaQLPodListContext("ql", velaQL)
e2e.JsonAppFileContextWithWait("json appfile apply with wait", waitAppfileToSuccess)
e2e.JsonAppFileContextWithTimeout("json appfile apply with wait but timeout", waitAppfileToFail, "3s")
})
var ApplicationStatusContext = func(context string, applicationName string, workloadType string) bool {
@@ -182,7 +188,7 @@ var ApplicationInitIntercativeCliContext = func(context string, appName string,
c.ExpectEOF()
})
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(output).To(gomega.ContainSubstring("Checking Status"))
gomega.Expect(output).To(gomega.ContainSubstring("Waiting app to be healthy"))
})
})
}

View File

@@ -84,6 +84,30 @@ var (
})
}
JsonAppFileContextWithWait = func(context, jsonAppFile string) bool {
return ginkgo.Context(context, func() {
ginkgo.It("Start the application through the app file in JSON format.", func() {
writeStatus := os.WriteFile("vela.json", []byte(jsonAppFile), 0644)
gomega.Expect(writeStatus).NotTo(gomega.HaveOccurred())
output, err := Exec("vela up -f vela.json --wait")
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(output).To(gomega.ContainSubstring("Application Deployed Successfully!"))
})
})
}
JsonAppFileContextWithTimeout = func(context, jsonAppFile, duration string) bool {
return ginkgo.Context(context, func() {
ginkgo.It("Start the application through the app file in JSON format.", func() {
writeStatus := os.WriteFile("vela.json", []byte(jsonAppFile), 0644)
gomega.Expect(writeStatus).NotTo(gomega.HaveOccurred())
output, err := Exec("vela up -f vela.json --wait --timeout=" + duration)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(output).To(gomega.ContainSubstring("Timeout waiting Application to be healthy!"))
})
})
}
DeleteEnvFunc = func(context string, envName string) bool {
return ginkgo.Context(context, func() {
ginkgo.It("should print env does not exist message", func() {

30
go.mod
View File

@@ -3,7 +3,7 @@ module github.com/oam-dev/kubevela
go 1.19
require (
cuelang.org/go v0.4.4-0.20220915174651-ad253ed099e9
cuelang.org/go v0.5.0-alpha.1
github.com/AlecAivazis/survey/v2 v2.1.1
github.com/FogDong/uitable v0.0.5
github.com/Masterminds/semver/v3 v3.1.1
@@ -14,6 +14,7 @@ require (
github.com/alibabacloud-go/tea v1.1.19
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b
github.com/barnettZQG/inject v0.0.1
github.com/bluele/gcache v0.0.2
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869
github.com/briandowns/spinner v1.11.1
github.com/chartmuseum/helm-push v0.10.2
@@ -53,13 +54,14 @@ require (
github.com/hashicorp/hcl/v2 v2.9.1
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174
github.com/imdario/mergo v0.3.12
github.com/klauspost/compress v1.15.9
github.com/klauspost/compress v1.15.11
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
github.com/kubevela/pkg v0.0.0-20221024115939-a103acee6db2
github.com/kubevela/prism v1.5.1-0.20220915071949-6bf3ad33f84f
github.com/kubevela/workflow v0.0.0-20221019093241-b5b7a0d79051
github.com/kubevela/workflow v0.3.3
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
github.com/oam-dev/cluster-gateway v1.4.0
github.com/oam-dev/cluster-register v1.0.4-0.20220928064144-5f76a9d7ca8c
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28
@@ -77,18 +79,17 @@ require (
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.4.0
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0
github.com/stretchr/testify v1.7.1
github.com/tidwall/gjson v1.9.3
github.com/wercker/stern v0.0.0-20190705090245-4fa46dd6987f
github.com/wonderflow/cert-manager-api v1.0.4-0.20210304051430-e08aa76f6c5f
github.com/xanzy/go-gitlab v0.60.0
github.com/xlab/treeprint v1.1.0
go.mongodb.org/mongo-driver v1.5.1
go.uber.org/zap v1.21.0
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122
golang.org/x/crypto v0.1.0
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
golang.org/x/text v0.3.8
golang.org/x/term v0.1.0
golang.org/x/text v0.4.0
gomodules.xyz/jsonpatch/v2 v2.2.0
gopkg.in/src-d/go-git.v4 v4.13.1
gopkg.in/yaml.v3 v3.0.1
@@ -103,7 +104,6 @@ require (
k8s.io/client-go v0.23.6
k8s.io/component-base v0.23.6
k8s.io/helm v2.17.0+incompatible
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.60.1
k8s.io/kube-aggregator v0.23.0
k8s.io/kubectl v0.23.6
@@ -239,7 +239,6 @@ require (
github.com/moby/locker v1.0.1 // indirect
github.com/moby/spdystream v0.2.0 // indirect
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
github.com/morikuni/aec v1.0.0 // indirect
@@ -292,12 +291,13 @@ require (
go.opentelemetry.io/proto/otlp v0.7.0 // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
go.uber.org/zap v1.21.0 // indirect
golang.org/x/mod v0.6.0-dev.0.20220818022119-ed83ed61efb9 // indirect
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c // indirect
golang.org/x/net v0.1.0 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
golang.org/x/tools v0.1.12 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/grpc v1.48.0 // indirect
@@ -314,6 +314,7 @@ require (
gopkg.in/warnings.v0 v0.1.2 // indirect
istio.io/api v0.0.0-20220512212136-561ffec82582 // indirect
istio.io/gogo-genproto v0.0.0-20211208193508-5ab4acc9eb1e // indirect
k8s.io/klog v1.0.0 // indirect
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect
oras.land/oras-go v0.4.0 // indirect
sigs.k8s.io/apiserver-network-proxy v0.0.30 // indirect
@@ -341,6 +342,7 @@ require (
)
replace (
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

42
go.sum
View File

@@ -73,8 +73,6 @@ cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq
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.4.4-0.20220915174651-ad253ed099e9 h1:4mfDNgtdb398g0bekqiW8J8tw+JN3/U/3wh+Jw/I4Yk=
cuelang.org/go v0.4.4-0.20220915174651-ad253ed099e9/go.mod h1:nxWFAPWKYvZJ+eYayxArWqKKjdBTeU1N52vJpML/c6w=
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=
@@ -330,6 +328,8 @@ github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blizzy78/varnamelen v0.3.0/go.mod h1:hbwRdBvoBqxk34XyQ6HA0UH3G0/1TKuv5AC4eaBT0Ec=
github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw=
github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+WjiTceGBHIoTvn60HIbs7Hm7bcHjyrSqYB9c=
@@ -1304,8 +1304,8 @@ github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM=
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
@@ -1330,12 +1330,14 @@ 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-20221024115939-a103acee6db2 h1:C3cAfrxst1+dIWgLLhUQt1TQvEEpp1UTq9ZQB2xKbeI=
github.com/kubevela/pkg v0.0.0-20221024115939-a103acee6db2/go.mod h1:TgIGEB/r0NOy63Jzem7WsL3AIr34l+ClH9dmPqcZ4d4=
github.com/kubevela/prism v1.5.1-0.20220915071949-6bf3ad33f84f h1:1lUtU1alPThdcsn4MI6XjPb7eJLuZPpmlEdgjtnUMKw=
github.com/kubevela/prism v1.5.1-0.20220915071949-6bf3ad33f84f/go.mod h1:m724/7ANnB/iukyHW20+DicpeJMEC/JA0ZhgsHY10MA=
github.com/kubevela/workflow v0.0.0-20221019093241-b5b7a0d79051 h1:ET01t1GCjbERb+uwgGZnLHoLo4ceE1+gHnmgM/9or5g=
github.com/kubevela/workflow v0.0.0-20221019093241-b5b7a0d79051/go.mod h1:1XyGmfIkD6gPAegUkeDBXXModeiu8NVUWIgersTqwr8=
github.com/kubevela/workflow v0.3.3 h1:NSbQGcABWJIzUV5wfWFJsrO/ffZ4mCVfofUtUHCTojQ=
github.com/kubevela/workflow v0.3.3/go.mod h1:5jfZ8T1m/En44wDGRf2YqCSlODfEnAV+9PnzoLoDlFs=
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=
@@ -1923,8 +1925,9 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/sylvia7788/contextcheck v1.0.4/go.mod h1:vuPKJMQ7MQ91ZTqfdyreNKwZjyUg6KO+IebVyQDedZQ=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
@@ -2137,8 +2140,9 @@ go.uber.org/multierr v0.0.0-20180122172545-ddea229ff1df/go.mod h1:wR5kodmAFQ0UK8
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec=
go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
@@ -2198,8 +2202,8 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122 h1:NvGWuYG8dkDHFSKksI1P9faiVJ9rayE6l0+ouWVIDs8=
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -2324,8 +2328,8 @@ golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c h1:yKufUcDwucU5urd+50/Opbt4AYpqthk7wHpHok8f1lo=
golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -2517,15 +2521,16 @@ golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2538,8 +2543,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -2550,8 +2555,9 @@ golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ=
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

View File

@@ -42,6 +42,7 @@ func main() {
defdir := flag.String("def-dir", "", "path of definition dir")
tp := flag.String("type", "", "choose one of the definition to print")
i18nfile := flag.String("i18n", "../kubevela.io/static/reference-i18n.json", "file path of i18n data")
forceExample := flag.Bool("force-example-doc", false, "example must be provided for definitions")
flag.Parse()
if *i18nfile != "" {
@@ -52,21 +53,29 @@ func main() {
fmt.Println("you must specify a type with definition ref path specified ")
os.Exit(1)
}
opt := mods.Options{
Path: *path,
Location: *location,
DefDir: *defdir,
ForceExamples: *forceExample,
}
fmt.Printf("creating docs with args path=%s, location=%s, defdir=%s, type=%s.\n", *path, *location, *defdir, *tp)
switch types.CapType(*tp) {
case types.TypeComponentDefinition, "component", "comp":
mods.ComponentDef(ctx, c, path, location, *defdir)
mods.ComponentDef(ctx, c, opt)
case types.TypeTrait:
mods.TraitDef(ctx, c, path, location, *defdir)
mods.TraitDef(ctx, c, opt)
case types.TypePolicy:
mods.PolicyDef(ctx, c, path, location, *defdir)
mods.PolicyDef(ctx, c, opt)
case types.TypeWorkflowStep, "workflow", "wf":
mods.WorkflowDef(ctx, c, path, location, *defdir)
mods.WorkflowDef(ctx, c, opt)
case "":
mods.ComponentDef(ctx, c, path, location, *defdir)
mods.TraitDef(ctx, c, path, location, *defdir)
mods.PolicyDef(ctx, c, path, location, *defdir)
mods.WorkflowDef(ctx, c, path, location, *defdir)
mods.ComponentDef(ctx, c, opt)
mods.TraitDef(ctx, c, opt)
mods.PolicyDef(ctx, c, opt)
mods.WorkflowDef(ctx, c, opt)
default:
fmt.Printf("type %s not supported\n", *tp)
os.Exit(1)

View File

@@ -19,7 +19,6 @@ package mods
import (
"context"
"fmt"
"io/ioutil"
"os"
"strings"
"time"
@@ -60,12 +59,13 @@ title: 内置组件列表
` + fmt.Sprintf("> 本文档由[脚本](../../contributor/cli-ref-doc)自动生成,请勿手动修改,上次更新于 %s。\n\n", time.Now().Format(time.RFC3339))
// ComponentDef generate component def reference doc
func ComponentDef(ctx context.Context, c common.Args, path, location *string, defdir string) {
if defdir == "" {
defdir = ComponentDefDir
func ComponentDef(ctx context.Context, c common.Args, opt Options) {
if opt.DefDir == "" {
opt.DefDir = ComponentDefDir
}
ref := &docgen.MarkdownReference{
AllInOne: true,
AllInOne: true,
ForceExample: opt.ForceExamples,
Filter: func(capability types.Capability) bool {
if capability.Type != types.TypeComponentDefinition || capability.Category != types.CUECategory {
return false
@@ -74,9 +74,9 @@ func ComponentDef(ctx context.Context, c common.Args, path, location *string, de
return false
}
// only print capability which contained in cue def
files, err := ioutil.ReadDir(defdir)
files, err := os.ReadDir(opt.DefDir)
if err != nil {
fmt.Println("read dir err", defdir, err)
fmt.Println("read dir err", opt.DefDir, err)
return false
}
for _, f := range files {
@@ -96,19 +96,20 @@ func ComponentDef(ctx context.Context, c common.Args, path, location *string, de
return
}
ref.DiscoveryMapper = dm
if *path != "" {
if opt.Path != "" {
ref.I18N = &docgen.En
if strings.Contains(*location, "zh") || strings.Contains(*location, "chinese") {
if strings.Contains(opt.Location, "zh") || strings.Contains(opt.Location, "chinese") {
ref.I18N = &docgen.Zh
ref.CustomDocHeader = CustomComponentHeaderZH
}
if err := ref.GenerateReferenceDocs(ctx, c, *path); err != nil {
if err := ref.GenerateReferenceDocs(ctx, c, opt.Path); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("component reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), *path)
fmt.Printf("component reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), opt.Path)
return
}
if *location == "" || *location == "en" {
if opt.Location == "" || opt.Location == "en" {
ref.I18N = &docgen.En
if err := ref.GenerateReferenceDocs(ctx, c, ComponentDefRefPath); err != nil {
fmt.Println(err)
@@ -116,7 +117,7 @@ func ComponentDef(ctx context.Context, c common.Args, path, location *string, de
}
fmt.Printf("component reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), ComponentDefRefPath)
}
if *location == "" || *location == "zh" {
if opt.Location == "" || opt.Location == "zh" {
ref.I18N = &docgen.Zh
ref.CustomDocHeader = CustomComponentHeaderZH
if err := ref.GenerateReferenceDocs(ctx, c, ComponentDefRefPathZh); err != nil {

View File

@@ -19,7 +19,6 @@ package mods
import (
"context"
"fmt"
"io/ioutil"
"os"
"strings"
"time"
@@ -58,12 +57,13 @@ title: 内置策略列表
` + fmt.Sprintf("> 本文档由[脚本](../../contributor/cli-ref-doc)自动生成,请勿手动修改,上次更新于 %s。\n\n", time.Now().Format(time.RFC3339))
// PolicyDef generate policy def reference doc
func PolicyDef(ctx context.Context, c common.Args, path, location *string, defdir string) {
if defdir == "" {
defdir = PolicyDefDir
func PolicyDef(ctx context.Context, c common.Args, opt Options) {
if opt.DefDir == "" {
opt.DefDir = PolicyDefDir
}
ref := &docgen.MarkdownReference{
AllInOne: true,
AllInOne: true,
ForceExample: opt.ForceExamples,
Filter: func(capability types.Capability) bool {
if capability.Type != types.TypePolicy || capability.Category != types.CUECategory {
return false
@@ -72,9 +72,9 @@ func PolicyDef(ctx context.Context, c common.Args, path, location *string, defdi
return false
}
// only print capability which contained in cue def
files, err := ioutil.ReadDir(defdir)
files, err := os.ReadDir(opt.DefDir)
if err != nil {
fmt.Println("read dir err", defdir, err)
fmt.Println("read dir err", opt.DefDir, err)
return false
}
for _, f := range files {
@@ -86,20 +86,21 @@ func PolicyDef(ctx context.Context, c common.Args, path, location *string, defdi
},
CustomDocHeader: CustomPolicyHeaderEN,
}
ref.Remote = &docgen.FromCluster{Namespace: types.DefaultKubeVelaNS}
if *path != "" {
ref.Local = &docgen.FromLocal{Path: PolicyDefDir}
if opt.Path != "" {
ref.I18N = &docgen.En
if strings.Contains(*location, "zh") || strings.Contains(*location, "chinese") {
if strings.Contains(opt.Location, "zh") || strings.Contains(opt.Location, "chinese") {
ref.I18N = &docgen.Zh
ref.CustomDocHeader = CustomPolicyHeaderZH
}
if err := ref.GenerateReferenceDocs(ctx, c, *path); err != nil {
if err := ref.GenerateReferenceDocs(ctx, c, opt.Path); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("policy reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), *path)
fmt.Printf("policy reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), opt.Path)
return
}
if *location == "" || *location == "en" {
if opt.Location == "" || opt.Location == "en" {
ref.I18N = &docgen.En
if err := ref.GenerateReferenceDocs(ctx, c, PolicyDefRefPath); err != nil {
fmt.Println(err)
@@ -107,7 +108,7 @@ func PolicyDef(ctx context.Context, c common.Args, path, location *string, defdi
}
fmt.Printf("policy reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), PolicyDefRefPath)
}
if *location == "" || *location == "zh" {
if opt.Location == "" || opt.Location == "zh" {
ref.I18N = &docgen.Zh
ref.CustomDocHeader = CustomPolicyHeaderZH
if err := ref.GenerateReferenceDocs(ctx, c, PolicyDefRefPathZh); err != nil {

View File

@@ -19,7 +19,6 @@ package mods
import (
"context"
"fmt"
"io/ioutil"
"os"
"strings"
"time"
@@ -58,12 +57,13 @@ title: 内置运维特征列表
` + fmt.Sprintf("> 本文档由[脚本](../../contributor/cli-ref-doc)自动生成,请勿手动修改,上次更新于 %s。\n\n", time.Now().Format(time.RFC3339))
// TraitDef generate trait def reference doc
func TraitDef(ctx context.Context, c common.Args, path, location *string, defdir string) {
if defdir == "" {
defdir = TraitDefDir
func TraitDef(ctx context.Context, c common.Args, opt Options) {
if opt.DefDir == "" {
opt.DefDir = TraitDefDir
}
ref := &docgen.MarkdownReference{
AllInOne: true,
AllInOne: true,
ForceExample: opt.ForceExamples,
Filter: func(capability types.Capability) bool {
if capability.Type != types.TypeTrait || capability.Category != types.CUECategory {
return false
@@ -72,9 +72,9 @@ func TraitDef(ctx context.Context, c common.Args, path, location *string, defdir
return false
}
// only print capability which contained in cue def
files, err := ioutil.ReadDir(defdir)
files, err := os.ReadDir(opt.DefDir)
if err != nil {
fmt.Println("read dir err", defdir, err)
fmt.Println("read dir err", opt.DefDir, err)
return false
}
for _, f := range files {
@@ -90,20 +90,20 @@ func TraitDef(ctx context.Context, c common.Args, path, location *string, defdir
Path: TraitDefDir,
}
if *path != "" {
if opt.Path != "" {
ref.I18N = &docgen.En
if strings.Contains(*location, "zh") || strings.Contains(*location, "chinese") {
if strings.Contains(opt.Location, "zh") || strings.Contains(opt.Location, "chinese") {
ref.I18N = &docgen.Zh
ref.CustomDocHeader = CustomTraitHeaderZH
}
if err := ref.GenerateReferenceDocs(ctx, c, *path); err != nil {
if err := ref.GenerateReferenceDocs(ctx, c, opt.Path); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("trait reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), *path)
fmt.Printf("trait reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), opt.Path)
} else {
// Generate to default path depends on language
if *location == "" || *location == "en" {
if opt.Location == "" || opt.Location == "en" {
ref.I18N = &docgen.En
if err := ref.GenerateReferenceDocs(ctx, c, TraitDefRefPath); err != nil {
fmt.Println(err)
@@ -111,7 +111,7 @@ func TraitDef(ctx context.Context, c common.Args, path, location *string, defdir
}
fmt.Printf("trait reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), TraitDefRefPath)
}
if *location == "" || *location == "zh" {
if opt.Location == "" || opt.Location == "zh" {
ref.I18N = &docgen.Zh
ref.CustomDocHeader = CustomTraitHeaderZH
if err := ref.GenerateReferenceDocs(ctx, c, TraitDefRefPathZh); err != nil {

View File

@@ -0,0 +1,25 @@
/*
Copyright 2022 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package mods
// Options defines the doc generate options
type Options struct {
Path string
Location string
DefDir string
ForceExamples bool
}

View File

@@ -19,7 +19,6 @@ package mods
import (
"context"
"fmt"
"io/ioutil"
"os"
"strings"
"time"
@@ -58,12 +57,13 @@ title: 内置工作流步骤列表
` + fmt.Sprintf("> 本文档由[脚本](../../contributor/cli-ref-doc)自动生成,请勿手动修改,上次更新于 %s。\n\n", time.Now().Format(time.RFC3339))
// WorkflowDef generate workflow def reference doc
func WorkflowDef(ctx context.Context, c common.Args, path, location *string, defdir string) {
if defdir == "" {
defdir = WorkflowDefDir
func WorkflowDef(ctx context.Context, c common.Args, opt Options) {
if opt.DefDir == "" {
opt.DefDir = WorkflowDefDir
}
ref := &docgen.MarkdownReference{
AllInOne: true,
AllInOne: true,
ForceExample: opt.ForceExamples,
Filter: func(capability types.Capability) bool {
if capability.Type != types.TypeWorkflowStep || capability.Category != types.CUECategory {
@@ -74,9 +74,9 @@ func WorkflowDef(ctx context.Context, c common.Args, path, location *string, def
return false
}
// only print capability which contained in cue def
files, err := ioutil.ReadDir(defdir)
files, err := os.ReadDir(opt.DefDir)
if err != nil {
fmt.Println("read dir err", defdir, err)
fmt.Println("read dir err", opt.DefDir, err)
return false
}
for _, f := range files {
@@ -88,21 +88,22 @@ func WorkflowDef(ctx context.Context, c common.Args, path, location *string, def
},
CustomDocHeader: CustomWorkflowHeaderEN,
}
ref.Remote = &docgen.FromCluster{Namespace: types.DefaultKubeVelaNS}
ref.Local = &docgen.FromLocal{Path: WorkflowDefDir}
if *path != "" {
if opt.Path != "" {
ref.I18N = &docgen.En
if strings.Contains(*location, "zh") || strings.Contains(*location, "chinese") {
if strings.Contains(opt.Location, "zh") || strings.Contains(opt.Location, "chinese") {
ref.I18N = &docgen.Zh
ref.CustomDocHeader = CustomWorkflowHeaderZH
}
if err := ref.GenerateReferenceDocs(ctx, c, *path); err != nil {
if err := ref.GenerateReferenceDocs(ctx, c, opt.Path); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("workflow reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), *path)
fmt.Printf("workflow reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), opt.Path)
return
}
if *location == "" || *location == "en" {
if opt.Location == "" || opt.Location == "en" {
ref.I18N = &docgen.En
if err := ref.GenerateReferenceDocs(ctx, c, WorkflowDefRefPath); err != nil {
fmt.Println(err)
@@ -110,7 +111,7 @@ func WorkflowDef(ctx context.Context, c common.Args, path, location *string, def
}
fmt.Printf("workflow reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), WorkflowDefRefPath)
}
if *location == "" || *location == "zh" {
if opt.Location == "" || opt.Location == "zh" {
ref.I18N = &docgen.Zh
ref.CustomDocHeader = CustomWorkflowHeaderZH
if err := ref.GenerateReferenceDocs(ctx, c, WorkflowDefRefPathZh); err != nil {

View File

@@ -2209,10 +2209,11 @@ spec:
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
description: SubSteps is the mode of workflow sub
steps execution
type: string
type: object
ref:
@@ -4008,6 +4009,17 @@ spec:
namespace:
type: string
type: object
mode:
description: WorkflowExecuteMode defines the mode of workflow
execution
properties:
steps:
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: SubSteps is the mode of workflow sub steps execution
type: string
type: object
steps:
items:
description: WorkflowStep defines how to execute a workflow

View File

@@ -1021,10 +1021,10 @@ spec:
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
description: SubSteps is the mode of workflow sub steps execution
type: string
type: object
ref:

View File

@@ -1,10 +1,9 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.6.2
controller-gen.kubebuilder.io/version: v0.9.0
name: workflows.core.oam.dev
spec:
group: core.oam.dev
@@ -34,6 +33,16 @@ spec:
type: string
metadata:
type: object
mode:
description: WorkflowExecuteMode defines the mode of workflow execution
properties:
steps:
description: Steps is the mode of workflow steps execution
type: string
subSteps:
description: SubSteps is the mode of workflow sub steps execution
type: string
type: object
steps:
items:
description: WorkflowStep defines how to execute a workflow step.
@@ -161,297 +170,3 @@ spec:
type: object
served: true
storage: true
- name: v1alpha1
schema:
openAPIV3Schema:
description: Workflow is the Schema for the workflow API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
steps:
items:
description: WorkflowStep defines how to execute a workflow step.
properties:
dependsOn:
description: DependsOn is the dependency of the step
items:
type: string
type: array
if:
description: If is the if condition of the step
type: string
inputs:
description: Inputs is the inputs of the step
items:
properties:
from:
type: string
parameterKey:
type: string
required:
- from
- parameterKey
type: object
type: array
meta:
description: Meta is the meta data of the workflow step.
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
outputs:
description: Outputs is the outputs of the step
items:
properties:
name:
type: string
valueFrom:
type: string
required:
- name
- valueFrom
type: object
type: array
properties:
description: Properties is the properties of the step
type: object
subSteps:
items:
description: WorkflowStepBase defines the workflow step base
properties:
dependsOn:
description: DependsOn is the dependency of the step
items:
type: string
type: array
if:
description: If is the if condition of the step
type: string
inputs:
description: Inputs is the inputs of the step
items:
properties:
from:
type: string
parameterKey:
type: string
required:
- from
- parameterKey
type: object
type: array
meta:
description: Meta is the meta data of the workflow step.
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
outputs:
description: Outputs is the outputs of the step
items:
properties:
name:
type: string
valueFrom:
type: string
required:
- name
- valueFrom
type: object
type: array
properties:
description: Properties is the properties of the step
type: object
timeout:
description: Timeout is the timeout of the step
type: string
type:
description: Type is the type of the workflow step.
type: string
required:
- name
- type
type: object
type: array
timeout:
description: Timeout is the timeout of the step
type: string
type:
description: Type is the type of the workflow step.
type: string
required:
- name
- type
type: object
type: array
type: object
served: true
storage: false
- name: v1beta1
schema:
openAPIV3Schema:
description: Workflow defines workflow steps and other attributes
properties:
mode:
description: WorkflowExecuteMode defines the mode of workflow execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
type: string
type: object
ref:
type: string
steps:
items:
description: WorkflowStep defines how to execute a workflow step.
properties:
dependsOn:
description: DependsOn is the dependency of the step
items:
type: string
type: array
if:
description: If is the if condition of the step
type: string
inputs:
description: Inputs is the inputs of the step
items:
properties:
from:
type: string
parameterKey:
type: string
required:
- from
- parameterKey
type: object
type: array
meta:
description: Meta is the meta data of the workflow step.
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
outputs:
description: Outputs is the outputs of the step
items:
properties:
name:
type: string
valueFrom:
type: string
required:
- name
- valueFrom
type: object
type: array
properties:
description: Properties is the properties of the step
type: object
subSteps:
items:
description: WorkflowStepBase defines the workflow step base
properties:
dependsOn:
description: DependsOn is the dependency of the step
items:
type: string
type: array
if:
description: If is the if condition of the step
type: string
inputs:
description: Inputs is the inputs of the step
items:
properties:
from:
type: string
parameterKey:
type: string
required:
- from
- parameterKey
type: object
type: array
meta:
description: Meta is the meta data of the workflow step.
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
outputs:
description: Outputs is the outputs of the step
items:
properties:
name:
type: string
valueFrom:
type: string
required:
- name
- valueFrom
type: object
type: array
properties:
description: Properties is the properties of the step
type: object
timeout:
description: Timeout is the timeout of the step
type: string
type:
description: Type is the type of the workflow step.
type: string
required:
- name
- type
type: object
type: array
timeout:
description: Timeout is the timeout of the step
type: string
type:
description: Type is the type of the workflow step.
type: string
required:
- name
- type
type: object
type: array
type: object
served: true
storage: false
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -6,8 +6,8 @@ e2e-setup-core-pre-hook:
e2e-setup-core-post-hook:
kubectl wait --for=condition=Available deployment/kubevela-vela-core -n vela-system --timeout=180s
helm install kruise https://github.com/openkruise/charts/releases/download/kruise-1.1.0/kruise-1.1.0.tgz --set featureGates="PreDownloadImageForInPlaceUpdate=true" --set daemon.socketLocation=/run/k3s/containerd/
kill -9 $(lsof -it:9098) || true
go run ./e2e/addon/mock &
sleep 15
bin/vela addon enable ./e2e/addon/mock/testdata/fluxcd
bin/vela addon enable ./e2e/addon/mock/testdata/rollout
bin/vela addon enable ./e2e/addon/mock/testdata/terraform
@@ -82,14 +82,9 @@ e2e-api-test:
ginkgo -v -skipPackage capability,setup,application -r e2e
ginkgo -v -r e2e/application
ADDONSERVER = $(shell pgrep vela_addon_mock_server)
.PHONY: e2e-apiserver-test
e2e-apiserver-test:
pkill vela_addon_mock_server || true
go run ./e2e/addon/mock/vela_addon_mock_server.go &
sleep 15
go test -v -coverpkg=./... -coverprofile=/tmp/e2e_apiserver_test.out ./test/e2e-apiserver-test
@$(OK) tests pass

View File

@@ -60,7 +60,6 @@ import (
common2 "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/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/config"
"github.com/oam-dev/kubevela/pkg/cue/script"
"github.com/oam-dev/kubevela/pkg/definition"
@@ -612,7 +611,7 @@ func unmarshalToContent(content []byte) (fileContent *github.RepositoryContent,
}
func genAddonAPISchema(addonRes *UIData) error {
cueScript := script.CUE([]byte(addonRes.Parameters))
cueScript := script.CUE(addonRes.Parameters)
schema, err := cueScript.ParsePropertiesToSchema()
if err != nil {
return err
@@ -932,10 +931,12 @@ type Installer struct {
dryRun bool
dryRunBuff *bytes.Buffer
registries []Registry
}
// NewAddonInstaller will create an installer for addon
func NewAddonInstaller(ctx context.Context, cli client.Client, discoveryClient *discovery.DiscoveryClient, apply apply.Applicator, config *rest.Config, r *Registry, args map[string]interface{}, cache *Cache, opts ...InstallOption) Installer {
func NewAddonInstaller(ctx context.Context, cli client.Client, discoveryClient *discovery.DiscoveryClient, apply apply.Applicator, config *rest.Config, r *Registry, args map[string]interface{}, cache *Cache, registries []Registry, opts ...InstallOption) Installer {
i := Installer{
ctx: ctx,
config: config,
@@ -946,6 +947,7 @@ func NewAddonInstaller(ctx context.Context, cli client.Client, discoveryClient *
cache: cache,
dc: discoveryClient,
dryRunBuff: &bytes.Buffer{},
registries: registries,
}
for _, opt := range opts {
opt(&i)
@@ -1042,16 +1044,41 @@ func (h *Installer) installDependency(addon *InstallPackage) error {
if h.dryRun {
continue
}
// always install addon's latest version
depAddon, err := h.loadInstallPackage(dep.Name, "")
if err != nil {
return err
}
depHandler := *h
depHandler.args = nil
if err = depHandler.enableAddon(depAddon); err != nil {
return errors.Wrap(err, "fail to dispatch dependent addon resource")
var depAddon *InstallPackage
// try to install the dependent addon from the same registry with the current addon
depAddon, err = h.loadInstallPackage(dep.Name, dep.Version)
if err == nil {
if err = depHandler.enableAddon(depAddon); err != nil {
return errors.Wrap(err, "fail to dispatch dependent addon resource")
}
return nil
}
if !errors.Is(err, ErrNotExist) {
return err
}
for _, registry := range h.registries {
// try to install dependent addon from other registries
depHandler.r = &Registry{
Name: registry.Name, Helm: registry.Helm, OSS: registry.OSS, Git: registry.Git, Gitee: registry.Gitee, Gitlab: registry.Gitlab,
}
depAddon, err = depHandler.loadInstallPackage(dep.Name, dep.Version)
if err == nil {
break
}
if errors.Is(err, ErrNotExist) {
continue
}
return err
}
if err == nil {
if err = depHandler.enableAddon(depAddon); err != nil {
return errors.Wrap(err, "fail to dispatch dependent addon resource")
}
return nil
}
return fmt.Errorf("dependency addon: %s with version: %s cannot be found from all registries", dep.Name, dep.Version)
}
if h.dryRun && len(dependencies) > 0 {
klog.Warningf("dry run addon won't install dependencies, please make sure your system has already installed these addons: %v", strings.Join(dependencies, ", "))
@@ -1372,12 +1399,12 @@ func checkSemVer(actual string, require string) (bool, error) {
l := strings.ReplaceAll(require, "v", " ")
constraint, err := semver.NewConstraint(l)
if err != nil {
log.Logger.Errorf("fail to new constraint: %s", err.Error())
klog.Errorf("fail to new constraint: %s", err.Error())
return false, err
}
v, err := semver.NewVersion(semVer)
if err != nil {
log.Logger.Errorf("fail to new version %s: %s", semVer, err.Error())
klog.Errorf("fail to new version %s: %s", semVer, err.Error())
return false, err
}
if constraint.Check(v) {
@@ -1391,7 +1418,7 @@ func checkSemVer(actual string, require string) (bool, error) {
}
v, err := semver.NewVersion(semVer)
if err != nil {
log.Logger.Errorf("fail to new version %s: %s", semVer, err.Error())
klog.Errorf("fail to new version %s: %s", semVer, err.Error())
return false, err
}
if constraint.Check(v) {

View File

@@ -355,7 +355,7 @@ var _ = Describe("func addon update ", func() {
}, time.Millisecond*500, 30*time.Second).Should(BeNil())
pkg := &InstallPackage{Meta: Meta{Name: "test-update", Version: "1.3.0"}}
h := NewAddonInstaller(context.Background(), k8sClient, nil, nil, nil, &Registry{Name: "test"}, nil, nil)
h := NewAddonInstaller(context.Background(), k8sClient, nil, nil, nil, &Registry{Name: "test"}, nil, nil, nil)
h.addon = pkg
Expect(h.dispatchAddonResource(pkg)).Should(BeNil())
@@ -418,7 +418,7 @@ var _ = Describe("test dry-run addon from local dir", func() {
pkg, err := GetInstallPackageFromReader(r, &meta, UIData)
Expect(err).Should(BeNil())
h := NewAddonInstaller(ctx, k8sClient, dc, apply.NewAPIApplicator(k8sClient), cfg, &Registry{Name: LocalAddonRegistryName}, map[string]interface{}{"example": "test-dry-run"}, nil, DryRunAddon)
h := NewAddonInstaller(ctx, k8sClient, dc, apply.NewAPIApplicator(k8sClient), cfg, &Registry{Name: LocalAddonRegistryName}, map[string]interface{}{"example": "test-dry-run"}, nil, nil, DryRunAddon)
err = h.enableAddon(pkg)
Expect(err).Should(BeNil())

View File

@@ -23,7 +23,8 @@ import (
"sync"
"time"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"k8s.io/klog/v2"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/common"
)
@@ -113,7 +114,7 @@ func (u *Cache) GetUIData(r Registry, addonName, version string) (*UIData, error
})
addon, err = versionedRegistry.GetAddonUIData(context.Background(), addonName, version)
if err != nil {
log.Logger.Errorf("fail to get addons from registry %s for cache updating, %v", utils.Sanitize(r.Name), err)
klog.Errorf("fail to get addons from registry %s for cache updating, %v", utils.Sanitize(r.Name), err)
return nil, err
}
}
@@ -278,7 +279,7 @@ func (u *Cache) putVersionedUIData2Cache(registryName, addonName, version string
func (u *Cache) discoverAndRefreshRegistry() {
registries, err := u.ds.ListRegistries(context.Background())
if err != nil {
log.Logger.Errorf("fail to get registry %v", err)
klog.Errorf("fail to get registry %v", err)
return
}
u.putRegistry2Cache(registries)
@@ -301,13 +302,13 @@ func (u *Cache) discoverAndRefreshRegistry() {
func (u *Cache) listUIDataAndCache(r Registry) ([]*UIData, error) {
registryMeta, err := r.ListAddonMeta()
if err != nil {
log.Logger.Errorf("fail to list registry %s metadata, %v", r.Name, err)
klog.Errorf("fail to list registry %s metadata, %v", r.Name, err)
return nil, err
}
u.putAddonMeta2Cache(r.Name, registryMeta)
uiData, err := r.ListUIData(registryMeta, UIMetaOptions)
if err != nil {
log.Logger.Errorf("fail to get addons from registry %s for cache updating, %v", r.Name, err)
klog.Errorf("fail to get addons from registry %s for cache updating, %v", r.Name, err)
return nil, err
}
u.putAddonUIData2Cache(r.Name, uiData)
@@ -322,13 +323,13 @@ func (u *Cache) listVersionRegistryUIDataAndCache(r Registry) ([]*UIData, error)
})
uiDatas, err := versionedRegistry.ListAddon()
if err != nil {
log.Logger.Errorf("fail to get addons from registry %s for cache updating, %v", r.Name, err)
klog.Errorf("fail to get addons from registry %s for cache updating, %v", r.Name, err)
return nil, err
}
for _, addon := range uiDatas {
uiData, err := versionedRegistry.GetAddonUIData(context.Background(), addon.Name, addon.Version)
if err != nil {
log.Logger.Errorf("fail to get addon from versioned registry %s, addon %s version %s for cache updating, %v", r.Name, addon.Name, addon.Version, err)
klog.Errorf("fail to get addon from versioned registry %s, addon %s version %s for cache updating, %v", r.Name, addon.Name, addon.Version, err)
continue
}
u.putVersionedUIData2Cache(r.Name, addon.Name, addon.Version, uiData)

View File

@@ -22,13 +22,13 @@ import (
"fmt"
"path/filepath"
"k8s.io/client-go/discovery"
"k8s.io/klog/v2"
"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
commontypes "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
@@ -55,8 +55,8 @@ const (
)
// EnableAddon will enable addon with dependency check, source is where addon from.
func EnableAddon(ctx context.Context, name string, version string, cli client.Client, discoveryClient *discovery.DiscoveryClient, apply apply.Applicator, config *rest.Config, r Registry, args map[string]interface{}, cache *Cache, opts ...InstallOption) error {
h := NewAddonInstaller(ctx, cli, discoveryClient, apply, config, &r, args, cache, opts...)
func EnableAddon(ctx context.Context, name string, version string, cli client.Client, discoveryClient *discovery.DiscoveryClient, apply apply.Applicator, config *rest.Config, r Registry, args map[string]interface{}, cache *Cache, registries []Registry, opts ...InstallOption) error {
h := NewAddonInstaller(ctx, cli, discoveryClient, apply, config, &r, args, cache, registries, opts...)
pkg, err := h.loadInstallPackage(name, version)
if err != nil {
return err
@@ -83,7 +83,7 @@ func DisableAddon(ctx context.Context, cli client.Client, name string, config *r
return err
}
if len(usingAddonApp) != 0 {
return fmt.Errorf(fmt.Sprintf("%s please delete them first", usingAppsInfo(usingAddonApp)))
return errors.New(appsDependsOnAddonErrInfo(usingAddonApp))
}
}
@@ -113,7 +113,7 @@ func EnableAddonByLocalDir(ctx context.Context, name string, dir string, cli cli
if err != nil {
return err
}
h := NewAddonInstaller(ctx, cli, dc, applicator, config, &Registry{Name: LocalAddonRegistryName}, args, nil, opts...)
h := NewAddonInstaller(ctx, cli, dc, applicator, config, &Registry{Name: LocalAddonRegistryName}, args, nil, nil, opts...)
needEnableAddonNames, err := h.checkDependency(pkg)
if err != nil {
return err

View File

@@ -105,7 +105,8 @@ type DeployTo struct {
// Dependency defines the other addons it depends on
type Dependency struct {
Name string `json:"name,omitempty"`
Name string `json:"name,omitempty"`
Version string `json:"version,omitempty"`
}
// ElementFile can be addon's definition or addon's component

View File

@@ -187,7 +187,7 @@ func findLegacyAddonDefs(ctx context.Context, k8sClient client.Client, addonName
if registry.Name == registryName {
var uiData *UIData
if !IsVersionRegistry(registry) {
installer := NewAddonInstaller(ctx, k8sClient, nil, nil, config, &registries[i], nil, nil)
installer := NewAddonInstaller(ctx, k8sClient, nil, nil, config, &registries[i], nil, nil, nil)
metas, err := installer.getAddonMeta()
if err != nil {
return err
@@ -244,18 +244,18 @@ func findLegacyAddonDefs(ctx context.Context, k8sClient client.Client, addonName
return nil
}
func usingAppsInfo(apps []v1beta1.Application) string {
res := "addon is being used :"
appsNamespaceNameList := map[string][]string{}
func appsDependsOnAddonErrInfo(apps []v1beta1.Application) string {
var appsNamespaceNameList []string
i := 0
for _, app := range apps {
appsNamespaceNameList[app.GetNamespace()] = append(appsNamespaceNameList[app.GetNamespace()], app.GetName())
appsNamespaceNameList = append(appsNamespaceNameList, app.Namespace+"/"+app.Name)
i++
if i > 2 && len(apps) > i {
appsNamespaceNameList = append(appsNamespaceNameList, fmt.Sprintf("and other %d more", len(apps)-i))
break
}
}
for namespace, appNames := range appsNamespaceNameList {
nameStr := strings.Join(appNames, ",")
res += fmt.Sprintf("{%s} in namespace:%s,", nameStr, namespace)
}
res = strings.TrimSuffix(res, ",") + ".Please delete them before disabling the addon."
return res
return fmt.Sprintf("this addon is being used by: %s applications. Please delete all of them before removing.", strings.Join(appsNamespaceNameList, ", "))
}
// IsVersionRegistry check the repo source if support multi-version addon
@@ -502,3 +502,17 @@ func checkBondComponentExist(u unstructured.Unstructured, app v1beta1.Applicatio
}
return false
}
// FilterDependencyRegistries will return all registries besides the target registry itself
func FilterDependencyRegistries(i int, rs []Registry) []Registry {
if i >= len(rs) {
return rs
}
if i < 0 {
return rs
}
ret := make([]Registry, len(rs)-1)
copy(ret, rs[:i])
copy(ret[i:], rs[i+1:])
return ret
}

View File

@@ -155,9 +155,31 @@ func TestUsingAddonInfo(t *testing.T) {
v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-1", Name: "app-1"}},
v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-2", Name: "app-2"}},
v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-1", Name: "app-3"}},
v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-3", Name: "app-3"}},
}
res := usingAppsInfo(apps)
assert.Equal(t, true, strings.Contains(res, "Please delete them before disabling the addon"))
res := appsDependsOnAddonErrInfo(apps)
assert.Contains(t, res, "and other 1 more applications. Please delete all of them before removing.")
apps = []v1beta1.Application{
v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-1", Name: "app-1"}},
v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-2", Name: "app-2"}},
v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-1", Name: "app-3"}},
}
res = appsDependsOnAddonErrInfo(apps)
assert.Contains(t, res, "Please delete all of them before removing.")
apps = []v1beta1.Application{
v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-1", Name: "app-1"}},
}
res = appsDependsOnAddonErrInfo(apps)
assert.Contains(t, res, "this addon is being used by: namespace-1/app-1 applications. Please delete all of them before removing.")
apps = []v1beta1.Application{
v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-1", Name: "app-1"}},
v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "namespace-2", Name: "app-2"}},
}
res = appsDependsOnAddonErrInfo(apps)
assert.Contains(t, res, ". Please delete all of them before removing.")
}
func TestIsAddonDir(t *testing.T) {
@@ -329,6 +351,57 @@ func TestCheckObjectBindingComponent(t *testing.T) {
}
}
func TestFilterDependencyRegistries(t *testing.T) {
testCases := []struct {
registries []Registry
index int
res []Registry
origin []Registry
}{
{
registries: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
index: 0,
res: []Registry{{Name: "r2"}, {Name: "r3"}},
origin: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
},
{
registries: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
index: 1,
res: []Registry{{Name: "r1"}, {Name: "r3"}},
origin: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
},
{
registries: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
index: 2,
res: []Registry{{Name: "r1"}, {Name: "r2"}},
origin: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
},
{
registries: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
index: 3,
res: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
origin: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
},
{
registries: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
index: -1,
res: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
origin: []Registry{{Name: "r1"}, {Name: "r2"}, {Name: "r3"}},
},
{
registries: []Registry{},
index: 0,
res: []Registry{},
origin: []Registry{},
},
}
for _, testCase := range testCases {
res := FilterDependencyRegistries(testCase.index, testCase.registries)
assert.Equal(t, res, testCase.res)
assert.Equal(t, testCase.registries, testCase.origin)
}
}
const (
compDefYaml = `
apiVersion: core.oam.dev/v1beta1

View File

@@ -23,10 +23,11 @@ import (
"sort"
"github.com/Masterminds/semver/v3"
"github.com/pkg/errors"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/repo"
"k8s.io/klog/v2"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/oam-dev/kubevela/pkg/utils/helm"
@@ -146,8 +147,9 @@ func (i versionedRegistry) loadAddon(ctx context.Context, name, version string)
sort.Sort(sort.Reverse(versions))
addonVersion, availableVersions := chooseVersion(version, versions)
if addonVersion == nil {
return nil, fmt.Errorf("specified version %s not exist", version)
return nil, errors.Errorf("specified version %s not exist", utils.Sanitize(version))
}
klog.Infof("Addon '%s' with version '%s' found from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
for _, chartURL := range addonVersion.URLs {
if !utils.IsValidURL(chartURL) {
chartURL, err = utils.JoinURL(i.url, chartURL)
@@ -172,7 +174,7 @@ func (i versionedRegistry) loadAddon(ctx context.Context, name, version string)
addonPkg.Meta.SystemRequirements = LoadSystemRequirements(addonVersion.Annotations)
return addonPkg, nil
}
return nil, fmt.Errorf("cannot fetch addon package")
return nil, fmt.Errorf("cannot load addon '%s'(%s) package from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
}
// loadAddonVersions Load all available versions of the addon
@@ -233,7 +235,6 @@ func chooseVersion(specifiedVersion string, versions []*repo.ChartVersion) (*rep
continue
}
addonVersion = v
log.Logger.Infof("Use the latest version %s by default, you can use --version to specify", v.Version)
}
}
return addonVersion, availableVersions

View File

@@ -247,6 +247,9 @@ var RevisionStatusTerminated = "terminated"
// RevisionStatusRollback event status rollback
var RevisionStatusRollback = "rollback"
// WorkflowStepPhaseStopped is the stopped phase
var WorkflowStepPhaseStopped workflowv1alpha1.WorkflowStepPhase = "stopped"
// ApplicationRevision be created when an application initiates deployment and describes the phased version of the application.
type ApplicationRevision struct {
BaseModel
@@ -383,6 +386,7 @@ type ApplicationTrigger struct {
Type string `json:"type"`
PayloadType string `json:"payloadType"`
ComponentName string `json:"componentName"`
Registry string `json:"registry,omitempty"`
}
const (

View File

@@ -23,9 +23,8 @@ import (
"time"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog/v2"
"sigs.k8s.io/yaml"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
)
var tableNamePrefix = "vela_"
@@ -102,7 +101,7 @@ func NewJSONStructByStruct(object interface{}) (*JSONStruct, error) {
func (j *JSONStruct) JSON() string {
b, err := json.Marshal(j)
if err != nil {
log.Logger.Errorf("json marshal failure %s", err.Error())
klog.Errorf("json marshal failure %s", err.Error())
}
return string(b)
}
@@ -111,12 +110,12 @@ func (j *JSONStruct) JSON() string {
func (j *JSONStruct) RawExtension() *runtime.RawExtension {
yamlByte, err := yaml.Marshal(j)
if err != nil {
log.Logger.Errorf("yaml marshal failure %s", err.Error())
klog.Errorf("yaml marshal failure %s", err.Error())
return nil
}
b, err := yaml.YAMLToJSON(yamlByte)
if err != nil {
log.Logger.Errorf("yaml to json failure %s", err.Error())
klog.Errorf("yaml to json failure %s", err.Error())
return nil
}
return &runtime.RawExtension{Raw: b}

View File

@@ -16,10 +16,60 @@ limitations under the License.
package model
import "fmt"
import (
"fmt"
"github.com/kubevela/workflow/api/v1alpha1"
)
func init() {
RegisterModel(&PipelineContext{})
RegisterModel(&Pipeline{})
}
// Structs copied from workflow/api/v1alpha1/types.go
// WorkflowSpec defines workflow steps and other attributes
type WorkflowSpec struct {
Mode *v1alpha1.WorkflowExecuteMode `json:"mode,omitempty"`
Steps []WorkflowStep `json:"steps,omitempty"`
}
// Pipeline is the model of pipeline
type Pipeline struct {
BaseModel
Spec WorkflowSpec
Name string `json:"name"`
Project string `json:"project"`
Alias string `json:"alias"`
Description string `json:"description"`
}
// PrimaryKey return custom primary key
func (p Pipeline) PrimaryKey() string {
return fmt.Sprintf("%s-%s", p.Project, p.Name)
}
// TableName return custom table name
func (p Pipeline) TableName() string {
return tableNamePrefix + "pipeline"
}
// ShortTableName is the compressed version of table name for kubeapi storage and others
func (p Pipeline) ShortTableName() string {
return "pipeline"
}
// Index return custom index
func (p Pipeline) Index() map[string]string {
var index = make(map[string]string)
if p.Project != "" {
index["project"] = p.Project
}
if p.Name != "" {
index["name"] = p.Name
}
return index
}
// Value is a k-v pair

View File

@@ -16,8 +16,6 @@ limitations under the License.
package model
import "fmt"
func init() {
RegisterModel(&Project{})
}
@@ -29,11 +27,15 @@ type Project struct {
Alias string `json:"alias"`
Owner string `json:"owner"`
Description string `json:"description,omitempty"`
Namespace string `json:"namespace"`
}
// GetNamespace get the namespace name of this project.
func (p *Project) GetNamespace() string {
return fmt.Sprintf("project-%s", p.Name)
if p.Namespace != "" {
return p.Namespace
}
return p.Name
}
// TableName return custom table name

View File

@@ -50,16 +50,25 @@ type Workflow struct {
// WorkflowStep defines how to execute a workflow step.
type WorkflowStep struct {
WorkflowStepBase `json:",inline"`
SubSteps []WorkflowStepBase `json:"subSteps,omitempty"`
}
// WorkflowStepBase is the step base of workflow
type WorkflowStepBase struct {
// Name is the unique name of the workflow step.
Name string `json:"name"`
Alias string `json:"alias"`
Type string `json:"type"`
Description string `json:"description"`
OrderIndex int `json:"orderIndex"`
Inputs workflowv1alpha1.StepInputs `json:"inputs,omitempty"`
Outputs workflowv1alpha1.StepOutputs `json:"outputs,omitempty"`
DependsOn []string `json:"dependsOn"`
Properties *JSONStruct `json:"properties,omitempty"`
Name string `json:"name"`
Alias string `json:"alias"`
Type string `json:"type"`
Description string `json:"description"`
OrderIndex int `json:"orderIndex"`
Inputs workflowv1alpha1.StepInputs `json:"inputs,omitempty"`
Outputs workflowv1alpha1.StepOutputs `json:"outputs,omitempty"`
DependsOn []string `json:"dependsOn"`
Properties *JSONStruct `json:"properties,omitempty"`
Meta *workflowv1alpha1.WorkflowStepMeta `json:"meta,omitempty"`
If string `json:"if,omitempty"`
Timeout string `json:"timeout,omitempty"`
}
// TableName return custom table name
@@ -114,6 +123,12 @@ type WorkflowRecord struct {
// WorkflowStepStatus is the workflow step status database model
type WorkflowStepStatus struct {
StepStatus `json:",inline"`
SubStepsStatus []StepStatus `json:"subSteps,omitempty"`
}
// StepStatus is the workflow step status database model
type StepStatus struct {
ID string `json:"id"`
Name string `json:"name"`
Alias string `json:"alias"`

View File

@@ -20,10 +20,12 @@ import (
"context"
"errors"
"k8s.io/klog/v2"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/utils"
)
// ListApplicationPolicies query the application policies
@@ -83,14 +85,14 @@ func ListApplicationCommonPolicies(ctx context.Context, store datastore.DataStor
// DeleteApplicationEnvPolicies delete the policies via app name and env name
func DeleteApplicationEnvPolicies(ctx context.Context, store datastore.DataStore, app *model.Application, envName string) error {
log.Logger.Debugf("clear the policies via app name %s and env name %s", app.PrimaryKey(), envName)
klog.Infof("clear the policies via app name %s and env name %s", app.PrimaryKey(), utils.Sanitize(envName))
policies, err := ListApplicationEnvPolicies(ctx, store, app, envName)
if err != nil {
return err
}
for _, policy := range policies {
if err := store.Delete(ctx, policy); err != nil && !errors.Is(err, datastore.ErrRecordNotExist) {
log.Logger.Errorf("fail to clear the policies belong to the env %w", err)
klog.Errorf("fail to clear the policies belong to the env %w", err)
continue
}
}

View File

@@ -20,12 +20,12 @@ import (
"context"
"errors"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/oam"
util "github.com/oam-dev/kubevela/pkg/utils"
velaerr "github.com/oam-dev/kubevela/pkg/utils/errors"
@@ -38,7 +38,7 @@ func CreateEnv(ctx context.Context, kubeClient client.Client, ds datastore.DataS
exist, err := ds.IsExist(ctx, tenv)
if err != nil {
log.Logger.Errorf("check if env name exists failure %s", err.Error())
klog.Errorf("check if env name exists failure %s", err.Error())
return err
}
if exist {
@@ -59,7 +59,7 @@ func CreateEnv(ctx context.Context, kubeClient client.Client, ds datastore.DataS
if velaerr.IsLabelConflict(err) {
return bcode.ErrEnvNamespaceAlreadyBound
}
log.Logger.Errorf("update namespace label failure %s", err.Error())
klog.Errorf("update namespace label failure %s", err.Error())
return bcode.ErrEnvNamespaceFail
}
if err = ds.Add(ctx, env); err != nil {

View File

@@ -19,12 +19,13 @@ package repository
import (
"context"
"k8s.io/klog/v2"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
assembler "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/assembler/v1"
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
)
const (
@@ -70,7 +71,7 @@ func ListFullEnvBinding(ctx context.Context, ds datastore.DataStore, option EnvL
for _, eb := range envBindings {
env, err := pickEnv(envs, eb.Name)
if err != nil {
log.Logger.Errorf("envbinding invalid %s", err.Error())
klog.Errorf("envbinding invalid %s", err.Error())
continue
}
list = append(list, assembler.ConvertEnvBindingModelToBase(eb, env, targets))

View File

@@ -20,12 +20,12 @@ import (
"context"
apierror "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/utils"
@@ -43,7 +43,7 @@ func CreateTargetNamespace(ctx context.Context, k8sClient client.Client, cluster
oam.LabelNamespaceOfTargetName: targetName,
}))
if velaerr.IsLabelConflict(err) {
log.Logger.Errorf("update namespace for target err %v", err)
klog.Errorf("update namespace for target err %v", err)
return bcode.ErrTargetNamespaceAlreadyBound
}
if err != nil {
@@ -74,7 +74,7 @@ func CreateTarget(ctx context.Context, ds datastore.DataStore, tg *model.Target)
// check Target name.
exit, err := ds.IsExist(ctx, tg)
if err != nil {
log.Logger.Errorf("check target existence failure %s", err.Error())
klog.Errorf("check target existence failure %s", err.Error())
return err
}
if exit {
@@ -82,7 +82,7 @@ func CreateTarget(ctx context.Context, ds datastore.DataStore, tg *model.Target)
}
if err = ds.Add(ctx, tg); err != nil {
log.Logger.Errorf("add target failure %s", err.Error())
klog.Errorf("add target failure %s", err.Error())
return err
}
return nil
@@ -99,7 +99,7 @@ func ListTarget(ctx context.Context, ds datastore.DataStore, project string, dsO
}
Targets, err := ds.List(ctx, &target, dsOption)
if err != nil {
log.Logger.Errorf("list target err %v", err)
klog.Errorf("list target err %v", err)
return nil, err
}
var respTargets []*model.Target

View File

@@ -25,6 +25,7 @@ import (
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
k8stypes "k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
@@ -32,10 +33,10 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/event/sync/convert"
"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"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/oam/util"
pkgUtils "github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/workflow/step"
@@ -369,20 +370,20 @@ func UpdateEnvWorkflow(ctx context.Context, kubeClient client.Client, ds datasto
created, updated, deleted := workflowSteps.getPolicies(existPolicies, policies)
for _, d := range deleted {
if err := ds.Delete(ctx, d); err != nil {
log.Logger.Errorf("fail to delete the policy %s", err.Error())
klog.Errorf("fail to delete the policy %s", err.Error())
}
log.Logger.Infof("deleted a policy %s where update the workflow", d.PrimaryKey())
klog.Infof("deleted a policy %s where update the workflow", d.PrimaryKey())
}
if err := ds.BatchAdd(ctx, created); err != nil {
log.Logger.Errorf("fail to create the policy %s", err.Error())
klog.Errorf("fail to create the policy %s", err.Error())
}
for _, d := range updated {
if err := ds.Put(ctx, d); err != nil {
log.Logger.Errorf("fail to update the policy %s", err.Error())
klog.Errorf("fail to update the policy %s", err.Error())
}
log.Logger.Infof("updated a policy %s where update the workflow", d.PrimaryKey())
klog.Infof("updated a policy %s where update the workflow", d.PrimaryKey())
}
return nil
@@ -416,10 +417,10 @@ func UpdateAppEnvWorkflow(ctx context.Context, kubeClient client.Client, ds data
}
for i := range envs {
if err := UpdateEnvWorkflow(ctx, kubeClient, ds, app, envs[i]); err != nil {
log.Logger.Errorf("fail to update the env workflow %s", envs[i].PrimaryKey())
klog.Errorf("fail to update the env workflow %s", envs[i].PrimaryKey())
}
}
log.Logger.Infof("The env workflows of app %s updated successfully", pkgUtils.Sanitize(app.PrimaryKey()))
klog.Infof("The env workflows of app %s updated successfully", pkgUtils.Sanitize(app.PrimaryKey()))
return nil
}
@@ -437,7 +438,7 @@ func HaveTerraformWorkload(ctx context.Context, kubeClient client.Client, compon
getComponentDeployType := func(component *model.ApplicationComponent) string {
definition, err := GetComponentDefinition(ctx, kubeClient, component.Type)
if err != nil {
log.Logger.Errorf("get component definition %s failure %s", component.Type, err.Error())
klog.Errorf("get component definition %s failure %s", component.Type, err.Error())
// using Deploy2Env by default
}
if definition != nil {
@@ -507,7 +508,7 @@ func GenEnvWorkflowStepsAndPolicies(ctx context.Context, kubeClient client.Clien
var policies []datastore.Entity
components, err := ds.List(ctx, &model.ApplicationComponent{AppPrimaryKey: app.PrimaryKey()}, nil)
if err != nil {
log.Logger.Errorf("list application component list failure %s", err.Error())
klog.Errorf("list application component list failure %s", err.Error())
}
userName, _ := ctx.Value(&apisv1.CtxKeyUser).(string)
terraformComponents := HaveTerraformWorkload(ctx, kubeClient, components)
@@ -520,7 +521,7 @@ func GenEnvWorkflowStepsAndPolicies(ctx context.Context, kubeClient client.Clien
}},
}})
if err != nil {
log.Logger.Errorf("fail to get the targets detail info, %s", err.Error())
klog.Errorf("fail to get the targets detail info, %s", err.Error())
}
if len(terraformComponents) > 0 {
appPolicy := &model.ApplicationPolicy{
@@ -552,7 +553,7 @@ func GenEnvWorkflowStepsAndPolicies(ctx context.Context, kubeClient client.Clien
Envs: envs,
})
if err != nil {
log.Logger.Errorf("fail to create the properties of the topology policy, %s", err.Error())
klog.Errorf("fail to create the properties of the topology policy, %s", err.Error())
} else {
appPolicy.Properties = properties
policies = append(policies, appPolicy)
@@ -590,7 +591,7 @@ func GenEnvWorkflowStepsAndPolicies(ctx context.Context, kubeClient client.Clien
Namespace: target.Cluster.Namespace,
})
if err != nil {
log.Logger.Errorf("fail to create the properties of the topology policy, %s", err.Error())
klog.Errorf("fail to create the properties of the topology policy, %s", err.Error())
continue
}
appPolicy.Properties = properties
@@ -599,25 +600,20 @@ func GenEnvWorkflowStepsAndPolicies(ctx context.Context, kubeClient client.Clien
}
var steps []model.WorkflowStep
for _, step := range workflowSteps {
base, err := convert.FromCRWorkflowStepBase(step.WorkflowStepBase)
if err != nil {
klog.Errorf("workflow %s step %s properties is invalid %s", pkgUtils.Sanitize(app.Name), pkgUtils.Sanitize(step.Name), err.Error())
continue
}
targetName := strings.Replace(step.Name, "-cloud-resource", "", 1)
s := model.WorkflowStep{
Name: step.Name,
Type: step.Type,
Alias: fmt.Sprintf("Deploy To %s", targetName),
Description: fmt.Sprintf("deploy app to delivery target %s", targetName),
DependsOn: step.DependsOn,
Inputs: step.Inputs,
Outputs: step.Outputs,
base.Alias = fmt.Sprintf("Deploy To %s", targetName)
base.Description = fmt.Sprintf("deploy app to delivery target %s", targetName)
ws := model.WorkflowStep{
WorkflowStepBase: *base,
SubSteps: make([]model.WorkflowStepBase, 0),
}
if step.Properties != nil {
properties, err := model.NewJSONStruct(step.Properties)
if err != nil {
log.Logger.Errorf("workflow %s step %s properties is invalid %s", pkgUtils.Sanitize(app.Name), pkgUtils.Sanitize(step.Name), err.Error())
continue
}
s.Properties = properties
}
steps = append(steps, s)
// no sub steps handle here
steps = append(steps, ws)
}
return steps, policies
}

View File

@@ -25,6 +25,7 @@ import (
. "github.com/onsi/gomega"
"github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
@@ -33,61 +34,76 @@ import (
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
pkgUtils "github.com/oam-dev/kubevela/pkg/utils"
)
func TestCompareWorkflowSteps(t *testing.T) {
existSteps := []model.WorkflowStep{
{
Name: "step1",
Type: "deploy2env",
Properties: &model.JSONStruct{
"policy": "env-policy",
"env": "target1",
WorkflowStepBase: model.WorkflowStepBase{
Name: "step1",
Type: "deploy2env",
Properties: &model.JSONStruct{
"policy": "env-policy",
"env": "target1",
},
},
},
{
Name: "suspend",
Type: "suspend",
},
{
Name: "step2",
Type: "deploy2env",
Properties: &model.JSONStruct{
"policy": "env-policy",
"env": "target2",
WorkflowStepBase: model.WorkflowStepBase{
Name: "suspend",
Type: "suspend",
},
},
{
Name: "step3",
Type: "deploy2env",
Properties: &model.JSONStruct{
"policy": "env-policy",
"env": "target3",
WorkflowStepBase: model.WorkflowStepBase{
Name: "step2",
Type: "deploy2env",
Properties: &model.JSONStruct{
"policy": "env-policy",
"env": "target2",
},
},
},
{
Name: "notify",
Type: "notify",
Properties: &model.JSONStruct{"message": "dddd"},
WorkflowStepBase: model.WorkflowStepBase{
Name: "step3",
Type: "deploy2env",
Properties: &model.JSONStruct{
"policy": "env-policy",
"env": "target3",
},
},
},
{
WorkflowStepBase: model.WorkflowStepBase{
Name: "notify",
Type: "notify",
Properties: &model.JSONStruct{"message": "dddd"},
},
},
}
newSteps := []model.WorkflowStep{
{
Name: "step1",
Type: "deploy",
Properties: &model.JSONStruct{"policies": []string{"target1"}},
WorkflowStepBase: model.WorkflowStepBase{
Name: "step1",
Type: "deploy",
Properties: &model.JSONStruct{"policies": []string{"target1"}},
},
},
{
Name: "step2",
Type: "deploy",
Properties: &model.JSONStruct{"policies": []string{"target2"}},
WorkflowStepBase: model.WorkflowStepBase{
Name: "step2",
Type: "deploy",
Properties: &model.JSONStruct{"policies": []string{"target2"}},
},
},
{
Name: "step4",
Type: "deploy",
Properties: &model.JSONStruct{"policies": []string{"target4"}},
WorkflowStepBase: model.WorkflowStepBase{
Name: "step4",
Type: "deploy",
Properties: &model.JSONStruct{"policies": []string{"target4"}},
},
},
}
exist := createWorkflowSteps(existSteps, []datastore.Entity{
@@ -368,11 +384,15 @@ var _ = Describe("Test workflow model", func() {
workflow.Steps = []model.WorkflowStep{
workflow.Steps[0], {
Type: "suspend",
Name: "suspend",
WorkflowStepBase: model.WorkflowStepBase{
Type: "suspend",
Name: "suspend",
},
}, workflow.Steps[1], {
Type: "notification",
Name: "notification",
WorkflowStepBase: model.WorkflowStepBase{
Type: "notification",
Name: "notification",
},
},
}
@@ -543,7 +563,7 @@ func CreateEnvWorkflow(ctx context.Context, store datastore.DataStore, kubeClien
EnvName: env.Name,
AppPrimaryKey: app.PrimaryKey(),
}
log.Logger.Infof("create workflow %s for app %s", pkgUtils.Sanitize(workflow.Name), pkgUtils.Sanitize(app.PrimaryKey()))
klog.Infof("create workflow %s for app %s", pkgUtils.Sanitize(workflow.Name), pkgUtils.Sanitize(app.PrimaryKey()))
if err := store.Add(ctx, workflow); err != nil {
return err
}

View File

@@ -34,6 +34,7 @@ import (
k8stypes "k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
common2 "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
@@ -44,7 +45,6 @@ import (
apis "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/definition"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam"
@@ -206,7 +206,7 @@ func (u *addonServiceImpl) StatusAddon(ctx context.Context, name string) (*apis.
var allClusters []apis.NameAlias
clusters, err := multicluster.ListVirtualClusters(ctx, u.kubeClient)
if err != nil {
log.Logger.Errorf("err while list all clusters: %v", err)
klog.Errorf("err while list all clusters: %v", err)
}
for _, c := range clusters {
@@ -302,7 +302,7 @@ func (u *addonServiceImpl) ListAddons(ctx context.Context, registry, query strin
for _, a := range addons {
addonRes, err := AddonImpl2AddonRes(a, u.config)
if err != nil {
log.Logger.Errorf("err while converting AddonImpl to DetailAddonResponse: %v", err)
klog.Errorf("err while converting AddonImpl to DetailAddonResponse: %v", err)
continue
}
addonResources = append(addonResources, addonRes)
@@ -400,8 +400,22 @@ func (u *addonServiceImpl) EnableAddon(ctx context.Context, name string, args ap
if err != nil {
return err
}
for _, r := range registries {
err = pkgaddon.EnableAddon(ctx, name, args.Version, u.kubeClient, u.discoveryClient, u.apply, u.config, r, args.Args, u.addonRegistryCache)
if len(args.RegistryName) != 0 {
foundRegistry := false
for _, registry := range registries {
if registry.Name == args.RegistryName {
foundRegistry = true
}
}
if !foundRegistry {
return bcode.ErrAddonRegistryNotExist.SetMessage(fmt.Sprintf("specified registry %s not exist", args.RegistryName))
}
}
for i, r := range registries {
if len(args.RegistryName) != 0 && args.RegistryName != r.Name {
continue
}
err = pkgaddon.EnableAddon(ctx, name, args.Version, u.kubeClient, u.discoveryClient, u.apply, u.config, r, args.Args, u.addonRegistryCache, pkgaddon.FilterDependencyRegistries(i, registries))
if err == nil {
return nil
}
@@ -412,14 +426,12 @@ func (u *addonServiceImpl) EnableAddon(ctx context.Context, name string, args ap
continue
}
if strings.Contains(err.Error(), "specified version") {
berr := bcode.ErrAddonInvalidVersion
berr.Message = err.Error()
return berr
return bcode.ErrAddonInvalidVersion.SetMessage(err.Error())
}
// wrap this error with special bcode
if errors.As(err, &pkgaddon.VersionUnMatchError{}) {
return bcode.ErrAddonSystemVersionMismatch
return bcode.ErrAddonSystemVersionMismatch.SetMessage(err.Error())
}
// except `addon not found`, other errors should return directly
return err
@@ -430,7 +442,7 @@ func (u *addonServiceImpl) EnableAddon(ctx context.Context, name string, args ap
func (u *addonServiceImpl) DisableAddon(ctx context.Context, name string, force bool) error {
err := pkgaddon.DisableAddon(ctx, u.kubeClient, name, u.config, force)
if err != nil {
log.Logger.Errorf("delete application fail: %s", err.Error())
klog.Errorf("delete application fail: %s", err.Error())
return err
}
return nil
@@ -473,8 +485,8 @@ func (u *addonServiceImpl) UpdateAddon(ctx context.Context, name string, args ap
return err
}
for _, r := range registries {
err = pkgaddon.EnableAddon(ctx, name, args.Version, u.kubeClient, u.discoveryClient, u.apply, u.config, r, args.Args, u.addonRegistryCache)
for i, r := range registries {
err = pkgaddon.EnableAddon(ctx, name, args.Version, u.kubeClient, u.discoveryClient, u.apply, u.config, r, args.Args, u.addonRegistryCache, pkgaddon.FilterDependencyRegistries(i, registries))
if err == nil {
return nil
}
@@ -543,7 +555,7 @@ func renderAddonCustomUISchema(ctx context.Context, cli client.Client, addonName
Name: fmt.Sprintf("addon-uischema-%s", addonName),
}, &cm); err != nil {
if !errors2.IsNotFound(err) {
log.Logger.Errorf("find uischema configmap from cluster failure %s", err.Error())
klog.Errorf("find uischema configmap from cluster failure %s", err.Error())
}
return defaultSchema
}
@@ -553,7 +565,7 @@ func renderAddonCustomUISchema(ctx context.Context, cli client.Client, addonName
}
schema := []*utils.UIParameter{}
if err := json.Unmarshal([]byte(data), &schema); err != nil {
log.Logger.Errorf("unmarshal ui schema failure %s", err.Error())
klog.Errorf("unmarshal ui schema failure %s", err.Error())
return defaultSchema
}
return patchSchema(defaultSchema, schema)

View File

@@ -33,6 +33,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
@@ -47,7 +48,6 @@ import (
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/appfile/dryrun"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
@@ -126,7 +126,7 @@ func listApp(ctx context.Context, ds datastore.DataStore, listOptions apisv1.Lis
if listOptions.Env != "" || listOptions.TargetName != "" {
envBinding, err = repository.ListFullEnvBinding(ctx, ds, repository.EnvListOption{})
if err != nil {
log.Logger.Errorf("list envbinding for list application in env %s err %v", pkgUtils.Sanitize(listOptions.Env), err)
klog.Errorf("list envbinding for list application in env %s err %v", pkgUtils.Sanitize(listOptions.Env), err)
return nil, err
}
}
@@ -359,7 +359,7 @@ func (c *applicationServiceImpl) CreateApplication(ctx context.Context, req apis
// check app name.
exist, err := c.Store.IsExist(ctx, &application)
if err != nil {
log.Logger.Errorf("check application name is exist failure %s", err.Error())
klog.Errorf("check application name is exist failure %s", err.Error())
return nil, bcode.ErrApplicationExist
}
if exist {
@@ -418,10 +418,11 @@ func (c *applicationServiceImpl) CreateApplicationTrigger(ctx context.Context, a
Type: req.Type,
PayloadType: req.PayloadType,
ComponentName: req.ComponentName,
Registry: req.Registry,
Token: genWebhookToken(),
}
if err := c.Store.Add(ctx, trigger); err != nil {
log.Logger.Errorf("failed to create application trigger, %s", err.Error())
klog.Errorf("failed to create application trigger, %s", err.Error())
return nil, err
}
@@ -449,7 +450,7 @@ func (c *applicationServiceImpl) DeleteApplicationTrigger(ctx context.Context, a
if errors.Is(err, datastore.ErrRecordNotExist) {
return bcode.ErrApplicationTriggerNotExist
}
log.Logger.Warnf("delete app trigger failure %s", err.Error())
klog.Warningf("delete app trigger failure %s", err.Error())
return err
}
return nil
@@ -464,7 +465,7 @@ func (c *applicationServiceImpl) ListApplicationTriggers(ctx context.Context, ap
SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}}},
)
if err != nil {
log.Logger.Errorf("failed to list application triggers, %s", err.Error())
klog.Errorf("failed to list application triggers, %s", err.Error())
return nil, err
}
@@ -604,7 +605,7 @@ func (c *applicationServiceImpl) DetailComponent(ctx context.Context, app *model
}
var cd v1beta1.ComponentDefinition
if err := c.KubeClient.Get(ctx, types.NamespacedName{Name: component.Type, Namespace: velatypes.DefaultKubeVelaNS}, &cd); err != nil {
log.Logger.Warnf("component definition %s get failure. %s", pkgUtils.Sanitize(component.Type), err.Error())
klog.Warningf("component definition %s get failure. %s", pkgUtils.Sanitize(component.Type), err.Error())
}
return &apisv1.DetailComponentResponse{
@@ -680,7 +681,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
list, err := c.Store.List(ctx, &lastVersion, &datastore.ListOptions{
PageSize: 1, Page: 1, SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}}})
if err != nil && !errors.Is(err, datastore.ErrRecordNotExist) {
log.Logger.Errorf("query app latest revision failure %s", err.Error())
klog.Errorf("query app latest revision failure %s", err.Error())
return nil, bcode.ErrDeployConflict
}
if len(list) > 0 {
@@ -698,7 +699,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
status = revision.Status
}
if status != model.RevisionStatusComplete && status != model.RevisionStatusTerminated {
log.Logger.Warnf("last app revision can not complete %s/%s", list[0].(*model.ApplicationRevision).AppPrimaryKey, list[0].(*model.ApplicationRevision).Version)
klog.Warningf("last app revision can not complete %s/%s", list[0].(*model.ApplicationRevision).AppPrimaryKey, list[0].(*model.ApplicationRevision).Version)
return nil, bcode.ErrDeployConflict
}
}
@@ -726,7 +727,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
if err := c.KubeClient.Get(ctx, types.NamespacedName{Name: oamApp.Namespace}, &namespace); apierrors.IsNotFound(err) {
namespace.Name = oamApp.Namespace
if err := c.KubeClient.Create(ctx, &namespace); err != nil {
log.Logger.Errorf("auto create namespace failure %s", err.Error())
klog.Errorf("auto create namespace failure %s", err.Error())
return nil, bcode.ErrCreateNamespace
}
}
@@ -736,22 +737,22 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
appRevision.Status = model.RevisionStatusFail
appRevision.Reason = err.Error()
if err := c.Store.Put(ctx, appRevision); err != nil {
log.Logger.Warnf("update deploy event failure %s", err.Error())
klog.Warningf("update deploy event failure %s", err.Error())
}
log.Logger.Errorf("deploy app %s failure %s", app.PrimaryKey(), err.Error())
klog.Errorf("deploy app %s failure %s", app.PrimaryKey(), err.Error())
return nil, bcode.ErrDeployApplyFail
}
// step5: create workflow record
if err := c.WorkflowService.CreateWorkflowRecord(ctx, app, oamApp, workflow); err != nil {
log.Logger.Warnf("create workflow record failure %s", err.Error())
klog.Warningf("create workflow record failure %s", err.Error())
}
// step6: update app revision status
appRevision.Status = model.RevisionStatusRunning
if err := c.Store.Put(ctx, appRevision); err != nil {
log.Logger.Warnf("update app revision failure %s", err.Error())
klog.Warningf("update app revision failure %s", err.Error())
}
// step7: change the source of trust
@@ -760,7 +761,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
}
app.Labels[model.LabelSourceOfTruth] = model.FromUX
if err := c.Store.Put(ctx, app); err != nil {
log.Logger.Warnf("failed to update app %s", err.Error())
klog.Warningf("failed to update app %s", err.Error())
}
return &apisv1.ApplicationDeployResponse{
@@ -963,38 +964,38 @@ func (c *applicationServiceImpl) DeleteApplication(ctx context.Context, app *mod
// delete workflow
if err := c.WorkflowService.DeleteWorkflowByApp(ctx, app); err != nil && !errors.Is(err, bcode.ErrWorkflowNotExist) {
log.Logger.Errorf("delete workflow %s failure %s", app.Name, err.Error())
klog.Errorf("delete workflow %s failure %s", app.Name, err.Error())
}
for _, component := range components {
err := c.Store.Delete(ctx, &model.ApplicationComponent{AppPrimaryKey: app.PrimaryKey(), Name: component.Name})
if err != nil && !errors.Is(err, datastore.ErrRecordNotExist) {
log.Logger.Errorf("delete component %s in app %s failure %s", component.Name, app.Name, err.Error())
klog.Errorf("delete component %s in app %s failure %s", component.Name, app.Name, err.Error())
}
}
for _, policy := range policies {
err := c.Store.Delete(ctx, &model.ApplicationPolicy{AppPrimaryKey: app.PrimaryKey(), Name: policy.Name})
if err != nil && errors.Is(err, datastore.ErrRecordNotExist) {
log.Logger.Errorf("delete policy %s in app %s failure %s", policy.Name, app.Name, err.Error())
klog.Errorf("delete policy %s in app %s failure %s", policy.Name, app.Name, err.Error())
}
}
for _, entity := range revisions {
revision := entity.(*model.ApplicationRevision)
if err := c.Store.Delete(ctx, &model.ApplicationRevision{AppPrimaryKey: app.PrimaryKey(), Version: revision.Version}); err != nil {
log.Logger.Errorf("delete revision %s in app %s failure %s", revision.Version, app.Name, err.Error())
klog.Errorf("delete revision %s in app %s failure %s", revision.Version, app.Name, err.Error())
}
}
for _, trigger := range triggers {
if err := c.Store.Delete(ctx, &model.ApplicationTrigger{AppPrimaryKey: app.PrimaryKey(), Name: trigger.Name, Token: trigger.Token}); err != nil {
log.Logger.Errorf("delete trigger %s in app %s failure %s", trigger.Name, app.Name, err.Error())
klog.Errorf("delete trigger %s in app %s failure %s", trigger.Name, app.Name, err.Error())
}
}
if err := c.EnvBindingService.BatchDeleteEnvBinding(ctx, app); err != nil {
log.Logger.Errorf("delete envbindings in app %s failure %s", app.Name, err.Error())
klog.Errorf("delete envbindings in app %s failure %s", app.Name, err.Error())
}
return c.Store.Delete(ctx, app)
@@ -1047,7 +1048,7 @@ 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 {
log.Logger.Warnf("component definition %s get failure. %s", pkgUtils.Sanitize(com.ComponentType), err.Error())
klog.Warningf("component definition %s get failure. %s", pkgUtils.Sanitize(com.ComponentType), err.Error())
return nil, bcode.ErrComponentTypeNotSupport
}
userName, _ := ctx.Value(&apisv1.CtxKeyUser).(string)
@@ -1075,7 +1076,7 @@ func (c *applicationServiceImpl) createComponent(ctx context.Context, app *model
traitTypes[trait.Type] = true
properties, err := model.NewJSONStructByString(trait.Properties)
if err != nil {
log.Logger.Errorf("new trait failure,%s", err.Error())
klog.Errorf("new trait failure,%s", err.Error())
return nil, bcode.ErrInvalidProperties
}
traits = append(traits, model.ApplicationTrait{
@@ -1102,7 +1103,7 @@ func (c *applicationServiceImpl) createComponent(ctx context.Context, app *model
if errors.Is(err, datastore.ErrRecordExist) {
return nil, bcode.ErrApplicationComponentExist
}
log.Logger.Warnf("add component for app %s failure %s", pkgUtils.Sanitize(app.PrimaryKey()), err.Error())
klog.Warningf("add component for app %s failure %s", pkgUtils.Sanitize(app.PrimaryKey()), err.Error())
return nil, err
}
// update the env workflow, the automatically generated workflow is determined by the component type.
@@ -1143,7 +1144,7 @@ func (c *applicationServiceImpl) DeleteComponent(ctx context.Context, app *model
if errors.Is(err, datastore.ErrRecordNotExist) {
return bcode.ErrApplicationComponentNotExist
}
log.Logger.Warnf("delete app component %s failure %s", app.PrimaryKey(), err.Error())
klog.Warningf("delete app component %s failure %s", app.PrimaryKey(), err.Error())
return err
}
if err := repository.UpdateAppEnvWorkflow(ctx, c.KubeClient, c.Store, app); err != nil {
@@ -1172,7 +1173,7 @@ func (c *applicationServiceImpl) CreatePolicy(ctx context.Context, app *model.Ap
if errors.Is(err, datastore.ErrRecordExist) {
return nil, bcode.ErrApplicationPolicyExist
}
log.Logger.Warnf("add policy for app %s failure %s", app.PrimaryKey(), err.Error())
klog.Warningf("add policy for app %s failure %s", app.PrimaryKey(), err.Error())
return nil, err
}
if err = c.handlePolicyBindingWorkflowStep(ctx, app, createPolicy.Name, createPolicy.WorkflowPolicyBindings); err != nil {
@@ -1199,7 +1200,7 @@ func (c *applicationServiceImpl) DeletePolicy(ctx context.Context, app *model.Ap
if errors.Is(err, datastore.ErrRecordNotExist) {
return bcode.ErrApplicationPolicyNotExist
}
log.Logger.Warnf("delete app policy %s failure %s", app.PrimaryKey(), err.Error())
klog.Warningf("delete app policy %s failure %s", app.PrimaryKey(), err.Error())
return err
}
return c.handlePolicyBindingWorkflowStep(ctx, app, policyName, nil)
@@ -1215,7 +1216,7 @@ func (c *applicationServiceImpl) UpdatePolicy(ctx context.Context, app *model.Ap
if errors.Is(err, datastore.ErrRecordNotExist) {
return nil, bcode.ErrApplicationPolicyNotExist
}
log.Logger.Warnf("update app policy %s failure %s", app.PrimaryKey(), err.Error())
klog.Warningf("update app policy %s failure %s", app.PrimaryKey(), err.Error())
return nil, err
}
policy.Type = policyUpdate.Type
@@ -1254,7 +1255,7 @@ func (c *applicationServiceImpl) CreateApplicationTrait(ctx context.Context, app
}
properties, err := model.NewJSONStructByString(req.Properties)
if err != nil {
log.Logger.Errorf("new trait failure,%s", err.Error())
klog.Errorf("new trait failure,%s", err.Error())
return nil, bcode.ErrInvalidProperties
}
trait := model.ApplicationTrait{CreateTime: time.Now(), Type: req.Type, Properties: properties, Alias: req.Alias, Description: req.Description}
@@ -1297,7 +1298,7 @@ func (c *applicationServiceImpl) UpdateApplicationTrait(ctx context.Context, app
if trait.Type == traitType {
properties, err := model.NewJSONStructByString(req.Properties)
if err != nil {
log.Logger.Errorf("update trait failure,%s", err.Error())
klog.Errorf("update trait failure,%s", err.Error())
return nil, bcode.ErrInvalidProperties
}
updatedTrait := model.ApplicationTrait{CreateTime: trait.CreateTime, UpdateTime: time.Now(), Properties: properties, Type: traitType, Alias: req.Alias, Description: req.Description}
@@ -1380,7 +1381,7 @@ func (c *applicationServiceImpl) Statistics(ctx context.Context, app *model.Appl
var targetMap = make(map[string]int)
envbinding, err := c.EnvBindingService.GetEnvBindings(ctx, app)
if err != nil {
log.Logger.Errorf("query app envbinding failure %s", err.Error())
klog.Errorf("query app envbinding failure %s", err.Error())
}
for _, env := range envbinding {
for _, target := range env.TargetNames {
@@ -1408,7 +1409,7 @@ func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model
case compareReq.CompareLatestWithRunning != nil:
base, err = c.renderOAMApplication(ctx, appModel, "", compareReq.CompareLatestWithRunning.Env, "")
if err != nil {
log.Logger.Errorf("failed to build the latest application %s", err.Error())
klog.Errorf("failed to build the latest application %s", err.Error())
break
}
case compareReq.CompareRevisionWithRunning != nil || compareReq.CompareRevisionWithLatest != nil:
@@ -1421,7 +1422,7 @@ func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model
}
base, envNameByRevision, err = c.getAppModelFromRevision(ctx, appModel.Name, revision)
if err != nil {
log.Logger.Errorf("failed to get the app model from the revision %s", err.Error())
klog.Errorf("failed to get the app model from the revision %s", err.Error())
break
}
}
@@ -1440,13 +1441,13 @@ func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model
}
compareTarget, err = c.GetApplicationCRInEnv(ctx, appModel, envName)
if err != nil {
log.Logger.Errorf("failed to query the application CR %s", err.Error())
klog.Errorf("failed to query the application CR %s", err.Error())
break
}
case compareReq.CompareRevisionWithLatest != nil:
compareTarget, err = c.renderOAMApplication(ctx, appModel, "", envNameByRevision, "")
if err != nil {
log.Logger.Errorf("failed to build the latest application %s", err.Error())
klog.Errorf("failed to build the latest application %s", err.Error())
break
}
}
@@ -1482,7 +1483,7 @@ func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model
args.SetClient(c.KubeClient)
diffResult, buff, err := compare(ctx, args, compareTarget, base)
if err != nil {
log.Logger.Errorf("fail to compare the app %s", err.Error())
klog.Errorf("fail to compare the app %s", err.Error())
compareResponse.IsDiff = false
return compareResponse, nil
}
@@ -1590,7 +1591,7 @@ func (c *applicationServiceImpl) resetApp(ctx context.Context, targetApp *v1beta
if errors.Is(err, datastore.ErrRecordNotExist) {
continue
}
log.Logger.Warnf("delete app %s comp %s failure %s", appPrimaryKey, compName, err.Error())
klog.Warningf("delete app %s comp %s failure %s", appPrimaryKey, compName, err.Error())
}
}
@@ -1610,11 +1611,11 @@ func (c *applicationServiceImpl) resetApp(ctx context.Context, targetApp *v1beta
if errors.Is(err, datastore.ErrRecordExist) {
err := c.Store.Put(ctx, &compModel)
if err != nil {
log.Logger.Warnf("update comp %s for app %s failure %s", comp.Name, pkgUtils.Sanitize(appPrimaryKey), err.Error())
klog.Warningf("update comp %s for app %s failure %s", comp.Name, pkgUtils.Sanitize(appPrimaryKey), err.Error())
}
return &apisv1.AppResetResponse{IsReset: true}, err
}
log.Logger.Warnf("add comp %s for app %s failure %s", comp.Name, pkgUtils.Sanitize(appPrimaryKey), err.Error())
klog.Warningf("add comp %s for app %s failure %s", comp.Name, pkgUtils.Sanitize(appPrimaryKey), err.Error())
return &apisv1.AppResetResponse{}, err
}
}

View File

@@ -533,7 +533,7 @@ var _ = Describe("Test application service function", func() {
Expect(cmp.Diff(compareResponse.TargetAppYAML, "")).Should(BeEmpty())
Expect(cmp.Diff(compareResponse.BaseAppYAML, "")).ShouldNot(BeEmpty())
By("compare when app's env add target, should return true")
By("compare when app's env add target, should return false")
_, err = targetService.CreateTarget(context.TODO(), v1.CreateTargetRequest{Name: "dev-target1", Project: appModel.Project, Cluster: &v1.ClusterTarget{ClusterName: "local", Namespace: "dev-target1"}})
Expect(err).Should(BeNil())
_, err = envService.UpdateEnv(context.TODO(), "app-dev",
@@ -548,7 +548,8 @@ var _ = Describe("Test application service function", func() {
},
})
Expect(err).Should(BeNil())
check(compareResponse, true)
// Existing applications are not affected after update env.
check(compareResponse, false)
By("compare when update app's trait, should return true")
// reset app config
@@ -846,19 +847,25 @@ var _ = Describe("Test apiserver policy rest api", func() {
EnvName: "default",
Steps: []v1.WorkflowStep{
{
Name: "default",
Type: "deploy",
Properties: `{"policies":["local"]}`,
WorkflowStepBase: v1.WorkflowStepBase{
Name: "default",
Type: "deploy",
Properties: `{"policies":["local"]}`,
},
},
{
Name: "suspend",
Type: "suspend",
Properties: `{"duration": "10m"}`,
WorkflowStepBase: v1.WorkflowStepBase{
Name: "suspend",
Type: "suspend",
Properties: `{"duration": "10m"}`,
},
},
{
Name: "second",
Type: "deploy",
Properties: `{"policies":["cluster1"]}`,
WorkflowStepBase: v1.WorkflowStepBase{
Name: "second",
Type: "deploy",
Properties: `{"policies":["cluster1"]}`,
},
},
},
}
@@ -870,9 +877,11 @@ var _ = Describe("Test apiserver policy rest api", func() {
EnvName: "default",
Steps: []v1.WorkflowStep{
{
Name: "second",
Type: "deploy",
Properties: `{"policies":["cluster3"]}`,
WorkflowStepBase: v1.WorkflowStepBase{
Name: "second",
Type: "deploy",
Properties: `{"policies":["cluster3"]}`,
},
},
},
}

View File

@@ -33,6 +33,7 @@ import (
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/yaml"
@@ -42,7 +43,6 @@ import (
"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"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
)
const (
@@ -424,7 +424,7 @@ func getDexConfig(ctx context.Context, kubeClient client.Client) (*model.DexConf
config := &model.DexConfig{}
if err := yaml.Unmarshal(dexConfigSecret.Data[secretDexConfigKey], config); err != nil {
log.Logger.Errorf("failed to unmarshal dex config: %s", err.Error())
klog.Errorf("failed to unmarshal dex config: %s", err.Error())
return nil, bcode.ErrInvalidDexConfig
}
if len(config.StaticClients) < 1 || len(config.StaticClients[0].RedirectURIs) < 1 {
@@ -487,7 +487,7 @@ func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) {
} else {
systemInfo, err := d.systemInfoService.GetSystemInfo(ctx)
if err != nil {
log.Logger.Errorf("failed to get the system info %s", err.Error())
klog.Errorf("failed to get the system info %s", err.Error())
}
user := &model.User{
Email: claims.Email,
@@ -500,7 +500,7 @@ func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) {
user.UserRoles = systemInfo.DexUserDefaultPlatformRoles
}
if err := d.Store.Add(ctx, user); err != nil {
log.Logger.Errorf("failed to save the user from the dex: %s", err.Error())
klog.Errorf("failed to save the user from the dex: %s", err.Error())
return nil, err
}
if systemInfo != nil {
@@ -510,7 +510,7 @@ func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) {
UserRoles: project.Roles,
})
if err != nil {
log.Logger.Errorf("failed to add a user to project %s", err.Error())
klog.Errorf("failed to add a user to project %s", err.Error())
}
}
}

View File

@@ -26,7 +26,7 @@ import (
"strings"
"time"
v1alpha1 "github.com/cloudtty/cloudtty/pkg/apis/cloudshell/v1alpha1"
"github.com/cloudtty/cloudtty/pkg/apis/cloudshell/v1alpha1"
"github.com/ghodss/yaml"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
@@ -36,6 +36,7 @@ import (
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/clientcmd/api"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
kubevelatypes "github.com/oam-dev/kubevela/apis/types"
@@ -43,7 +44,6 @@ import (
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/auth"
)
@@ -144,7 +144,7 @@ func (c *cloudShellServiceImpl) Prepare(ctx context.Context) (*apisv1.CloudShell
} else {
if cloudShell.Status.Phase == v1alpha1.PhaseFailed {
if err := c.KubeClient.Delete(ctx, &cloudShell); err != nil {
log.Logger.Errorf("failed to clear the failed cloud shell:%s", err.Error())
klog.Errorf("failed to clear the failed cloud shell:%s", err.Error())
}
res.Status = StatusFailed
}
@@ -231,25 +231,33 @@ func (c *cloudShellServiceImpl) prepareKubeConfig(ctx context.Context) error {
var groups []string
for _, p := range projects {
permissions, err := c.RBACService.GetUserPermissions(ctx, user, p.Name, false)
// The kubernetes permission set is generated based on simple rules, but this is not completely strict.
var readOnly bool
if err != nil {
log.Logger.Errorf("failed to get the user permissions %s", err.Error())
klog.Errorf("failed to get the user permissions %s", err.Error())
readOnly = true
} else {
readOnly = checkReadOnly(p.Name, permissions)
}
if readOnly {
groupName, err := c.managePrivilegesForProjectRead(ctx, p.Name, true)
groupName, err := c.managePrivilegesForProject(ctx, p, true)
if err != nil {
log.Logger.Errorf("failed to privileges the user %s", err.Error())
klog.Errorf("failed to privileges the user %s", err.Error())
}
if groupName != "" {
groups = append(groups, groupName)
}
} else {
groups = append(groups, utils.KubeVelaProjectGroupPrefix+p.Name)
groupName, err := c.managePrivilegesForProject(ctx, p, false)
if err != nil {
klog.Errorf("failed to privileges the user %s", err.Error())
}
if groupName != "" {
groups = append(groups, groupName)
}
}
}
groups = append(groups, utils.TemplateReaderGroup)
if utils.StringsContain(user.UserRoles, "admin") {
groups = append(groups, utils.KubeVelaAdminGroupPrefix+"admin")
@@ -267,7 +275,7 @@ func (c *cloudShellServiceImpl) prepareKubeConfig(ctx context.Context) error {
if len(c.CACert) == 0 {
caFromServiceAccount, err := os.ReadFile(CAFilePathInCluster)
if err != nil {
log.Logger.Errorf("failed to read the ca file from the service account dir,%s", err.Error())
klog.Errorf("failed to read the ca file from the service account dir,%s", err.Error())
return err
}
c.CACert = caFromServiceAccount
@@ -288,7 +296,7 @@ func (c *cloudShellServiceImpl) prepareKubeConfig(ctx context.Context) error {
Groups: groups,
}))
if err != nil {
log.Logger.Errorf("failed to generate the kube config:%s Message: %s", err.Error(), strings.ReplaceAll(buffer.String(), "\n", "\t"))
klog.Errorf("failed to generate the kube config:%s Message: %s", err.Error(), strings.ReplaceAll(buffer.String(), "\n", "\t"))
return err
}
bs, err := clientcmd.Write(*cfg)
@@ -375,11 +383,12 @@ func checkReadOnly(projectName string, permissions []*model.Permission) bool {
return !ra.Match(permissions)
}
// managePrivilegesForProjectRead grant the read privileges for a project
func (c *cloudShellServiceImpl) managePrivilegesForProjectRead(ctx context.Context, projectName string, readOnly bool) (string, error) {
// managePrivilegesForProject grant the privileges for a project
func (c *cloudShellServiceImpl) managePrivilegesForProject(ctx context.Context, project *apisv1.ProjectBase, readOnly bool) (string, error) {
projectName := project.Name
targets, err := c.TargetService.ListTargets(ctx, 0, 0, projectName)
if err != nil {
log.Logger.Infof("failed to list the targets by the project name %s :%s", projectName, err.Error())
klog.Infof("failed to list the targets by the project name %s :%s", projectName, err.Error())
}
var authPDs []auth.PrivilegeDescription
for _, t := range targets.Targets {
@@ -387,17 +396,24 @@ func (c *cloudShellServiceImpl) managePrivilegesForProjectRead(ctx context.Conte
}
envs, err := c.EnvService.ListEnvs(ctx, 0, 0, apisv1.ListEnvOptions{Project: projectName})
if err != nil {
log.Logger.Infof("failed to list the envs by the project name %s :%s", projectName, err.Error())
klog.Infof("failed to list the envs by the project name %s :%s", projectName, err.Error())
}
for _, e := range envs.Envs {
authPDs = append(authPDs, &auth.ApplicationPrivilege{Cluster: kubevelatypes.ClusterLocalName, Namespace: e.Namespace, ReadOnly: readOnly})
}
// The namespace of the environment: Application and WorkflowRun
authPDs = append(authPDs, &auth.ApplicationPrivilege{Cluster: kubevelatypes.ClusterLocalName, Namespace: project.Namespace, ReadOnly: readOnly})
groupName := utils.KubeVelaProjectReadGroupPrefix + projectName
if !readOnly {
groupName = utils.KubeVelaProjectGroupPrefix + projectName
}
identity := &auth.Identity{Groups: []string{groupName}}
writer := &bytes.Buffer{}
if err := auth.GrantPrivileges(ctx, c.KubeClient, authPDs, identity, writer, auth.WithReplace); err != nil {
return "", err
}
log.Logger.Debugf("GrantPrivileges: %s", writer.String())
klog.Infof("GrantPrivileges: %s", writer.String())
return groupName, nil
}

View File

@@ -48,6 +48,7 @@ var _ = Describe("Test cloudshell service function", func() {
cloudShellService *cloudShellServiceImpl
userService *userServiceImpl
projectService *projectServiceImpl
envService *envServiceImpl
err error
database string
)
@@ -56,7 +57,7 @@ var _ = Describe("Test cloudshell service function", func() {
database = "cloudshell-test-kubevela"
ds, err = NewDatastore(datastore.Config{Type: "kubeapi", Database: database})
Expect(err).Should(Succeed())
envService := &envServiceImpl{
envService = &envServiceImpl{
Store: ds,
KubeClient: k8sClient,
}
@@ -66,7 +67,8 @@ var _ = Describe("Test cloudshell service function", func() {
ProjectService: projectService,
}
projectService = &projectServiceImpl{
Store: ds,
Store: ds,
K8sClient: k8sClient,
RbacService: &rbacServiceImpl{
Store: ds,
},
@@ -99,14 +101,13 @@ var _ = Describe("Test cloudshell service function", func() {
}
})
It("test prepareKubeConfig", func() {
It("Test prepareKubeConfig", func() {
err = userService.Init(context.TODO())
Expect(err).Should(BeNil())
err = projectService.Init(context.TODO())
Expect(err).Should(BeNil())
By("test the developer users")
_, err = userService.CreateUser(context.TODO(), apisv1.CreateUserRequest{Name: "test-dev", Password: "test"})
Expect(err).Should(BeNil())
@@ -170,17 +171,37 @@ var _ = Describe("Test cloudshell service function", func() {
err = cloudShellService.prepareKubeConfig(ctx)
Expect(err).Should(BeNil())
var cm corev1.ConfigMap
err = k8sClient.Get(context.TODO(), types.NamespacedName{Namespace: kubevelatypes.DefaultKubeVelaNS, Name: makeUserConfigName("admin-test")}, &cm)
checkConfig := func() {
var cm corev1.ConfigMap
err = k8sClient.Get(context.TODO(), types.NamespacedName{Namespace: kubevelatypes.DefaultKubeVelaNS, Name: makeUserConfigName("admin-test")}, &cm)
Expect(err).Should(BeNil())
Expect(len(cm.Data["identity"]) > 0).Should(BeTrue())
var identity auth.Identity
err = yaml.Unmarshal([]byte(cm.Data["identity"]), &identity)
Expect(err).Should(BeNil())
Expect(utils.StringsContain(identity.Groups, utils.KubeVelaAdminGroupPrefix+"admin")).Should(BeTrue())
Expect(utils.StringsContain(identity.Groups, utils.TemplateReaderGroup)).Should(BeTrue())
}
checkConfig()
By("Test other projects")
_, err = projectService.CreateProject(ctx, apisv1.CreateProjectRequest{Name: "cloudshell"})
Expect(err).Should(BeNil())
Expect(len(cm.Data["identity"]) > 0).Should(BeTrue())
var identity auth.Identity
err = yaml.Unmarshal([]byte(cm.Data["identity"]), &identity)
_, err = envService.CreateEnv(ctx, apisv1.CreateEnvRequest{Name: "cloudshell-env", Project: "cloudshell"})
Expect(err).Should(BeNil())
Expect(utils.StringsContain(identity.Groups, utils.KubeVelaAdminGroupPrefix+"admin")).Should(BeTrue())
err = cloudShellService.prepareKubeConfig(ctx)
Expect(err).Should(BeNil())
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "kubevela:writer:application:binding", Namespace: "cloudshell-env"}, &rb)
Expect(err).Should(BeNil())
Expect(rb.Subjects[0].Name).Should(Equal(utils.KubeVelaProjectGroupPrefix + "cloudshell"))
checkConfig()
})
It("test prepare", func() {
It("Test prepare", func() {
By("Test with not CRD")
_, err = userService.CreateUser(context.TODO(), apisv1.CreateUserRequest{Name: "test", Password: "test"})
Expect(err).Should(BeNil())

View File

@@ -29,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/api/resource"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/kubevela/pkg/util/rand"
@@ -43,7 +44,6 @@ import (
apis "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
utils2 "github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/cloudprovider"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/utils"
@@ -100,25 +100,25 @@ func (c *clusterServiceImpl) getClusterFromDataStore(ctx context.Context, cluste
func (c *clusterServiceImpl) rollbackAddedClusterInDataStore(ctx context.Context, cluster *model.Cluster) {
if e := c.Store.Delete(ctx, cluster); e != nil {
log.Logger.Errorf("failed to rollback added cluster %s in data store: %s", utils.Sanitize(cluster.Name), e.Error())
klog.Errorf("failed to rollback added cluster %s in data store: %s", utils.Sanitize(cluster.Name), e.Error())
}
}
func (c *clusterServiceImpl) rollbackDeletedClusterInDataStore(ctx context.Context, cluster *model.Cluster) {
if e := c.Store.Add(ctx, cluster); e != nil {
log.Logger.Errorf("failed to rollback deleted cluster %s in data store: %s", utils.Sanitize(cluster.Name), e.Error())
klog.Errorf("failed to rollback deleted cluster %s in data store: %s", utils.Sanitize(cluster.Name), e.Error())
}
}
func (c *clusterServiceImpl) rollbackJoinedKubeCluster(ctx context.Context, cluster *model.Cluster) {
if e := multicluster.DetachCluster(ctx, c.K8sClient, cluster.Name); e != nil {
log.Logger.Errorf("failed to rollback joined cluster %s in kubevela: %s", utils.Sanitize(cluster.Name), e.Error())
klog.Errorf("failed to rollback joined cluster %s in kubevela: %s", utils.Sanitize(cluster.Name), e.Error())
}
}
func (c *clusterServiceImpl) rollbackDetachedKubeCluster(ctx context.Context, cluster *model.Cluster) {
if _, e := joinClusterByKubeConfigString(context.WithValue(ctx, multicluster.KubeConfigContext, c.KubeConfig), c.K8sClient, cluster.Name, cluster.KubeConfig); e != nil {
log.Logger.Errorf("failed to rollback detached cluster %s in kubevela: %s", utils.Sanitize(cluster.Name), e.Error())
klog.Errorf("failed to rollback detached cluster %s in kubevela: %s", utils.Sanitize(cluster.Name), e.Error())
}
}
@@ -492,7 +492,7 @@ func (c *clusterServiceImpl) getClusterResourceInfoFromK8s(ctx context.Context,
func (c *clusterServiceImpl) ListCloudClusters(ctx context.Context, provider string, req apis.AccessKeyRequest, pageNumber int, pageSize int) (*apis.ListCloudClusterResponse, error) {
p, err := cloudprovider.GetClusterProvider(provider, req.AccessKeyID, req.AccessKeySecret, c.K8sClient)
if err != nil {
log.Logger.Errorf("failed to get cluster provider: %s", err.Error())
klog.Errorf("failed to get cluster provider: %s", err.Error())
return nil, bcode.ErrInvalidCloudClusterProvider
}
clusters, total, err := p.ListCloudClusters(pageNumber, pageSize)
@@ -500,7 +500,7 @@ func (c *clusterServiceImpl) ListCloudClusters(ctx context.Context, provider str
if p.IsInvalidKey(err) {
return nil, bcode.ErrInvalidAccessKeyOrSecretKey
}
log.Logger.Errorf("failed to list cloud clusters: %s", err.Error())
klog.Errorf("failed to list cloud clusters: %s", err.Error())
return nil, bcode.ErrGetCloudClusterFailure
}
resp := &apis.ListCloudClusterResponse{
@@ -516,12 +516,12 @@ func (c *clusterServiceImpl) ListCloudClusters(ctx context.Context, provider str
func (c *clusterServiceImpl) ConnectCloudCluster(ctx context.Context, provider string, req apis.ConnectCloudClusterRequest) (*apis.ClusterBase, error) {
p, err := cloudprovider.GetClusterProvider(provider, req.AccessKeyID, req.AccessKeySecret, c.K8sClient)
if err != nil {
log.Logger.Errorf("failed to get cluster provider: %s", err.Error())
klog.Errorf("failed to get cluster provider: %s", err.Error())
return nil, bcode.ErrInvalidCloudClusterProvider
}
kubeConfig, err := p.GetClusterKubeConfig(req.ClusterID)
if err != nil {
log.Logger.Errorf("failed to get cluster kubeConfig: %s", err.Error())
klog.Errorf("failed to get cluster kubeConfig: %s", err.Error())
return nil, bcode.ErrGetCloudClusterFailure
}
cluster, err := p.GetClusterInfo(req.ClusterID)
@@ -529,7 +529,7 @@ func (c *clusterServiceImpl) ConnectCloudCluster(ctx context.Context, provider s
if p.IsInvalidKey(err) {
return nil, bcode.ErrInvalidAccessKeyOrSecretKey
}
log.Logger.Errorf("failed to get cluster info: %s", err.Error())
klog.Errorf("failed to get cluster info: %s", err.Error())
return nil, bcode.ErrGetCloudClusterFailure
}
createReq := apis.CreateClusterRequest{
@@ -546,7 +546,7 @@ func (c *clusterServiceImpl) ConnectCloudCluster(ctx context.Context, provider s
func (c *clusterServiceImpl) CreateCloudCluster(ctx context.Context, provider string, req apis.CreateCloudClusterRequest) (*apis.CreateCloudClusterResponse, error) {
p, err := cloudprovider.GetClusterProvider(provider, req.AccessKeyID, req.AccessKeySecret, c.K8sClient)
if err != nil {
log.Logger.Errorf("failed to get cluster provider: %s", err.Error())
klog.Errorf("failed to get cluster provider: %s", err.Error())
return nil, bcode.ErrInvalidCloudClusterProvider
}
_, err = p.CreateCloudCluster(ctx, req.Name, req.Zone, req.WorkerNumber, req.CPUCoresPerWorker, req.MemoryPerWorker)
@@ -554,7 +554,7 @@ func (c *clusterServiceImpl) CreateCloudCluster(ctx context.Context, provider st
if kerrors.IsAlreadyExists(err) {
return nil, bcode.ErrCloudClusterAlreadyExists
}
log.Logger.Errorf("failed to bootstrap terraform configuration: %s", err.Error())
klog.Errorf("failed to bootstrap terraform configuration: %s", err.Error())
return nil, bcode.ErrBootstrapTerraformConfiguration
}
return c.GetCloudClusterCreationStatus(ctx, provider, req.Name)

View File

@@ -23,12 +23,12 @@ import (
"github.com/pkg/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/types"
apis "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/config"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/apply"
@@ -234,7 +234,7 @@ func (u *configServiceImpl) ListConfigs(ctx context.Context, project string, tem
for i := range configs {
if projectNamespace != "" {
if err := u.Factory.MergeDistributionStatus(ctx, configs[i], projectNamespace); err != nil && !errors.Is(err, config.ErrNotFoundDistribution) {
log.Logger.Warnf("fail to merge the status %s:%s", configs[i].Name, err.Error())
klog.Warningf("fail to merge the status %s:%s", configs[i].Name, err.Error())
}
}
item := convertConfig(project, *configs[i])

View File

@@ -34,6 +34,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
k8stypes "k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
@@ -41,7 +42,6 @@ import (
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
)
// DefinitionService definition service, Implement the management of ComponentDefinition、TraitDefinition and WorkflowStepDefinition.
@@ -69,6 +69,7 @@ type DefinitionQueryOption struct {
AppliedWorkloads string `json:"appliedWorkloads"`
OwnerAddon string `json:"sourceAddon"`
QueryAll bool `json:"queryAll"`
Scope string `json:"scope"`
}
// String return cache key string
@@ -109,6 +110,19 @@ func (d *definitionServiceImpl) listDefinitions(ctx context.Context, list *unstr
},
},
}
if ops.Scope != "" {
var filterScope string
if ops.Scope == "Application" {
filterScope = "WorkflowRun"
} else {
filterScope = "Application"
}
matchLabels.MatchExpressions = append(matchLabels.MatchExpressions, metav1.LabelSelectorRequirement{
Key: types.LabelDefinitionScope,
Operator: metav1.LabelSelectorOpNotIn,
Values: []string{filterScope},
})
}
if !ops.QueryAll {
matchLabels.MatchExpressions = append(matchLabels.MatchExpressions, metav1.LabelSelectorRequirement{
Key: types.LabelDefinitionHidden,
@@ -137,7 +151,7 @@ func (d *definitionServiceImpl) listDefinitions(ctx context.Context, list *unstr
for _, def := range filteredList.Items {
definition, err := convertDefinitionBase(def, kind)
if err != nil {
log.Logger.Errorf("convert definition to base failure %s", err.Error())
klog.Errorf("convert definition to base failure %s", err.Error())
continue
}
defs = append(defs, definition)
@@ -271,7 +285,7 @@ func renderCustomUISchema(ctx context.Context, cli client.Client, name, defType
Name: fmt.Sprintf("%s-uischema-%s", defType, name),
}, &cm); err != nil {
if !apierrors.IsNotFound(err) {
log.Logger.Errorf("find uischema configmap from cluster failure %s", err.Error())
klog.Errorf("find uischema configmap from cluster failure %s", err.Error())
}
return defaultSchema
}
@@ -281,7 +295,7 @@ func renderCustomUISchema(ctx context.Context, cli client.Client, name, defType
}
schema := []*utils.UIParameter{}
if err := json.Unmarshal([]byte(data), &schema); err != nil {
log.Logger.Errorf("unmarshal ui schema failure %s", err.Error())
klog.Errorf("unmarshal ui schema failure %s", err.Error())
return defaultSchema
}
return patchSchema(defaultSchema, schema)
@@ -291,7 +305,7 @@ func renderCustomUISchema(ctx context.Context, cli client.Client, name, defType
func (d *definitionServiceImpl) AddDefinitionUISchema(ctx context.Context, name, defType string, schema []*utils.UIParameter) ([]*utils.UIParameter, error) {
dataBate, err := json.Marshal(schema)
if err != nil {
log.Logger.Errorf("json marshal failure %s", err.Error())
klog.Errorf("json marshal failure %s", err.Error())
return nil, bcode.ErrInvalidDefinitionUISchema
}
var cm v1.ConfigMap

View File

@@ -112,6 +112,11 @@ var _ = Describe("Test namespace service functions", func() {
Expect(wfstep[0].WorkflowStep.Schematic).ShouldNot(BeNil())
Expect(wfstep[0].Alias).Should(Equal("test-alias"))
wfstep, err = definitionService.ListDefinitions(context.TODO(), DefinitionQueryOption{Type: "workflowstep", Scope: "WorkflowRun"})
Expect(err).Should(BeNil())
// the definition should be filtered
Expect(cmp.Diff(len(wfstep), 1)).Should(BeEmpty())
step, err = ioutil.ReadFile("./testdata/apply-application-hide.yaml")
Expect(err).Should(Succeed())
var sd2 v1beta1.WorkflowStepDefinition

View File

@@ -24,8 +24,10 @@ import (
"sort"
apierror "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"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"
@@ -33,7 +35,6 @@ import (
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/auth"
"github.com/oam-dev/kubevela/pkg/oam"
util "github.com/oam-dev/kubevela/pkg/utils"
@@ -184,30 +185,13 @@ func checkEqual(old, new []string) bool {
return reflect.DeepEqual(old, new)
}
func (p *envServiceImpl) updateAppWithNewEnv(ctx context.Context, envName string, env *model.Env) error {
// List all apps inside the env
apps, err := listApp(ctx, p.Store, apisv1.ListApplicationOptions{Env: envName})
if err != nil {
return err
}
for _, app := range apps {
err = repository.UpdateEnvWorkflow(ctx, p.KubeClient, p.Store, app, env)
if err != nil {
return err
}
}
return nil
}
// UpdateEnv update an env for request
func (p *envServiceImpl) UpdateEnv(ctx context.Context, name string, req apisv1.UpdateEnvRequest) (*apisv1.Env, error) {
env := &model.Env{}
env.Name = name
err := p.Store.Get(ctx, env)
if err != nil {
log.Logger.Errorf("check if env name exists failure %s", err.Error())
klog.Errorf("check if env name exists failure %s", err.Error())
return nil, bcode.ErrEnvNotExisted
}
if req.Alias != "" {
@@ -221,25 +205,33 @@ func (p *envServiceImpl) UpdateEnv(ctx context.Context, name string, req apisv1.
if err != nil || !pass {
return nil, bcode.ErrEnvTargetConflict
}
var targetChanged bool
if len(req.Targets) > 0 && !checkEqual(env.Targets, req.Targets) {
targetChanged = true
env.Targets = req.Targets
}
targets, err := repository.ListTarget(ctx, p.Store, "", nil)
if err != nil {
return nil, err
}
var targetMap = make(map[string]*model.Target, len(targets))
for i, existTarget := range targets {
targetMap[existTarget.Name] = targets[i]
}
for _, target := range req.Targets {
if _, exist := targetMap[target]; !exist {
var targets []*model.Target
if len(req.Targets) > 0 {
_, _, deleted := util.ThreeWaySliceCompare(req.Targets, env.Targets)
if len(deleted) > 0 {
count, err := p.GetAppCountInEnv(ctx, env)
if err != nil {
return nil, err
}
if count > 0 {
return nil, bcode.ErrEnvTargetNotAllowDelete
}
}
targets, err = repository.ListTarget(ctx, p.Store, "", &datastore.ListOptions{
FilterOptions: datastore.FilterOptions{
In: []datastore.InQueryOption{{
Key: "name",
Values: req.Targets,
}},
},
})
if err != nil {
return nil, err
}
if len(targets) != len(req.Targets) {
return nil, bcode.ErrTargetNotExist
}
env.Targets = req.Targets
}
// create namespace at first
@@ -247,13 +239,6 @@ func (p *envServiceImpl) UpdateEnv(ctx context.Context, name string, req apisv1.
return nil, err
}
if targetChanged {
if err = p.updateAppWithNewEnv(ctx, name, env); err != nil {
log.Logger.Errorf("update envbinding failure %s", err.Error())
return nil, err
}
}
if err := managePrivilegesForEnvironment(ctx, p.KubeClient, env, false); err != nil {
return nil, err
}
@@ -262,6 +247,14 @@ func (p *envServiceImpl) UpdateEnv(ctx context.Context, name string, req apisv1.
return resp, nil
}
func (p *envServiceImpl) GetAppCountInEnv(ctx context.Context, env *model.Env) (int, error) {
var appList v1beta1.ApplicationList
if err := p.KubeClient.List(ctx, &appList, client.InNamespace(env.Namespace), client.MatchingLabels{model.LabelSourceOfTruth: model.FromUX}); err != nil {
return 0, err
}
return len(appList.Items), nil
}
// CreateEnv create an env for request
func (p *envServiceImpl) CreateEnv(ctx context.Context, req apisv1.CreateEnvRequest) (*apisv1.Env, error) {
newEnv := &model.Env{
@@ -344,14 +337,23 @@ func convertEnvModel2Base(env *model.Env, targets []*model.Target) *apisv1.Env {
UpdateTime: env.UpdateTime,
}
for _, dt := range env.Targets {
var t *model.Target
for _, tg := range targets {
if dt == tg.Name {
data.Targets = append(data.Targets, apisv1.NameAlias{
Name: dt,
Alias: tg.Alias,
})
t = tg
break
}
}
if t != nil {
data.Targets = append(data.Targets, apisv1.NameAlias{
Name: dt,
Alias: t.Alias,
})
} else {
data.Targets = append(data.Targets, apisv1.NameAlias{
Name: dt,
})
}
}
return &data
}
@@ -368,7 +370,7 @@ func managePrivilegesForEnvironment(ctx context.Context, cli client.Client, env
if err := f(ctx, cli, []auth.PrivilegeDescription{p}, identity, writer); err != nil {
return err
}
log.Logger.Debugf("%s: %s", msg, writer.String())
klog.Infof("%s: %s", msg, writer.String())
return nil
}

View File

@@ -25,8 +25,11 @@ import (
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"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/infrastructure/datastore"
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
@@ -53,6 +56,8 @@ var _ = Describe("Test env service functions", func() {
// create target
err := ds.Add(context.TODO(), &model.Target{Name: "env-test"})
Expect(err).Should(BeNil())
err = ds.Add(context.TODO(), &model.Target{Name: "env-test-2"})
Expect(err).Should(BeNil())
req := apisv1.CreateEnvRequest{
Name: "test-env",
@@ -113,6 +118,35 @@ var _ = Describe("Test env service functions", func() {
Expect(err).Should(BeNil())
Expect(cmp.Diff(env.Description, req5.Description)).Should(BeEmpty())
By("Test update the targets of the env")
req6 := apisv1.UpdateEnvRequest{
Description: "this is a env description update",
Targets: []string{"env-test", "env-test-2"},
}
env, err = envService.UpdateEnv(context.TODO(), "test-env-2", req6)
Expect(err).Should(BeNil())
Expect(cmp.Diff(len(env.Targets), len(req6.Targets))).Should(BeEmpty())
Expect(k8sClient.Create(context.TODO(), &v1beta1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "env-app",
Namespace: env.Namespace,
Labels: map[string]string{
model.LabelSourceOfTruth: model.FromUX,
},
},
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{},
},
})).Should(BeNil())
req7 := apisv1.UpdateEnvRequest{
Description: "this is a env description update",
Targets: []string{"env-test"},
}
_, err = envService.UpdateEnv(context.TODO(), "test-env-2", req7)
Expect(err).Should(Equal(bcode.ErrEnvTargetNotAllowDelete))
// clean up the env
err = envService.DeleteEnv(context.TODO(), "test-env")
Expect(err).Should(BeNil())

View File

@@ -23,6 +23,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
@@ -33,7 +34,6 @@ import (
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
pkgUtils "github.com/oam-dev/kubevela/pkg/utils"
)
@@ -66,7 +66,7 @@ func NewEnvBindingService() EnvBindingService {
func (e *envBindingServiceImpl) GetEnvBindings(ctx context.Context, app *model.Application) ([]*apisv1.EnvBindingBase, error) {
full, err := repository.ListFullEnvBinding(ctx, e.Store, repository.EnvListOption{AppPrimaryKey: app.PrimaryKey(), ProjectName: app.Project})
if err != nil {
log.Logger.Errorf("list envbinding for app %s err: %v\n", app.Name, err)
klog.Errorf("list envbinding for app %s err: %v\n", app.Name, err)
return nil, err
}
return full, nil
@@ -125,16 +125,16 @@ func (e *envBindingServiceImpl) BatchCreateEnvBinding(ctx context.Context, app *
envBindingModel := assembler.ConvertToEnvBindingModel(app, *envbindings[i])
env, err := repository.GetEnv(ctx, e.Store, envBindingModel.Name)
if err != nil {
log.Logger.Errorf("get env failure %s", err.Error())
klog.Errorf("get env failure %s", err.Error())
continue
}
if err := e.Store.Add(ctx, envBindingModel); err != nil {
log.Logger.Errorf("add envbinding %s failure %s", pkgUtils.Sanitize(envBindingModel.Name), err.Error())
klog.Errorf("add envbinding %s failure %s", pkgUtils.Sanitize(envBindingModel.Name), err.Error())
continue
}
err = e.createEnvWorkflow(ctx, app, env, i == 0)
if err != nil {
log.Logger.Errorf("create env workflow failure %s", err.Error())
klog.Errorf("create env workflow failure %s", err.Error())
continue
}
}
@@ -237,14 +237,14 @@ func (e *envBindingServiceImpl) createEnvWorkflow(ctx context.Context, app *mode
EnvName: env.Name,
AppPrimaryKey: app.PrimaryKey(),
}
log.Logger.Infof("create workflow %s for app %s", pkgUtils.Sanitize(workflow.Name), pkgUtils.Sanitize(app.PrimaryKey()))
klog.Infof("create workflow %s for app %s", pkgUtils.Sanitize(workflow.Name), pkgUtils.Sanitize(app.PrimaryKey()))
if err := e.Store.Add(ctx, workflow); err != nil {
return err
}
err := e.Store.BatchAdd(ctx, policies)
if err != nil {
if err := e.WorkflowService.DeleteWorkflow(ctx, app, repository.ConvertWorkflowName(env.Name)); err != nil {
log.Logger.Errorf("fail to rollback the workflow after fail to create policies, %s", err.Error())
klog.Errorf("fail to rollback the workflow after fail to create policies, %s", err.Error())
}
return fmt.Errorf("fail to create policies %w", err)
}
@@ -299,6 +299,6 @@ func (e *envBindingServiceImpl) ApplicationEnvRecycle(ctx context.Context, appMo
if err := resetRevisionsAndRecords(ctx, e.Store, appModel.Name, "", "", ""); err != nil {
return err
}
log.Logger.Infof("Application %s(%s) recycle successfully from env %s", appModel.Name, name, env.Name)
klog.Infof("Application %s(%s) recycle successfully from env %s", appModel.Name, name, env.Name)
return nil
}

View File

@@ -23,12 +23,12 @@ import (
"github.com/oam-dev/kubevela/apis/types"
v1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/oam-dev/kubevela/pkg/utils/helm"
types2 "k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
"helm.sh/helm/v3/pkg/repo"
@@ -69,7 +69,7 @@ func (d defaultHelmImpl) ListChartNames(ctx context.Context, repoURL string, sec
}
charts, err := d.helper.ListChartsFromRepo(repoURL, skipCache, opts)
if err != nil {
log.Logger.Errorf("cannot fetch charts repo: %s, error: %s", utils.Sanitize(repoURL), err.Error())
klog.Errorf("cannot fetch charts repo: %s, error: %s", utils.Sanitize(repoURL), err.Error())
return nil, bcode.ErrListHelmChart
}
return charts, nil
@@ -89,11 +89,11 @@ func (d defaultHelmImpl) ListChartVersions(ctx context.Context, repoURL string,
}
chartVersions, err := d.helper.ListVersions(repoURL, chartName, skipCache, opts)
if err != nil {
log.Logger.Errorf("cannot fetch chart versions repo: %s, chart: %s error: %s", utils.Sanitize(repoURL), utils.Sanitize(chartName), err.Error())
klog.Errorf("cannot fetch chart versions repo: %s, chart: %s error: %s", utils.Sanitize(repoURL), utils.Sanitize(chartName), err.Error())
return nil, bcode.ErrListHelmVersions
}
if len(chartVersions) == 0 {
log.Logger.Errorf("cannot fetch chart versions repo: %s, chart: %s", utils.Sanitize(repoURL), utils.Sanitize(chartName))
klog.Errorf("cannot fetch chart versions repo: %s, chart: %s", utils.Sanitize(repoURL), utils.Sanitize(chartName))
return nil, bcode.ErrChartNotExist
}
return chartVersions, nil
@@ -113,7 +113,7 @@ func (d defaultHelmImpl) GetChartValues(ctx context.Context, repoURL string, cha
}
v, err := d.helper.GetValuesFromChart(repoURL, chartName, version, skipCache, opts)
if err != nil {
log.Logger.Errorf("cannot fetch chart values repo: %s, chart: %s, version: %s, error: %s", utils.Sanitize(repoURL), utils.Sanitize(chartName), utils.Sanitize(version), err.Error())
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))

View File

@@ -83,7 +83,7 @@ var _ = Describe("Test helm repo list", func() {
pSec = v1.Secret{}
gSec = v1.Secret{}
Expect(k8sClient.Create(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "vela-system"}})).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{}))
Expect(k8sClient.Create(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "project-my-project"}})).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{}))
Expect(k8sClient.Create(ctx, &v1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "my-project"}})).Should(SatisfyAny(BeNil(), util.AlreadyExistMatcher{}))
Expect(yaml.Unmarshal([]byte(projectSecret), &pSec)).Should(BeNil())
Expect(yaml.Unmarshal([]byte(globalSecret), &gSec)).Should(BeNil())
Expect(k8sClient.Create(ctx, &pSec)).Should(BeNil())
@@ -390,7 +390,7 @@ apiVersion: v1
kind: Secret
metadata:
name: project-helm-repo
namespace: project-my-project
namespace: my-project
labels:
config.oam.dev/type: helm-repository
config.oam.dev/catalog: velacore-config

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