Compare commits

..

59 Commits

Author SHA1 Message Date
Somefive
2d28fb35eb Feat: multi-cluster authentication (#3713)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-24 14:48:26 +08:00
qiaozp
d7c6f6cc73 Chore: fix missing trigger for e2e tests (#3738)
Signed-off-by: qiaozp <chivalry.pp@gmail.com>
2022-04-24 10:15:28 +08:00
StevenLeiZhang
4162c413b3 Fix: vela-cli does not print cluster name, if application installed in default cluster (#3691)
Signed-off-by: StevenLeiZhang <zhangleiic@163.com>
2022-04-24 09:16:34 +08:00
Ziqi Zhao
172d41583f enhance slack url (#3727)
Signed-off-by: Ziqi Zhao <zhaoziqi9146@gmail.com>
2022-04-22 18:02:06 +08:00
Zheng Xi Zhou
58edb344f6 Feat: check whether a project matched a config's project (#3725)
* Feat: check whether a project matched a config's project

If the config project is not nil, it's matched whether the project
matched the target project.
If the config project is nil, the target project matched the config.

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>

* fix CI

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>

* fix CI

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>

* change imports order

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>

* change imported libraries order again

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>

* fix CI

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>
2022-04-22 17:53:41 +08:00
qiaozp
1125f87fd7 Feat: run e2e test on several K8s version (#3714)
* Feat: run e2e test on several K8s version

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* upgrade kind version

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* rollback 1.22

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* bump up kruise

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* with sha

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* try fix ci

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* use 1.22

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* remove sah

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* revert kind

Signed-off-by: qiaozp <chivalry.pp@gmail.com>
2022-04-22 17:05:19 +08:00
Xiangbo Ma
520e67f63b Feat: Delete the annotation "kubernetes.io/last-applied-configuration" in applicationRevision. Signed-off-by: Xiangbo Ma <maxiangboo@cmbchina.com> (#3724)
Signed-off-by: fourierr <maxiangboo@qq.com>
2022-04-22 17:04:24 +08:00
Tianxin Dong
7eb0002692 Feat: add sequential in gc policy (#3701)
* Feat: add sequential in gc policy

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* tidy the code

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* add suite test

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* add example docs and update the field

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix lint

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* change the name to dependency

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-04-22 16:34:07 +08:00
barnettZQG
1237f7350e Feat: change the webservice and config-image-registry definitions (#3732)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
2022-04-22 16:33:23 +08:00
Basuotian
7907618a6a Feat: add env for sidecar and init-container trait (#3730)
Signed-off-by: tianshuai <tianshuai@huya.com>

Co-authored-by: tianshuai <tianshuai@huya.com>
2022-04-22 15:59:34 +08:00
fengkang01
54e333148f Feat(lang): The policy controller generate the OpenAPI schema (#3703)
* Fix: The policy controller generate the OpenAPI schema  (#3683)

Signed-off-by: DESKTOP-FV8IFEC\10690 <1069029381@qq.com>

* Feat(lang): The policy controller generate the OpenAPI schema  (#3683)

The policy controller does not generate the OpenAPI schema #3683
add CapabilityPolicyDefinition struct comment
add StoreOpenAPISchema of CapabilityPolicyDefinition comment

Signed-off-by: fengkang <fengkangb@digitalchina.com>

* Feat(lang): The policy controller generate the OpenAPI schema  (#3683)

The policy controller does not generate the OpenAPI schema #3683
fix unit-test

Signed-off-by: fengkang <fengkangb@digitalchina.com>

* Feat(lang): The policy controller generate the OpenAPI schema  (#3683)
fix unit-test about policydefinition_controller_test.go
The policy controller does not generate the OpenAPI schema #3683
fix unit-test

Signed-off-by: fengkang <fengkangb@digitalchina.com>

* Feat(lang): The policy controller generate the OpenAPI schema  (#3683)
fix unit-test about policydefinition_controller_test.go

Signed-off-by: fengkang <fengkangb@digitalchina.com>

* Feat(lang): The policy controller generate the OpenAPI schema  (#3683) gen crd

Signed-off-by: fengkang <fengkangb@digitalchina.com>

* Feat(lang): The policy controller generate the OpenAPI schema  (#3683) make reviewable

Signed-off-by: fengkang01 <fengkangb@digitalchina.com>

Co-authored-by: DESKTOP-FV8IFEC\10690 <1069029381@qq.com>
2022-04-22 15:53:20 +08:00
wyike
c126a5b272 fix several issues (#3729)
Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-04-22 15:47:08 +08:00
wyike
3eb1f53606 specify staticcheck version (#3726)
Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>

fix the workflow

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

fix

try to fix

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

fix make file

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

fix makefile

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-04-22 14:16:15 +08:00
Tianxin Dong
426b22d2e5 Feat: add log provider (#3711)
* Feat: add log provider

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix lift

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix vet

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix rebase vet

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-04-22 13:14:51 +08:00
Arena.Su
007f13d2ee Feat(delay suspend): delayDuration in suspend step properties (#3644)
* Feat(delay suspend): add delayDuration in suspend step properties to support delay by certain time.Duration

Signed-off-by: suxiang <suxiang@asiainfo.com>
Signed-off-by: ArenaSu <704427617@qq.com>

* Feat(delay suspend): add delayDuration parameter to suspend cue

Signed-off-by: ArenaSu <704427617@qq.com>

* Feat(wait suspend): optimize wait suspend

Signed-off-by: ArenaSu <704427617@qq.com>

* Feat(wait suspend): change e2e test to local cluster env

Signed-off-by: ArenaSu <704427617@qq.com>

* Feat(wait suspend): fix WaitSuspend status modify bug

Signed-off-by: ArenaSu <704427617@qq.com>

* Feat(wait suspend): suspend cue parameter type error

Signed-off-by: ArenaSu <704427617@qq.com>

* Feat(wait suspend): set waitDuration optional param in suspend workflow step

Signed-off-by: ArenaSu <704427617@qq.com>

* Feat(wait suspend): add lost suspend.yaml

Signed-off-by: ArenaSu <704427617@qq.com>

* Feat(wait suspend): change solution to add suspendState

Signed-off-by: ArenaSu <704427617@qq.com>

* Feat(wait suspend): change durationWaiting to duration and add isPatch to gcResourceTrackers

Signed-off-by: ArenaSu <704427617@qq.com>
2022-04-22 11:40:13 +08:00
wyike
81d479aedf Fix: change systemInfo some fields (#3715)
* add some field an calculate workflow step

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

* fix the calculate job cannot start issue

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

* fix comments

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

fix test

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-04-22 10:18:28 +08:00
Lei Chu
25e33cdd6d Fix: embed.FS filepath that follow the unix style file path when running on windows (#3718)
* fix: "builtin-apply-component.cue: file does not exist"

Signed-off-by: lei.chu <1062186165@qq.com>

* fix: "builtin-apply-component.cue: file does not exist"

Signed-off-by: lei.chu <1062186165@qq.com>
2022-04-21 14:31:53 +08:00
qiaozp
900653a2da Feat: vela def gen-api command (#3699)
* Feat: vela def go-gen command

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* reviewable

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* Add unittest

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* lint

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* header

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* Add test case

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* more test

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* fix

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* add optional prefix, add omitempty in json tag

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* lint

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* lint

Signed-off-by: qiaozp <chivalry.pp@gmail.com>
2022-04-20 18:08:24 +08:00
StevenLeiZhang
e3612ac352 Fix: vela-core does not report error, when component depends on invalid component (#3636)
Signed-off-by: StevenLeiZhang <zhangleiic@163.com>
2022-04-20 13:37:34 +08:00
Diego Pinheiro
62fb10625d Fix: Addressing CVEs (#3708)
* fix - patching vuln go mod

Signed-off-by: Diego Milhomes Pinheiro <diego.milhomes@ORA-7869.local>
Signed-off-by: s4rd1nh4 <diego.milhomes@gmail.com>

* fix - addressing cves

Signed-off-by: Diego Milhomes Pinheiro <diego.milhomes@ORA-7869.local>
Signed-off-by: s4rd1nh4 <diego.milhomes@gmail.com>

* fix - cves

Signed-off-by: Diego Milhomes Pinheiro <diego.milhomes@ORA-7869.local>
Signed-off-by: s4rd1nh4 <diego.milhomes@gmail.com>

* fix - cves

Signed-off-by: Diego Milhomes Pinheiro <diego.milhomes@ORA-7869.local>
Signed-off-by: s4rd1nh4 <diego.milhomes@gmail.com>
2022-04-20 09:54:49 +08:00
Somefive
571e154af3 Fix: bind env to system namespace (#3706)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-19 20:55:59 +08:00
wyike
2ac4ddad03 Feat: calculate systemInfo everyday periodically and store them in datastore (#3689)
* add framework

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

add

finish the framework

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

finish test manually

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

add update time

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

adding test

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

finish test

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

abs

fix test

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

* move start func to leader election call back funcs

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

* resolve the recycle import problecm

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

fix issue

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

fix ci
2022-04-19 10:24:54 +08:00
Somefive
c5e1855a55 Feat: support disable legacy gc upgrade operation (#3694)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-18 17:05:47 +08:00
Zheng Xi Zhou
cb4a9ea1a8 Fix: set provider name as the config name (#3687)
- For VelaUX, hidden a provider name (users don't need to manual set it). Used
the application/component name (config name) to be the provider name.
- Store description of a config to the annotation of the config application

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>
2022-04-18 16:47:51 +08:00
Tianxin Dong
21216055fb Feat: add vela debug command (#3580)
* Feat: add debug configmap if debug policy is specified

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* Feat: add vela debug command

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* make code reviewable

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix sonartype lift

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix cue string

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* Feat: display better for debug

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* tidy the go mod

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* Feat: add debug test

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* change uitable vendor

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* add more tests

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* pass resource keeper from handler

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix lint

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix rebase

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* Pending test temporary

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-04-18 11:06:14 +08:00
Michiel Stigter
eb60d94a06 Feat: Expose optimizeDisableComponentRevision in helm chart (#3470)
* Feat: Expose optimizeDisableComponentRevision in helm chart

Signed-off-by: michiel <michiel.stigter@springer.com>

* Feat: Expose optimizeDisableComponentRevision in helm chart

Signed-off-by: michiel <michiel.stigter@springer.com>

* Feat: Expose optimizeDisableComponentRevision in helm chart

Signed-off-by: michiel <michiel.stigter@springer.com>

* Feat: Expose optimizeDisableComponentRevision in helm chart

Signed-off-by: michiel <michiel.stigter@springer.com>

* Feat: Add all the other possible optimization params to the helm-values.

Taken from: https://kubevela.io/docs/platform-engineers/system-operation/performance-finetuning#advanced-optimization

Signed-off-by: michiel <michiel.stigter@springer.com>
2022-04-15 17:48:14 +08:00
Somefive
8998537dc8 Fix: rt resource key compare mismatch local cluster (#3681)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-15 16:13:07 +08:00
barnettZQG
4ddfe32fc4 Fix: can not query the instance list for the app with apply once policy (#3670)
* Fix: can not query the instance list for the app with apply once policy

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Fix: change the test case about ListResourcesInApp

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
2022-04-15 14:38:01 +08:00
wyike
28e2284284 mock an addon to fix flaky test (#3665)
Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-04-15 10:30:05 +08:00
Tianxin Dong
62ecc70ade Fix: fix token invalid after the server restarted (#3658)
* Fix: fix token invalid after the server restarted

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix lint

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* Pending test temporary

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* Pending test temporary

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-04-14 22:25:43 +08:00
Somefive
5857aa8790 Fix: vela status tree show cluster alias & raw format (#3659)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-14 19:35:47 +08:00
ZhongsJie
49646ddc8e Feat: enhance storage trait to support multi-mountToEnv config Signed-off-by: Shijie Zhong <zhongsjie@cmbchina.com> (#3657)
Signed-off-by: ZhongsJie <zhongsjie@gmail.com>
2022-04-14 19:34:12 +08:00
Jianbo Sun
707905d877 Fix: add label from inner system in CR can prevent sync (#3655)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-04-14 19:32:53 +08:00
barnettZQG
7d3ef0595a Fix: duplicately list pods in velaQL (#3650)
* Fix: duplicately list pods in velaQL

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>

* Fix: the create time of synced app is empty

Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
2022-04-14 17:43:54 +08:00
Zheng Xi Zhou
af6dc4bda3 Fix: failed to deploy application when no there is no avaiable (#3652)
When there are configs, but not in the project where the appliation
is about to deploy, the sync application will hit an issue. It will
lead to block the deploy of an application.

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>
2022-04-14 17:25:34 +08:00
Zheng Xi Zhou
f44bd7c6dd Fix: refine the config sync logic (#3602)
* Fix: refine config management

- Refine the config sync logics

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>

* address comments

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>
2022-04-14 13:03:59 +08:00
wyike
eaec8348d9 Fix: try to fix CVE (#3641)
* try to fix cve

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

* add parse input func

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

fix lint

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

fix lint

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

* use santize

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-04-14 10:03:15 +08:00
wyike
2849dfc1fb Fix: clear info when addon version cannot meet require (#3642)
* first

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

version miss match erro for addon

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

add log

* add test for this

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

small fix
2022-04-14 10:02:47 +08:00
Somefive
d657ea4daf Feat: rework vela up to support specified revision (#3634)
* Feat: rework vela up to support specified revision

Signed-off-by: Somefive <yd219913@alibaba-inc.com>

* Fix: add legacy compatibility

Signed-off-by: Somefive <yd219913@alibaba-inc.com>

* Feat: fix test

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-13 22:20:07 +08:00
Zhiyu Wang
68500b3f17 Fix: verify password valid (#3545)
Signed-off-by: Zhiyu Wang <zhiyuwang.newbis@gmail.com>
2022-04-13 19:39:00 +08:00
Somefive
c33eaa0609 Fix: enhance vela status tree print (#3639)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-13 17:46:55 +08:00
Somefive
7a0d2b552b Feat: support alias in cluster (#3630)
* Feat: support alias in cluster

Signed-off-by: Somefive <yd219913@alibaba-inc.com>

* Fix: add test for cluster alias

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-13 13:58:35 +08:00
Zheng Xi Zhou
385b2462e9 Feat: refine config creation and provide config list (#3637)
- Make the api of creation a config to be async
- In listing config page, show the status of a config

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>
2022-04-13 13:45:41 +08:00
Kunshuai Zhu
0c35753530 Feat: allow select resource by resource type for gc policy (#3598)
* Feat: allow select resource by resource type for gc policy

Signed-off-by: zhukunshuai <jookunshuai@gmail.com>

* Modify match label key

Signed-off-by: zhukunshuai <jookunshuai@gmail.com>

* Unified label key

Signed-off-by: zhukunshuai <jookunshuai@gmail.com>
2022-04-12 18:51:07 +08:00
Somefive
0e97aa2291 Feat: vela status --tree (#3609)
* Feat: vela status --tree

Signed-off-by: Somefive <yd219913@alibaba-inc.com>

* Feat: support show not-deployed clusters

Signed-off-by: Somefive <yd219913@alibaba-inc.com>

* Fix: add tests

Signed-off-by: Somefive <yd219913@alibaba-inc.com>

* Fix: add multicluster e2e coverage

Signed-off-by: Somefive <yd219913@alibaba-inc.com>

* Chore: minor fix

Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-12 17:58:45 +08:00
Tianxin Dong
7fcb89906c Fix: fix dex login with existed email (#3623)
* Fix: fix dex login with existed email

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* add dex connector check

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* unset users' alias

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix ut

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>

* fix ut

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-04-12 16:29:21 +08:00
Somefive
86ef2d68e0 Fix: flags for controller (#3627)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-12 16:12:50 +08:00
wyike
2e57be1022 Feat: support basic auth private helm repo (#3595)
* support auth

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

* add test

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

fix check diff

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

fix test

fix

add comments

fix test

* add tests

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

fix

add more test

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

* add more test

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

* extract set auth info as a global func

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

* return bcode

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-04-12 14:33:44 +08:00
Gallardot
ad01f3062a Feat: add HealthProbe for sidecar (#3629)
* Feat: add HealthProbe for sidecar

Signed-off-by: Gallardot <tttick@163.com>

* Feat: add HealthProbe for sidecar

Signed-off-by: Gallardot <tttick@163.com>
2022-04-12 13:21:51 +08:00
Somefive
b6fac3f4d5 Fix: cli default switch on feature flags (#3625)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
2022-04-11 20:40:13 +08:00
Min Kim
2eb7826070 bump cluster-gateway to 1.3.2 (#3619)
Signed-off-by: yue9944882 <291271447@qq.com>
2022-04-11 19:31:51 +08:00
Zheng Xi Zhou
5f7371815c Feat: add api of listing configs for project when creating a target (#3581)
* Feat: add api of listing configs for project

In a project, list configs by its type

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>

* address comments

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>

* fix ci

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>

* add query parameter definition

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>

* Update pkg/apiserver/rest/webservice/project.go

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-04-11 19:05:18 +08:00
wyike
d6b96fee5a Fix: add e2e apiserver test for addon (#3607)
* add e2e apiserver test for addon

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

delete comment

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

fix

* fix test

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

* close the reponse body

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

* cover list enabled addon

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

fix e2e test

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

fix test

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

fix test

* fix test

Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-04-11 17:46:46 +08:00
Jianbo Sun
85c673a574 Fix: reuse chart values in vela install (#3616)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-04-11 09:50:18 +08:00
qiaozp
7e6d9ccc73 Fix: vela logs without specified resource name (#3605)
* Fix: vela logs without specified resource name

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* add unittest

Signed-off-by: qiaozp <chivalry.pp@gmail.com>

* reviewable

Signed-off-by: qiaozp <chivalry.pp@gmail.com>
2022-04-08 17:22:05 +08:00
Avery
e65dcf12db add sorting for properties, outputs, writeSecretRefParameters in vela def doc-gen (#3593)
Signed-off-by: Nicola115 <2225992901@qq.com>
2022-04-08 15:27:35 +08:00
Diego Pinheiro
fd5faed71a Chore: Nominate s4rd1nh4 as a Reviewer member (#3603)
Signed-off-by: GitHub <noreply@github.com>
2022-04-08 13:21:45 +08:00
Zheng Xi Zhou
b1823084af Fix: add terraform aws provider without AWS_SESSION_TOKEN (#3590)
* Fix: add terraform aws provider without AWS_SESSION_TOKEN

Fix #3589 and refine prompts for cli

Signed-off-by: Zheng Xi Zhou <zzxwill@gmail.com>
2022-04-07 13:41:29 +08:00
namo
83fe4a160e Feat(lang): add addons gitlab support (#3543)
* add addons gitlab support

Signed-off-by: Namo <lgj112113@163.com>

* add addons gitlab support

Signed-off-by: Namo <lgj112113@163.com>

* test file edit

Signed-off-by: Namo <lgj112113@163.com>

* typo edit

Signed-off-by: Namo <lgj112113@163.com>

* notes edit

Signed-off-by: Namo <lgj112113@163.com>

* move third party imports block

Signed-off-by: Namo <lgj112113@163.com>

* code format edit

Signed-off-by: Namo <lgj112113@163.com>

* notes edit

Signed-off-by: Namo <lgj112113@163.com>

* create addon registry bug fix

Signed-off-by: Namo <lgj112113@163.com>

* add gitlab addon registry bug fix

Signed-off-by: Namo <lgj112113@163.com>

* add addon gitlab support test file

Signed-off-by: Namo <lgj112113@163.com>

* add addon gitlab support test note edit

Signed-off-by: Namo <lgj112113@163.com>

* add addon gitlab branch support and fix bug

Signed-off-by: Namo <lgj112113@163.com>

* addon gitlab registry repo name invalid

Signed-off-by: Namo <lgj112113@163.com>

Co-authored-by: Namo <lgj112113@163.com>
2022-04-07 11:05:14 +08:00
212 changed files with 5849 additions and 4612 deletions

View File

@@ -6,7 +6,9 @@ on:
- master
- release-*
- apiserver
workflow_dispatch: {}
tags:
- v*
workflow_dispatch: { }
pull_request:
branches:
- master
@@ -18,6 +20,8 @@ env:
GO_VERSION: '1.17'
GOLANGCI_VERSION: 'v1.38'
KIND_VERSION: 'v0.7.0'
KIND_IMAGE_VERSION: '[\"v1.20.7\"]'
KIND_IMAGE_VERSIONS: '[\"v1.18.20\",\"v1.20.7\",\"v1.22.7\"]'
jobs:
@@ -35,10 +39,36 @@ jobs:
do_not_skip: '["workflow_dispatch", "schedule", "push"]'
concurrent_skipping: false
set-k8s-matrix:
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.set-k8s-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v2
- uses: mukunku/tag-exists-action@v1.0.0
id: checkTag
with:
tag: 'v1'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: set-k8s-matrix
run: |
echo ${{ steps.checkTag.outputs.exists }}
if [ "${{ steps.checkTag.outputs.exists }}" = "true" ]; then
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSIONS }}"
else
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSION }}"
fi
apiserver-unit-tests:
runs-on: aliyun
needs: detect-noop
needs: [ detect-noop,set-k8s-matrix ]
if: needs.detect-noop.outputs.noop != 'true'
strategy:
matrix:
k8s-version: ${{ fromJson(needs.set-k8s-matrix.outputs.matrix) }}
steps:
- name: Set up Go
@@ -65,7 +95,7 @@ jobs:
- name: Setup Kind Cluster (Worker)
run: |
kind delete cluster --name worker
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca --name worker
kind create cluster --image kindest/node:${{ matrix.k8s-version }} --name worker
kubectl version
kubectl cluster-info
kind get kubeconfig --name worker --internal > /tmp/worker.kubeconfig
@@ -74,7 +104,7 @@ jobs:
- name: Setup Kind Cluster (Hub)
run: |
kind delete cluster
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca
kind create cluster --image kindest/node:${{ matrix.k8s-version }}
kubectl version
kubectl cluster-info

View File

@@ -1,89 +0,0 @@
name: Publish Chart
on:
push:
tags:
- "v*"
workflow_dispatch: { }
env:
BUCKET: ${{ secrets.OSS_BUCKET }}
ENDPOINT: ${{ secrets.OSS_ENDPOINT }}
ACCESS_KEY: ${{ secrets.OSS_ACCESS_KEY }}
ACCESS_KEY_SECRET: ${{ secrets.OSS_ACCESS_KEY_SECRET }}
ARTIFACT_HUB_REPOSITORY_ID: ${{ secrets.ARTIFACT_HUB_REPOSITORY_ID }}
jobs:
publish-charts:
env:
HELM_CHARTS_DIR: charts
HELM_CHART: charts/vela-core
MINIMAL_HELM_CHART: charts/vela-minimal
LEGACY_HELM_CHART: legacy/charts/vela-core-legacy
VELA_ROLLOUT_HELM_CHART: runtime/rollout/charts
LOCAL_OSS_DIRECTORY: .oss/
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@master
- name: Get git revision
id: vars
shell: bash
run: |
echo "::set-output name=git_revision::$(git rev-parse --short HEAD)"
- name: Install Helm
uses: azure/setup-helm@v1
with:
version: v3.4.0
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Generate helm doc
run: |
make helm-doc-gen
- name: Prepare legacy chart
run: |
rsync -r $LEGACY_HELM_CHART $HELM_CHARTS_DIR
rsync -r $HELM_CHART/* $LEGACY_HELM_CHART --exclude=Chart.yaml --exclude=crds
- name: Prepare vela chart
run: |
rsync -r $VELA_ROLLOUT_HELM_CHART $HELM_CHARTS_DIR
- name: Get the version
id: get_version
run: |
VERSION=${GITHUB_REF#refs/tags/}
echo ::set-output name=VERSION::${VERSION}
- name: Tag helm chart image
run: |
image_tag=${{ steps.get_version.outputs.VERSION }}
chart_version=${{ steps.get_version.outputs.VERSION }}
sed -i "s/latest/${image_tag}/g" $HELM_CHART/values.yaml
sed -i "s/latest/${image_tag}/g" $MINIMAL_HELM_CHART/values.yaml
sed -i "s/latest/${image_tag}/g" $LEGACY_HELM_CHART/values.yaml
sed -i "s/latest/${image_tag}/g" $VELA_ROLLOUT_HELM_CHART/values.yaml
chart_smever=${chart_version#"v"}
sed -i "s/0.1.0/$chart_smever/g" $HELM_CHART/Chart.yaml
sed -i "s/0.1.0/$chart_smever/g" $MINIMAL_HELM_CHART/Chart.yaml
sed -i "s/0.1.0/$chart_smever/g" $LEGACY_HELM_CHART/Chart.yaml
sed -i "s/0.1.0/$chart_smever/g" $VELA_ROLLOUT_HELM_CHART/Chart.yaml
- name: Install ossutil
run: wget http://gosspublic.alicdn.com/ossutil/1.7.0/ossutil64 && chmod +x ossutil64 && mv ossutil64 ossutil
- name: Configure Alibaba Cloud OSSUTIL
run: ./ossutil --config-file .ossutilconfig config -i ${ACCESS_KEY} -k ${ACCESS_KEY_SECRET} -e ${ENDPOINT} -c .ossutilconfig
- name: sync cloud to local
run: ./ossutil --config-file .ossutilconfig sync oss://$BUCKET/core $LOCAL_OSS_DIRECTORY
- name: add artifacthub stuff to the repo
run: |
rsync $HELM_CHART/README.md $LEGACY_HELM_CHART/README.md
rsync $HELM_CHART/README.md $VELA_ROLLOUT_HELM_CHART/README.md
sed -i "s/ARTIFACT_HUB_REPOSITORY_ID/$ARTIFACT_HUB_REPOSITORY_ID/g" hack/artifacthub/artifacthub-repo.yml
rsync hack/artifacthub/artifacthub-repo.yml $LOCAL_OSS_DIRECTORY
- name: Package helm charts
run: |
helm package $HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm package $MINIMAL_HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm package $LEGACY_HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm package $VELA_ROLLOUT_HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm repo index --url https://$BUCKET.$ENDPOINT/core $LOCAL_OSS_DIRECTORY
- name: sync local to cloud
run: ./ossutil --config-file .ossutilconfig sync $LOCAL_OSS_DIRECTORY oss://$BUCKET/core -f -u

View File

@@ -5,6 +5,8 @@ on:
branches:
- master
- release-*
tags:
- v*
workflow_dispatch: {}
pull_request:
branches:
@@ -16,6 +18,8 @@ env:
GO_VERSION: '1.17'
GOLANGCI_VERSION: 'v1.38'
KIND_VERSION: 'v0.7.0'
KIND_IMAGE_VERSION: '[\"v1.20.7\"]'
KIND_IMAGE_VERSIONS: '[\"v1.18.20\",\"v1.20.7\",\"v1.22.7\"]'
jobs:
@@ -33,10 +37,37 @@ jobs:
do_not_skip: '["workflow_dispatch", "schedule", "push"]'
concurrent_skipping: false
set-k8s-matrix:
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.set-k8s-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v2
- uses: mukunku/tag-exists-action@v1.0.0
id: checkTag
with:
tag: 'v1'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: set-k8s-matrix
run: |
echo ${{ steps.checkTag.outputs.exists }}
if [ "${{ steps.checkTag.outputs.exists }}" = "true" ]; then
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSIONS }}"
else
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSION }}"
fi
e2e-multi-cluster-tests:
runs-on: aliyun
needs: detect-noop
needs: [ detect-noop,set-k8s-matrix ]
if: needs.detect-noop.outputs.noop != 'true'
strategy:
matrix:
k8s-version: ${{ fromJson(needs.set-k8s-matrix.outputs.matrix) }}
steps:
- name: Check out code into the Go module directory
@@ -60,7 +91,7 @@ jobs:
- name: Setup Kind Cluster (Worker)
run: |
kind delete cluster --name worker
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca --name worker
kind create cluster --image kindest/node:${{ matrix.k8s-version }} --name worker
kubectl version
kubectl cluster-info
kind get kubeconfig --name worker --internal > /tmp/worker.kubeconfig
@@ -69,7 +100,7 @@ jobs:
- name: Setup Kind Cluster (Hub)
run: |
kind delete cluster
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca
kind create cluster --image kindest/node:${{ matrix.k8s-version }}
kubectl version
kubectl cluster-info

View File

@@ -5,6 +5,8 @@ on:
branches:
- master
- release-*
tags:
- v*
workflow_dispatch: {}
pull_request:
branches:
@@ -16,6 +18,8 @@ env:
GO_VERSION: '1.17'
GOLANGCI_VERSION: 'v1.38'
KIND_VERSION: 'v0.7.0'
KIND_IMAGE_VERSION: '[\"v1.20.7\"]'
KIND_IMAGE_VERSIONS: '[\"v1.18.20\",\"v1.20.7\",\"v1.22.7\"]'
jobs:
@@ -33,10 +37,35 @@ jobs:
do_not_skip: '["workflow_dispatch", "schedule", "push"]'
concurrent_skipping: false
set-k8s-matrix:
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.set-k8s-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v2
- uses: mukunku/tag-exists-action@v1.0.0
id: checkTag
with:
tag: 'v1'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: set-k8s-matrix
run: |
echo ${{ steps.checkTag.outputs.exists }}
if [ "${{ steps.checkTag.outputs.exists }}" = "true" ]; then
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSIONS }}"
else
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSION }}"
fi
e2e-rollout-tests:
runs-on: aliyun
needs: detect-noop
needs: [ detect-noop,set-k8s-matrix ]
if: needs.detect-noop.outputs.noop != 'true'
strategy:
matrix:
k8s-version: ${{ fromJson(needs.set-k8s-matrix.outputs.matrix) }}
steps:
- name: Check out code into the Go module directory
@@ -60,7 +89,7 @@ jobs:
- name: Setup Kind Cluster
run: |
kind delete cluster
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca
kind create cluster --image kindest/node:${{ matrix.k8s-version }}
kubectl version
kubectl cluster-info

View File

@@ -5,6 +5,8 @@ on:
branches:
- master
- release-*
tags:
- v*
workflow_dispatch: {}
pull_request:
branches:
@@ -16,6 +18,8 @@ env:
GO_VERSION: '1.17'
GOLANGCI_VERSION: 'v1.38'
KIND_VERSION: 'v0.7.0'
KIND_IMAGE_VERSION: '[\"v1.20.7\"]'
KIND_IMAGE_VERSIONS: '[\"v1.18.20\",\"v1.20.7\",\"v1.22.7\"]'
jobs:
@@ -33,10 +37,35 @@ jobs:
do_not_skip: '["workflow_dispatch", "schedule", "push"]'
concurrent_skipping: false
set-k8s-matrix:
runs-on: ubuntu-20.04
outputs:
matrix: ${{ steps.set-k8s-matrix.outputs.matrix }}
steps:
- uses: actions/checkout@v2
- uses: mukunku/tag-exists-action@v1.0.0
id: checkTag
with:
tag: 'v1'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- id: set-k8s-matrix
run: |
echo ${{ steps.checkTag.outputs.exists }}
if [ "${{ steps.checkTag.outputs.exists }}" = "true" ]; then
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSIONS }}"
else
echo "::set-output name=matrix::${{ env.KIND_IMAGE_VERSION }}"
fi
e2e-tests:
runs-on: aliyun
needs: detect-noop
needs: [ detect-noop,set-k8s-matrix ]
if: needs.detect-noop.outputs.noop != 'true'
strategy:
matrix:
k8s-version: ${{ fromJson(needs.set-k8s-matrix.outputs.matrix) }}
steps:
- name: Check out code into the Go module directory
@@ -60,7 +89,7 @@ jobs:
- name: Setup Kind Cluster
run: |
kind delete cluster
kind create cluster --image kindest/node:v1.20.7@sha256:688fba5ce6b825be62a7c7fe1415b35da2bdfbb5a69227c499ea4cc0008661ca
kind create cluster --image kindest/node:${{ matrix.k8s-version }}
kubectl version
kubectl cluster-info

View File

@@ -8,11 +8,14 @@ on:
workflow_dispatch: {}
env:
BUCKET: ${{ secrets.OSS_BUCKET }}
ENDPOINT: ${{ secrets.OSS_ENDPOINT }}
ACCESS_KEY: ${{ secrets.OSS_ACCESS_KEY }}
ACCESS_KEY_SECRET: ${{ secrets.OSS_ACCESS_KEY_SECRET }}
ARTIFACT_HUB_REPOSITORY_ID: ${{ secrets.ARTIFACT_HUB_REPOSITORY_ID }}
jobs:
publish-core-images:
publish-images:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
@@ -44,16 +47,20 @@ jobs:
- name: Login Alibaba Cloud ACR
uses: docker/login-action@v1
with:
registry: ${{ secrets.ACR_DOMAIN }}
username: ${{ secrets.ACR_USERNAME }}
registry: kubevela-registry.cn-hangzhou.cr.aliyuncs.com
username: ${{ secrets.ACR_USERNAME }}@aliyun-inner.com
password: ${{ secrets.ACR_PASSWORD }}
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
with:
driver-opts: image=moby/buildkit:master
- name: Build & Pushing vela-core for ACR
run: |
docker build --build-arg GOPROXY=https://proxy.golang.org --build-arg VERSION=${{ steps.get_version.outputs.VERSION }} --build-arg GITVERSION=git-${{ steps.vars.outputs.git_revision }} -t kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }} .
docker push kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
- uses: docker/build-push-action@v2
name: Build & Pushing vela-core for Dockerhub, GHCR and ACR
name: Build & Pushing vela-core for Dockerhub and GHCR
with:
context: .
file: Dockerfile
@@ -68,51 +75,14 @@ jobs:
GOPROXY=https://proxy.golang.org
tags: |-
docker.io/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
${{ secrets.ACR_DOMAIN }}/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository }}/vela-core:${{ steps.get_version.outputs.VERSION }}
publish-addon-images:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Get the version
id: get_version
- name: Build & Pushing vela-apiserver for ACR
run: |
VERSION=${GITHUB_REF#refs/tags/}
if [[ ${GITHUB_REF} == "refs/heads/master" ]]; then
VERSION=latest
fi
echo ::set-output name=VERSION::${VERSION}
- name: Get git revision
id: vars
shell: bash
run: |
echo "::set-output name=git_revision::$(git rev-parse --short HEAD)"
- name: Login ghcr.io
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login docker.io
uses: docker/login-action@v1
with:
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Login Alibaba Cloud ACR
uses: docker/login-action@v1
with:
registry: ${{ secrets.ACR_DOMAIN }}
username: ${{ secrets.ACR_USERNAME }}
password: ${{ secrets.ACR_PASSWORD }}
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
with:
driver-opts: image=moby/buildkit:master
docker build --build-arg GOPROXY=https://proxy.golang.org --build-arg VERSION=${{ steps.get_version.outputs.VERSION }} --build-arg GITVERSION=git-${{ steps.vars.outputs.git_revision }} -t kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-apiserver:${{ steps.get_version.outputs.VERSION }} -f Dockerfile.apiserver .
docker push kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-apiserver:${{ steps.get_version.outputs.VERSION }}
- uses: docker/build-push-action@v2
name: Build & Pushing vela-apiserver for Dockerhub, GHCR and ACR
name: Build & Pushing vela-apiserver for Dockerhub and GHCR
with:
context: .
file: Dockerfile.apiserver
@@ -127,10 +97,14 @@ jobs:
GOPROXY=https://proxy.golang.org
tags: |-
docker.io/oamdev/vela-apiserver:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/oamdev/vela-apiserver:${{ steps.get_version.outputs.VERSION }}
${{ secrets.ACR_DOMAIN }}/oamdev/vela-apiserver:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository }}/vela-apiserver:${{ steps.get_version.outputs.VERSION }}
- name: Build & Pushing vela runtime rollout for ACR
run: |
docker build --build-arg GOPROXY=https://proxy.golang.org --build-arg VERSION=${{ steps.get_version.outputs.VERSION }} --build-arg GITVERSION=git-${{ steps.vars.outputs.git_revision }} -t kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-rollout:${{ steps.get_version.outputs.VERSION }} .
docker push kubevela-registry.cn-hangzhou.cr.aliyuncs.com/oamdev/vela-rollout:${{ steps.get_version.outputs.VERSION }}
- uses: docker/build-push-action@v2
name: Build & Pushing runtime rollout Dockerhub, GHCR and ACR
name: Build & Pushing runtime rollout for Dockerhub and GHCR
with:
context: .
file: runtime/rollout/Dockerfile
@@ -145,8 +119,96 @@ jobs:
GOPROXY=https://proxy.golang.org
tags: |-
docker.io/oamdev/vela-rollout:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/oamdev/vela-rollout:${{ steps.get_version.outputs.VERSION }}
${{ secrets.ACR_DOMAIN }}/oamdev/vela-rollout:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository }}/vela-rollout:${{ steps.get_version.outputs.VERSION }}
publish-charts:
env:
HELM_CHARTS_DIR: charts
HELM_CHART: charts/vela-core
MINIMAL_HELM_CHART: charts/vela-minimal
LEGACY_HELM_CHART: legacy/charts/vela-core-legacy
OAM_RUNTIME_HELM_CHART: charts/oam-runtime
VELA_ROLLOUT_HELM_CHART: runtime/rollout/charts
LOCAL_OSS_DIRECTORY: .oss/
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@master
- name: Get git revision
id: vars
shell: bash
run: |
echo "::set-output name=git_revision::$(git rev-parse --short HEAD)"
- name: Install Helm
uses: azure/setup-helm@v1
with:
version: v3.4.0
- name: Setup node
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Generate helm doc
run: |
make helm-doc-gen
- name: Prepare legacy chart
run: |
rsync -r $LEGACY_HELM_CHART $HELM_CHARTS_DIR
rsync -r $HELM_CHART/* $LEGACY_HELM_CHART --exclude=Chart.yaml --exclude=crds
- name: Prepare vela chart
run: |
rsync -r $VELA_ROLLOUT_HELM_CHART $HELM_CHARTS_DIR
- uses: oprypin/find-latest-tag@v1
with:
repository: oam-dev/kubevela
releases-only: true
id: latest_tag
- name: Tag helm chart image
run: |
latest_repo_tag=${{ steps.latest_tag.outputs.tag }}
sub="."
major="$(cut -d"$sub" -f1 <<<"$latest_repo_tag")"
minor="$(cut -d"$sub" -f2 <<<"$latest_repo_tag")"
patch="0"
current_repo_tag="$major.$minor.$patch"
image_tag=${GITHUB_REF#refs/tags/}
chart_version=$latest_repo_tag
if [[ ${GITHUB_REF} == "refs/heads/master" ]]; then
image_tag=latest
chart_version=${current_repo_tag}-nightly-build
fi
sed -i "s/latest/${image_tag}/g" $HELM_CHART/values.yaml
sed -i "s/latest/${image_tag}/g" $MINIMAL_HELM_CHART/values.yaml
sed -i "s/latest/${image_tag}/g" $LEGACY_HELM_CHART/values.yaml
sed -i "s/latest/${image_tag}/g" $OAM_RUNTIME_HELM_CHART/values.yaml
sed -i "s/latest/${image_tag}/g" $VELA_ROLLOUT_HELM_CHART/values.yaml
chart_smever=${chart_version#"v"}
sed -i "s/0.1.0/$chart_smever/g" $HELM_CHART/Chart.yaml
sed -i "s/0.1.0/$chart_smever/g" $MINIMAL_HELM_CHART/Chart.yaml
sed -i "s/0.1.0/$chart_smever/g" $LEGACY_HELM_CHART/Chart.yaml
sed -i "s/0.1.0/$chart_smever/g" $OAM_RUNTIME_HELM_CHART/Chart.yaml
sed -i "s/0.1.0/$chart_smever/g" $VELA_ROLLOUT_HELM_CHART/Chart.yaml
- name: Install ossutil
run: wget http://gosspublic.alicdn.com/ossutil/1.7.0/ossutil64 && chmod +x ossutil64 && mv ossutil64 ossutil
- name: Configure Alibaba Cloud OSSUTIL
run: ./ossutil --config-file .ossutilconfig config -i ${ACCESS_KEY} -k ${ACCESS_KEY_SECRET} -e ${ENDPOINT} -c .ossutilconfig
- name: sync cloud to local
run: ./ossutil --config-file .ossutilconfig sync oss://$BUCKET/core $LOCAL_OSS_DIRECTORY
- name: add artifacthub stuff to the repo
run: |
rsync $HELM_CHART/README.md $LEGACY_HELM_CHART/README.md
rsync $HELM_CHART/README.md $OAM_RUNTIME_HELM_CHART/README.md
rsync $HELM_CHART/README.md $VELA_ROLLOUT_HELM_CHART/README.md
sed -i "s/ARTIFACT_HUB_REPOSITORY_ID/$ARTIFACT_HUB_REPOSITORY_ID/g" hack/artifacthub/artifacthub-repo.yml
rsync hack/artifacthub/artifacthub-repo.yml $LOCAL_OSS_DIRECTORY
- name: Package helm charts
run: |
helm package $HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm package $MINIMAL_HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm package $LEGACY_HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm package $OAM_RUNTIME_HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm package $VELA_ROLLOUT_HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm repo index --url https://$BUCKET.$ENDPOINT/core $LOCAL_OSS_DIRECTORY
- name: sync local to cloud
run: ./ossutil --config-file .ossutilconfig sync $LOCAL_OSS_DIRECTORY oss://$BUCKET/core -f
publish-capabilities:
env:
@@ -165,4 +227,4 @@ jobs:
- name: rsync all capabilites
run: rsync vela-templates/registry/auto-gen/* $CAPABILITY_DIR
- name: sync local to cloud
run: ./ossutil --config-file .ossutilconfig sync $CAPABILITY_DIR oss://$CAPABILITY_BUCKET -f -u
run: ./ossutil --config-file .ossutilconfig sync $CAPABILITY_DIR oss://$CAPABILITY_BUCKET -f

View File

@@ -8,10 +8,6 @@ on:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BUCKET: ${{ secrets.CLI_OSS_BUCKET }}
ENDPOINT: ${{ secrets.CLI_OSS_ENDPOINT }}
ACCESS_KEY: ${{ secrets.CLI_OSS_ACCESS_KEY }}
ACCESS_KEY_SECRET: ${{ secrets.CLI_OSS_ACCESS_KEY_SECRET }}
jobs:
build:
@@ -108,23 +104,6 @@ jobs:
name: sha256sums
path: ./_bin/sha256-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.txt
retention-days: 1
- name: clear the asset
run: |
rm -rf ./_bin/vela/${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}
mv ./_bin/vela/vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz ./_bin/vela/vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
mv ./_bin/vela/vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip ./_bin/vela/vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
- name: Install ossutil
run: wget http://gosspublic.alicdn.com/ossutil/1.7.0/ossutil64 && chmod +x ossutil64 && mv ossutil64 ossutil
- name: Configure Alibaba Cloud OSSUTIL
run: ./ossutil --config-file .ossutilconfig config -i ${ACCESS_KEY} -k ${ACCESS_KEY_SECRET} -e ${ENDPOINT} -c .ossutilconfig
- name: sync local to cloud
run: ./ossutil --config-file .ossutilconfig sync ./_bin/vela oss://$BUCKET/binary/vela/${{ env.VELA_VERSION }}
- name: sync the latest version file
run: |
echo ${{ env.VELA_VERSION }} > ./latest_version
./ossutil --config-file .ossutilconfig cp -u ./latest_version oss://$BUCKET/binary/vela/latest_version
upload-plugin-homebrew:
needs: build

View File

@@ -58,7 +58,7 @@ jobs:
restore-keys: ${{ runner.os }}-pkg-
- name: Install ginkgo
run: |
run: |
sudo apt-get install -y golang-ginkgo-dev
- name: Setup Kind Cluster
@@ -72,7 +72,7 @@ jobs:
version: 3.1.0
kubebuilderOnly: false
kubernetesVersion: v1.21.2
- name: Run Make test
run: make test

View File

@@ -10,6 +10,7 @@ Reviewers:
- devholic
- fourierr
- JooKS-me
- s4rd1nh4
Approvers:
- Somefive (Multi-Cluster)

View File

@@ -45,7 +45,7 @@ Full documentation is available on the [KubeVela website](https://kubevela.io/).
## Community
- Slack: [CNCF Slack](https://slack.cncf.io/) #kubevela channel (*English*)
- Slack: [CNCF Slack kubevela channel](https://cloud-native.slack.com/archives/C01BLQ3HTJA) (*English*)
- Gitter: [oam-dev](https://gitter.im/oam-dev/community) (*English*)
- [DingTalk Group](https://page.dingtalk.com/wow/dingtalk/act/en-home): `23310022` (*Chinese*)
- Wechat Group (*Chinese*): Broker wechat to add you into the user group.

View File

@@ -0,0 +1,22 @@
/*
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 common
const (
// Group api group name
Group = "core.oam.dev"
)

View File

@@ -345,6 +345,8 @@ type WorkflowStatus struct {
Mode WorkflowMode `json:"mode"`
Message string `json:"message,omitempty"`
SuspendState string `json:"suspendState,omitempty"`
Suspend bool `json:"suspend"`
Terminated bool `json:"terminated"`
Finished bool `json:"finished"`
@@ -496,6 +498,8 @@ const (
PolicyResourceCreator ResourceCreatorRole = "policy"
// WorkflowResourceCreator create the resource in workflow.
WorkflowResourceCreator ResourceCreatorRole = "workflow"
// DebugResourceCreator create the debug resource.
DebugResourceCreator ResourceCreatorRole = "debug"
)
// OAMObjectReference defines the object reference for an oam resource

View File

@@ -33,11 +33,22 @@ type GarbageCollectPolicySpec struct {
// outdated resources will be kept until resourcetracker be deleted manually
KeepLegacyResource bool `json:"keepLegacyResource,omitempty"`
// Order defines the order of garbage collect
Order GarbageCollectOrder `json:"order,omitempty"`
// Rules defines list of rules to control gc strategy at resource level
// if one resource is controlled by multiple rules, first rule will be used
Rules []GarbageCollectPolicyRule `json:"rules,omitempty"`
}
// GarbageCollectOrder is the order of garbage collect
type GarbageCollectOrder string
const (
// OrderDependency is the order of dependency
OrderDependency GarbageCollectOrder = "dependency"
)
// GarbageCollectPolicyRule defines a single garbage-collect policy rule
type GarbageCollectPolicyRule struct {
Selector GarbageCollectPolicyRuleSelector `json:"selector"`
@@ -45,12 +56,13 @@ type GarbageCollectPolicyRule struct {
}
// GarbageCollectPolicyRuleSelector select the targets of the rule
// if both traitTypes and componentTypes are specified, combination logic is OR
// if both traitTypes, oamTypes and componentTypes are specified, combination logic is OR
// if one resource is specified with conflict strategies, strategy as component go first.
type GarbageCollectPolicyRuleSelector struct {
CompNames []string `json:"componentNames"`
CompTypes []string `json:"componentTypes"`
TraitTypes []string `json:"traitTypes"`
CompNames []string `json:"componentNames"`
CompTypes []string `json:"componentTypes"`
OAMResourceTypes []string `json:"oamTypes"`
TraitTypes []string `json:"traitTypes"`
}
// GarbageCollectStrategy the strategy for target resource to recycle
@@ -69,10 +81,11 @@ const (
// FindStrategy find gc strategy for target resource
func (in GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstructured) *GarbageCollectStrategy {
for _, rule := range in.Rules {
var compName, compType, traitType string
var compName, compType, oamType, traitType string
if labels := manifest.GetLabels(); labels != nil {
compName = labels[oam.LabelAppComponent]
compType = labels[oam.WorkloadTypeLabel]
oamType = labels[oam.LabelOAMResourceType]
traitType = labels[oam.TraitTypeLabel]
}
match := func(src []string, val string) (found bool) {
@@ -83,6 +96,7 @@ func (in GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstructu
}
if match(rule.Selector.CompNames, compName) ||
match(rule.Selector.CompTypes, compType) ||
match(rule.Selector.OAMResourceTypes, oamType) ||
match(rule.Selector.TraitTypes, traitType) {
return &rule.Strategy
}

View File

@@ -109,6 +109,18 @@ func TestGarbageCollectPolicySpec_FindStrategy(t *testing.T) {
}},
expectStrategy: GarbageCollectStrategyNever,
},
"resource type rule match": {
rules: []GarbageCollectPolicyRule{{
Selector: GarbageCollectPolicyRuleSelector{OAMResourceTypes: []string{"TRAIT"}},
Strategy: GarbageCollectStrategyNever,
}},
input: &unstructured.Unstructured{Object: map[string]interface{}{
"metadata": map[string]interface{}{
"labels": map[string]interface{}{oam.LabelOAMResourceType: "TRAIT"},
},
}},
expectStrategy: GarbageCollectStrategyNever,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {

View File

@@ -21,6 +21,8 @@ const (
TopologyPolicyType = "topology"
// OverridePolicyType refers to the type of override policy
OverridePolicyType = "override"
// DebugPolicyType refers to the type of debug policy
DebugPolicyType = "debug"
)
// TopologyPolicySpec defines the spec of topology policy

View File

@@ -19,11 +19,13 @@ package v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
)
// Package type metadata.
const (
Group = "core.oam.dev"
Group = common.Group
Version = "v1alpha1"
)

View File

@@ -291,6 +291,11 @@ func (in *GarbageCollectPolicyRuleSelector) DeepCopyInto(out *GarbageCollectPoli
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.OAMResourceTypes != nil {
in, out := &in.OAMResourceTypes, &out.OAMResourceTypes
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.TraitTypes != nil {
in, out := &in.TraitTypes, &out.TraitTypes
*out = make([]string, len(*in))

View File

@@ -21,11 +21,13 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
)
// Package type metadata.
const (
Group = "core.oam.dev"
Group = common.Group
Version = "v1alpha2"
)

View File

@@ -43,6 +43,9 @@ type PolicyDefinitionStatus struct {
// ConditionedStatus reflects the observed status of a resource
condition.ConditionedStatus `json:",inline"`
// ConfigMapRef refer to a ConfigMap which contains OpenAPI V3 JSON schema of Component parameters.
ConfigMapRef string `json:"configMapRef,omitempty"`
// LatestRevision of the component definition
// +optional
LatestRevision *common.Revision `json:"latestRevision,omitempty"`

View File

@@ -21,11 +21,13 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
)
// Package type metadata.
const (
Group = "core.oam.dev"
Group = common.Group
Version = "v1beta1"
)

View File

@@ -192,7 +192,7 @@ func (in *ResourceTracker) findMangedResourceIndex(mr ManagedResource) int {
}
// AddManagedResource add object to managed resources, if exists, update
func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool) (updated bool) {
func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool, creator common.ResourceCreatorRole) (updated bool) {
gvk := rsc.GetObjectKind().GroupVersionKind()
mr := ManagedResource{
ClusterObjectReference: common.ClusterObjectReference{
@@ -210,6 +210,9 @@ func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool)
if !metaOnly {
mr.Data = &runtime.RawExtension{Object: rsc}
}
if creator != "" {
mr.ClusterObjectReference.Creator = creator
}
if idx := in.findMangedResourceIndex(mr); idx >= 0 {
if reflect.DeepEqual(in.Spec.ManagedResources[idx], mr) {
return false

View File

@@ -156,16 +156,16 @@ func TestResourceTracker_ManagedResource(t *testing.T) {
r := require.New(t)
input := &ResourceTracker{}
deploy1 := v12.Deployment{ObjectMeta: v13.ObjectMeta{Name: "deploy1"}}
input.AddManagedResource(&deploy1, true)
input.AddManagedResource(&deploy1, true, "")
r.Equal(1, len(input.Spec.ManagedResources))
cm2 := v1.ConfigMap{ObjectMeta: v13.ObjectMeta{Name: "cm2"}}
input.AddManagedResource(&cm2, false)
input.AddManagedResource(&cm2, false, "")
r.Equal(2, len(input.Spec.ManagedResources))
pod3 := v1.Pod{ObjectMeta: v13.ObjectMeta{Name: "pod3"}}
input.AddManagedResource(&pod3, false)
input.AddManagedResource(&pod3, false, "")
r.Equal(3, len(input.Spec.ManagedResources))
deploy1.Spec.Replicas = pointer.Int32(5)
input.AddManagedResource(&deploy1, false)
input.AddManagedResource(&deploy1, false, "")
r.Equal(3, len(input.Spec.ManagedResources))
input.DeleteManagedResource(&cm2, false)
r.Equal(3, len(input.Spec.ManagedResources))

View File

@@ -18,6 +18,13 @@ package types
import "github.com/oam-dev/kubevela/pkg/oam"
const (
// KubeVelaName name of kubevela
KubeVelaName = "kubevela"
// VelaCoreName name of vela-core
VelaCoreName = "vela-core"
)
const (
// DefaultKubeVelaReleaseName defines the default name of KubeVela Release
DefaultKubeVelaReleaseName = "kubevela"
@@ -150,13 +157,11 @@ const (
)
const (
// TerraformComponentPrefix is the prefix of component type of terraform-xxx
TerraformComponentPrefix = "terraform-"
// ProviderAppPrefix is the prefix of the application to create a Terraform Provider
ProviderAppPrefix = "config-terraform-provider"
// ProviderNamespace is the namespace of Terraform Cloud Provider
ProviderNamespace = "default"
// VelaCoreConfig is to mark application, config and its secret or Terraform provider lelong to a KubeVela config
VelaCoreConfig = "velacore-config"
// TerrfaormComponentPrefix is the prefix of component type of terraform-xxx
TerrfaormComponentPrefix = "terraform-"
)
const (
// ClusterGatewayAccessorGroup the group to impersonate which allows the access to the cluster-gateway
ClusterGatewayAccessorGroup = "cluster-gateway-accessor"
)

View File

@@ -78,6 +78,22 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
| `healthCheck.port` | KubeVela health check port | `9440` |
### KubeVela controller optimization parameters
| Name | Description | Value |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| `optimize.optimizeCachedGvks` | Optimize types of resources to be cached. | `nil` |
| `optimize.resourceTrackerListOp` | Optimize ResourceTracker List Op by adding index. | `true` |
| `optimize.controllerReconcileLoopReduction` | Optimize ApplicationController reconcile by reducing the number of loops to reconcile application. | `false` |
| `optimize.markWithProb` | Optimize ResourceTracker GC by only run mark with probability. Side effect: outdated ResourceTracker might not be able to be removed immediately. | `0.1` |
| `optimize.disableComponentRevision` | Optimize componentRevision by disabling the creation and gc | `false` |
| `optimize.disableApplicationRevision` | Optimize ApplicationRevision by disabling the creation and gc. | `false` |
| `optimize.disableWorkflowRecorder` | Optimize workflow recorder by disabling the creation and gc. | `false` |
| `optimize.enableInMemoryWorkflowContext` | Optimize workflow by use in-memory context. | `false` |
| `optimize.disableResourceApplyDoubleCheck` | Optimize workflow by ignoring resource double check after apply. | `false` |
| `optimize.enableResourceTrackerDeleteOnlyTrigger` | Optimize resourcetracker by only trigger reconcile when resourcetracker is deleted. | `true` |
### MultiCluster parameters
| Name | Description | Value |
@@ -106,23 +122,27 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
### Common parameters
| Name | Description | Value |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- |
| `imagePullSecrets` | Image pull secrets | `[]` |
| `nameOverride` | Override name | `""` |
| `fullnameOverride` | Fullname override | `""` |
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `nil` |
| `nodeSelector` | Node selector | `{}` |
| `tolerations` | Tolerations | `[]` |
| `affinity` | Affinity | `{}` |
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
| `logDebug` | Enable debug logs for development purpose | `false` |
| `logFilePath` | If non-empty, write log files in this path | `""` |
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
| `kubeClient.qps` | The qps for reconcile clients, default is 50 | `50` |
| `kubeClient.burst` | The burst for reconcile clients, default is 100 | `100` |
| Name | Description | Value |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `imagePullSecrets` | Image pull secrets | `[]` |
| `nameOverride` | Override name | `""` |
| `fullnameOverride` | Fullname override | `""` |
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `nil` |
| `nodeSelector` | Node selector | `{}` |
| `tolerations` | Tolerations | `[]` |
| `affinity` | Affinity | `{}` |
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
| `logDebug` | Enable debug logs for development purpose | `false` |
| `logFilePath` | If non-empty, write log files in this path | `""` |
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
| `kubeClient.qps` | The qps for reconcile clients, default is 50 | `50` |
| `kubeClient.burst` | The burst for reconcile clients, default is 100 | `100` |
| `authentication.enabled` | Enable authentication for application | `false` |
| `authentication.withUser` | Application authentication will impersonate as the request User | `false` |
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided in Application | `kubevela:vela-core` |
| `authentication.groupPattern` | Application authentication will impersonate as the request Group that matches the pattern | `kubevela:*` |
## Uninstallation
@@ -164,10 +184,4 @@ To uninstall the KubeVela helm release:
$ helm uninstall -n vela-system kubevela
```
Finally, this command will remove all the Kubernetes resources associated with KubeVela and remove this chart release.
Finally, this command will remove all the Kubernetes resources associated with KubeVela and remove this chart release.

View File

@@ -934,6 +934,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:
@@ -2743,6 +2745,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:
@@ -3386,6 +3390,10 @@ spec:
- type
type: object
type: array
configMapRef:
description: ConfigMapRef refer to a ConfigMap which contains
OpenAPI V3 JSON schema of Component parameters.
type: string
latestRevision:
description: LatestRevision of the component definition
properties:
@@ -4682,6 +4690,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:

File diff suppressed because it is too large Load Diff

View File

@@ -636,6 +636,10 @@ spec:
- type
type: object
type: array
configMapRef:
description: ConfigMapRef refer to a ConfigMap which contains
OpenAPI V3 JSON schema of Component parameters.
type: string
latestRevision:
description: LatestRevision of the component definition
properties:

View File

@@ -244,6 +244,10 @@ spec:
- type
type: object
type: array
configMapRef:
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
V3 JSON schema of Component parameters.
type: string
latestRevision:
description: LatestRevision of the component definition
properties:

View File

@@ -120,6 +120,32 @@ webhooks:
- UPDATE
resources:
- podspecworkloads
- clientConfig:
caBundle: Cg==
service:
name: {{ template "kubevela.name" . }}-webhook
namespace: {{ .Release.Namespace }}
path: /mutating-core-oam-dev-v1beta1-applications
{{- if .Values.admissionWebhooks.patch.enabled }}
failurePolicy: Ignore
{{- else }}
failurePolicy: Fail
{{- end }}
name: mutating.core.oam.dev.v1beta1.applications
admissionReviewVersions:
- v1beta1
- v1
sideEffects: None
rules:
- apiGroups:
- core.oam.dev
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- applications
- clientConfig:
caBundle: Cg==
service:

View File

@@ -274,4 +274,30 @@ spec:
runAsGroup: 2000
runAsNonRoot: true
runAsUser: 2000
{{ end }}
---
{{ if and .Values.multicluster.enabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-role
rules:
- apiGroups: [ "cluster.core.oam.dev" ]
resources: [ "clustergateways/proxy" ]
verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ]
{{ end }}
---
{{ if and .Values.multicluster.enabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-role
subjects:
- kind: Group
name: cluster-gateway-accessor
apiGroup: rbac.authorization.k8s.io
{{ end }}

View File

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

View File

@@ -36,23 +36,20 @@ spec:
"config.oam.dev/sub-type": "auth"
}
}
if parameter.auth != _|_ {
type: "kubernetes.io/dockerconfigjson"
}
if parameter.auth == _|_ {
type: "Opaque"
}
if parameter.auth != _|_ {
stringData: ".dockerconfigjson": json.Marshal({
auths: "\(parameter.registry)": {
username: parameter.auth.username
password: parameter.auth.password
if parameter.auth.email != _|_ {
email: parameter.auth.email
type: "kubernetes.io/dockerconfigjson"
stringData: {
if parameter.auth != _|_ {
".dockerconfigjson": json.Marshal({
auths: "\(parameter.registry)": {
username: parameter.auth.username
password: parameter.auth.password
if parameter.auth.email != _|_ {
email: parameter.auth.email
}
auth: base64.Encode(null, (parameter.auth.username + ":" + parameter.auth.password))
}
auth: base64.Encode(null, (parameter.auth.username + ":" + parameter.auth.password))
}
})
})
}
}
}
parameter: {

View File

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

View File

@@ -46,7 +46,7 @@ spec:
}]
}
if _baseEnv != _|_ {
_baseEnvMap: {for envVar in _baseEnv {"\(envVar.name)": envVar}}
_baseEnvMap: {for envVar in _baseEnv {"\(envVar.name)": envVar.value}}
// +patchStrategy=replace
env: [ for envVar in _baseEnv if _delKeys[envVar.name] == _|_ && !_params.replace {
name: envVar.name
@@ -54,12 +54,7 @@ spec:
value: _params.env[envVar.name]
}
if _params.env[envVar.name] == _|_ {
if envVar.value != _|_ {
value: envVar.value
}
if envVar.valueFrom != _|_ {
valueFrom: envVar.valueFrom
}
value: envVar.value
}
}] + [ for k, v in _params.env if _delKeys[k] == _|_ && (_params.replace || _baseEnvMap[k] == _|_) {
name: k
@@ -97,7 +92,7 @@ spec:
}]
}
}
parameter: *#PatchParams | close({
parameter: #PatchParams | close({
// +usage=Specify the environment variables for multiple containers
containers: [...#PatchParams]
})

View File

@@ -35,6 +35,9 @@ spec:
if parameter.args != _|_ {
args: parameter.args
}
if parameter["env"] != _|_ {
env: parameter.env
}
// +patchKey=name
volumeMounts: [{
@@ -61,6 +64,31 @@ spec:
// +usage=Specify the args run in the init container
args?: [...string]
// +usage=Specify the env run in the init container
env?: [...{
// +usage=Environment variable name
name: string
// +usage=The value of the environment variable
value?: string
// +usage=Specifies a source the value of this var should come from
valueFrom?: {
// +usage=Selects a key of a secret in the pod's namespace
secretKeyRef?: {
// +usage=The name of the secret in the pod's namespace to select from
name: string
// +usage=The key of the secret to select from. Must be a valid secret key
key: string
}
// +usage=Selects a key of a config map in the pod's namespace
configMapKeyRef?: {
// +usage=The name of the config map in the pod's namespace to select from
name: string
// +usage=The key of the config map to select from. Must be a valid secret key
key: string
}
}
}]
// +usage=Specify the mount name of shared volume
mountName: *"workdir" | string

View File

@@ -27,6 +27,9 @@ spec:
if parameter.args != _|_ {
args: parameter.args
}
if parameter["env"] != _|_ {
env: parameter.env
}
if parameter["volumes"] != _|_ {
volumeMounts: [ for v in parameter.volumes {
{
@@ -35,6 +38,13 @@ spec:
}
}]
}
if parameter["livenessProbe"] != _|_ {
livenessProbe: parameter.livenessProbe
}
if parameter["readinessProbe"] != _|_ {
readinessProbe: parameter.readinessProbe
}
}]
}
parameter: {
@@ -50,10 +60,82 @@ spec:
// +usage=Specify the args in the sidecar
args?: [...string]
// +usage=Specify the env in the sidecar
env?: [...{
// +usage=Environment variable name
name: string
// +usage=The value of the environment variable
value?: string
// +usage=Specifies a source the value of this var should come from
valueFrom?: {
// +usage=Selects a key of a secret in the pod's namespace
secretKeyRef?: {
// +usage=The name of the secret in the pod's namespace to select from
name: string
// +usage=The key of the secret to select from. Must be a valid secret key
key: string
}
// +usage=Selects a key of a config map in the pod's namespace
configMapKeyRef?: {
// +usage=The name of the config map in the pod's namespace to select from
name: string
// +usage=The key of the config map to select from. Must be a valid secret key
key: string
}
}
}]
// +usage=Specify the shared volume path
volumes?: [...{
name: string
path: string
}]
// +usage=Instructions for assessing whether the container is alive.
livenessProbe?: #HealthProbe
// +usage=Instructions for assessing whether the container is in a suitable state to serve traffic.
readinessProbe?: #HealthProbe
}
#HealthProbe: {
// +usage=Instructions for assessing container health by executing a command. Either this attribute or the httpGet attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the httpGet attribute and the tcpSocket attribute.
exec?: {
// +usage=A command to be executed inside the container to assess its health. Each space delimited token of the command is a separate array element. Commands exiting 0 are considered to be successful probes, whilst all other exit codes are considered failures.
command: [...string]
}
// +usage=Instructions for assessing container health by executing an HTTP GET request. Either this attribute or the exec attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the tcpSocket attribute.
httpGet?: {
// +usage=The endpoint, relative to the port, to which the HTTP GET request should be directed.
path: string
// +usage=The TCP socket within the container to which the HTTP GET request should be directed.
port: int
httpHeaders?: [...{
name: string
value: string
}]
}
// +usage=Instructions for assessing container health by probing a TCP socket. Either this attribute or the exec attribute or the httpGet attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the httpGet attribute.
tcpSocket?: {
// +usage=The TCP socket within the container that should be probed to assess container health.
port: int
}
// +usage=Number of seconds after the container is started before the first probe is initiated.
initialDelaySeconds: *0 | int
// +usage=How often, in seconds, to execute the probe.
periodSeconds: *10 | int
// +usage=Number of seconds after which the probe times out.
timeoutSeconds: *1 | int
// +usage=Minimum consecutive successes for the probe to be considered successful after having failed.
successThreshold: *1 | int
// +usage=Number of consecutive failures required to determine the container is not alive (liveness probe) or not ready (readiness probe).
failureThreshold: *3 | int
}

View File

@@ -87,6 +87,17 @@ spec:
}
},
] | []
configMountToEnvsList: *[
for v in parameter.configMap if v.mountToEnvs != _|_ for k in v.mountToEnvs {
{
name: k.envName
valueFrom: configMapKeyRef: {
name: v.name
key: k.configMapKey
}
}
},
] | []
secretVolumeMountsList: *[
for v in parameter.secret if v.mountPath != _|_ {
{
@@ -106,6 +117,17 @@ spec:
}
},
] | []
secretMountToEnvsList: *[
for v in parameter.secret if v.mountToEnvs != _|_ for k in v.mountToEnvs {
{
name: k.envName
valueFrom: secretKeyRef: {
name: v.name
key: k.secretKey
}
}
},
] | []
emptyDirVolumeMountsList: *[
for v in parameter.emptyDir {
{
@@ -128,7 +150,7 @@ spec:
containers: [{
// +patchKey=name
env: configMapEnvMountsList + secretEnvMountsList
env: configMapEnvMountsList + secretEnvMountsList + configMountToEnvsList + secretMountToEnvsList
// +patchKey=name
volumeDevices: volumeDevicesList
// +patchKey=name
@@ -248,6 +270,10 @@ spec:
envName: string
configMapKey: string
}
mountToEnvs?: [...{
envName: string
configMapKey: string
}]
mountPath?: string
defaultMode: *420 | int
readOnly: *false | bool
@@ -267,6 +293,10 @@ spec:
envName: string
secretKey: string
}
mountToEnvs?: [...{
envName: string
secretKey: string
}]
mountPath?: string
defaultMode: *420 | int
readOnly: *false | bool

View File

@@ -11,6 +11,8 @@ spec:
schematic:
cue:
template: |
// no parameters
parameter: {}
parameter: {
// +usage=Specify the wait duration time to resume workflow such as "30s", "1min" or "2m15s"
duration?: string
}

View File

@@ -132,9 +132,10 @@ spec:
parameter.labels
}
if parameter.addRevisionLabel {
"app.oam.dev/revision": context.revision
"app.oam.dev/appRevision": context.appRevision
}
"app.oam.dev/component": context.name
"app.oam.dev/revision": context.revision
}
if parameter.annotations != _|_ {
annotations: parameter.annotations
@@ -332,7 +333,7 @@ spec:
exposeType: *"ClusterIP" | "NodePort" | "LoadBalancer" | "ExternalName"
// +ignore
// +usage=If addRevisionLabel is true, the revision label will be added to the underlying pods
// +usage=If addRevisionLabel is true, the appRevision label will be added to the underlying pods
addRevisionLabel: *false | bool
// +usage=Commands to run in the container

View File

@@ -25,6 +25,9 @@ subjects:
- kind: ServiceAccount
name: {{ include "kubevela.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
- kind: Group
name: core.oam.dev
apiGroup: rbac.authorization.k8s.io
---
# permissions to do leader election.
@@ -121,6 +124,36 @@ spec:
- "--webhook-port={{ .Values.webhookService.port }}"
- "--webhook-cert-dir={{ .Values.admissionWebhooks.certificate.mountPath }}"
{{ end }}
{{ if ne .Values.optimize.cachedGvks "" }}
- "--optimize-cached-gvks={{ .Values.optimize.cachedGvks }}"
{{ end }}
{{ if not .Values.optimize.resourceTrackerListOp }}
- "--optimize-resource-tracker-list-op=false"
{{ end }}
{{ if .Values.optimize.controllerReconcileLoopReduction }}
- "--optimize-controller-reconcile-loop-reduction"
{{ end }}
{{ if .Values.optimize.markWithProb }}
- "--optimize-mark-with-prob={{ .Values.optimize.markWithProb }}"
{{ end }}
{{ if .Values.optimize.disableComponentRevision }}
- "--optimize-disable-component-revision"
{{ end }}
{{ if .Values.optimize.disableApplicationRevision }}
- "--optimize-disable-application-revision"
{{ end }}
{{ if .Values.optimize.disableWorkflowRecorder }}
- "--optimize-disable-workflow-recorder"
{{ end }}
{{ if .Values.optimize.enableInMemoryWorkflowContext }}
- "--optimize-enable-in-memory-workflow-context"
{{ end }}
{{ if .Values.optimize.disableResourceApplyDoubleCheck }}
- "--optimize-disable-resource-apply-double-check"
{{ end }}
{{ if not .Values.optimize.enableResourceTrackerDeleteOnlyTrigger }}
- "--optimize-enable-resource-tracker-delete-only-trigger=false"
{{ end }}
- "--health-addr=:{{ .Values.healthCheck.port }}"
{{ if ne .Values.disableCaps "" }}
- "--disable-caps={{ .Values.disableCaps }}"
@@ -139,6 +172,14 @@ spec:
- "--max-workflow-wait-backoff-time={{ .Values.workflow.backoff.maxTime.waitState }}"
- "--max-workflow-failed-backoff-time={{ .Values.workflow.backoff.maxTime.failedState }}"
- "--max-workflow-step-error-retry-times={{ .Values.workflow.step.errorRetryTimes }}"
- "--feature-gates=AuthenticateApplication={{- .Values.authentication.enabled | toString -}}"
{{ if .Values.authentication.enabled }}
{{ if .Values.authentication.withUser }}
- "--authentication-with-user"
{{ end }}
- "--authentication-default-user={{ .Values.authentication.defaultUser }}"
- "--authentication-group-pattern={{ .Values.authentication.groupPattern }}"
{{ end }}
image: {{ .Values.imageRegistry }}{{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: {{ quote .Values.image.pullPolicy }}
resources:
@@ -186,4 +227,4 @@ spec:
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- end }}

View File

@@ -84,6 +84,28 @@ webhookService:
healthCheck:
port: 9440
## @section KubeVela controller optimization parameters
##@param optimize.optimizeCachedGvks Optimize types of resources to be cached.
##@param optimize.resourceTrackerListOp Optimize ResourceTracker List Op by adding index.
##@param optimize.controllerReconcileLoopReduction Optimize ApplicationController reconcile by reducing the number of loops to reconcile application.
##@param optimize.markWithProb Optimize ResourceTracker GC by only run mark with probability. Side effect: outdated ResourceTracker might not be able to be removed immediately.
##@param optimize.disableComponentRevision Optimize componentRevision by disabling the creation and gc
##@param optimize.disableApplicationRevision Optimize ApplicationRevision by disabling the creation and gc.
##@param optimize.disableWorkflowRecorder Optimize workflow recorder by disabling the creation and gc.
##@param optimize.enableInMemoryWorkflowContext Optimize workflow by use in-memory context.
##@param optimize.disableResourceApplyDoubleCheck Optimize workflow by ignoring resource double check after apply.
##@param optimize.enableResourceTrackerDeleteOnlyTrigger Optimize resourcetracker by only trigger reconcile when resourcetracker is deleted.
optimize:
optimizeCachedGvks:
resourceTrackerListOp: true
controllerReconcileLoopReduction: false
markWithProb: 0.1
disableComponentRevision: false
disableApplicationRevision: false
disableWorkflowRecorder: false
enableInMemoryWorkflowContext: false
disableResourceApplyDoubleCheck: false
enableResourceTrackerDeleteOnlyTrigger: true
## @section MultiCluster parameters
@@ -210,3 +232,13 @@ admissionWebhooks:
kubeClient:
qps: 50
burst: 100
## @param authentication.enabled Enable authentication for application
## @param authentication.withUser Application authentication will impersonate as the request User
## @param authentication.defaultUser Application authentication will impersonate as the User if no user provided in Application
## @param authentication.groupPattern Application authentication will impersonate as the request Group that matches the pattern
authentication:
enabled: false
withUser: false
defaultUser: kubevela:vela-core
groupPattern: kubevela:*

View File

@@ -125,22 +125,26 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-minimal --
### Common parameters
| Name | Description | Value |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------- |
| `imagePullSecrets` | Image pull secrets | `[]` |
| `nameOverride` | Override name | `""` |
| `fullnameOverride` | Fullname override | `""` |
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `nil` |
| `nodeSelector` | Node selector | `{}` |
| `tolerations` | Tolerations | `[]` |
| `affinity` | Affinity | `{}` |
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
| `logDebug` | Enable debug logs for development purpose | `false` |
| `logFilePath` | If non-empty, write log files in this path | `""` |
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
| `kubeClient.qps` | The qps for reconcile clients, default is 50 | `50` |
| `kubeClient.burst` | The burst for reconcile clients, default is 100 | `100` |
| Name | Description | Value |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| `imagePullSecrets` | Image pull secrets | `[]` |
| `nameOverride` | Override name | `""` |
| `fullnameOverride` | Fullname override | `""` |
| `serviceAccount.create` | Specifies whether a service account should be created | `true` |
| `serviceAccount.annotations` | Annotations to add to the service account | `{}` |
| `serviceAccount.name` | The name of the service account to use. If not set and create is true, a name is generated using the fullname template | `nil` |
| `nodeSelector` | Node selector | `{}` |
| `tolerations` | Tolerations | `[]` |
| `affinity` | Affinity | `{}` |
| `rbac.create` | Specifies whether a RBAC role should be created | `true` |
| `logDebug` | Enable debug logs for development purpose | `false` |
| `logFilePath` | If non-empty, write log files in this path | `""` |
| `logFileMaxSize` | Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. | `1024` |
| `kubeClient.qps` | The qps for reconcile clients, default is 50 | `50` |
| `kubeClient.burst` | The burst for reconcile clients, default is 100 | `100` |
| `authentication.enabled` | Enable authentication for application | `false` |
| `authentication.withUser` | Application authentication will impersonate as the request User | `false` |
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided in Application | `kubevela:vela-core` |
| `authentication.groupPattern` | Application authentication will impersonate as the request Group that matches the pattern | `kubevela:*` |

View File

@@ -934,6 +934,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:
@@ -2743,6 +2745,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:
@@ -3386,6 +3390,10 @@ spec:
- type
type: object
type: array
configMapRef:
description: ConfigMapRef refer to a ConfigMap which contains
OpenAPI V3 JSON schema of Component parameters.
type: string
latestRevision:
description: LatestRevision of the component definition
properties:
@@ -4682,6 +4690,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:

File diff suppressed because it is too large Load Diff

View File

@@ -636,6 +636,10 @@ spec:
- type
type: object
type: array
configMapRef:
description: ConfigMapRef refer to a ConfigMap which contains
OpenAPI V3 JSON schema of Component parameters.
type: string
latestRevision:
description: LatestRevision of the component definition
properties:

View File

@@ -244,6 +244,10 @@ spec:
- type
type: object
type: array
configMapRef:
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
V3 JSON schema of Component parameters.
type: string
latestRevision:
description: LatestRevision of the component definition
properties:

View File

@@ -92,6 +92,32 @@ webhooks:
- UPDATE
resources:
- podspecworkloads
- clientConfig:
caBundle: Cg==
service:
name: {{ template "kubevela.name" . }}-webhook
namespace: {{ .Release.Namespace }}
path: /mutating-core-oam-dev-v1beta1-applications
{{- if .Values.admissionWebhooks.patch.enabled }}
failurePolicy: Ignore
{{- else }}
failurePolicy: Fail
{{- end }}
name: mutating.core.oam.dev.v1beta1.applications
admissionReviewVersions:
- v1beta1
- v1
sideEffects: None
rules:
- apiGroups:
- core.oam.dev
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- applications
- clientConfig:
caBundle: Cg==
service:

View File

@@ -188,4 +188,30 @@ spec:
runAsGroup: 2000
runAsNonRoot: true
runAsUser: 2000
{{ end }}
{{ end }}
---
{{ if and .Values.multicluster.enabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-role
rules:
- apiGroups: [ "cluster.core.oam.dev" ]
resources: [ "clustergateways/proxy" ]
verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ]
{{ end }}
---
{{ if and .Values.multicluster.enabled }}
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "kubevela.fullname" . }}:cluster-gateway-access-role
subjects:
- kind: Group
name: cluster-gateway-accessor
apiGroup: rbac.authorization.k8s.io
{{ end }}

View File

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

View File

@@ -36,23 +36,20 @@ spec:
"config.oam.dev/sub-type": "auth"
}
}
if parameter.auth != _|_ {
type: "kubernetes.io/dockerconfigjson"
}
if parameter.auth == _|_ {
type: "Opaque"
}
if parameter.auth != _|_ {
stringData: ".dockerconfigjson": json.Marshal({
auths: "\(parameter.registry)": {
username: parameter.auth.username
password: parameter.auth.password
if parameter.auth.email != _|_ {
email: parameter.auth.email
type: "kubernetes.io/dockerconfigjson"
stringData: {
if parameter.auth != _|_ {
".dockerconfigjson": json.Marshal({
auths: "\(parameter.registry)": {
username: parameter.auth.username
password: parameter.auth.password
if parameter.auth.email != _|_ {
email: parameter.auth.email
}
auth: base64.Encode(null, (parameter.auth.username + ":" + parameter.auth.password))
}
auth: base64.Encode(null, (parameter.auth.username + ":" + parameter.auth.password))
}
})
})
}
}
}
parameter: {

View File

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

View File

@@ -46,7 +46,7 @@ spec:
}]
}
if _baseEnv != _|_ {
_baseEnvMap: {for envVar in _baseEnv {"\(envVar.name)": envVar}}
_baseEnvMap: {for envVar in _baseEnv {"\(envVar.name)": envVar.value}}
// +patchStrategy=replace
env: [ for envVar in _baseEnv if _delKeys[envVar.name] == _|_ && !_params.replace {
name: envVar.name
@@ -54,12 +54,7 @@ spec:
value: _params.env[envVar.name]
}
if _params.env[envVar.name] == _|_ {
if envVar.value != _|_ {
value: envVar.value
}
if envVar.valueFrom != _|_ {
valueFrom: envVar.valueFrom
}
value: envVar.value
}
}] + [ for k, v in _params.env if _delKeys[k] == _|_ && (_params.replace || _baseEnvMap[k] == _|_) {
name: k
@@ -97,7 +92,7 @@ spec:
}]
}
}
parameter: *#PatchParams | close({
parameter: #PatchParams | close({
// +usage=Specify the environment variables for multiple containers
containers: [...#PatchParams]
})

View File

@@ -35,6 +35,9 @@ spec:
if parameter.args != _|_ {
args: parameter.args
}
if parameter["env"] != _|_ {
env: parameter.env
}
// +patchKey=name
volumeMounts: [{
@@ -61,6 +64,31 @@ spec:
// +usage=Specify the args run in the init container
args?: [...string]
// +usage=Specify the env run in the init container
env?: [...{
// +usage=Environment variable name
name: string
// +usage=The value of the environment variable
value?: string
// +usage=Specifies a source the value of this var should come from
valueFrom?: {
// +usage=Selects a key of a secret in the pod's namespace
secretKeyRef?: {
// +usage=The name of the secret in the pod's namespace to select from
name: string
// +usage=The key of the secret to select from. Must be a valid secret key
key: string
}
// +usage=Selects a key of a config map in the pod's namespace
configMapKeyRef?: {
// +usage=The name of the config map in the pod's namespace to select from
name: string
// +usage=The key of the config map to select from. Must be a valid secret key
key: string
}
}
}]
// +usage=Specify the mount name of shared volume
mountName: *"workdir" | string

View File

@@ -27,6 +27,9 @@ spec:
if parameter.args != _|_ {
args: parameter.args
}
if parameter["env"] != _|_ {
env: parameter.env
}
if parameter["volumes"] != _|_ {
volumeMounts: [ for v in parameter.volumes {
{
@@ -35,6 +38,13 @@ spec:
}
}]
}
if parameter["livenessProbe"] != _|_ {
livenessProbe: parameter.livenessProbe
}
if parameter["readinessProbe"] != _|_ {
readinessProbe: parameter.readinessProbe
}
}]
}
parameter: {
@@ -50,10 +60,82 @@ spec:
// +usage=Specify the args in the sidecar
args?: [...string]
// +usage=Specify the env in the sidecar
env?: [...{
// +usage=Environment variable name
name: string
// +usage=The value of the environment variable
value?: string
// +usage=Specifies a source the value of this var should come from
valueFrom?: {
// +usage=Selects a key of a secret in the pod's namespace
secretKeyRef?: {
// +usage=The name of the secret in the pod's namespace to select from
name: string
// +usage=The key of the secret to select from. Must be a valid secret key
key: string
}
// +usage=Selects a key of a config map in the pod's namespace
configMapKeyRef?: {
// +usage=The name of the config map in the pod's namespace to select from
name: string
// +usage=The key of the config map to select from. Must be a valid secret key
key: string
}
}
}]
// +usage=Specify the shared volume path
volumes?: [...{
name: string
path: string
}]
// +usage=Instructions for assessing whether the container is alive.
livenessProbe?: #HealthProbe
// +usage=Instructions for assessing whether the container is in a suitable state to serve traffic.
readinessProbe?: #HealthProbe
}
#HealthProbe: {
// +usage=Instructions for assessing container health by executing a command. Either this attribute or the httpGet attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the httpGet attribute and the tcpSocket attribute.
exec?: {
// +usage=A command to be executed inside the container to assess its health. Each space delimited token of the command is a separate array element. Commands exiting 0 are considered to be successful probes, whilst all other exit codes are considered failures.
command: [...string]
}
// +usage=Instructions for assessing container health by executing an HTTP GET request. Either this attribute or the exec attribute or the tcpSocket attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the tcpSocket attribute.
httpGet?: {
// +usage=The endpoint, relative to the port, to which the HTTP GET request should be directed.
path: string
// +usage=The TCP socket within the container to which the HTTP GET request should be directed.
port: int
httpHeaders?: [...{
name: string
value: string
}]
}
// +usage=Instructions for assessing container health by probing a TCP socket. Either this attribute or the exec attribute or the httpGet attribute MUST be specified. This attribute is mutually exclusive with both the exec attribute and the httpGet attribute.
tcpSocket?: {
// +usage=The TCP socket within the container that should be probed to assess container health.
port: int
}
// +usage=Number of seconds after the container is started before the first probe is initiated.
initialDelaySeconds: *0 | int
// +usage=How often, in seconds, to execute the probe.
periodSeconds: *10 | int
// +usage=Number of seconds after which the probe times out.
timeoutSeconds: *1 | int
// +usage=Minimum consecutive successes for the probe to be considered successful after having failed.
successThreshold: *1 | int
// +usage=Number of consecutive failures required to determine the container is not alive (liveness probe) or not ready (readiness probe).
failureThreshold: *3 | int
}

View File

@@ -87,6 +87,17 @@ spec:
}
},
] | []
configMountToEnvsList: *[
for v in parameter.configMap if v.mountToEnvs != _|_ for k in v.mountToEnvs {
{
name: k.envName
valueFrom: configMapKeyRef: {
name: v.name
key: k.configMapKey
}
}
},
] | []
secretVolumeMountsList: *[
for v in parameter.secret if v.mountPath != _|_ {
{
@@ -106,6 +117,17 @@ spec:
}
},
] | []
secretMountToEnvsList: *[
for v in parameter.secret if v.mountToEnvs != _|_ for k in v.mountToEnvs {
{
name: k.envName
valueFrom: secretKeyRef: {
name: v.name
key: k.secretKey
}
}
},
] | []
emptyDirVolumeMountsList: *[
for v in parameter.emptyDir {
{
@@ -128,7 +150,7 @@ spec:
containers: [{
// +patchKey=name
env: configMapEnvMountsList + secretEnvMountsList
env: configMapEnvMountsList + secretEnvMountsList + configMountToEnvsList + secretMountToEnvsList
// +patchKey=name
volumeDevices: volumeDevicesList
// +patchKey=name
@@ -248,6 +270,10 @@ spec:
envName: string
configMapKey: string
}
mountToEnvs?: [...{
envName: string
configMapKey: string
}]
mountPath?: string
defaultMode: *420 | int
readOnly: *false | bool
@@ -267,6 +293,10 @@ spec:
envName: string
secretKey: string
}
mountToEnvs?: [...{
envName: string
secretKey: string
}]
mountPath?: string
defaultMode: *420 | int
readOnly: *false | bool

View File

@@ -11,6 +11,8 @@ spec:
schematic:
cue:
template: |
// no parameters
parameter: {}
parameter: {
// +usage=Specify the wait duration time to resume workflow such as "30s", "1min" or "2m15s"
duration?: string
}

View File

@@ -132,9 +132,10 @@ spec:
parameter.labels
}
if parameter.addRevisionLabel {
"app.oam.dev/revision": context.revision
"app.oam.dev/appRevision": context.appRevision
}
"app.oam.dev/component": context.name
"app.oam.dev/revision": context.revision
}
if parameter.annotations != _|_ {
annotations: parameter.annotations
@@ -332,7 +333,7 @@ spec:
exposeType: *"ClusterIP" | "NodePort" | "LoadBalancer" | "ExternalName"
// +ignore
// +usage=If addRevisionLabel is true, the revision label will be added to the underlying pods
// +usage=If addRevisionLabel is true, the appRevision label will be added to the underlying pods
addRevisionLabel: *false | bool
// +usage=Commands to run in the container

View File

@@ -27,6 +27,9 @@ subjects:
- kind: ServiceAccount
name: {{ include "kubevela.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
- kind: Group
name: core.oam.dev
apiGroup: rbac.authorization.k8s.io
---
# permissions to do leader election.
@@ -142,6 +145,14 @@ spec:
- "--max-workflow-wait-backoff-time={{ .Values.workflow.backoff.maxTime.waitState }}"
- "--max-workflow-failed-backoff-time={{ .Values.workflow.backoff.maxTime.failedState }}"
- "--max-workflow-step-error-retry-times={{ .Values.workflow.step.errorRetryTimes }}"
- "--feature-gates=AuthenticateApplication={{- .Values.authentication.enabled | toString -}}"
{{ if .Values.authentication.enabled }}
{{ if .Values.authentication.withUser }}
- "--authentication-with-user"
{{ end }}
- "--authentication-default-user={{ .Values.authentication.defaultUser }}"
- "--authentication-group-pattern={{ .Values.authentication.groupPattern }}"
{{ end }}
image: {{ .Values.imageRegistry }}{{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: {{ quote .Values.image.pullPolicy }}
resources:

View File

@@ -215,3 +215,13 @@ admissionWebhooks:
kubeClient:
qps: 50
burst: 100
## @param authentication.enabled Enable authentication for application
## @param authentication.withUser Application authentication will impersonate as the request User
## @param authentication.defaultUser Application authentication will impersonate as the User if no user provided in Application
## @param authentication.groupPattern Application authentication will impersonate as the request Group that matches the pattern
authentication:
enabled: false
withUser: false
defaultUser: kubevela:vela-core
groupPattern: kubevela:*

View File

@@ -46,6 +46,7 @@ func main() {
flag.StringVar(&s.restCfg.LeaderConfig.LockName, "lock-name", "apiserver-lock", "the lease lock resource name")
flag.DurationVar(&s.restCfg.LeaderConfig.Duration, "duration", time.Second*5, "the lease lock resource name")
flag.DurationVar(&s.restCfg.AddonCacheTime, "addon-cache-duration", time.Minute*10, "how long between two addon cache operation")
flag.BoolVar(&s.restCfg.DisableStatisticCronJob, "disable-statistic-cronJob", false, "close the system statistic info calculating cronJob")
flag.Parse()
if len(os.Args) > 2 && os.Args[1] == "build-swagger" {

View File

@@ -36,6 +36,8 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
apicommon "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/auth"
ctrlClient "github.com/oam-dev/kubevela/pkg/client"
standardcontroller "github.com/oam-dev/kubevela/pkg/controller"
@@ -50,6 +52,7 @@ import (
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
"github.com/oam-dev/kubevela/pkg/resourcekeeper"
pkgutils "github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/oam-dev/kubevela/pkg/utils/system"
"github.com/oam-dev/kubevela/pkg/utils/util"
@@ -59,10 +62,6 @@ import (
"github.com/oam-dev/kubevela/version"
)
const (
kubevelaName = "kubevela"
)
var (
scheme = common.Scheme
waitSecretTimeout = 90 * time.Second
@@ -202,10 +201,22 @@ func main() {
klog.InfoS("Vela-Core init", "definition namespace", oam.SystemDefinitonNamespace)
restConfig := ctrl.GetConfigOrDie()
restConfig.UserAgent = kubevelaName + "/" + version.GitRevision
restConfig.UserAgent = types.KubeVelaName + "/" + version.GitRevision
restConfig.QPS = float32(qps)
restConfig.Burst = burst
restConfig.Wrap(auth.NewImpersonatingRoundTripper)
restConfig.Impersonate.UserName = types.VelaCoreName
if sub := pkgutils.GetServiceAccountSubjectFromConfig(restConfig); sub != "" {
restConfig.Impersonate.UserName = sub
}
restConfig.Impersonate.Groups = []string{apicommon.Group}
klog.InfoS("Kubernetes Config Loaded",
"UserAgent", restConfig.UserAgent,
"QPS", restConfig.QPS,
"Burst", restConfig.Burst,
"Impersonate-User", restConfig.Impersonate.UserName,
"Impersonate-Group", strings.Join(restConfig.Impersonate.Groups, ","),
)
// wrapper the round tripper by multi cluster rewriter
if enableClusterGateway {
@@ -225,7 +236,7 @@ func main() {
}
ctrl.SetLogger(klogr.New())
leaderElectionID := util.GenerateLeaderElectionID(kubevelaName, controllerArgs.IgnoreAppWithoutControllerRequirement)
leaderElectionID := util.GenerateLeaderElectionID(types.KubeVelaName, controllerArgs.IgnoreAppWithoutControllerRequirement)
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,

View File

@@ -2,6 +2,8 @@
By leveraging the garbage-collect policy, users can persist some resources, which skip the normal garbage-collect process when application is updated.
### traitTypes
Take the following app as an example, in the garbage-collect policy, a rule is added which marks all the resources created by the `expose` trait to use the `onAppDelete` strategy. This will keep those services until application is deleted.
```shell
$ cat <<EOF | kubectl apply -f -
@@ -78,6 +80,8 @@ hello-world ClusterIP 10.96.160.208 <none> 8000/TCP 5m56s
hello-world-new ClusterIP 10.96.20.4 <none> 8000/TCP 13s
```
### componentTypes
Users can also keep component if they are deploying job-like components. Resources dispatched by `job-like-component` type component will be kept after application is deleted.
```yaml
@@ -100,6 +104,8 @@ spec:
strategy: never
```
### componentNames
A more straightforward way is to specify `compNames` to match specified components.
```yaml
apiVersion: core.oam.dev/v1beta1
@@ -124,3 +130,74 @@ spec:
- example-addon-namespace
strategy: never
```
### oamTypes
Users can also persist resources using `oamTypes`, where the values of `oamTypes` can be `TRAIT` and `WORKLOAD`.
```shell
$ cat <<EOF | kubectl apply -f -
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: garbage-collect-app
spec:
components:
- name: hello-world
type: webservice
properties:
image: crccheck/hello-world
traits:
- type: expose
properties:
port: [8000]
policies:
- name: garbage-collect
type: garbage-collect
properties:
rules:
- selector:
oamTypes:
- TRAIT
strategy: onAppDelete
EOF
```
And then, let's modify the component name.
```shell
$ cat <<EOF | kubectl apply -f -
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: garbage-collect-app
spec:
components:
- name: hello-world-new
type: webservice
properties:
image: crccheck/hello-world
traits:
- type: expose
properties:
port: [8000]
policies:
- name: garbage-collect
type: garbage-collect
properties:
rules:
- selector:
oamTypes:
- TRAIT
strategy: onAppDelete
EOF
```
List the service in cluster, you will find:
```shell
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-world ClusterIP 10.96.31.209 <none> 8000/TCP 31s
hello-world-new ClusterIP 10.96.17.103 <none> 8000/TCP 5s
```

View File

@@ -0,0 +1,50 @@
# How to garbage collect resources in the order of dependency
If you want to garbage collect resources in the order of dependency, you can add `order: dependency` in the `garbage-collect` policy.
> Notice that this order policy is only valid for the resources that are created in the components.
In the following example, component `test1` depends on `test2`, and `test2` need the output from `test3`.
So the order of deployment is: `test3 -> test2 -> test1`.
When we add `order: dependency` in `garbage-collect` policy and delete the application, the order of garbage collect is: `test3 -> test2 -> test1`.
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: gc-dependency
namespace: default
spec:
components:
- name: test1
type: webservice
properties:
image: crccheck/hello-world
port: 8000
dependsOn:
- "test2"
- name: test2
type: webservice
properties:
image: crccheck/hello-world
port: 8000
inputs:
- from: test3-output
parameterKey: test
- name: test3
type: webservice
properties:
image: crccheck/hello-world
port: 8000
outputs:
- name: test3-output
valueFrom: output.metadata.name
policies:
- name: gc-dependency
type: garbage-collect
properties:
order: dependency
```

View File

@@ -32,6 +32,9 @@ spec:
mountToEnv:
envName: TEST_ENV
configMapKey: key1
mountToEnvs:
- envName: TEST_CM_ENV
configMapKey: key2
data:
key1: value1
key2: value2
@@ -49,9 +52,15 @@ spec:
mountToEnv:
envName: TEST_SECRET
secretKey: key1
mountToEnvs:
- envName: TEST_SECRET_ENV_2
secretKey: key2
- envName: TEST_SECRET_ENV_3
secretKey: key3
data:
key1: dmFsdWUx
key2: dmFsdWUy
key3: dmFsdWUz
emptyDir:
- name: test1
mountPath: /test/mount/emptydir

38
go.mod
View File

@@ -5,6 +5,7 @@ go 1.17
require (
cuelang.org/go v0.2.2
github.com/AlecAivazis/survey/v2 v2.1.1
github.com/FogDong/uitable v0.0.5
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8
github.com/agiledragon/gomonkey/v2 v2.4.0
github.com/alibabacloud-go/cs-20151215/v2 v2.4.5
@@ -63,11 +64,10 @@ require (
github.com/wonderflow/cert-manager-api v1.0.3
go.mongodb.org/mongo-driver v1.5.1
go.uber.org/zap v1.18.1
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a // indirect
golang.org/x/tools v0.1.7 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/src-d/go-git.v4 v4.13.1
@@ -97,7 +97,17 @@ require (
sigs.k8s.io/yaml v1.2.0
)
require github.com/robfig/cron/v3 v3.0.1
require (
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
github.com/xanzy/go-gitlab v0.60.0
github.com/xanzy/ssh-agent v0.3.0 // indirect
golang.org/x/net v0.0.0-20220325170049-de3da57026de // indirect
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
google.golang.org/protobuf v1.28.0 // indirect
)
require (
cloud.google.com/go v0.81.0 // indirect
@@ -108,7 +118,7 @@ require (
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
github.com/Azure/go-autorest/logger v0.2.1 // indirect
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
github.com/BurntSushi/toml v0.4.1 // indirect
github.com/BurntSushi/toml v0.3.1 // indirect
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver v1.5.0 // indirect
@@ -142,8 +152,7 @@ require (
github.com/cyphar/filepath-securejoin v0.2.2 // indirect
github.com/deislabs/oras v0.11.1 // indirect
github.com/docker/cli v20.10.5+incompatible // indirect
github.com/docker/distribution v2.8.0-beta.1+incompatible // indirect
github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible // indirect
github.com/docker/docker v20.10.14+incompatible // indirect
github.com/docker/docker-credential-helpers v0.6.3 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916 // indirect
@@ -154,7 +163,7 @@ require (
github.com/emirpasic/gods v1.12.0 // indirect
github.com/evanphx/json-patch/v5 v5.1.0 // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/fatih/camelcase v1.0.0 // indirect
github.com/fatih/camelcase v1.0.0
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-logr/zapr v0.4.0 // indirect
@@ -171,7 +180,7 @@ require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/google/btree v1.0.1 // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/gofuzz v1.1.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/googleapis/gnostic v0.5.5 // indirect
@@ -186,7 +195,6 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.11 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect
github.com/klauspost/compress v1.11.0 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/kr/pty v1.1.8 // indirect
@@ -224,6 +232,7 @@ require (
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/robfig/cron/v3 v3.0.1
github.com/rogpeppe/go-internal v1.8.0 // indirect
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351 // indirect
github.com/russross/blackfriday v1.5.2 // indirect
@@ -237,7 +246,6 @@ require (
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect
github.com/tjfoc/gmsm v1.3.2 // indirect
github.com/xanzy/ssh-agent v0.3.0 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.0.2 // indirect
github.com/xdg-go/stringprep v1.0.2 // indirect
@@ -251,17 +259,15 @@ require (
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.6.0 // indirect
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect
google.golang.org/grpc v1.38.0 // indirect
google.golang.org/protobuf v1.26.0 // indirect
gopkg.in/gorp.v1 v1.7.2 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect

48
go.sum
View File

@@ -110,15 +110,16 @@ github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
github.com/FogDong/uitable v0.0.5 h1:1bJo/uvhGUC6i8JPHZCr8XKMHiDExE7mQkOCmDl0ryQ=
github.com/FogDong/uitable v0.0.5/go.mod h1:1yEaP13SkkBUj3HvqKIUWnsb42XigyZbNle84mc5kLM=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
@@ -410,8 +411,8 @@ github.com/docker/cli v20.10.9+incompatible h1:OJ7YkwQA+k2Oi51lmCojpjiygKpi76P7b
github.com/docker/cli v20.10.9+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.0-beta.1+incompatible h1:9MjVa+OTMHm4C0kKZB68jPlDM9Cg75ta4i46Gxxxn8o=
github.com/docker/distribution v2.8.0-beta.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
@@ -782,8 +783,9 @@ github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -896,8 +898,12 @@ github.com/hashicorp/consul/sdk v0.4.0/go.mod h1:fY08Y9z5SvJqevyZNy6WWPXiG3KwBPA
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-hclog v0.12.2 h1:F1fdYblUEsxKiailtkhCCG2g4bipEgaHiDc8vffNpD4=
github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-immutable-radix v1.1.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
@@ -907,6 +913,9 @@ github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4=
github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
@@ -1621,6 +1630,8 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq
github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
github.com/wonderflow/cert-manager-api v1.0.3 h1:xQQMkJNQ12oYyy00jOQUlSKgdraApaURxv3PHFdVTfA=
github.com/wonderflow/cert-manager-api v1.0.3/go.mod h1:1Se7MSg11/eNYlo4fWv6vOM55/jTBMOzg2DN1kVFiSc=
github.com/xanzy/go-gitlab v0.60.0 h1:HaIlc14k4t9eJjAhY0Gmq2fBHgKd1MthBn3+vzDtsbA=
github.com/xanzy/go-gitlab v0.60.0/go.mod h1:F0QEXwmqiBUxCgJm8fE9S+1veX4XC9Z4cfaAbqwk4YM=
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
@@ -1657,7 +1668,7 @@ github.com/yuin/goldmark v1.1.30/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43 h1:+lm10QQTNSBd8DVTNGHx7o/IKu9HYDvLMffDhbyLccI=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMztlGpl/VA+Zm1AcTPHYkHJPbHqE6WJUXE=
@@ -1799,9 +1810,8 @@ golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWP
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
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=
@@ -1845,9 +1855,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1912,11 +1921,13 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220325170049-de3da57026de h1:pZB1TWnKi+o4bENlbzAgLrEbY4RMYmUIRobMcSmfeYc=
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/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=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -2053,7 +2064,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
@@ -2084,8 +2095,9 @@ golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxb
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
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 h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs=
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs=
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/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=
@@ -2209,8 +2221,8 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a h1:ofrrl6c6NG5/IOSx/R1cyiQxxjqlur0h/TvbUhkH0II=
golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -2255,6 +2267,7 @@ google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
@@ -2363,8 +2376,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=

View File

@@ -934,6 +934,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:
@@ -2743,6 +2745,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:
@@ -3386,6 +3390,10 @@ spec:
- type
type: object
type: array
configMapRef:
description: ConfigMapRef refer to a ConfigMap which contains
OpenAPI V3 JSON schema of Component parameters.
type: string
latestRevision:
description: LatestRevision of the component definition
properties:
@@ -4682,6 +4690,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:

View File

@@ -854,6 +854,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:
@@ -1519,6 +1521,8 @@ spec:
type: array
suspend:
type: boolean
suspendState:
type: string
terminated:
type: boolean
required:

View File

@@ -636,6 +636,10 @@ spec:
- type
type: object
type: array
configMapRef:
description: ConfigMapRef refer to a ConfigMap which contains
OpenAPI V3 JSON schema of Component parameters.
type: string
latestRevision:
description: LatestRevision of the component definition
properties:

View File

@@ -244,6 +244,10 @@ spec:
- type
type: object
type: array
configMapRef:
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
V3 JSON schema of Component parameters.
type: string
latestRevision:
description: LatestRevision of the component definition
properties:

View File

@@ -47,5 +47,5 @@ VELA_CORE_TEST_IMAGE ?= vela-core-test:$(GIT_COMMIT)
VELA_APISERVER_IMAGE ?= apiserver:latest
VELA_RUNTIME_ROLLOUT_IMAGE ?= vela-runtime-rollout:latest
VELA_RUNTIME_ROLLOUT_TEST_IMAGE ?= vela-runtime-rollout-test:$(GIT_COMMIT)
RUNTIME_CLUSTER_CONFIG ?= /tmp/worker.kubeconfig
RUNTIME_CLUSTER_CONFIG ?= /tmp/worker.client.kubeconfig
RUNTIME_CLUSTER_NAME ?= worker

View File

@@ -56,7 +56,7 @@ else
CUE=$(shell which cue)
endif
KUSTOMIZE_VERSION ?= 4.5.4
KUSTOMIZE_VERSION ?= 3.8.2
.PHONY: kustomize
kustomize:

View File

@@ -15,7 +15,7 @@ setup-runtime-e2e-cluster:
.PHONY: e2e-setup
e2e-setup:
helm install kruise https://github.com/openkruise/kruise/releases/download/v0.9.0/kruise-chart.tgz --set featureGates="PreDownloadImageForInPlaceUpdate=true"
helm install kruise https://github.com/openkruise/charts/releases/download/kruise-1.1.0/kruise-1.1.0.tgz --set featureGates="PreDownloadImageForInPlaceUpdate=true"
sh ./hack/e2e/modify_charts.sh
helm upgrade --install --create-namespace --namespace vela-system --set image.pullPolicy=IfNotPresent --set image.repository=vela-core-test --set applicationRevisionLimit=5 --set dependCheckWait=10s --set image.tag=$(GIT_COMMIT) --wait kubevela ./charts/vela-core
helm upgrade --install --create-namespace --namespace oam-runtime-system --set image.pullPolicy=IfNotPresent --set image.repository=vela-core-test --set dependCheckWait=10s --set image.tag=$(GIT_COMMIT) --wait oam-runtime ./charts/oam-runtime
@@ -48,8 +48,8 @@ ADDONSERVER = $(shell pgrep vela_addon_mock_server)
e2e-apiserver-test:
pkill vela_addon_mock_server || true
go run ./e2e/addon/mock/vela_addon_mock_server.go &
go test -v -coverpkg=./... -coverprofile=/tmp/e2e_apiserver_test.out ./test/e2e-apiserver-test
sleep 15
go test -v -coverpkg=./... -coverprofile=/tmp/e2e_apiserver_test.out ./test/e2e-apiserver-test
@$(OK) tests pass
.PHONY: e2e-test

View File

@@ -36,6 +36,7 @@ import (
"github.com/google/go-github/v32/github"
"github.com/hashicorp/go-version"
"github.com/pkg/errors"
"github.com/xanzy/go-gitlab"
"golang.org/x/oauth2"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
@@ -195,10 +196,6 @@ func GetPatternFromItem(it Item, r AsyncReader, rootPath string) string {
if strings.HasPrefix(relativePath, strings.Join([]string{rootPath, p.Value}, "/")) {
return p.Value
}
if strings.HasPrefix(relativePath, filepath.Join(rootPath, p.Value)) {
// for enable addon by load dir, compatible with linux or windows os
return p.Value
}
}
return ""
}
@@ -361,7 +358,7 @@ func readResFile(a *InstallPackage, reader AsyncReader, readPath string) error {
if filename == "parameter.cue" {
return nil
}
file := ElementFile{Data: b, Name: filepath.Base(readPath)}
file := ElementFile{Data: b, Name: path.Base(readPath)}
switch filepath.Ext(filename) {
case ".cue":
a.CUETemplates = append(a.CUETemplates, file)
@@ -379,7 +376,7 @@ func readDefSchemaFile(a *InstallPackage, reader AsyncReader, readPath string) e
if err != nil {
return err
}
a.DefSchemas = append(a.DefSchemas, ElementFile{Data: b, Name: filepath.Base(readPath)})
a.DefSchemas = append(a.DefSchemas, ElementFile{Data: b, Name: path.Base(readPath)})
return nil
}
@@ -390,7 +387,7 @@ func readDefFile(a *UIData, reader AsyncReader, readPath string) error {
return err
}
filename := path.Base(readPath)
file := ElementFile{Data: b, Name: filepath.Base(readPath)}
file := ElementFile{Data: b, Name: path.Base(readPath)}
switch filepath.Ext(filename) {
case ".cue":
a.CUEDefinitions = append(a.CUEDefinitions, file)
@@ -451,6 +448,15 @@ func createGiteeHelper(content *utils.Content, token string) *giteeHelper {
}
}
func createGitlabHelper(content *utils.Content, token string) (*gitlabHelper, error) {
newClient, err := gitlab.NewClient(token, gitlab.WithBaseURL(content.GitlabContent.Host))
return &gitlabHelper{
Client: newClient,
Meta: content,
}, err
}
// readRepo will read relative path (relative to Meta.Path)
func (h *gitHelper) readRepo(relativePath string) (*github.RepositoryContent, []*github.RepositoryContent, error) {
file, items, _, err := h.Client.Repositories.GetContents(context.Background(), h.Meta.GithubContent.Owner, h.Meta.GithubContent.Repo, path.Join(h.Meta.GithubContent.Path, relativePath), nil)

View File

@@ -21,8 +21,6 @@ import (
"fmt"
"time"
"github.com/oam-dev/kubevela/pkg/utils/apply"
"github.com/oam-dev/cluster-gateway/pkg/apis/cluster/v1alpha1"
appsv1 "k8s.io/api/apps/v1"
"k8s.io/apimachinery/pkg/runtime"
@@ -364,21 +362,6 @@ var _ = Describe("func addon update ", func() {
})
})
var _ = Describe("test enable addon in local dir", func() {
BeforeEach(func() {
app := v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "vela-system", Name: "addon-example"}}
Expect(k8sClient.Delete(ctx, &app)).Should(SatisfyAny(BeNil(), util.NotFoundMatcher{}))
})
It("test enable addon by local dir", func() {
ctx := context.Background()
err := EnableAddonByLocalDir(ctx, "example", "./testdata/example", k8sClient, dc, apply.NewAPIApplicator(k8sClient), cfg, map[string]interface{}{"example": "test"})
Expect(err).Should(BeNil())
app := v1beta1.Application{}
Expect(k8sClient.Get(ctx, types2.NamespacedName{Namespace: "vela-system", Name: "addon-example"}, &app)).Should(BeNil())
})
})
const (
appYaml = `apiVersion: core.oam.dev/v1beta1
kind: Application

View File

@@ -147,7 +147,7 @@ func TestGetAddonData(t *testing.T) {
server := httptest.NewServer(ossHandler)
defer server.Close()
reader, err := NewAsyncReader(server.URL, "", "", "", ossType)
reader, err := NewAsyncReader(server.URL, "", "", "", "", ossType)
assert.NoError(t, err)
testReaderFunc(t, reader)
}
@@ -617,9 +617,9 @@ func TestRenderApp4ObservabilityWithK8sData(t *testing.T) {
}
func TestGetPatternFromItem(t *testing.T) {
ossR, err := NewAsyncReader("http://ep.beijing", "some-bucket", "some-sub-path", "", ossType)
ossR, err := NewAsyncReader("http://ep.beijing", "some-bucket", "", "some-sub-path", "", ossType)
assert.NoError(t, err)
gitR, err := NewAsyncReader("https://github.com/oam-dev/catalog", "", "addons", "", gitType)
gitR, err := NewAsyncReader("https://github.com/oam-dev/catalog", "", "", "addons", "", gitType)
assert.NoError(t, err)
gitItemName := "parameter.cue"
gitItemType := FileType
@@ -657,7 +657,7 @@ func TestGetPatternFromItem(t *testing.T) {
}
func TestGitLabReaderNotPanic(t *testing.T) {
_, err := NewAsyncReader("https://gitlab.com/test/catalog", "", "addons", "", gitType)
_, err := NewAsyncReader("https://gitlab.com/test/catalog", "", "", "addons", "", gitType)
assert.EqualError(t, err, "git type repository only support github for now")
}

View File

@@ -19,12 +19,12 @@ package addon
import (
"context"
"fmt"
"strings"
"sync"
"time"
"github.com/oam-dev/kubevela/pkg/apiserver/log"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/log"
)
// We have three addon layer here
@@ -119,27 +119,28 @@ func (u *Cache) GetUIData(r Registry, addonName, version string) (*UIData, error
// ListUIData will always list UIData from cache first, if not exist, read from source.
func (u *Cache) ListUIData(r Registry) ([]*UIData, error) {
var err error
var listAddons []*UIData
listAddons := u.listCachedUIData(r.Name)
if listAddons != nil {
return listAddons, nil
}
if !IsVersionRegistry(r) {
listAddons = u.listCachedUIData(r.Name)
if listAddons != nil {
return listAddons, nil
}
listAddons, err = u.listUIDataAndCache(r)
addonMeta, err := u.ListAddonMeta(r)
if err != nil {
return nil, err
}
} else {
listAddons = u.listVersionRegistryCachedUIData(r.Name)
if listAddons != nil {
return listAddons, nil
}
listAddons, err = u.listVersionRegistryUIDataAndCache(r)
listAddons, err = r.ListUIData(addonMeta, UIMetaOptions)
if err != nil {
return nil, fmt.Errorf("fail to get addons from registry %s, %w", r.Name, err)
}
} else {
versionedRegistry := BuildVersionedRegistry(r.Name, r.Helm.URL)
listAddons, err = versionedRegistry.ListAddon()
if err != nil {
log.Logger.Errorf("fail to get addons from registry %s for cache updating, %v", r.Name, err)
return nil, err
}
}
u.putAddonUIData2Cache(r.Name, listAddons)
return listAddons, nil
}
@@ -174,27 +175,6 @@ func (u *Cache) listCachedUIData(name string) []*UIData {
return d
}
// listVersionRegistryCachedUIData will get cached addons from specified VersionRegistry in cache
func (u *Cache) listVersionRegistryCachedUIData(name string) []*UIData {
if u == nil {
return nil
}
u.mutex.RLock()
defer u.mutex.RUnlock()
d, ok := u.versionedUIData[name]
if !ok {
return nil
}
var uiDatas []*UIData
for version, uiData := range d {
if !strings.Contains(version, "-latest") {
uiDatas = append(uiDatas, uiData)
}
}
return uiDatas
}
// getCachedAddonMeta will get cached registry meta from specified registry in cache
func (u *Cache) getCachedAddonMeta(name string) map[string]SourceMeta {
if u == nil {
@@ -280,51 +260,35 @@ func (u *Cache) discoverAndRefreshRegistry() {
for _, r := range registries {
if !IsVersionRegistry(r) {
_, err = u.listUIDataAndCache(r)
registryMeta, err := r.ListAddonMeta()
if err != nil {
log.Logger.Errorf("fail to list registry %s metadata, %v", r.Name, err)
continue
}
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)
continue
}
u.putAddonUIData2Cache(r.Name, uiData)
} else {
_, err = u.listVersionRegistryUIDataAndCache(r)
versionedRegistry := BuildVersionedRegistry(r.Name, r.Helm.URL)
uiDatas, err := versionedRegistry.ListAddon()
if err != nil {
log.Logger.Errorf("fail to get addons from registry %s for cache updating, %v", r.Name, err)
continue
}
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 registry %s, addon %s version %s for cache updating, %v", addon.Name, r.Name, err)
continue
}
u.putVersionedUIData2Cache(r.Name, addon.Name, addon.Version, uiData)
// we also no version key, if use get addonUIData without version will return this vale as latest data.
u.putVersionedUIData2Cache(r.Name, addon.Name, "latest", uiData)
}
}
}
}
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)
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)
return nil, err
}
u.putAddonUIData2Cache(r.Name, uiData)
return uiData, nil
}
func (u *Cache) listVersionRegistryUIDataAndCache(r Registry) ([]*UIData, error) {
versionedRegistry := BuildVersionedRegistry(r.Name, r.Helm.URL)
uiDatas, err := versionedRegistry.ListAddon()
if err != nil {
log.Logger.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)
continue
}
u.putVersionedUIData2Cache(r.Name, addon.Name, addon.Version, uiData)
// we also no version key, if use get addonUIData without version will return this vale as latest data.
u.putVersionedUIData2Cache(r.Name, addon.Name, "latest", uiData)
}
return uiDatas, nil
}

View File

@@ -31,63 +31,3 @@ func TestPutVersionedUIData2cache(t *testing.T) {
assert.NotEmpty(t, u.versionedUIData["helm-repo"]["fluxcd-1.0.0"])
assert.Equal(t, u.versionedUIData["helm-repo"]["fluxcd-1.0.0"].Name, "fluxcd")
}
func TestPutAddonUIData2Cache(t *testing.T) {
uiData := UIData{Meta: Meta{Name: "fluxcd", Icon: "test.com/fluxcd.png", Version: "1.0.0"}}
addons := []*UIData{&uiData}
name := "helm-repo"
u := NewCache(nil)
u.putAddonUIData2Cache(name, addons)
assert.NotEmpty(t, u.uiData)
assert.Equal(t, u.uiData[name], addons)
}
func TestListCachedUIData(t *testing.T) {
uiData := UIData{Meta: Meta{Name: "fluxcd", Icon: "test.com/fluxcd.png", Version: "1.0.0"}}
addons := []*UIData{&uiData}
name := "helm-repo"
u := NewCache(nil)
u.putAddonUIData2Cache(name, addons)
assert.Equal(t, u.listCachedUIData(name), addons)
}
func TestPutAddonMeta2Cache(t *testing.T) {
addonMeta := map[string]SourceMeta{
"fluxcd": {
Name: "fluxcd",
Items: []Item{
&OSSItem{
tp: FileType,
path: "fluxcd/definitions/helm-release.yaml",
name: "helm-release.yaml",
},
},
},
}
name := "helm-repo"
u := NewCache(nil)
u.putAddonMeta2Cache(name, addonMeta)
assert.NotEmpty(t, u.registryMeta)
assert.Equal(t, u.registryMeta[name], addonMeta)
}
func TestGetCachedAddonMeta(t *testing.T) {
addonMeta := map[string]SourceMeta{
"fluxcd": {
Name: "fluxcd",
Items: []Item{
&OSSItem{
tp: FileType,
path: "fluxcd/definitions/helm-release.yaml",
name: "helm-release.yaml",
},
},
},
}
name := "helm-repo"
u := NewCache(nil)
u.putAddonMeta2Cache(name, addonMeta)
assert.Equal(t, u.getCachedAddonMeta(name), addonMeta)
}

View File

@@ -20,7 +20,6 @@ import (
"context"
"encoding/json"
"fmt"
"path/filepath"
"k8s.io/client-go/discovery"
"k8s.io/klog/v2"
@@ -93,11 +92,7 @@ func DisableAddon(ctx context.Context, cli client.Client, name string, config *r
// EnableAddonByLocalDir enable an addon from local dir
func EnableAddonByLocalDir(ctx context.Context, name string, dir string, cli client.Client, dc *discovery.DiscoveryClient, applicator apply.Applicator, config *rest.Config, args map[string]interface{}) error {
absDir, err := filepath.Abs(dir)
if err != nil {
return err
}
r := localReader{dir: absDir, name: name}
r := localReader{dir: dir, name: name}
metas, err := r.ListAddonMeta()
if err != nil {
return err

150
pkg/addon/reader_gitlab.go Normal file
View File

@@ -0,0 +1,150 @@
/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package addon
import (
"encoding/base64"
"github.com/xanzy/go-gitlab"
"github.com/oam-dev/kubevela/pkg/utils"
)
var _ AsyncReader = &gitlabReader{}
// gitlabReader helps get addon's file by git
type gitlabReader struct {
h *gitlabHelper
}
// gitlabHelper helps get addon's file by git
type gitlabHelper struct {
Client *gitlab.Client
Meta *utils.Content
}
// GitLabItem addon's sub item
type GitLabItem struct {
basePath string
tp string
path string
name string
}
// GetType get addon's sub item type
func (g GitLabItem) GetType() string {
return g.tp
}
// GetPath get addon's sub item path
func (g GitLabItem) GetPath() string {
return g.path[len(g.basePath)+1:]
}
// GetName get addon's sub item name
func (g GitLabItem) GetName() string {
return g.name
}
// GetRef ref is empty , use default branch master
func (g *gitlabReader) GetRef() string {
var ref = "master"
if g.h.Meta.GitlabContent.Ref != "" {
return g.h.Meta.GitlabContent.Ref
}
return ref
}
// GetProjectID get gitlab project id
func (g *gitlabReader) GetProjectID() int {
return g.h.Meta.GitlabContent.PId
}
// GetProjectPath get gitlab project path
func (g *gitlabReader) GetProjectPath() string {
return g.h.Meta.GitlabContent.Path
}
// ListAddonMeta relative path to repoURL/basePath
func (g *gitlabReader) ListAddonMeta() (addonCandidates map[string]SourceMeta, err error) {
addonCandidates = make(map[string]SourceMeta)
path := g.GetProjectPath()
ref := g.GetRef()
tree, _, err := g.h.Client.Repositories.ListTree(g.GetProjectID(), &gitlab.ListTreeOptions{Path: &path, Ref: &ref})
if err != nil {
return nil, err
}
for _, node := range tree {
if node.Type == TreeType {
items, err := g.listAddonItem(make([]Item, 0), node.Path)
if err != nil {
return nil, err
}
addonCandidates[node.Name] = SourceMeta{
Name: node.Name,
Items: items,
}
}
}
return addonCandidates, nil
}
func (g *gitlabReader) listAddonItem(item []Item, path string) ([]Item, error) {
ref := g.GetRef()
tree, _, err := g.h.Client.Repositories.ListTree(g.GetProjectID(), &gitlab.ListTreeOptions{Path: &path, Ref: &ref})
if err != nil {
return item, err
}
for _, node := range tree {
switch node.Type {
case TreeType:
item, err = g.listAddonItem(item, node.Path)
if err != nil {
return nil, err
}
case BlobType:
item = append(item, &GitLabItem{
basePath: g.GetProjectPath(),
tp: FileType,
path: node.Path,
name: node.Name,
})
}
}
return item, nil
}
// ReadFile read file content from gitlab
func (g *gitlabReader) ReadFile(path string) (content string, err error) {
ref := g.GetRef()
getFile, _, err := g.h.Client.RepositoryFiles.GetFile(g.GetProjectID(), g.GetProjectPath()+"/"+path, &gitlab.GetFileOptions{Ref: &ref})
if err != nil {
return "", err
}
decodeString, err := base64.StdEncoding.DecodeString(getFile.Content)
if err != nil {
return "", err
}
return string(decodeString), nil
}
func (g *gitlabReader) RelativePath(item Item) string {
return item.GetPath()
}

View File

@@ -0,0 +1,113 @@
/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package addon
import (
"encoding/base64"
"encoding/json"
"net/http"
"net/http/httptest"
"path"
"strings"
"testing"
"github.com/stretchr/testify/assert"
"github.com/xanzy/go-gitlab"
"github.com/oam-dev/kubevela/pkg/utils"
)
var baseUrl = "/api/v4"
func gitlabSetup() (client *gitlab.Client, mux *http.ServeMux, teardown func()) {
// mux is the HTTP request multiplexer used with the test server.
mux = http.NewServeMux()
apiHandler := http.NewServeMux()
apiHandler.Handle(baseUrl+"/", http.StripPrefix(baseUrl, mux))
// server is a test HTTP server used to provide mock API responses.
server := httptest.NewServer(apiHandler)
// client is the Gitlab client being tested and is
// configured to use test server.
client, err := gitlab.NewClient("", gitlab.WithBaseURL(server.URL+baseUrl+"/"))
if err != nil {
return
}
return client, mux, server.Close
}
func TestGitlabReader(t *testing.T) {
client, mux, teardown := gitlabSetup()
gitlabPattern := "/projects/9999/repository/files/"
mux.HandleFunc(gitlabPattern, func(rw http.ResponseWriter, req *http.Request) {
queryPath := strings.TrimPrefix(req.URL.Path, gitlabPattern)
localPath := path.Join(testdataPrefix, queryPath)
file, err := testdata.ReadFile(localPath)
// test if it's a file
if err == nil {
content := &gitlab.File{
FilePath: localPath,
FileName: path.Base(queryPath),
Size: *Int(len(file)),
Encoding: "base64",
Ref: "master",
Content: base64.StdEncoding.EncodeToString(file),
}
res, _ := json.Marshal(content)
rw.Write(res)
return
}
// otherwise, it could be directory
dir, err := testdata.ReadDir(localPath)
if err == nil {
contents := make([]*gitlab.TreeNode, 0)
for _, item := range dir {
tp := "file"
if item.IsDir() {
tp = "dir"
}
contents = append(contents, &gitlab.TreeNode{
ID: "",
Name: item.Name(),
Type: tp,
Path: localPath + "/" + item.Name(),
Mode: "",
})
}
dRes, _ := json.Marshal(contents)
rw.Write(dRes)
return
}
rw.Write([]byte("invalid gitlab query"))
})
defer teardown()
gith := &gitlabHelper{
Client: client,
Meta: &utils.Content{GitlabContent: utils.GitlabContent{
PId: 9999,
}},
}
var r AsyncReader = &gitlabReader{gith}
_, err := r.ReadFile("example/metadata.yaml")
assert.NoError(t, err)
}

View File

@@ -37,10 +37,8 @@ func (l localReader) ListAddonMeta() (map[string]SourceMeta, error) {
}
func (l localReader) ReadFile(path string) (string, error) {
path = strings.TrimPrefix(path, l.name+"/")
// for windows
path = strings.TrimPrefix(path, l.name+"\\")
b, err := ioutil.ReadFile(filepath.Clean(filepath.Join(l.dir, path)))
file := strings.TrimPrefix(path, l.name+"/")
b, err := ioutil.ReadFile(filepath.Clean(filepath.Join(l.dir, file)))
if err != nil {
return "", err
}
@@ -48,8 +46,7 @@ func (l localReader) ReadFile(path string) (string, error) {
}
func (l localReader) RelativePath(item Item) string {
file := strings.TrimPrefix(item.GetPath(), filepath.Clean(l.dir))
return filepath.Join(l.name, file)
return filepath.Join(l.name, strings.TrimPrefix(item.GetPath()+"/", l.dir))
}
func recursiveFetchFiles(path string, metas *SourceMeta) error {
@@ -63,7 +60,7 @@ func recursiveFetchFiles(path string, metas *SourceMeta) error {
return err
}
} else {
metas.Items = append(metas.Items, OSSItem{tp: "file", path: filepath.Join(path, file.Name()), name: file.Name()})
metas.Items = append(metas.Items, OSSItem{tp: "file", path: fmt.Sprintf("%s/%s", path, file.Name()), name: file.Name()})
}
}
return nil

View File

@@ -37,10 +37,11 @@ const registriesKey = "registries"
type Registry struct {
Name string `json:"name"`
Helm *HelmSource `json:"helm,omitempty"`
Git *GitAddonSource `json:"git,omitempty"`
OSS *OSSAddonSource `json:"oss,omitempty"`
Gitee *GiteeAddonSource `json:"gitee,omitempty"`
Helm *HelmSource `json:"helm,omitempty"`
Git *GitAddonSource `json:"git,omitempty"`
OSS *OSSAddonSource `json:"oss,omitempty"`
Gitee *GiteeAddonSource `json:"gitee,omitempty"`
Gitlab *GitlabAddonSource `json:"gitlab,omitempty"`
}
// RegistryDataStore CRUD addon registry data in configmap

View File

@@ -24,6 +24,7 @@ import (
"github.com/go-resty/resty/v2"
"github.com/pkg/errors"
"github.com/xanzy/go-gitlab"
"github.com/oam-dev/kubevela/pkg/utils"
)
@@ -35,6 +36,10 @@ const (
DirType = "dir"
// FileType means a file
FileType = "file"
// BlobType means a blob
BlobType = "blob"
// TreeType means a tree
TreeType = "tree"
bucketTmpl = "%s://%s.%s"
singleOSSFileTmpl = "%s/%s"
@@ -63,48 +68,19 @@ type GiteeAddonSource struct {
Token string `json:"token,omitempty"`
}
// GitlabAddonSource defines the information about the Gitlab as addon source
type GitlabAddonSource struct {
URL string `json:"url,omitempty" validate:"required"`
Repo string `json:"repo,omitempty" validate:"required"`
Path string `json:"path,omitempty"`
Token string `json:"token,omitempty"`
}
// HelmSource defines the information about the helm repo addon source
type HelmSource struct {
URL string `json:"url,omitempty" validate:"required"`
}
// SafeCopier is an interface to copy Struct without sensitive fields, such as Token, Username, Password
type SafeCopier interface {
SafeCopy() interface{}
}
// SafeCopy hides field Token
func (g *GitAddonSource) SafeCopy() *GitAddonSource {
if g == nil {
return nil
}
return &GitAddonSource{
URL: g.URL,
Path: g.Path,
}
}
// SafeCopy hides field Token
func (g *GiteeAddonSource) SafeCopy() *GiteeAddonSource {
if g == nil {
return nil
}
return &GiteeAddonSource{
URL: g.URL,
Path: g.Path,
}
}
// SafeCopy hides field Username, Password
func (h *HelmSource) SafeCopy() *HelmSource {
if h == nil {
return nil
}
return &HelmSource{
URL: h.URL,
}
}
// Item is a partial interface for github.RepositoryContent
type Item interface {
// GetType return "dir" or "file"
@@ -159,15 +135,16 @@ func pathWithParent(subPath, parent string) string {
type ReaderType string
const (
gitType ReaderType = "git"
ossType ReaderType = "oss"
giteeType ReaderType = "gitee"
gitType ReaderType = "git"
ossType ReaderType = "oss"
giteeType ReaderType = "gitee"
gitlabType ReaderType = "gitlab"
)
// NewAsyncReader create AsyncReader from
// 1. GitHub url and directory
// 2. OSS endpoint and bucket
func NewAsyncReader(baseURL, bucket, subPath, token string, rdType ReaderType) (AsyncReader, error) {
func NewAsyncReader(baseURL, bucket, repo, subPath, token string, rdType ReaderType) (AsyncReader, error) {
switch rdType {
case gitType:
@@ -219,23 +196,63 @@ func NewAsyncReader(baseURL, bucket, subPath, token string, rdType ReaderType) (
return &giteeReader{
h: gitee,
}, nil
case gitlabType:
baseURL = strings.TrimSuffix(baseURL, ".git")
u, err := url.Parse(baseURL)
if err != nil {
return nil, errors.New("addon registry invalid")
}
_, content, err := utils.ParseGitlab(u.String(), repo)
content.GitlabContent.Path = subPath
if err != nil {
return nil, err
}
gitlabHelper, err := createGitlabHelper(content, token)
if err != nil {
return nil, errors.New("addon registry connect fail")
}
err = gitlabHelper.getGitlabProject(content)
if err != nil {
return nil, err
}
return &gitlabReader{
h: gitlabHelper,
}, nil
}
return nil, fmt.Errorf("invalid addon registry type '%s'", rdType)
}
// getGitlabProject get gitlab project , set project id
func (h *gitlabHelper) getGitlabProject(content *utils.Content) error {
projectURL := content.GitlabContent.Owner + "/" + content.GitlabContent.Repo
projects, _, err := h.Client.Projects.GetProject(projectURL, &gitlab.GetProjectOptions{})
if err != nil {
return err
}
content.GitlabContent.PId = projects.ID
return nil
}
// BuildReader will build a AsyncReader from registry, AsyncReader are needed to read addon files
func (r *Registry) BuildReader() (AsyncReader, error) {
if r.OSS != nil {
o := r.OSS
return NewAsyncReader(o.Endpoint, o.Bucket, o.Path, "", ossType)
return NewAsyncReader(o.Endpoint, o.Bucket, "", o.Path, "", ossType)
}
if r.Git != nil {
g := r.Git
return NewAsyncReader(g.URL, "", g.Path, g.Token, gitType)
return NewAsyncReader(g.URL, "", "", g.Path, g.Token, gitType)
}
if r.Gitee != nil {
g := r.Gitee
return NewAsyncReader(g.URL, "", g.Path, g.Token, giteeType)
return NewAsyncReader(g.URL, "", "", g.Path, g.Token, giteeType)
}
if r.Gitlab != nil {
g := r.Gitlab
return NewAsyncReader(g.URL, "", g.Repo, g.Path, g.Token, gitlabType)
}
return nil, errors.New("registry don't have enough info to build a reader")
}

View File

@@ -47,7 +47,7 @@ func TestPathWithParent(t *testing.T) {
func TestConvert2OssItem(t *testing.T) {
subPath := "sub-addons"
reader, err := NewAsyncReader("ep-beijing.com", "bucket", subPath, "", ossType)
reader, err := NewAsyncReader("ep-beijing.com", "bucket", "", subPath, "", ossType)
assert.NoError(t, err)
@@ -115,30 +115,3 @@ func TestConvert2OssItem(t *testing.T) {
assert.Equal(t, expectItemCase, addonMetas)
}
func TestSafeCopy(t *testing.T) {
var git *GitAddonSource
sgit := git.SafeCopy()
assert.Nil(t, sgit)
git = &GitAddonSource{URL: "http://github.com/kubevela", Path: "addons", Token: "123456"}
sgit = git.SafeCopy()
assert.Empty(t, sgit.Token)
assert.Equal(t, "http://github.com/kubevela", sgit.URL)
assert.Equal(t, "addons", sgit.Path)
var gitee *GiteeAddonSource
sgitee := gitee.SafeCopy()
assert.Nil(t, sgitee)
gitee = &GiteeAddonSource{URL: "http://gitee.com/kubevela", Path: "addons", Token: "123456"}
sgitee = gitee.SafeCopy()
assert.Empty(t, sgitee.Token)
assert.Equal(t, "http://gitee.com/kubevela", sgitee.URL)
assert.Equal(t, "addons", sgitee.Path)
var helm *HelmSource
shelm := helm.SafeCopy()
assert.Nil(t, shelm)
helm = &HelmSource{URL: "https://hub.vela.com/chartrepo/addons"}
shelm = helm.SafeCopy()
assert.Equal(t, "https://hub.vela.com/chartrepo/addons", shelm.URL)
}

View File

@@ -74,28 +74,31 @@ type NameAlias struct {
// CreateAddonRegistryRequest defines the format for addon registry create request
type CreateAddonRegistryRequest struct {
Name string `json:"name" validate:"checkname"`
Helm *addon.HelmSource `json:"helm,omitempty"`
Git *addon.GitAddonSource `json:"git,omitempty" `
Oss *addon.OSSAddonSource `json:"oss,omitempty"`
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
Name string `json:"name" validate:"checkname"`
Helm *addon.HelmSource `json:"helm,omitempty"`
Git *addon.GitAddonSource `json:"git,omitempty" `
Oss *addon.OSSAddonSource `json:"oss,omitempty"`
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
Gitlab *addon.GitlabAddonSource `json:"gitlab,omitempty" `
}
// UpdateAddonRegistryRequest defines the format for addon registry update request
type UpdateAddonRegistryRequest struct {
Helm *addon.HelmSource `json:"helm,omitempty"`
Git *addon.GitAddonSource `json:"git,omitempty"`
Oss *addon.OSSAddonSource `json:"oss,omitempty"`
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
Helm *addon.HelmSource `json:"helm,omitempty"`
Git *addon.GitAddonSource `json:"git,omitempty"`
Oss *addon.OSSAddonSource `json:"oss,omitempty"`
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
Gitlab *addon.GitlabAddonSource `json:"gitlab,omitempty" `
}
// AddonRegistry defines the format for a single addon registry
type AddonRegistry struct {
Name string `json:"name" validate:"required"`
Helm *addon.HelmSource `json:"helm,omitempty"`
Git *addon.GitAddonSource `json:"git,omitempty"`
OSS *addon.OSSAddonSource `json:"oss,omitempty"`
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
Name string `json:"name" validate:"required"`
Helm *addon.HelmSource `json:"helm,omitempty"`
Git *addon.GitAddonSource `json:"git,omitempty"`
OSS *addon.OSSAddonSource `json:"oss,omitempty"`
Gitee *addon.GiteeAddonSource `json:"gitee,omitempty" `
Gitlab *addon.GitlabAddonSource `json:"gitlab,omitempty" `
}
// ListAddonRegistryResponse list addon registry

View File

@@ -313,11 +313,12 @@ func (u *defaultAddonHandler) CreateAddonRegistry(ctx context.Context, req apis.
func convertAddonRegistry(r pkgaddon.Registry) *apis.AddonRegistry {
return &apis.AddonRegistry{
Name: r.Name,
Git: r.Git.SafeCopy(),
Gitee: r.Gitee.SafeCopy(),
OSS: r.OSS,
Helm: r.Helm.SafeCopy(),
Name: r.Name,
Git: r.Git,
Gitee: r.Gitee,
OSS: r.OSS,
Helm: r.Helm,
Gitlab: r.Gitlab,
}
}
@@ -343,6 +344,8 @@ func (u defaultAddonHandler) UpdateAddonRegistry(ctx context.Context, name strin
r.OSS = req.Oss
case req.Helm != nil:
r.Helm = req.Helm
case req.Gitlab != nil:
r.Gitlab = req.Gitlab
}
err = u.addonRegistryDS.UpdateRegistry(ctx, r)
@@ -476,11 +479,12 @@ func (u *defaultAddonHandler) UpdateAddon(ctx context.Context, name string, args
func addonRegistryModelFromCreateAddonRegistryRequest(req apis.CreateAddonRegistryRequest) pkgaddon.Registry {
return pkgaddon.Registry{
Name: req.Name,
Git: req.Git,
OSS: req.Oss,
Gitee: req.Gitee,
Helm: req.Helm,
Name: req.Name,
Git: req.Git,
OSS: req.Oss,
Gitee: req.Gitee,
Helm: req.Helm,
Gitlab: req.Gitlab,
}
}

View File

@@ -23,7 +23,6 @@ import (
"strings"
set "github.com/deckarep/golang-set"
terraformtypes "github.com/oam-dev/terraform-controller/api/types"
"github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
@@ -39,13 +38,13 @@ import (
"github.com/oam-dev/kubevela/pkg/apiserver/model"
apis "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
"github.com/oam-dev/kubevela/pkg/definition"
"github.com/oam-dev/kubevela/pkg/utils/config"
)
const (
definitionAlias = definition.UserPrefix + "alias.config.oam.dev"
definitionType = definition.UserPrefix + "type.config.oam.dev"
velaCoreConfig = "velacore-config"
configIsReady = "Ready"
configIsNotReady = "Not ready"
terraformProviderAlias = "Terraform Cloud Provider"
@@ -83,7 +82,7 @@ type configUseCaseImpl struct {
func (u *configUseCaseImpl) ListConfigTypes(ctx context.Context, query string) ([]*apis.ConfigType, error) {
defs := &v1beta1.ComponentDefinitionList{}
if err := u.kubeClient.List(ctx, defs, client.InNamespace(types.DefaultKubeVelaNS),
client.MatchingLabels{definition.UserPrefix + "catalog.config.oam.dev": types.VelaCoreConfig}); err != nil {
client.MatchingLabels{definition.UserPrefix + "catalog.config.oam.dev": velaCoreConfig}); err != nil {
return nil, err
}
@@ -138,7 +137,7 @@ func (u *configUseCaseImpl) GetConfigType(ctx context.Context, configType string
func (u *configUseCaseImpl) CreateConfig(ctx context.Context, req apis.CreateConfigRequest) error {
p := req.Properties
// If the component is Terraform type, set the provider name same as the application name and the component name
if strings.HasPrefix(req.ComponentType, types.TerraformComponentPrefix) {
if strings.HasPrefix(req.ComponentType, types.TerrfaormComponentPrefix) {
var properties map[string]interface{}
if err := json.Unmarshal([]byte(p), &properties); err != nil {
return errors.Wrapf(err, "unable to process the properties of %s", req.ComponentType)
@@ -150,45 +149,52 @@ func (u *configUseCaseImpl) CreateConfig(ctx context.Context, req apis.CreateCon
}
p = string(tmp)
}
ui := config.UIParam{
Alias: req.Alias,
Description: req.Description,
Project: req.Project,
app := v1beta1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: req.Name,
Namespace: types.DefaultKubeVelaNS,
Annotations: map[string]string{
types.AnnotationConfigAlias: req.Alias,
types.AnnotationConfigDescription: req.Description,
},
Labels: map[string]string{
model.LabelSourceOfTruth: model.FromInner,
types.LabelConfigCatalog: velaCoreConfig,
types.LabelConfigType: req.ComponentType,
types.LabelConfigProject: req.Project,
},
},
Spec: v1beta1.ApplicationSpec{
Components: []common.ApplicationComponent{
{
Name: req.Name,
Type: req.ComponentType,
Properties: &runtime.RawExtension{Raw: []byte(p)},
},
},
},
}
return config.CreateApplication(ctx, u.kubeClient, req.Name, req.ComponentType, p, ui)
return u.kubeClient.Create(ctx, &app)
}
func (u *configUseCaseImpl) GetConfigs(ctx context.Context, configType string) ([]*apis.Config, error) {
switch configType {
case types.TerraformProvider:
providers, err := config.ListTerraformProviders(ctx, u.kubeClient)
if err != nil {
defs := &v1beta1.ComponentDefinitionList{}
if err := u.kubeClient.List(ctx, defs, client.InNamespace(types.DefaultKubeVelaNS),
client.MatchingLabels{
definition.UserPrefix + "catalog.config.oam.dev": velaCoreConfig,
definition.UserPrefix + "type.config.oam.dev": types.TerraformProvider,
}); err != nil {
return nil, err
}
configs := make([]*apis.Config, len(providers))
for i, p := range providers {
var a v1beta1.Application
if err := u.kubeClient.Get(ctx, client.ObjectKey{Namespace: types.DefaultKubeVelaNS, Name: p.Name}, &a); err != nil {
if kerrors.IsNotFound(err) {
t := p.CreationTimestamp.Time
configs[i] = &apis.Config{
Name: p.Name,
CreatedTime: &t,
}
if p.Status.State == terraformtypes.ProviderIsReady {
configs[i].Status = configIsReady
} else {
configs[i].Status = configIsNotReady
}
continue
}
var configs []*apis.Config
for _, d := range defs.Items {
subConfigs, err := u.getConfigsByConfigType(ctx, d.Name)
if err != nil {
return nil, err
}
// If the application doesn't have any components, skip it as something wrong happened.
if !strings.HasPrefix(a.Labels[types.LabelConfigType], types.TerraformComponentPrefix) {
continue
}
configs[i] = retrieveConfigFromApplication(a, a.Labels[types.LabelConfigProject])
configs = append(configs, subConfigs...)
}
return configs, nil
@@ -203,7 +209,7 @@ func (u *configUseCaseImpl) getConfigsByConfigType(ctx context.Context, configTy
if err := u.kubeClient.List(ctx, apps, client.InNamespace(types.DefaultKubeVelaNS),
client.MatchingLabels{
model.LabelSourceOfTruth: model.FromInner,
types.LabelConfigCatalog: types.VelaCoreConfig,
types.LabelConfigCatalog: velaCoreConfig,
types.LabelConfigType: configType,
}); err != nil {
return nil, err
@@ -212,6 +218,12 @@ func (u *configUseCaseImpl) getConfigsByConfigType(ctx context.Context, configTy
configs := make([]*apis.Config, len(apps.Items))
for i, a := range apps.Items {
configs[i] = retrieveConfigFromApplication(a, a.Labels[types.LabelConfigProject])
switch a.Status.Phase {
case common.ApplicationRunning:
configs[i].Status = configIsReady
default:
configs[i].Status = configIsNotReady
}
}
return configs, nil
}
@@ -233,11 +245,11 @@ func (u *configUseCaseImpl) GetConfig(ctx context.Context, configType, name stri
}
func (u *configUseCaseImpl) DeleteConfig(ctx context.Context, configType, name string) error {
var isTerraformProvider bool
if strings.HasPrefix(configType, types.TerraformComponentPrefix) {
isTerraformProvider = true
var a = &v1beta1.Application{}
if err := u.kubeClient.Get(ctx, client.ObjectKey{Namespace: types.DefaultKubeVelaNS, Name: name}, a); err != nil {
return err
}
return config.DeleteApplication(ctx, u.kubeClient, name, isTerraformProvider)
return u.kubeClient.Delete(ctx, a)
}
// ApplicationDeployTarget is the struct of application deploy target
@@ -253,7 +265,7 @@ func SyncConfigs(ctx context.Context, k8sClient client.Client, project string, t
var secrets v1.SecretList
if err := k8sClient.List(ctx, &secrets, client.InNamespace(types.DefaultKubeVelaNS),
client.MatchingLabels{
types.LabelConfigCatalog: types.VelaCoreConfig,
types.LabelConfigCatalog: velaCoreConfig,
types.LabelConfigSyncToMultiCluster: "true",
}); err != nil {
return err
@@ -312,7 +324,7 @@ func SyncConfigs(ctx context.Context, k8sClient client.Client, project string, t
Namespace: types.DefaultKubeVelaNS,
Labels: map[string]string{
model.LabelSourceOfTruth: model.FromInner,
types.LabelConfigCatalog: types.VelaCoreConfig,
types.LabelConfigCatalog: velaCoreConfig,
types.LabelConfigProject: project,
},
},

View File

@@ -22,11 +22,8 @@ import (
"sort"
"strings"
"testing"
"time"
. "github.com/agiledragon/gomonkey/v2"
terraformtypes "github.com/oam-dev/terraform-controller/api/types"
terraformapi "github.com/oam-dev/terraform-controller/api/v1beta1"
"gotest.tools/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -35,7 +32,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"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/model"
@@ -57,7 +53,7 @@ func TestListConfigTypes(t *testing.T) {
Name: "def1",
Namespace: types.DefaultKubeVelaNS,
Labels: map[string]string{
definition.UserPrefix + "catalog.config.oam.dev": types.VelaCoreConfig,
definition.UserPrefix + "catalog.config.oam.dev": velaCoreConfig,
definitionType: types.TerraformProvider,
},
},
@@ -74,7 +70,7 @@ func TestListConfigTypes(t *testing.T) {
definitionAlias: "Def2",
},
Labels: map[string]string{
definition.UserPrefix + "catalog.config.oam.dev": types.VelaCoreConfig,
definition.UserPrefix + "catalog.config.oam.dev": velaCoreConfig,
},
},
}
@@ -154,7 +150,7 @@ func TestGetConfigType(t *testing.T) {
definitionAlias: "Def2",
},
Labels: map[string]string{
definition.UserPrefix + "catalog.config.oam.dev": types.VelaCoreConfig,
definition.UserPrefix + "catalog.config.oam.dev": velaCoreConfig,
},
},
}
@@ -289,53 +285,37 @@ func TestGetConfigs(t *testing.T) {
s := runtime.NewScheme()
v1beta1.AddToScheme(s)
corev1.AddToScheme(s)
terraformapi.AddToScheme(s)
createdTime, _ := time.Parse(time.UnixDate, "Wed Apr 7 11:06:39 PST 2022")
provider1 := &terraformapi.Provider{
def1 := &v1beta1.ComponentDefinition{
TypeMeta: metav1.TypeMeta{
Kind: "ComponentDefinition",
APIVersion: "core.oam.dev/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "provider1",
Namespace: "default",
CreationTimestamp: metav1.NewTime(createdTime),
},
Status: terraformapi.ProviderStatus{
State: terraformtypes.ProviderIsReady,
},
}
provider2 := &terraformapi.Provider{
ObjectMeta: metav1.ObjectMeta{
Name: "provider2",
Namespace: "default",
CreationTimestamp: metav1.NewTime(createdTime),
},
Status: terraformapi.ProviderStatus{
State: terraformtypes.ProviderIsNotReady,
},
}
provider3 := &terraformapi.Provider{
ObjectMeta: metav1.ObjectMeta{
Name: "provider3",
Namespace: "default",
},
}
app1 := &v1beta1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "provider3",
Name: "def1",
Namespace: types.DefaultKubeVelaNS,
Labels: map[string]string{
types.LabelConfigType: "terraform-alibaba",
definition.UserPrefix + "catalog.config.oam.dev": velaCoreConfig,
definitionType: types.TerraformProvider,
},
CreationTimestamp: metav1.NewTime(createdTime),
},
Status: common.AppStatus{
Phase: common.ApplicationRendering,
},
}
k8sClient := fake.NewClientBuilder().WithScheme(s).WithObjects(provider1, provider2, provider3, app1).Build()
def2 := &v1beta1.ComponentDefinition{
TypeMeta: metav1.TypeMeta{
Kind: "ComponentDefinition",
APIVersion: "core.oam.dev/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "def2",
Namespace: types.DefaultKubeVelaNS,
Annotations: map[string]string{
definitionAlias: "Def2",
},
Labels: map[string]string{
definition.UserPrefix + "catalog.config.oam.dev": velaCoreConfig,
},
},
}
k8sClient := fake.NewClientBuilder().WithScheme(s).WithObjects(def1, def2).Build()
h := &configUseCaseImpl{kubeClient: k8sClient}
@@ -363,25 +343,7 @@ func TestGetConfigs(t *testing.T) {
h: h,
},
want: want{
configs: []*apis.Config{
{
Name: "provider1",
CreatedTime: &createdTime,
Status: "Ready",
},
{
Name: "provider2",
CreatedTime: &createdTime,
Status: "Not ready",
},
{
Name: "provider3",
CreatedTime: &createdTime,
Status: "Not ready",
ConfigType: "terraform-alibaba",
ApplicationStatus: common.ApplicationRendering,
},
},
configs: nil,
},
},
}
@@ -557,7 +519,7 @@ func TestSyncConfigs(t *testing.T) {
Name: "s1",
Namespace: types.DefaultKubeVelaNS,
Labels: map[string]string{
types.LabelConfigCatalog: types.VelaCoreConfig,
types.LabelConfigCatalog: velaCoreConfig,
types.LabelConfigProject: "p1",
types.LabelConfigSyncToMultiCluster: "true",
},
@@ -642,129 +604,3 @@ func TestSyncConfigs(t *testing.T) {
})
}
}
func TestDeleteConfig(t *testing.T) {
s := runtime.NewScheme()
v1beta1.AddToScheme(s)
corev1.AddToScheme(s)
terraformapi.AddToScheme(s)
provider1 := &terraformapi.Provider{
ObjectMeta: metav1.ObjectMeta{
Name: "p1",
Namespace: "default",
},
}
provider2 := &terraformapi.Provider{
ObjectMeta: metav1.ObjectMeta{
Name: "p2",
Namespace: "default",
},
}
provider3 := &terraformapi.Provider{
ObjectMeta: metav1.ObjectMeta{
Name: "p3",
Namespace: "default",
},
}
app1 := &v1beta1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "config-terraform-provider-p1",
Namespace: types.DefaultKubeVelaNS,
Labels: map[string]string{
types.LabelConfigType: "terraform-alibaba",
},
},
}
app2 := &v1beta1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "p2",
Namespace: types.DefaultKubeVelaNS,
Labels: map[string]string{
types.LabelConfigType: "terraform-alibaba",
},
},
}
normalApp := &v1beta1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "a9",
Namespace: types.DefaultKubeVelaNS,
},
}
k8sClient := fake.NewClientBuilder().WithScheme(s).WithObjects(provider1, provider2, provider3, app1, app2, normalApp).Build()
h := &configUseCaseImpl{kubeClient: k8sClient}
type args struct {
configType string
name string
h ConfigHandler
}
type want struct {
errMsg string
}
ctx := context.Background()
testcases := []struct {
name string
args args
want want
}{
{
name: "delete a legacy terraform provider",
args: args{
configType: "terraform-alibaba",
name: "p1",
h: h,
},
want: want{},
},
{
name: "delete a terraform provider",
args: args{
configType: "terraform-alibaba",
name: "p2",
h: h,
},
want: want{},
},
{
name: "delete a terraform provider, but its application not found",
args: args{
configType: "terraform-alibaba",
name: "p3",
h: h,
},
want: want{
errMsg: "could not be disabled because it was created by enabling a Terraform provider or was manually created",
},
},
{
name: "delete a normal config, but failed",
args: args{
configType: "config-image-registry",
name: "a10",
h: h,
},
want: want{
errMsg: "not found",
},
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
err := tc.args.h.DeleteConfig(ctx, tc.args.configType, tc.args.name)
if tc.want.errMsg != "" || err != nil {
assert.ErrorContains(t, err, tc.want.errMsg)
}
})
}
}

View File

@@ -190,7 +190,7 @@ func (d *definitionUsecaseImpl) listDefinitions(ctx context.Context, list *unstr
// DetailDefinition get definition detail
func (d *definitionUsecaseImpl) DetailDefinition(ctx context.Context, name, defType string) (*apisv1.DetailDefinitionResponse, error) {
if !utils.StringsContain([]string{"component", "trait", "workflowstep"}, defType) {
if !utils.StringsContain([]string{"component", "trait", "workflowstep", "policy"}, defType) {
return nil, bcode.ErrDefinitionTypeNotSupport
}
var cm v1.ConfigMap

View File

@@ -20,8 +20,6 @@ import (
"context"
"strconv"
"github.com/oam-dev/kubevela/pkg/utils/config"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/apiserver/clients"
"github.com/oam-dev/kubevela/pkg/apiserver/log"
@@ -33,6 +31,7 @@ import (
"github.com/oam-dev/kubevela/pkg/utils/helm"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types2 "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -134,20 +133,41 @@ func (d defaultHelmHandler) ListChartRepo(ctx context.Context, projectName strin
var res []*v1.ChartRepoResponse
var err error
projectSecrets := corev1.SecretList{}
opts := []client.ListOption{
client.MatchingLabels{oam.LabelConfigType: "config-helm-repository"},
client.InNamespace(types.DefaultKubeVelaNS),
if len(projectName) != 0 {
projectSecrets := corev1.SecretList{}
opts := []client.ListOption{
client.MatchingLabels{oam.LabelConfigType: "config-helm-repository", types.LabelConfigProject: projectName},
client.InNamespace(types.DefaultKubeVelaNS),
}
err = d.k8sClient.List(ctx, &projectSecrets, opts...)
if err != nil {
return nil, err
}
for _, item := range projectSecrets.Items {
res = append(res, &v1.ChartRepoResponse{URL: string(item.Data["url"]), SecretName: item.Name})
}
}
err = d.k8sClient.List(ctx, &projectSecrets, opts...)
globalSecrets := corev1.SecretList{}
selector := metav1.LabelSelector{
MatchLabels: map[string]string{oam.LabelConfigType: "config-helm-repository"},
MatchExpressions: []metav1.LabelSelectorRequirement{
{Key: types.LabelConfigProject, Operator: metav1.LabelSelectorOpDoesNotExist},
},
}
ls, _ := metav1.LabelSelectorAsSelector(&selector)
err = d.k8sClient.List(ctx, &globalSecrets, &client.ListOptions{
LabelSelector: ls,
Namespace: types.DefaultKubeVelaNS,
})
if err != nil {
return nil, err
}
for _, item := range projectSecrets.Items {
if config.ProjectMatched(item.DeepCopy(), projectName) {
res = append(res, &v1.ChartRepoResponse{URL: string(item.Data["url"]), SecretName: item.Name})
}
for _, item := range globalSecrets.Items {
res = append(res, &v1.ChartRepoResponse{URL: string(item.Data["url"]), SecretName: item.Name})
}
return &v1.ChartRepoResponseList{ChartRepoResponse: res}, nil

View File

@@ -338,7 +338,6 @@ kind: Secret
metadata:
labels:
config.oam.dev/type: config-helm-repository
config.oam.dev/project: ""
name: global-helm-repo
namespace: vela-system
type: Opaque

View File

@@ -487,7 +487,7 @@ func (p *projectUsecaseImpl) GetConfigs(ctx context.Context, projectName, config
if err := p.k8sClient.List(ctx, apps, client.InNamespace(types.DefaultKubeVelaNS),
client.MatchingLabels{
model.LabelSourceOfTruth: model.FromInner,
types.LabelConfigCatalog: types.VelaCoreConfig,
types.LabelConfigCatalog: velaCoreConfig,
}); err != nil {
return nil, err
}
@@ -499,7 +499,7 @@ func (p *projectUsecaseImpl) GetConfigs(ctx context.Context, projectName, config
return nil, err
}
for _, p := range providers.Items {
if p.Labels[types.LabelConfigCatalog] == types.VelaCoreConfig {
if p.Labels[types.LabelConfigCatalog] == velaCoreConfig {
continue
}
t := p.CreationTimestamp.Time
@@ -520,7 +520,7 @@ func (p *projectUsecaseImpl) GetConfigs(ctx context.Context, projectName, config
for _, a := range apps.Items {
appProject := a.Labels[types.LabelConfigProject]
if a.Status.Phase != common.ApplicationRunning || (appProject != "" && appProject != projectName) ||
!strings.Contains(a.Labels[types.LabelConfigType], types.TerraformComponentPrefix) {
!strings.Contains(a.Labels[types.LabelConfigType], types.TerrfaormComponentPrefix) {
continue
}
configs = append(configs, retrieveConfigFromApplication(a, appProject))
@@ -561,6 +561,13 @@ func (p *projectUsecaseImpl) GetConfigs(ctx context.Context, projectName, config
configs[i].ConfigTypeAlias = d.Annotations[definitionAlias]
}
}
if c.ApplicationStatus != "" {
if c.ApplicationStatus == common.ApplicationRunning {
configs[i].Status = configIsReady
} else {
configs[i].Status = configIsNotReady
}
}
}
return configs, nil
}
@@ -593,22 +600,12 @@ func ConvertProjectUserModel2Base(user *model.ProjectUser) *apisv1.ProjectUserBa
}
func retrieveConfigFromApplication(a v1beta1.Application, project string) *apisv1.Config {
var (
applicationStatus = a.Status.Phase
status string
)
if applicationStatus == common.ApplicationRunning {
status = configIsReady
} else {
status = configIsNotReady
}
return &apisv1.Config{
ConfigType: a.Labels[types.LabelConfigType],
Name: a.Name,
Project: project,
CreatedTime: &(a.CreationTimestamp.Time),
ApplicationStatus: applicationStatus,
Status: status,
ApplicationStatus: a.Status.Phase,
Alias: a.Annotations[types.AnnotationConfigAlias],
Description: a.Annotations[types.AnnotationConfigDescription],
}

View File

@@ -293,7 +293,7 @@ func TestProjectGetConfigs(t *testing.T) {
Namespace: velatypes.DefaultKubeVelaNS,
Labels: map[string]string{
model.LabelSourceOfTruth: model.FromInner,
velatypes.LabelConfigCatalog: velatypes.VelaCoreConfig,
velatypes.LabelConfigCatalog: velaCoreConfig,
velatypes.LabelConfigType: "terraform-provider",
"config.oam.dev/project": "p1",
},
@@ -308,7 +308,7 @@ func TestProjectGetConfigs(t *testing.T) {
Namespace: velatypes.DefaultKubeVelaNS,
Labels: map[string]string{
model.LabelSourceOfTruth: model.FromInner,
velatypes.LabelConfigCatalog: velatypes.VelaCoreConfig,
velatypes.LabelConfigCatalog: velaCoreConfig,
velatypes.LabelConfigType: "terraform-provider",
},
CreationTimestamp: metav1.NewTime(createdTime),
@@ -322,7 +322,7 @@ func TestProjectGetConfigs(t *testing.T) {
Namespace: velatypes.DefaultKubeVelaNS,
Labels: map[string]string{
model.LabelSourceOfTruth: model.FromInner,
velatypes.LabelConfigCatalog: velatypes.VelaCoreConfig,
velatypes.LabelConfigCatalog: velaCoreConfig,
velatypes.LabelConfigType: "dex-connector",
"config.oam.dev/project": "p3",
},
@@ -347,7 +347,7 @@ func TestProjectGetConfigs(t *testing.T) {
Name: "provider2",
Namespace: "default",
Labels: map[string]string{
velatypes.LabelConfigCatalog: velatypes.VelaCoreConfig,
velatypes.LabelConfigCatalog: velaCoreConfig,
},
},
Status: terraformapi.ProviderStatus{

View File

@@ -22,11 +22,11 @@ import (
"net/http"
"time"
"github.com/emicklei/go-restful/v3"
"github.com/oam-dev/kubevela/pkg/apiserver/datastore"
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/rest/apis/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/rest/usecase"
"github.com/emicklei/go-restful/v3"
)
// versionPrefix API version prefix.

View File

@@ -27,7 +27,7 @@ import (
"cuelang.org/go/cue/format"
json2cue "cuelang.org/go/encoding/json"
"github.com/crossplane/crossplane-runtime/pkg/fieldpath"
terraformapi "github.com/oam-dev/terraform-controller/api/v1beta2"
terraformapi "github.com/oam-dev/terraform-controller/api/v1beta1"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
@@ -63,9 +63,7 @@ const (
// WriteConnectionSecretToRefKey is used to create a secret for cloud resource connection
WriteConnectionSecretToRefKey = "writeConnectionSecretToRef"
// RegionKey is the region of a Cloud Provider
// It's used to override the region of a Cloud Provider
// Refer to https://github.com/oam-dev/terraform-controller/blob/master/api/v1beta2/configuration_types.go#L66 for details
RegionKey = "customRegion"
RegionKey = "region"
// ProviderRefKey is the reference of a Provider
ProviderRefKey = "providerRef"
)
@@ -184,6 +182,8 @@ type Appfile struct {
parser *Parser
app *v1beta1.Application
Debug bool
}
// GeneratePolicyManifests generates policy manifests from an appFile
@@ -668,7 +668,7 @@ func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructu
}
configuration := terraformapi.Configuration{
TypeMeta: metav1.TypeMeta{APIVersion: "terraform.core.oam.dev/v1beta2", Kind: "Configuration"},
TypeMeta: metav1.TypeMeta{APIVersion: "terraform.core.oam.dev/v1beta1", Kind: "Configuration"},
ObjectMeta: metav1.ObjectMeta{
Name: wl.Name,
Namespace: ns,
@@ -681,6 +681,8 @@ func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructu
switch wl.FullTemplate.Terraform.Type {
case "hcl":
configuration.Spec.HCL = wl.FullTemplate.Terraform.Configuration
case "json":
configuration.Spec.JSON = wl.FullTemplate.Terraform.Configuration
case "remote":
configuration.Spec.Remote = wl.FullTemplate.Terraform.Configuration
configuration.Spec.Path = wl.FullTemplate.Terraform.Path

View File

@@ -30,7 +30,7 @@ import (
"github.com/crossplane/crossplane-runtime/pkg/test"
"github.com/google/go-cmp/cmp"
terraformtypes "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
terraformapi "github.com/oam-dev/terraform-controller/api/v1beta2"
terraformapi "github.com/oam-dev/terraform-controller/api/v1beta1"
"github.com/pkg/errors"
"gotest.tools/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -584,6 +584,10 @@ variable "password" {
raw.Raw = data
workload := terraformapi.Configuration{
TypeMeta: metav1.TypeMeta{
APIVersion: "terraform.core.oam.dev/v1beta1",
Kind: "Configuration",
},
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{
"app.oam.dev/appRevision": "v1",
@@ -898,6 +902,7 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
type args struct {
writeConnectionSecretToRef *terraformtypes.SecretReference
json string
hcl string
remote string
params map[string]interface{}
@@ -912,6 +917,16 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
args args
want want
}{
"json workload with secret": {
args: args{
json: "abc",
params: map[string]interface{}{"acl": "private",
"writeConnectionSecretToRef": map[string]interface{}{"name": "oss", "namespace": ""}},
writeConnectionSecretToRef: &terraformtypes.SecretReference{Name: "oss", Namespace: "default"},
},
want: want{err: nil}},
"valid hcl workload": {
args: args{
hcl: "abc",
@@ -984,6 +999,19 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
}
configSpec.WriteConnectionSecretToReference = tc.args.writeConnectionSecretToRef
}
if tc.args.json != "" {
template = &Template{
Terraform: &common.Terraform{
Configuration: tc.args.json,
Type: "json",
},
}
configSpec = terraformapi.ConfigurationSpec{
JSON: tc.args.json,
Variable: raw,
}
configSpec.WriteConnectionSecretToReference = tc.args.writeConnectionSecretToRef
}
if tc.args.remote != "" {
template = &Template{
Terraform: &common.Terraform{
@@ -997,7 +1025,7 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
}
configSpec.WriteConnectionSecretToReference = tc.args.writeConnectionSecretToRef
}
if tc.args.hcl == "" && tc.args.remote == "" {
if tc.args.hcl == "" && tc.args.json == "" && tc.args.remote == "" {
template = &Template{
Terraform: &common.Terraform{},
}
@@ -1033,7 +1061,7 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
if err == nil {
tfConfiguration := terraformapi.Configuration{
TypeMeta: metav1.TypeMeta{APIVersion: "terraform.core.oam.dev/v1beta2", Kind: "Configuration"},
TypeMeta: metav1.TypeMeta{APIVersion: "terraform.core.oam.dev/v1beta1", Kind: "Configuration"},
ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: ns},
Spec: configSpec,
}

View File

@@ -288,30 +288,6 @@ func (p *Parser) GenerateAppFileFromRevision(appRev *v1beta1.ApplicationRevision
for k, v := range appRev.Spec.WorkflowStepDefinitions {
appfile.RelatedWorkflowStepDefinitions[k] = v.DeepCopy()
}
// add compatible code for upgrading to v1.3 as the workflow steps were not recorded before v1.2
if len(appfile.RelatedWorkflowStepDefinitions) == 0 && len(appfile.WorkflowSteps) > 0 {
ctx := context.Background()
for _, workflowStep := range appfile.WorkflowSteps {
if wftypes.IsBuiltinWorkflowStepType(workflowStep.Type) {
continue
}
if _, found := appfile.RelatedWorkflowStepDefinitions[workflowStep.Type]; found {
continue
}
def := &v1beta1.WorkflowStepDefinition{}
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStep.Type); err != nil {
return nil, errors.Wrapf(err, "failed to get workflow step definition %s", workflowStep.Type)
}
appfile.RelatedWorkflowStepDefinitions[workflowStep.Type] = def
}
appRev.Spec.WorkflowStepDefinitions = make(map[string]v1beta1.WorkflowStepDefinition)
for name, def := range appfile.RelatedWorkflowStepDefinitions {
appRev.Spec.WorkflowStepDefinitions[name] = *def
}
}
for k, v := range appRev.Spec.ScopeDefinitions {
appfile.RelatedScopeDefinitions[k] = v.DeepCopy()
}
@@ -369,6 +345,8 @@ func (p *Parser) parsePoliciesFromRevision(ctx context.Context, af *Appfile) (er
case v1alpha1.EnvBindingPolicyType:
case v1alpha1.TopologyPolicyType:
case v1alpha1.OverridePolicyType:
case v1alpha1.DebugPolicyType:
af.Debug = true
default:
w, err := p.makeWorkloadFromRevision(policy.Name, policy.Type, types.TypePolicy, policy.Properties, af.AppRevision)
if err != nil {
@@ -391,6 +369,8 @@ func (p *Parser) parsePolicies(ctx context.Context, af *Appfile) (err error) {
case v1alpha1.ApplyOncePolicyType:
case v1alpha1.EnvBindingPolicyType:
case v1alpha1.TopologyPolicyType:
case v1alpha1.DebugPolicyType:
af.Debug = true
case v1alpha1.OverridePolicyType:
compDefs, traitDefs, err := policypkg.ParseOverridePolicyRelatedDefinitions(ctx, p.client, af.app, policy)
if err != nil {

View File

@@ -22,8 +22,6 @@ import (
"reflect"
"strings"
common2 "github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/google/go-cmp/cmp"
"github.com/crossplane/crossplane-runtime/pkg/test"
@@ -508,202 +506,3 @@ var _ = Describe("Test appFile parser", func() {
})
})
var _ = Describe("Test application parser", func() {
var app v1beta1.Application
var apprev v1beta1.ApplicationRevision
var wsd v1beta1.WorkflowStepDefinition
var expectedExceptAppfile *Appfile
var mockClient test.MockClient
BeforeEach(func() {
// prepare WorkflowStepDefinition
Expect(common2.ReadYamlToObject("testdata/backport-1-2/wsd.yaml", &wsd)).Should(BeNil())
// prepare verify data
expectedExceptAppfile = &Appfile{
Name: "backport-1-2-test-demo",
Workloads: []*Workload{
{
Name: "backport-1-2-test-demo",
Type: "webservice",
Params: map[string]interface{}{
"image": "nginx",
},
FullTemplate: &Template{
TemplateStr: `
output: {
apiVersion: "apps/v1"
kind: "Deployment"
spec: {
selector: matchLabels: {
"app.oam.dev/component": context.name
}
template: {
metadata: labels: {
"app.oam.dev/component": context.name
}
spec: {
containers: [{
name: context.name
image: parameter.image
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
}]
}
}
selector:
matchLabels:
"app.oam.dev/component": context.name
}
}
parameter: {
// +usage=Which image would you like to use for your service
// +short=i
image: string
cmd?: [...string]
}`,
},
Traits: []*Trait{
{
Name: "scaler",
Params: map[string]interface{}{
"replicas": float64(1),
},
Template: `
parameter: {
// +usage=Specify the number of workload
replicas: *1 | int
}
// +patchStrategy=retainKeys
patch: spec: replicas: parameter.replicas
`,
},
},
},
},
WorkflowSteps: []v1beta1.WorkflowStep{
{
Name: "apply",
Type: "apply-application",
},
},
}
// Create mock client
mockClient = test.MockClient{
MockGet: func(ctx context.Context, key client.ObjectKey, obj client.Object) error {
if strings.Contains(key.Name, "unknown") {
return &errors2.StatusError{ErrStatus: metav1.Status{Reason: "NotFound", Message: "not found"}}
}
switch o := obj.(type) {
case *v1beta1.ComponentDefinition:
wd, err := util.UnMarshalStringToComponentDefinition(componenetDefinition)
if err != nil {
return err
}
*o = *wd
case *v1beta1.TraitDefinition:
td, err := util.UnMarshalStringToTraitDefinition(traitDefinition)
if err != nil {
return err
}
*o = *td
case *v1beta1.WorkflowStepDefinition:
*o = wsd
case *v1beta1.ApplicationRevision:
*o = apprev
default:
// skip
}
return nil
},
}
})
When("with apply-application workflowStep", func() {
BeforeEach(func() {
// prepare application
Expect(common2.ReadYamlToObject("testdata/backport-1-2/app.yaml", &app)).Should(BeNil())
// prepare application revision
Expect(common2.ReadYamlToObject("testdata/backport-1-2/apprev1.yaml", &apprev)).Should(BeNil())
})
It("Test we can parse an application revision to an appFile 1", func() {
appfile, err := NewApplicationParser(&mockClient, dm, pd).GenerateAppFile(context.TODO(), &app)
Expect(err).ShouldNot(HaveOccurred())
Expect(equal(expectedExceptAppfile, appfile)).Should(BeTrue())
Expect(len(appfile.WorkflowSteps) > 0 &&
len(appfile.RelatedWorkflowStepDefinitions) == len(appfile.AppRevision.Spec.WorkflowStepDefinitions)).Should(BeTrue())
Expect(len(appfile.WorkflowSteps) > 0 && func() bool {
this := appfile.RelatedWorkflowStepDefinitions
that := appfile.AppRevision.Spec.WorkflowStepDefinitions
for i, w := range this {
thatW := that[i]
if !reflect.DeepEqual(*w, thatW) {
fmt.Printf("appfile wsd:%s apprev wsd%s", (*w).Name, thatW.Name)
return false
}
}
return true
}()).Should(BeTrue())
})
})
When("with apply-application and apply-component build-in workflowStep", func() {
BeforeEach(func() {
// prepare application
Expect(common2.ReadYamlToObject("testdata/backport-1-2/app.yaml", &app)).Should(BeNil())
// prepare application revision
Expect(common2.ReadYamlToObject("testdata/backport-1-2/apprev2.yaml", &apprev)).Should(BeNil())
})
It("Test we can parse an application revision to an appFile 2", func() {
appfile, err := NewApplicationParser(&mockClient, dm, pd).GenerateAppFile(context.TODO(), &app)
Expect(err).ShouldNot(HaveOccurred())
Expect(equal(expectedExceptAppfile, appfile)).Should(BeTrue())
Expect(len(appfile.WorkflowSteps) > 0 &&
len(appfile.RelatedWorkflowStepDefinitions) == len(appfile.AppRevision.Spec.WorkflowStepDefinitions)).Should(BeTrue())
Expect(len(appfile.WorkflowSteps) > 0 && func() bool {
this := appfile.RelatedWorkflowStepDefinitions
that := appfile.AppRevision.Spec.WorkflowStepDefinitions
for i, w := range this {
thatW := that[i]
if !reflect.DeepEqual(*w, thatW) {
fmt.Printf("appfile wsd:%s apprev wsd%s", (*w).Name, thatW.Name)
return false
}
}
return true
}()).Should(BeTrue())
})
})
When("with unknown workflowStep", func() {
BeforeEach(func() {
// prepare application
Expect(common2.ReadYamlToObject("testdata/backport-1-2/app.yaml", &app)).Should(BeNil())
// prepare application revision
Expect(common2.ReadYamlToObject("testdata/backport-1-2/apprev3.yaml", &apprev)).Should(BeNil())
})
It("Test we can parse an application revision to an appFile 3", func() {
_, err := NewApplicationParser(&mockClient, dm, pd).GenerateAppFile(context.TODO(), &app)
Expect(err).Should(HaveOccurred())
Expect(err.Error() == "failed to get workflow step definition apply-application-unknown: not found").Should(BeTrue())
})
})
})

View File

@@ -1,26 +0,0 @@
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
annotations:
app.oam.dev/publishVersion: workflow-default-123456
name: backport-1-2-test-demo
namespace: default
spec:
components:
- name: backport-1-2-test-demo
properties:
image: nginx
traits:
- properties:
replicas: 1
type: scaler
type: webservice
workflow:
steps:
- name: apply
type: apply-application
status:
latestRevision:
name: backport-1-2-test-demo-v1
revision: 1
revisionHash: 38ddf4e721073703

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