Compare commits

..

90 Commits

Author SHA1 Message Date
Jianbo Sun
b596b70ebe Fix: addon function converted (#4411)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-07-19 19:54:44 +08:00
github-actions[bot]
0cd370e867 Fix: fix volumes duplicate in list (#4390)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 08fb73aa95)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-07-15 20:11:49 +08:00
github-actions[bot]
d9adc73e5c Fix: add usage comment for ref-objects (#4386)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 0418c83117)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-07-14 18:51:05 +08:00
github-actions[bot]
4a2d9807c8 [Backport release-1.4] Fix: fail directly when app terminated (#4385)
* fail directly when app terminated

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

* support suspend

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

fix typo

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-07-14 18:50:23 +08:00
github-actions[bot]
840cb8ce58 Fix: several minor bugs (#4381)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit c5f10a5723)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-07-14 11:22:41 +08:00
github-actions[bot]
5a64fec916 Fix: abuse timeout context in terraform provider (#4375)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit ab56b3c274)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-07-13 15:48:13 +08:00
Jianbo Sun
657a374ded Fix: add the job of independently publishing chart packages (#4360) (#4361)
* Fix: add the job of independently publishing chart packages

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

* Fix: add the job of independently publishing chart packages

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-07-12 12:31:05 +08:00
Tianxin Dong
dfe12cd9ca [Backport-1.4]: optimize imports packages to reduce 75% cpu with better performance (#4355)
* Feat: optimize imports packages

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

* fix test

Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-07-11 18:33:53 +08:00
github-actions[bot]
cd42f67848 Fix: init container bug (#4354)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 3f116c7f10)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-07-11 17:03:49 +08:00
github-actions[bot]
61d2c588e3 Fix: health check use original ns if no override and original exists (#4353)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit f7923b5ac9)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-07-11 16:49:24 +08:00
github-actions[bot]
b3dad698a5 Fix: enhance sidecar & init traits (#4343)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit dc9b18d119)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-07-08 19:09:55 +08:00
github-actions[bot]
ec5159c2ca Fix: disable apprev status update when apprev disabled (#4338)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit b4c8e3265a)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-07-07 15:51:35 +08:00
github-actions[bot]
a7b2b221e0 [Backport release-1.4] Fix: more cluster system info range. (#4333)
* more collect info

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

* fix comments

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-07-06 16:15:31 +08:00
github-actions[bot]
caa495a5d9 [Backport release-1.4] Fix: ref-objects parameter with invalid field definition (#4330)
* fix: ref-objects parameter with invalid field definition

which cause validating webhook failed when use ref-objects component

Signed-off-by: jiangshantao <jiangshantao-dbg@qq.com>
(cherry picked from commit 13f328f362)

* fix: run make reviewable

Signed-off-by: jiangshantao <jiangshantao-dbg@qq.com>
(cherry picked from commit e09410af90)

Co-authored-by: jst <jst@meitu.com>
2022-07-06 14:18:17 +08:00
github-actions[bot]
15bea4fb64 Fix: fail to query the application logs with the special characters (#4308)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 0101396a42)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-07-01 20:15:09 +08:00
github-actions[bot]
1a094a4eea Fix: Jfrog Webhook Handler Cannot Get Right Image (#4306)
Merge branch 'release-1.4'

Apply suggestions from code review

Co-authored-by: lqs429521992 <lqs429521992@qq.com>

Update webhook.go

Fix: format

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

Co-authored-by: qingsliu <lqs429521992@qq.com>
2022-07-01 20:08:40 +08:00
github-actions[bot]
65b6f47330 Fix: fix the goroutine leak in http request (#4304)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 559ef83abd)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-07-01 17:57:34 +08:00
github-actions[bot]
3a4cd2dca6 Fix: kube apply ignore userinfo for rt (#4300)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 2a9e741d4c)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-07-01 17:32:52 +08:00
github-actions[bot]
9fabd950e5 Chore: avoid update version file when publish smaller version (#4287)
Signed-off-by: qiaozp <chivalry.pp@gmail.com>
(cherry picked from commit 696234e1aa)

Co-authored-by: qiaozp <chivalry.pp@gmail.com>
2022-06-30 15:51:17 +08:00
github-actions[bot]
0a012b4d34 Feat: enhance ServiceAccount trait to support privileges (#4278)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit f8d4aca499)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-06-29 15:00:32 +08:00
github-actions[bot]
7c231e6c48 Fix: support stdin and url for vela ql (#4277)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit 235a4471c0)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-06-29 14:53:26 +08:00
github-actions[bot]
36b6c3e7b5 Fix: trim quot char for velaql output (#4269)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit fdd0c93dba)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-06-27 16:52:26 +08:00
github-actions[bot]
4cc019722c [Backport release-1.4] Feat: enhance velq ql and support cue file (#4266)
* Feat: enhance velq ql and support cue file

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

* add statement

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

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-06-27 16:17:21 +08:00
github-actions[bot]
b040ae65da [Backport release-1.4] Fix: provider can't be added since 1.4 as context abused && Feat: add cache for remote terraform module in vela show (#4263)
* Fix: provider can't be added since 1.4 as context abused

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

* Feat: add cache for remote terraform module in vela show

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

* Fix: add message for terraform resource in error state

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

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-06-27 11:32:20 +08:00
github-actions[bot]
f0fb4ed099 Feat: omit service output if there's nothing (#4262)
Signed-off-by: Sumit Tembe <sumit.tembe@outlook.com>
(cherry picked from commit 8911143389)

Co-authored-by: Sumit Tembe <sumit.tembe@outlook.com>
2022-06-27 10:31:49 +08:00
github-actions[bot]
7f89d12059 environment from configmap or secret not mandatory in task and crontask componentdefinition (#4254)
Signed-off-by: Carmendelope <carmen@napptive.com>
(cherry picked from commit 35f130ea08)

Co-authored-by: Carmendelope <carmen@napptive.com>
2022-06-25 09:00:24 +08:00
github-actions[bot]
3c61bcb8f0 Fix: vela status print wrong STATUS (#4249)
Signed-off-by: StevenLeiZhang <zhangleiic@163.com>
(cherry picked from commit 5f4616a453)

Co-authored-by: StevenLeiZhang <zhangleiic@163.com>
2022-06-24 17:16:58 +08:00
github-actions[bot]
a14b536fd1 [Backport release-1.4] Feat: skip validating version check (#4247)
* skip validating version check

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

* add comments

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

* fix comments

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

* fix test

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

* fix commments

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

* add compatible logic for old controller

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

* modify minimal

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-06-24 14:13:17 +08:00
github-actions[bot]
ba5a726854 [Backport release-1.4] Fix: fixed the problems of display definition in web and support displaying WorkflowStep and Policy (#4241)
* Fix: fixed the problems of display definition in web

Some ComponentDefinitions, TraitDefinitions, WorkflowDefinitions
failed to show the usage in web browser

Signed-off-by: Zheng Xi Zhou <zhengxi.zzx@alibaba-inc.com>
(cherry picked from commit c8985ccc3e)

* set printable type for {}

Signed-off-by: Zheng Xi Zhou <zhengxi.zzx@alibaba-inc.com>
(cherry picked from commit 87efb357b2)

* support WorkflowSteps and Policies

Signed-off-by: Zheng Xi Zhou <zhengxi.zzx@alibaba-inc.com>
(cherry picked from commit 8fb83152bc)

Co-authored-by: Zheng Xi Zhou <zhengxi.zzx@alibaba-inc.com>
2022-06-23 19:46:51 +08:00
github-actions[bot]
ffb9d06427 Fix: json-patch & json-merge-patch open result (#4229)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 4ea3ca8d5b)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-06-22 20:05:19 +08:00
barnettZQG
819dc26ace Chore: change the acr registry address (#4214) (#4216)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
2022-06-22 14:46:13 +08:00
github-actions[bot]
5e3ab732df [Backport release-1.4] Feat: add the API for querying the image info (#4211)
* Feat: add the API for querying the image info

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

* Fix: the code style

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-06-21 15:05:15 +08:00
github-actions[bot]
62d5507499 Fix: cue patch remove temp var (#4208)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 660e89b3a0)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-06-20 17:38:34 +08:00
github-actions[bot]
c0daf688a6 Fix: clear namespace for cluster scoped resource for dispatching (#4195)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 7c9de1b071)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-06-16 14:50:44 +08:00
github-actions[bot]
48d19a2427 [Backport release-1.4] Feat: cli addon add registry add more git types (#4191)
* add more git types

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

* fix comments

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

fix comments

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-06-16 12:23:15 +08:00
github-actions[bot]
4da8d49e60 Fix: fix the annotation for APIService (#4190)
Make the annatation for cert-manger be the same as the new version
secret

Signed-off-by: Zheng Xi Zhou <zhengxi.zzx@alibaba-inc.com>
(cherry picked from commit 62ef7b7f99)

Co-authored-by: Zheng Xi Zhou <zhengxi.zzx@alibaba-inc.com>
2022-06-16 11:02:35 +08:00
github-actions[bot]
4db9e89816 Fix: enhance CLI for managing OCM clusters (#4178)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 0662e2a79d)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-06-15 11:23:12 +08:00
github-actions[bot]
667053409d Fix: fix trait customStatus error when controlPlanOnly=true (#4177)
Signed-off-by: fourierr <maxiangboo@qq.com>
(cherry picked from commit 38648fcf30)

Co-authored-by: fourierr <maxiangboo@qq.com>
2022-06-15 11:22:15 +08:00
github-actions[bot]
eb9ddaabd3 [Backport release-1.4] Feat: optimize the API that list and detail definition (#4160)
* Fix: ignore the error that the definition API schema is not exist

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

* Fix: disable the cache when listing the definitions

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-06-13 13:25:41 +08:00
github-actions[bot]
f11a94612f Feat: support insecure cluster (#4159)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 8abedf3005)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-06-13 13:15:34 +08:00
github-actions[bot]
56f9d7cb9c [Backport release-1.4] Fix: mongoDB datastore can't list special email user(#4104) (#4148)
* Add description column to vela trait and component command (#4107)

Signed-off-by: Holger Protzek <holger.protzek@springernature.com>
Signed-off-by: fengkang <fengkangb@digitalchina.com>
(cherry picked from commit 9c57ae2a15)

* Fix: mongoDB datastore can't list special email user(#4104)

Signed-off-by: fengkang <fengkangb@digitalchina.com>
(cherry picked from commit ec07790935)

* Fix: mongoDB datastore can't list special email user(#4104)
     change the function name from verifyUserValue to verifyValue
     add test case to test kubeapi.go:87

Signed-off-by: fengkang <fengkangb@digitalchina.com>
(cherry picked from commit 4c55e0688f)

* Fix: mongoDB datastore can't list special email user(#4104)
     change the function name from verifyUserValue to verifyValue
     add test case to test kubeapi.go:87
     add delete test case

Signed-off-by: fengkang <fengkangb@digitalchina.com>
(cherry picked from commit b2e76001c9)

* Fix: mongoDB datastore can't list special email user(#4104)
     optimize the test case

Signed-off-by: fengkang <fengkangb@digitalchina.com>
(cherry picked from commit a63c96fae1)

* Fix: mongoDB datastore can't list special email user(#4104)
     optimize the test case use user
     change all verify timing in kubeapi

Signed-off-by: fengkang <fengkangb@digitalchina.com>
(cherry picked from commit 2ede4f7b0c)

* Fix: mongoDB datastore can't list special email user(#4104)

Signed-off-by: fengkang <fengkangb@digitalchina.com>
(cherry picked from commit 356150642f)

* Fix: mongoDB datastore can't list special email user(#4104)

Signed-off-by: fengkang <fengkangb@digitalchina.com>
(cherry picked from commit 48a9e55937)

Co-authored-by: Holger Protzek <3481523+hprotzek@users.noreply.github.com>
Co-authored-by: fengkang01 <fengkangb@digitalchina.com>
2022-06-10 15:33:53 +08:00
github-actions[bot]
fbbc666019 [Backport release-1.4] Fix: api not exist don't break whole query process (#4137)
* make resource tree more

resourceTree more robust

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

* log the error

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-06-09 11:36:57 +08:00
github-actions[bot]
d0788254cb Fix: vela addon registry get panic (#4136)
Signed-off-by: ZhongsJie <zhongsjie@gmail.com>
(cherry picked from commit 0d329e394e)

Co-authored-by: ZhongsJie <zhongsjie@gmail.com>
2022-06-09 10:19:28 +08:00
github-actions[bot]
c72a6aef87 Chore(deps): Bump github.com/containerd/containerd from 1.5.10 to 1.5.13 (#4125)
Bumps [github.com/containerd/containerd](https://github.com/containerd/containerd) from 1.5.10 to 1.5.13.
- [Release notes](https://github.com/containerd/containerd/releases)
- [Changelog](https://github.com/containerd/containerd/blob/main/RELEASES.md)
- [Commits](https://github.com/containerd/containerd/compare/v1.5.10...v1.5.13)

---
updated-dependencies:
- dependency-name: github.com/containerd/containerd
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
(cherry picked from commit 9982c7ceaa)

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-06-08 12:56:05 +08:00
github-actions[bot]
195b7fe0c7 [Backport release-1.4] Fix: bump oamdev/kube-webhook-certgen to v2.4.1 to support arm64 (#4117)
* Fix: split the image build process to make it faster

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

* Fix: bump oamdev/kube-webhook-certgen to v2.4.1 to support arm64

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

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-06-05 15:10:48 +08:00
github-actions[bot]
33c9e3b170 Fix: change the image name in ghcr to align with docker image registry (#4111)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit 71776c374b)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-06-04 14:19:21 +08:00
github-actions[bot]
ea0508a634 [Backport release-1.4] Fix: hold the force uninstalling process untill the last addon been deleted (#4103)
* hold the force uninstalling process untill the last addon been deleted

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

fix lint

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

fix comments

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

fix comments

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

* fix comments

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

fix lint

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

* add period

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-06-02 16:29:02 +08:00
github-actions[bot]
23e29aa62a Fix: vela provider delete command's example is wrong (#4099)
Signed-off-by: StevenLeiZhang <zhangleiic@163.com>
(cherry picked from commit 9b66f90100)

Co-authored-by: StevenLeiZhang <zhangleiic@163.com>
2022-06-02 11:04:34 +08:00
github-actions[bot]
ed2cb80219 Fix: the new default values do not take effect when upgrading the vela core (#4097)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 0ccbbb2636)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-06-02 10:23:30 +08:00
github-actions[bot]
1a3d5debd5 Fix: show the default password (#4095)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit c3cfc4729e)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-06-02 10:14:43 +08:00
github-actions[bot]
d4a82fe292 Fix: load the provider subcommands on demand (#4090)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 52bbf937bb)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-06-01 16:32:53 +08:00
github-actions[bot]
963ae400fa Feat: use deferred config in CLI (#4085)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 478434003b)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-06-01 10:24:57 +08:00
github-actions[bot]
8f7a8258fe [Backport release-1.4] Fix(addon): more note info and filter prerelease addon version (#4082)
* more note info and filter prerelease addon version

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

* wrap the error optimize the show info

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

* fix golint

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-05-31 18:56:54 +08:00
github-actions[bot]
70bc306678 Chore: hide some definitions in VelaUX (#4080)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 68b8db1d00)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-05-31 16:41:54 +08:00
github-actions[bot]
57428bbc8d Fix: change the region to customRegion (#4079)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 9f0008f001)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-05-31 16:19:37 +08:00
github-actions[bot]
e08541ca5c Fix: Improve vela provider add response (#4078)
Signed-off-by: StevenLeiZhang <zhangleiic@163.com>
(cherry picked from commit 39e96d287b)

Co-authored-by: StevenLeiZhang <zhangleiic@163.com>
2022-05-31 16:16:54 +08:00
github-actions[bot]
521a4edc10 Feat: vela ql into vela-cli (#4077)
Signed-off-by: Shukun Zhang <2236407598@qq.com>
(cherry picked from commit 38886a0ee2)

Co-authored-by: Shukun Zhang <2236407598@qq.com>
2022-05-31 16:13:00 +08:00
github-actions[bot]
82b330710c Fix: upgrade from v1.3+ to v1.4+ with new secret for cluster-gateway (#4076)
Signed-off-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
(cherry picked from commit 161588c64e)

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-05-31 16:05:36 +08:00
github-actions[bot]
4a649f2cf1 Fix: Can not delete terraform provider (#4074)
Signed-off-by: StevenLeiZhang <zhangleiic@163.com>
(cherry picked from commit de79442f53)

Co-authored-by: StevenLeiZhang <zhangleiic@163.com>
2022-05-31 15:21:17 +08:00
github-actions[bot]
f6664106a2 Fix: remove the tcp protocol prefix in the endpoint string (#4068)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 8852ac691a)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-05-30 20:17:47 +08:00
github-actions[bot]
bbe2a2dec6 [Backport release-1.4] Fix: CI workflow for rollout acr image build and push (#4067)
* fix the rollout acr image

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

* fix

test

test

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

finish fix

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

* merge two sction

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-05-30 19:35:47 +08:00
github-actions[bot]
404c7f6975 Fix: set workflow to finish before record in controller revision (#4066)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 7042c63e90)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-05-30 19:30:03 +08:00
github-actions[bot]
2edfbabdab Fix: fix the dependency gc policy to reverse dependency (#4065)
Signed-off-by: FogDong <dongtianxin.tx@alibaba-inc.com>
(cherry picked from commit 45cf38edb0)

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-05-30 19:29:42 +08:00
github-actions[bot]
e7b304de3b Fix: the policies can not be deleted (#4062)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 0c11a69779)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-05-30 16:23:03 +08:00
github-actions[bot]
b8b54baf26 Fix: fail to get the endpoints via the velaql (#4058)
Signed-off-by: yangsoon <songyang.song@alibaba-inc.com>
(cherry picked from commit a40d99f8d8)

Co-authored-by: yangsoon <songyang.song@alibaba-inc.com>
2022-05-30 15:52:38 +08:00
github-actions[bot]
87b6c9416e [Backport release-1.4] Feat: minimize controller privileges & enforce authentication in multicluster e2e test (#4044)
* Feat: enable auth in multicluster test & restrict controller privileges while enabling authentication

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

* Feat: fix statekeep permission leak & comprev cleanup leak

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

* Fix: use user info in ref-object select

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

* Feat: set legacy-rt-gc to disabled by default

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

* Fix: pending healthscope with authentication test

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

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-05-28 01:27:35 +08:00
qiaozp
cd171d27db Fix: release script condition syntax (#4043)
Signed-off-by: qiaozp <chivalry.pp@gmail.com>
2022-05-27 23:29:31 +08:00
github-actions[bot]
6d8be8b061 [Backport release-1.4] Feat: add if in workflow (#4041)
* Feat: add if in workflow struct

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

* Feat: implement the if in workflow

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

* Feat: support dependency and skip for suspend step

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

* Fix: fix the rebase from sub steps

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

* Fix: fix the lint

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

* Feat: support if in sub steps

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

* Feat: add tests in application controller

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

* Fix: fix the lint

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

* Test: add more tests in discover and custom

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

* Lint: fix lint

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

* Tests: add more tests in application controller

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

* Fix: change failed after retries into reason

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

* Fix: fix the terminate cli

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

* fix lint

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

* remove the terminate workflow to pkg and add feature gates

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

* resolve comments

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

* nit fix

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

* make finish condition more clear

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

Co-authored-by: FogDong <dongtianxin.tx@alibaba-inc.com>
2022-05-27 22:02:02 +08:00
github-actions[bot]
e93912acff Fix: env trait error when existing env exists (#4040)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 2d5a16d45f)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-05-27 21:12:35 +08:00
github-actions[bot]
e48e39987f some small fixes (#4034)
Signed-off-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
(cherry picked from commit 99af188f91)

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-05-27 18:38:12 +08:00
github-actions[bot]
6264a66021 Feat: add the creating and deleting permission APIs (#4032)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 193515dfaf)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-05-27 17:42:49 +08:00
github-actions[bot]
9191127e01 Feat: add affinity trait to merge node and pod affinity (#4030)
Signed-off-by: ZhongsJie <zhongsjie@gmail.com>
(cherry picked from commit a4966310ae)

Co-authored-by: ZhongsJie <zhongsjie@gmail.com>
2022-05-27 17:39:10 +08:00
github-actions[bot]
1b047c10ba Fix: error message of vela init env is not clear (#4029)
Signed-off-by: fourierr <maxiangboo@qq.com>
(cherry picked from commit 378fdbdafb)

Co-authored-by: fourierr <maxiangboo@qq.com>
2022-05-27 17:35:23 +08:00
github-actions[bot]
02a1d390c4 Fix: vela port-forward not working for webservice component (#4028)
Signed-off-by: fourierr <maxiangboo@qq.com>
(cherry picked from commit 391532dd24)

Co-authored-by: fourierr <maxiangboo@qq.com>
2022-05-27 17:15:51 +08:00
github-actions[bot]
62866e19d8 Fix: unknown field ignoreTerraformComponent (#4027)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 0c27fe8199)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-05-27 17:15:23 +08:00
github-actions[bot]
3dc645ed52 Fix: velaql fail to parse query result to json format (#4025)
Signed-off-by: yangsoon <songyang.song@alibaba-inc.com>
(cherry picked from commit 6c1576c5a6)

Co-authored-by: yangsoon <songyang.song@alibaba-inc.com>
2022-05-27 16:57:38 +08:00
github-actions[bot]
e20ef02a6a [Backport release-1.4] Feat: enhance controller auth by removing useless features & add authentication for componentrevision+healthcheck (#4023)
* Feat: use application identity in gc & componentrevision & collectHealthStatus

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

* Chore: remove useless features and roles

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

* Fix: remove DELETE from mutating webhook

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

* Chore: enhance deploy error display

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

* Fix: e2e test vela cli output match & controllerrevision recycle for serviceaccount impersonation

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

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-05-27 16:00:04 +08:00
github-actions[bot]
371affb389 Fix: step group documentation update and bug fix of firstExecuteTime not record (#4021)
Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com>

Fix: step group documentation update and bug fix of firstExecuteTime not record

Signed-off-by: Qiang Zheng <zhengq20018@cmbchina.com>
(cherry picked from commit 751dd181be)

Co-authored-by: Qiang Zheng <zhengq20018@cmbchina.com>
2022-05-27 11:50:58 +08:00
github-actions[bot]
b35145be82 Fix: fail to query the count with mongodb (#4014)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit ee2b446b5c)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-05-27 10:56:13 +08:00
github-actions[bot]
d92c8844ba [Backport release-1.4] Feat: optimize some logic of topology resource-tree (#4010)
* format

finish tests

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

* add comments

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

no lint

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

* add pvc

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

* go mod tidy

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

* fix panic bug

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

fix panic

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-05-26 22:18:12 +08:00
github-actions[bot]
82aaf5098b Fix: optimized the version comparison (#4006)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 8bfab07f8f)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-05-26 19:34:47 +08:00
github-actions[bot]
7399666275 Fix: add some default permissions about the configuration (#4005)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 595ccea622)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-05-26 17:27:06 +08:00
github-actions[bot]
0b394e766b [Backport release-1.4] Feat: upgrade cluster-gateway version (#4004)
* Feat: upgrade cluster-gateway version

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

* Fix: multicluster test unstable

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

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-05-26 17:26:34 +08:00
github-actions[bot]
eb386ce9f7 Feat: support impersonation for application in apiserver (#4000)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 10dc83b60a)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-05-26 16:55:09 +08:00
github-actions[bot]
e4fa5a5cf1 Fix: add Target fail by fetch terraform-provider error (#3999)
Signed-off-by: StevenLeiZhang <zhangleiic@163.com>
(cherry picked from commit 4a44ba2550)

Co-authored-by: StevenLeiZhang <zhangleiic@163.com>
2022-05-26 15:46:07 +08:00
github-actions[bot]
165e011bd0 Fix: delete Project fail (#3996)
Signed-off-by: StevenLeiZhang <zhangleiic@163.com>
(cherry picked from commit 87347f128d)

Co-authored-by: StevenLeiZhang <zhangleiic@163.com>
2022-05-26 11:31:40 +08:00
github-actions[bot]
9489b8d511 Fix: don't update version file when publish alpha/beta version (#3995)
Signed-off-by: qiaozp <chivalry.pp@gmail.com>
(cherry picked from commit 2c2809b975)

Co-authored-by: qiaozp <chivalry.pp@gmail.com>
2022-05-26 11:31:16 +08:00
github-actions[bot]
d95942c992 Feat: build docker image(oamdev/vela-cli) for vela-cli (#3991)
fixes #1392

One of the use case could be https://github.com/kubevela/kubevela/discussions/3821

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

Co-authored-by: Jianbo Sun <jianbo.sjb@alibaba-inc.com>
2022-05-26 10:30:37 +08:00
github-actions[bot]
c6aa8ddbbc [Backport release-1.4] Fix: initialize kube config multiple times (#3990)
* Fix: initialize kube config multiple times

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

* Fix: e2e test case

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-05-26 10:21:16 +08:00
github-actions[bot]
c370ef04f3 [Backport release-1.4] Feat: mechanism to let user add relationship mapping rule by configmap (#3982)
* WIP add some code

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

small fix

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

fix all tests

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

* add comment

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

fix ci

delete useless code

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

go mod vendor

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

* fix failed test

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

* more test

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-05-25 16:45:42 +08:00
285 changed files with 2319 additions and 17025 deletions

24
.github/CODEOWNERS vendored
View File

@@ -1,14 +1,14 @@
# This file is a github code protect rule follow the codeowners https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-code-owners#example-of-a-codeowners-file
* @barnettZQG @wonderflow @leejanee @Somefive
design/ @barnettZQG @leejanee @wonderflow @Somefive
* @barnettZQG @wonderflow @leejanee
design/ @barnettZQG @leejanee @wonderflow
# Owner of CUE
pkg/cue @leejanee @FogDong @Somefive
pkg/stdlib @leejanee @FogDong @Somefive
pkg/cue @leejanee @FogDong
pkg/stdlib @leejanee @FogDong
# Owner of Workflow
pkg/workflow @leejanee @FogDong @Somefive
pkg/workflow @leejanee @FogDong
# Owner of rollout
pkg/controller/common/rollout/ @wangyikewxgm @wonderflow
@@ -17,20 +17,20 @@ pkg/controller/standard.oam.dev/v1alpha1/rollout @wangyikewxgm @wonde
runtime/rollout @wangyikewxgm @wonderflow
# Owner of definition controller
pkg/controller/core.oam.dev/v1alpha2/core/workflow/workflowstepdefinition @yangsoon @Somefive @FogDong
pkg/controller/core.oam.dev/v1alpha2/core/policies/policydefinition @yangsoon @Somefive @FogDong
pkg/controller/core.oam.dev/v1alpha2/core/components/componentdefinition @yangsoon @zzxwill @Somefive
pkg/controller/core.oam.dev/v1alpha2/core/traits/traitdefinition @yangsoon @zzxwill @Somefive
pkg/controller/core.oam.dev/v1alpha2/core/workflow/workflowstepdefinition @yangsoon @Somefive
pkg/controller/core.oam.dev/v1alpha2/core/policies/policydefinition @yangsoon @Somefive
pkg/controller/core.oam.dev/v1alpha2/core/components/componentdefinition @yangsoon @zzxwill
pkg/controller/core.oam.dev/v1alpha2/core/traits/traitdefinition @yangsoon @zzxwill
# Owner of health scope controller
pkg/controller/core.oam.dev/v1alpha2/core/scopes/healthscope @captainroy-hy @zzxwill @yangsoon
pkg/controller/core.oam.dev/v1alpha2/core/scopes/healthscope @captainroy-hy @zzxwill
# Owner of vela templates
vela-templates/ @Somefive @barnettZQG @wonderflow
# Owner of vela CLI
references/cli/ @Somefive @zzxwill @StevenLeiZhang
references/cli/ @Somefive @zzxwill
# Owner of vela APIServer
pkg/apiserver/ @barnettZQG @yangsoon @FogDong
pkg/apiserver/ @barnettZQG @yangsoon

View File

@@ -7,7 +7,7 @@ on:
jobs:
bot:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- name: Checkout Actions
uses: actions/checkout@v2
@@ -15,13 +15,7 @@ jobs:
repository: "oam-dev/kubevela-github-actions"
path: ./actions
ref: v0.4.2
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '14'
cache: 'npm'
cache-dependency-path: ./actions/package-lock.json
- name: Install Dependencies
- name: Install Actions
run: npm ci --production --prefix ./actions
- name: Run Commands
uses: ./actions/commands

View File

@@ -167,25 +167,6 @@ jobs:
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 }}
- uses: docker/build-push-action@v2
name: Build & Pushing CloudShell for Dockerhub, GHCR and ACR
with:
context: .
file: Dockerfile.cloudshell
labels: |-
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
build-args: |
GITVERSION=git-${{ steps.vars.outputs.git_revision }}
VERSION=${{ steps.get_version.outputs.VERSION }}
GOPROXY=https://proxy.golang.org
tags: |-
docker.io/oamdev/cloudshell:${{ steps.get_version.outputs.VERSION }}
ghcr.io/${{ github.repository_owner }}/oamdev/cloudshell:${{ steps.get_version.outputs.VERSION }}
${{ secrets.ACR_DOMAIN }}/oamdev/cloudshell:${{ steps.get_version.outputs.VERSION }}
publish-capabilities:
env:

3
.gitignore vendored
View File

@@ -7,7 +7,6 @@
bin
_bin
e2e/vela
vela
# Test binary, build with `go test -c`
*.test
@@ -50,4 +49,4 @@ tmp/
git-page/
# e2e rollout runtime image build
runtime/rollout/e2e/tmp
runtime/rollout/e2e/tmp

View File

@@ -15,7 +15,7 @@ This is a minor fix for release-1.0, please refer to release-1.1.x for the lates
# v1.0.5
1. Fix Terraform application status issue (#1611)
2. application supports specifying different versions of Definition (#1597)
2. applicaiton supports specifying different versions of Definition (#1597)
3. Enable Dynamic Admission Control for Application (#1619)
4. Update inner samples for "vela show xxx --web" (#1616)
5. fix empty rolloutBatch will panic whole controller bug (#1646)

View File

@@ -31,7 +31,7 @@
## What's Changed
* Fix: can't query data from the MongoDB by @barnettZQG in https://github.com/oam-dev/kubevela/pull/3095
* Fix: use personal token of vela-bot instead of github token for homebrew update by @wonderflow in https://github.com/oam-dev/kubevela/pull/3096
* Fix: use personel token of vela-bot instead of github token for homebrew update by @wonderflow in https://github.com/oam-dev/kubevela/pull/3096
* Fix: acr image no version by @wangyikewxgm in https://github.com/oam-dev/kubevela/pull/3100
* Fix: support generate cloud resource docs in Chinese by @zzxwill in https://github.com/oam-dev/kubevela/pull/3079
* Fix: clear old data in mongodb unit test case by @barnettZQG in https://github.com/oam-dev/kubevela/pull/3103

View File

@@ -1,31 +0,0 @@
ARG BASE_IMAGE
# Build the cli binary
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.17-alpine as builder
ARG GOPROXY
ENV GOPROXY=${GOPROXY:-https://goproxy.cn}
WORKDIR /workspace
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache deps before building and copying source so that we don't need to re-download as much
# and so that source changes don't invalidate our downloaded layer
RUN go mod download
# Copy the go source
COPY apis/ apis/
COPY pkg/ pkg/
COPY version/ version/
COPY references/ references/
# Build
ARG VERSION
ARG GITVERSION
RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
go build -a -ldflags "-s -w -X github.com/oam-dev/kubevela/version.VelaVersion=${VERSION:-undefined} -X github.com/oam-dev/kubevela/version.GitRevision=${GITVERSION:-undefined}" \
-o vela ./references/cmd/cli/main.go
FROM ghcr.io/cloudtty/cloudshell:v0.2.0
RUN apt-get install -y vim
ENV API_TOKEN_PATH=/usr/local/kubeconfig/token
COPY --from=builder /workspace/vela /usr/local/bin/vela

View File

@@ -21,29 +21,23 @@
KubeVela is a modern application delivery platform that makes deploying and operating applications across today's hybrid, multi-cloud environments easier, faster and more reliable.
![kubevela](docs/resources/what-is-kubevela.png)
![](docs/resources/what-is-kubevela.png)
## Highlights
KubeVela practices the "render, orchestrate, deploy" workflow with below highlighted values added to existing ecosystem:
* Deployment as Code
- *Application Centric* - KubeVela introduces [Open Application Model (OAM)](https://oam.dev/) as the consistent yet higher level API to capture and render a full deployment of microservices on top of hybrid environments. Placement strategy, traffic shifting and rolling update are declared at application level. No infrastructure level concern, simply deploy.
Declare your deployment plan as workflow, run it automatically with any CI/CD or GitOps system, extend or re-program the workflow steps with CUE. No add-hoc scripts, no dirty glue code, just deploy. The deployment workflow in KubeVela is powered by [Open Application Model](https://oam.dev/).
- *Programmable Workflow* - KubeVela models application delivery as DAG (Directed Acyclic Graph) and expresses it with [CUE](https://cuelang.org/) - a modern data configuration language. This allows you to design application deployment steps per needs and orchestrate them in programmable approach. No restrictions, natively extensible.
* Built-in security and compliance building blocks
Choose from the wide range of LDAP integrations we provided out-of-box, enjoy multi-cluster authorization that is fully automated, pick and apply fine-grained RBAC modules and customize them per your own supply chain requirements.
* Multi-cloud/hybrid-environments app delivery as first-class citizen
Progressive rollout across test/staging/production environments, automatic canary, blue-green and continuous verification, rich placement strategy across clusters and clouds, fully managed cloud environments provision.
- *Infrastructure Agnostic* - KubeVela works as an application delivery control plane that is fully decoupled from runtime infrastructure. It can deploy any workload types including containers, cloud services, databases, or even VM instances to any cloud or Kubernetes cluster, following the workflow designed by you.
## Getting Started
* [Introduction](https://kubevela.io/docs)
* [Installation](https://kubevela.io/docs/install)
* [Deploy Your Application](https://kubevela.io/docs/quick-start)
- [Introduction](https://kubevela.io/docs)
- [Installation](https://kubevela.io/docs/install)
- [Design Your First Deployment Plan](https://kubevela.io/docs/quick-start)
## Documentation
@@ -55,7 +49,7 @@ Official blog is available on [KubeVela blog](https://kubevela.io/blog).
## Community
We want your contributions and suggestions!
We want your contributions and suggestions!
One of the easiest ways to contribute is to participate in discussions on the Github Issues/Discussion, chat on IM or the bi-weekly community calls.
For more information on the community engagement, developer and contributing guidelines and more, head over to the [KubeVela community repo](https://github.com/kubevela/community).
@@ -75,17 +69,23 @@ Every two weeks we host a community call to showcase new features, review upcomi
- Bi-weekly Community Call:
- [Meeting Notes](https://docs.google.com/document/d/1nqdFEyULekyksFHtFvgvFAYE-0AMHKoS3RMnaKsarjs).
- [Video Records](https://www.youtube.com/channel/UCSCTHhGI5XJ0SEhDHVakPAA/videos).
- [Video Records](https://kubevela.io/videos/meetings/en/meetings).
- Bi-weekly Chinese Community Call:
- [Video Records](https://space.bilibili.com/180074935/channel/seriesdetail?sid=1842207).
- [Video Records](https://kubevela.io/videos/meetings/cn/v1.3).
## Talks and Conferences
Check out [KubeVela videos](https://kubevela.io/videos/talks/en/oam-dapr) for these talks and conferences.
| Engagement | Link |
|:-----------|:------------|
| 🎤 Talks | - [KubeVela - The Modern App Delivery System in Alibaba](https://docs.google.com/presentation/d/1CWCLcsKpDQB3bBDTfdv2BZ8ilGGJv2E8L-iOA5HMrV0/edit?usp=sharing) |
| 🌎 KubeCon | - [ [NA 2020] Standardizing Cloud Native Application Delivery Across Different Clouds](https://www.youtube.com/watch?v=0yhVuBIbHcI) <br> - [ [EU 2021] Zero Pain Microservice Development and Deployment with Dapr and KubeVela](https://sched.co/iE4S) |
| 📺 Conferences | - [Dapr, Rudr, OAM: Mark Russinovich presents next gen app development & deployment](https://www.youtube.com/watch?v=eJCu6a-x9uo) <br> - [Mark Russinovich presents "The Future of Cloud Native Applications with OAM and Dapr"](https://myignite.techcommunity.microsoft.com/sessions/82059)|
For more talks, please checkout [KubeVela Talks](https://kubevela.io/videos/talks/en/standardizing-app).
## Contributing
Check out [CONTRIBUTING](https://kubevela.io/docs/contributor/overview) to see how to develop with KubeVela.
Check out [CONTRIBUTING](./CONTRIBUTING.md) to see how to develop with KubeVela.
## Report Vulnerability

View File

@@ -216,19 +216,19 @@ type WorkflowState string
const (
// WorkflowStateInitializing means the workflow is in initial state
WorkflowStateInitializing WorkflowState = "Initializing"
WorkflowStateInitializing WorkflowState = "initializing"
// WorkflowStateTerminated means workflow is terminated manually, and it won't be started unless the spec changed.
WorkflowStateTerminated WorkflowState = "Terminated"
WorkflowStateTerminated WorkflowState = "terminated"
// WorkflowStateSuspended means workflow is suspended manually, and it can be resumed.
WorkflowStateSuspended WorkflowState = "Suspended"
WorkflowStateSuspended WorkflowState = "suspended"
// WorkflowStateSucceeded means workflow is running successfully, all steps finished.
WorkflowStateSucceeded WorkflowState = "Succeeded"
// WorkflowStateFinished means workflow is end.
WorkflowStateFinished WorkflowState = "Finished"
WorkflowStateFinished WorkflowState = "finished"
// WorkflowStateExecuting means workflow is still running or waiting some steps.
WorkflowStateExecuting WorkflowState = "Executing"
WorkflowStateExecuting WorkflowState = "executing"
// WorkflowStateSkipping means it will skip this reconcile and let next reconcile to handle it.
WorkflowStateSkipping WorkflowState = "Skipping"
WorkflowStateSkipping WorkflowState = "skipping"
)
// ApplicationComponentStatus record the health status of App component
@@ -342,8 +342,6 @@ type WorkflowStep struct {
Type string `json:"type"`
Meta *WorkflowStepMeta `json:"meta,omitempty"`
// +kubebuilder:pruning:PreserveUnknownFields
Properties *runtime.RawExtension `json:"properties,omitempty"`
@@ -351,8 +349,6 @@ type WorkflowStep struct {
If string `json:"if,omitempty"`
Timeout string `json:"timeout,omitempty"`
DependsOn []string `json:"dependsOn,omitempty"`
Inputs StepInputs `json:"inputs,omitempty"`
@@ -360,11 +356,6 @@ type WorkflowStep struct {
Outputs StepOutputs `json:"outputs,omitempty"`
}
// WorkflowStepMeta contains the meta data of a workflow step
type WorkflowStepMeta struct {
Alias string `json:"alias,omitempty"`
}
// WorkflowSubStep defines how to execute a workflow subStep.
type WorkflowSubStep struct {
// Name is the unique name of the workflow step.
@@ -372,15 +363,11 @@ type WorkflowSubStep struct {
Type string `json:"type"`
Meta *WorkflowStepMeta `json:"meta,omitempty"`
// +kubebuilder:pruning:PreserveUnknownFields
Properties *runtime.RawExtension `json:"properties,omitempty"`
If string `json:"if,omitempty"`
Timeout string `json:"timeout,omitempty"`
DependsOn []string `json:"dependsOn,omitempty"`
Inputs StepInputs `json:"inputs,omitempty"`

View File

@@ -684,11 +684,6 @@ func (in *WorkflowStatus) DeepCopy() *WorkflowStatus {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WorkflowStep) DeepCopyInto(out *WorkflowStep) {
*out = *in
if in.Meta != nil {
in, out := &in.Meta, &out.Meta
*out = new(WorkflowStepMeta)
**out = **in
}
if in.Properties != nil {
in, out := &in.Properties, &out.Properties
*out = new(runtime.RawExtension)
@@ -728,21 +723,6 @@ func (in *WorkflowStep) DeepCopy() *WorkflowStep {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WorkflowStepMeta) DeepCopyInto(out *WorkflowStepMeta) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowStepMeta.
func (in *WorkflowStepMeta) DeepCopy() *WorkflowStepMeta {
if in == nil {
return nil
}
out := new(WorkflowStepMeta)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WorkflowStepStatus) DeepCopyInto(out *WorkflowStepStatus) {
*out = *in
@@ -769,11 +749,6 @@ func (in *WorkflowStepStatus) DeepCopy() *WorkflowStepStatus {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WorkflowSubStep) DeepCopyInto(out *WorkflowSubStep) {
*out = *in
if in.Meta != nil {
in, out := &in.Meta, &out.Meta
*out = new(WorkflowStepMeta)
**out = **in
}
if in.Properties != nil {
in, out := &in.Properties, &out.Properties
*out = new(runtime.RawExtension)

View File

@@ -25,8 +25,6 @@ const (
type RefObjectsComponentSpec struct {
// Objects the referrers to the Kubernetes objects
Objects []ObjectReferrer `json:"objects,omitempty"`
// URLs are the links that stores the referred objects
URLs []string `json:"urls,omitempty"`
}
// ObjectReferrer selects Kubernetes objects

View File

@@ -18,7 +18,6 @@ package v1alpha1
import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/utils/strings/slices"
"github.com/oam-dev/kubevela/pkg/oam"
)
@@ -67,29 +66,6 @@ type ResourcePolicyRuleSelector struct {
OAMResourceTypes []string `json:"oamTypes"`
TraitTypes []string `json:"traitTypes"`
ResourceTypes []string `json:"resourceTypes"`
ResourceNames []string `json:"resourceNames"`
}
// Match check if current rule selector match the target resource
func (in *ResourcePolicyRuleSelector) Match(manifest *unstructured.Unstructured) bool {
var compName, compType, oamType, traitType, resourceType, resourceName string
if labels := manifest.GetLabels(); labels != nil {
compName = labels[oam.LabelAppComponent]
compType = labels[oam.WorkloadTypeLabel]
oamType = labels[oam.LabelOAMResourceType]
traitType = labels[oam.TraitTypeLabel]
}
resourceType = manifest.GetKind()
resourceName = manifest.GetName()
match := func(src []string, val string) (found bool) {
return val != "" && slices.Contains(src, val)
}
return match(in.CompNames, compName) ||
match(in.CompTypes, compType) ||
match(in.OAMResourceTypes, oamType) ||
match(in.TraitTypes, traitType) ||
match(in.ResourceTypes, resourceType) ||
match(in.ResourceNames, resourceName)
}
// GarbageCollectStrategy the strategy for target resource to recycle
@@ -108,7 +84,23 @@ const (
// FindStrategy find gc strategy for target resource
func (in GarbageCollectPolicySpec) FindStrategy(manifest *unstructured.Unstructured) *GarbageCollectStrategy {
for _, rule := range in.Rules {
if rule.Selector.Match(manifest) {
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) {
for _, _val := range src {
found = found || _val == val
}
return val != "" && found
}
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

@@ -16,8 +16,6 @@ limitations under the License.
package v1alpha1
import "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
const (
// TopologyPolicyType refers to the type of topology policy
TopologyPolicyType = "topology"
@@ -25,8 +23,6 @@ const (
OverridePolicyType = "override"
// DebugPolicyType refers to the type of debug policy
DebugPolicyType = "debug"
// SharedResourcePolicyType refers to the type of shared resource policy
SharedResourcePolicyType = "shared-resource"
)
// TopologyPolicySpec defines the spec of topology policy
@@ -57,23 +53,3 @@ type OverridePolicySpec struct {
Components []EnvComponentPatch `json:"components,omitempty"`
Selector []string `json:"selector,omitempty"`
}
// SharedResourcePolicySpec defines the spec of shared-resource policy
type SharedResourcePolicySpec struct {
Rules []SharedResourcePolicyRule `json:"rules"`
}
// SharedResourcePolicyRule defines the rule for sharing resources
type SharedResourcePolicyRule struct {
Selector ResourcePolicyRuleSelector `json:"selector"`
}
// FindStrategy return if the target resource should be shared
func (in SharedResourcePolicySpec) FindStrategy(manifest *unstructured.Unstructured) bool {
for _, rule := range in.Rules {
if rule.Selector.Match(manifest) {
return true
}
}
return false
}

View File

@@ -1,69 +0,0 @@
/*
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 v1alpha1
import (
"testing"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
func TestSharedResourcePolicySpec_FindStrategy(t *testing.T) {
testCases := map[string]struct {
rules []SharedResourcePolicyRule
input *unstructured.Unstructured
matched bool
}{
"shared resource rule resourceName match": {
rules: []SharedResourcePolicyRule{{
Selector: ResourcePolicyRuleSelector{ResourceNames: []string{"example"}},
}},
input: &unstructured.Unstructured{Object: map[string]interface{}{
"metadata": map[string]interface{}{
"name": "example",
},
}},
matched: true,
},
"shared resource rule resourceType match": {
rules: []SharedResourcePolicyRule{{
Selector: ResourcePolicyRuleSelector{ResourceTypes: []string{"ConfigMap", "Namespace"}},
}},
input: &unstructured.Unstructured{Object: map[string]interface{}{
"kind": "Namespace",
}},
matched: true,
},
"shared resource rule mismatch": {
rules: []SharedResourcePolicyRule{{
Selector: ResourcePolicyRuleSelector{ResourceNames: []string{"mismatch"}},
}},
input: &unstructured.Unstructured{Object: map[string]interface{}{
"kind": "Namespace",
}},
matched: false,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
r := require.New(t)
spec := SharedResourcePolicySpec{Rules: tc.rules}
r.Equal(tc.matched, spec.FindStrategy(tc.input))
})
}
}

View File

@@ -595,11 +595,6 @@ func (in *RefObjectsComponentSpec) DeepCopyInto(out *RefObjectsComponentSpec) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.URLs != nil {
in, out := &in.URLs, &out.URLs
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RefObjectsComponentSpec.
@@ -640,11 +635,6 @@ func (in *ResourcePolicyRuleSelector) DeepCopyInto(out *ResourcePolicyRuleSelect
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ResourceNames != nil {
in, out := &in.ResourceNames, &out.ResourceNames
*out = make([]string, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourcePolicyRuleSelector.
@@ -657,44 +647,6 @@ func (in *ResourcePolicyRuleSelector) DeepCopy() *ResourcePolicyRuleSelector {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SharedResourcePolicyRule) DeepCopyInto(out *SharedResourcePolicyRule) {
*out = *in
in.Selector.DeepCopyInto(&out.Selector)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SharedResourcePolicyRule.
func (in *SharedResourcePolicyRule) DeepCopy() *SharedResourcePolicyRule {
if in == nil {
return nil
}
out := new(SharedResourcePolicyRule)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SharedResourcePolicySpec) DeepCopyInto(out *SharedResourcePolicySpec) {
*out = *in
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]SharedResourcePolicyRule, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SharedResourcePolicySpec.
func (in *SharedResourcePolicySpec) DeepCopy() *SharedResourcePolicySpec {
if in == nil {
return nil
}
out := new(SharedResourcePolicySpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TopologyPolicySpec) DeepCopyInto(out *TopologyPolicySpec) {
*out = *in

View File

@@ -54,15 +54,8 @@ type WorkflowStep common.WorkflowStep
// Workflow defines workflow steps and other attributes
type Workflow struct {
Ref string `json:"ref,omitempty"`
Mode *WorkflowExecuteMode `json:"mode,omitempty"`
Steps []WorkflowStep `json:"steps,omitempty"`
}
// WorkflowExecuteMode defines the mode of workflow execution
type WorkflowExecuteMode struct {
Steps common.WorkflowMode `json:"steps,omitempty"`
SubSteps common.WorkflowMode `json:"subSteps,omitempty"`
Ref string `json:"ref,omitempty"`
Steps []WorkflowStep `json:"steps,omitempty"`
}
// ApplicationSpec is the spec of Application

View File

@@ -927,11 +927,6 @@ func (in *TraitDefinitionStatus) DeepCopy() *TraitDefinitionStatus {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Workflow) DeepCopyInto(out *Workflow) {
*out = *in
if in.Mode != nil {
in, out := &in.Mode, &out.Mode
*out = new(WorkflowExecuteMode)
**out = **in
}
if in.Steps != nil {
in, out := &in.Steps, &out.Steps
*out = make([]WorkflowStep, len(*in))
@@ -951,29 +946,9 @@ func (in *Workflow) DeepCopy() *Workflow {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WorkflowExecuteMode) DeepCopyInto(out *WorkflowExecuteMode) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkflowExecuteMode.
func (in *WorkflowExecuteMode) DeepCopy() *WorkflowExecuteMode {
if in == nil {
return nil
}
out := new(WorkflowExecuteMode)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *WorkflowStep) DeepCopyInto(out *WorkflowStep) {
*out = *in
if in.Meta != nil {
in, out := &in.Meta, &out.Meta
*out = new(common.WorkflowStepMeta)
**out = **in
}
if in.Properties != nil {
in, out := &in.Properties, &out.Properties
*out = new(runtime.RawExtension)

View File

@@ -80,8 +80,6 @@ const (
OpenapiV3JSONSchema string = "openapi-v3-json-schema"
// UISchema is the key to store ui custom schema
UISchema string = "ui-schema"
// VelaQLConfigmapKey is the key to store velaql view
VelaQLConfigmapKey string = "template"
)
// CapabilityCategory defines the category of a capability

View File

@@ -93,7 +93,6 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
| `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` |
| `featureGates.enableLegacyComponentRevision` | if disabled, only component with rollout trait will create component revisions | `false` |
### MultiCluster parameters

View File

@@ -2198,17 +2198,6 @@ spec:
a context in annotation. - should mark "finish" phase in
status.conditions.'
properties:
mode:
description: WorkflowExecuteMode defines the mode of workflow
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
type: string
type: object
ref:
type: string
steps:
@@ -2236,13 +2225,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta
data of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow
step.
@@ -2289,13 +2271,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the
meta data of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the
workflow step.
@@ -2317,8 +2292,6 @@ spec:
properties:
type: object
x-kubernetes-preserve-unknown-fields: true
timeout:
type: string
type:
type: string
required:
@@ -2326,8 +2299,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:
@@ -4002,13 +3973,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of
a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -4053,13 +4017,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data
of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow
step.
@@ -4081,8 +4038,6 @@ spec:
properties:
type: object
x-kubernetes-preserve-unknown-fields: true
timeout:
type: string
type:
type: string
required:
@@ -4090,8 +4045,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:

View File

@@ -1009,17 +1009,6 @@ spec:
order, and each step: - will have a context in annotation. - should
mark "finish" phase in status.conditions.'
properties:
mode:
description: WorkflowExecuteMode defines the mode of workflow
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
type: string
type: object
ref:
type: string
steps:
@@ -1046,13 +1035,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of
a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -1097,13 +1079,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data
of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow
step.
@@ -1125,8 +1100,6 @@ spec:
properties:
type: object
x-kubernetes-preserve-unknown-fields: true
timeout:
type: string
type:
type: string
required:
@@ -1134,8 +1107,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:

View File

@@ -57,13 +57,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of a workflow
step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -107,13 +100,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of a
workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -133,8 +119,6 @@ spec:
properties:
type: object
x-kubernetes-preserve-unknown-fields: true
timeout:
type: string
type:
type: string
required:
@@ -142,8 +126,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:
@@ -159,16 +141,6 @@ spec:
openAPIV3Schema:
description: Workflow defines workflow steps and other attributes
properties:
mode:
description: WorkflowExecuteMode defines the mode of workflow execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
type: string
type: object
ref:
type: string
steps:
@@ -194,13 +166,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of a workflow
step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -244,13 +209,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of a
workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -270,8 +228,6 @@ spec:
properties:
type: object
x-kubernetes-preserve-unknown-fields: true
timeout:
type: string
type:
type: string
required:
@@ -279,8 +235,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:

View File

@@ -1,574 +0,0 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/daemon.cue
apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
annotations:
definition.oam.dev/description: Describes daemonset services in Kubernetes.
name: daemon
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
schematic:
cue:
template: |
import (
"strconv"
)
mountsArray: {
pvc: *[
for v in parameter.volumeMounts.pvc {
{
mountPath: v.mountPath
name: v.name
}
},
] | []
configMap: *[
for v in parameter.volumeMounts.configMap {
{
mountPath: v.mountPath
name: v.name
}
},
] | []
secret: *[
for v in parameter.volumeMounts.secret {
{
mountPath: v.mountPath
name: v.name
}
},
] | []
emptyDir: *[
for v in parameter.volumeMounts.emptyDir {
{
mountPath: v.mountPath
name: v.name
}
},
] | []
hostPath: *[
for v in parameter.volumeMounts.hostPath {
{
mountPath: v.mountPath
if v.mountPropagation != _|_ {
mountPropagation: v.mountPropagation
}
name: v.name
if v.readOnly != _|_ {
readOnly: v.readOnly
}
}
},
] | []
}
volumesArray: {
pvc: *[
for v in parameter.volumeMounts.pvc {
{
name: v.name
persistentVolumeClaim: claimName: v.claimName
}
},
] | []
configMap: *[
for v in parameter.volumeMounts.configMap {
{
name: v.name
configMap: {
defaultMode: v.defaultMode
name: v.cmName
if v.items != _|_ {
items: v.items
}
}
}
},
] | []
secret: *[
for v in parameter.volumeMounts.secret {
{
name: v.name
secret: {
defaultMode: v.defaultMode
secretName: v.secretName
if v.items != _|_ {
items: v.items
}
}
}
},
] | []
emptyDir: *[
for v in parameter.volumeMounts.emptyDir {
{
name: v.name
emptyDir: medium: v.medium
}
},
] | []
hostPath: *[
for v in parameter.volumeMounts.hostPath {
{
name: v.name
hostPath: path: v.path
}
},
] | []
}
output: {
apiVersion: "apps/v1"
kind: "DaemonSet"
spec: {
selector: matchLabels: "app.oam.dev/component": context.name
template: {
metadata: {
labels: {
if parameter.labels != _|_ {
parameter.labels
}
if parameter.addRevisionLabel {
"app.oam.dev/revision": context.revision
}
"app.oam.dev/name": context.appName
"app.oam.dev/component": context.name
}
if parameter.annotations != _|_ {
annotations: parameter.annotations
}
}
spec: {
containers: [{
name: context.name
image: parameter.image
if parameter["port"] != _|_ && parameter["ports"] == _|_ {
ports: [{
containerPort: parameter.port
}]
}
if parameter["ports"] != _|_ {
ports: [ for v in parameter.ports {
{
containerPort: v.port
protocol: v.protocol
if v.name != _|_ {
name: v.name
}
if v.name == _|_ {
name: "port-" + strconv.FormatInt(v.port, 10)
}
}}]
}
if parameter["imagePullPolicy"] != _|_ {
imagePullPolicy: parameter.imagePullPolicy
}
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
if parameter["env"] != _|_ {
env: parameter.env
}
if context["config"] != _|_ {
env: context.config
}
if parameter["cpu"] != _|_ {
resources: {
limits: cpu: parameter.cpu
requests: cpu: parameter.cpu
}
}
if parameter["memory"] != _|_ {
resources: {
limits: memory: parameter.memory
requests: memory: parameter.memory
}
}
if parameter["volumes"] != _|_ && parameter["volumeMounts"] == _|_ {
volumeMounts: [ for v in parameter.volumes {
{
mountPath: v.mountPath
name: v.name
}}]
}
if parameter["volumeMounts"] != _|_ {
volumeMounts: mountsArray.pvc + mountsArray.configMap + mountsArray.secret + mountsArray.emptyDir + mountsArray.hostPath
}
if parameter["livenessProbe"] != _|_ {
livenessProbe: parameter.livenessProbe
}
if parameter["readinessProbe"] != _|_ {
readinessProbe: parameter.readinessProbe
}
}]
if parameter["hostAliases"] != _|_ {
// +patchKey=ip
hostAliases: parameter.hostAliases
}
if parameter["imagePullSecrets"] != _|_ {
imagePullSecrets: [ for v in parameter.imagePullSecrets {
name: v
},
]
}
if parameter["volumes"] != _|_ && parameter["volumeMounts"] == _|_ {
volumes: [ for v in parameter.volumes {
{
name: v.name
if v.type == "pvc" {
persistentVolumeClaim: claimName: v.claimName
}
if v.type == "configMap" {
configMap: {
defaultMode: v.defaultMode
name: v.cmName
if v.items != _|_ {
items: v.items
}
}
}
if v.type == "secret" {
secret: {
defaultMode: v.defaultMode
secretName: v.secretName
if v.items != _|_ {
items: v.items
}
}
}
if v.type == "emptyDir" {
emptyDir: medium: v.medium
}
}
}]
}
if parameter["volumeMounts"] != _|_ {
volumes: volumesArray.pvc + volumesArray.configMap + volumesArray.secret + volumesArray.emptyDir + volumesArray.hostPath
}
}
}
}
}
exposePorts: [
for v in parameter.ports if v.expose == true {
port: v.port
targetPort: v.port
if v.name != _|_ {
name: v.name
}
if v.name == _|_ {
name: "port-" + strconv.FormatInt(v.port, 10)
}
},
]
outputs: {
if len(exposePorts) != 0 {
webserviceExpose: {
apiVersion: "v1"
kind: "Service"
metadata: name: context.name
spec: {
selector: "app.oam.dev/component": context.name
ports: exposePorts
type: parameter.exposeType
}
}
}
}
parameter: {
// +usage=Specify the labels in the workload
labels?: [string]: string
// +usage=Specify the annotations in the workload
annotations?: [string]: string
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Specify image pull policy for your service
imagePullPolicy?: "Always" | "Never" | "IfNotPresent"
// +usage=Specify image pull secrets for your service
imagePullSecrets?: [...string]
// +ignore
// +usage=Deprecated field, please use ports instead
// +short=p
port?: int
// +usage=Which ports do you want customer traffic sent to, defaults to 80
ports?: [...{
// +usage=Number of port to expose on the pod's IP address
port: int
// +usage=Name of the port
name?: string
// +usage=Protocol for port. Must be UDP, TCP, or SCTP
protocol: *"TCP" | "UDP" | "SCTP"
// +usage=Specify if the port should be exposed
expose: *false | bool
}]
// +ignore
// +usage=Specify what kind of Service you want. options: "ClusterIP", "NodePort", "LoadBalancer", "ExternalName"
exposeType: *"ClusterIP" | "NodePort" | "LoadBalancer" | "ExternalName"
// +ignore
// +usage=If addRevisionLabel is true, the revision label will be added to the underlying pods
addRevisionLabel: *false | bool
// +usage=Commands to run in the container
cmd?: [...string]
// +usage=Define arguments by using environment variables
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=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
cpu?: string
// +usage=Specifies the attributes of the memory resource required for the container.
memory?: string
volumeMounts?: {
// +usage=Mount PVC type volume
pvc?: [...{
name: string
mountPath: string
// +usage=The name of the PVC
claimName: string
}]
// +usage=Mount ConfigMap type volume
configMap?: [...{
name: string
mountPath: string
defaultMode: *420 | int
cmName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}]
// +usage=Mount Secret type volume
secret?: [...{
name: string
mountPath: string
defaultMode: *420 | int
secretName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}]
// +usage=Mount EmptyDir type volume
emptyDir?: [...{
name: string
mountPath: string
medium: *"" | "Memory"
}]
// +usage=Mount HostPath type volume
hostPath?: [...{
name: string
mountPath: string
mountPropagation?: "None" | "HostToContainer" | "Bidirectional"
path: string
readOnly?: bool
}]
}
// +usage=Deprecated field, use volumeMounts instead.
volumes?: [...{
name: string
mountPath: string
// +usage=Specify volume type, options: "pvc","configMap","secret","emptyDir"
type: "pvc" | "configMap" | "secret" | "emptyDir"
if type == "pvc" {
claimName: string
}
if type == "configMap" {
defaultMode: *420 | int
cmName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}
if type == "secret" {
defaultMode: *420 | int
secretName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}
if type == "emptyDir" {
medium: *"" | "Memory"
}
}]
// +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
// +usage=Specify the hostAliases to add
hostAliases?: [...{
ip: string
hostnames: [...string]
}]
}
#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
host?: string
scheme?: *"HTTP" | string
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
}
status:
customStatus: |-
ready: {
replicas: *0 | int
} & {
if context.output.status.numberReady != _|_ {
replicas: context.output.status.numberReady
}
}
desired: {
replicas: *0 | int
} & {
if context.output.status.desiredNumberScheduled != _|_ {
replicas: context.output.status.desiredNumberScheduled
}
}
message: "Ready:\(ready.replicas)/\(desired.replicas)"
healthPolicy: |-
ready: {
replicas: *0 | int
} & {
if context.output.status.numberReady != _|_ {
replicas: context.output.status.numberReady
}
}
desired: {
replicas: *0 | int
} & {
if context.output.status.desiredNumberScheduled != _|_ {
replicas: context.output.status.desiredNumberScheduled
}
}
current: {
replicas: *0 | int
} & {
if context.output.status.currentNumberScheduled != _|_ {
replicas: context.output.status.currentNumberScheduled
}
}
updated: {
replicas: *0 | int
} & {
if context.output.status.updatedNumberScheduled != _|_ {
replicas: context.output.status.updatedNumberScheduled
}
}
generation: {
metadata: context.output.metadata.generation
observed: *0 | int
} & {
if context.output.status.observedGeneration != _|_ {
observed: context.output.status.observedGeneration
}
}
isHealth: (desired.replicas == ready.replicas) && (desired.replicas == updated.replicas) && (desired.replicas == current.replicas) && (generation.observed == generation.metadata || generation.observed > generation.metadata)
workload:
definition:
apiVersion: apps/v1
kind: DaemonSet
type: daemonsets.apps

View File

@@ -14,20 +14,21 @@ spec:
cue:
template: |
#K8sObject: {
resource?: string
group?: string
name?: string
// +usage=The resource type for the Kubernetes objects
resource?: string
// +usage=The group name for the Kubernetes objects
group?: string
// +usage=If specified, fetch the Kubernetes objects with the name, exclusive to labelSelector
name?: string
// +usage=If specified, fetch the Kubernetes objects from the namespace. Otherwise, fetch from the application's namespace.
namespace?: string
cluster?: string
// +usage=If specified, fetch the Kubernetes objects from the cluster. Otherwise, fetch from the local cluster.
cluster?: string
// +usage=If specified, fetch the Kubernetes objects according to the label selector, exclusive to name
labelSelector?: [string]: string
...
}
output: {
if len(parameter.objects) > 0 {
parameter.objects[0]
}
...
}
output: parameter.objects[0]
outputs: {
for i, v in parameter.objects {
if i > 0 {
@@ -35,7 +36,12 @@ spec:
}
}
}
parameter: objects: [...#K8sObject]
parameter: {
// +usage=If specified, application will fetch native Kubernetes objects according to the object description
objects?: [...#K8sObject]
// +usage=If specified, the objects in the urls will be loaded.
urls?: [...string]
}
status:
customStatus: |-
if context.output.apiVersion == "apps/v1" && context.output.kind == "Deployment" {

View File

@@ -64,6 +64,9 @@ spec:
{
name: "pvc-" + v.name
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
}
}
},
@@ -73,6 +76,9 @@ spec:
{
name: "configmap-" + v.name
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
}
},
] | []
@@ -103,6 +109,9 @@ spec:
{
name: "secret-" + v.name
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
}
},
] | []
@@ -133,6 +142,9 @@ spec:
{
name: "emptydir-" + v.name
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
}
},
] | []
@@ -141,12 +153,28 @@ spec:
{
name: "pvc-" + v.name
devicePath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
}
},
] | []
volumesList: pvcVolumesList + configMapVolumesList + secretVolumesList + emptyDirVolumesList
deDupVolumesArray: [
for val in [
for i, vi in volumesList {
for j, vj in volumesList if j < i && vi.name == vj.name {
_ignore: true
}
vi
},
] if val._ignore == _|_ {
val
},
]
patch: spec: template: spec: {
// +patchKey=name
volumes: pvcVolumesList + configMapVolumesList + secretVolumesList + emptyDirVolumesList
volumes: deDupVolumesArray
containers: [{
// +patchKey=name
@@ -234,6 +262,7 @@ spec:
name: string
mountOnly: *false | bool
mountPath: string
subPath?: string
volumeMode: *"Filesystem" | string
volumeName?: string
accessModes: *["ReadWriteOnce"] | [...string]
@@ -275,6 +304,7 @@ spec:
configMapKey: string
}]
mountPath?: string
subPath?: string
defaultMode: *420 | int
readOnly: *false | bool
data?: {...}
@@ -298,6 +328,7 @@ spec:
secretKey: string
}]
mountPath?: string
subPath?: string
defaultMode: *420 | int
readOnly: *false | bool
stringData?: {...}
@@ -313,6 +344,7 @@ spec:
emptyDir?: [...{
name: string
mountPath: string
subPath?: string
medium: *"" | "Memory"
}]
}

View File

@@ -20,7 +20,10 @@ spec:
for v in parameter.volumeMounts.pvc {
{
mountPath: v.mountPath
name: v.name
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
] | []
@@ -29,7 +32,10 @@ spec:
for v in parameter.volumeMounts.configMap {
{
mountPath: v.mountPath
name: v.name
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
] | []
@@ -38,7 +44,10 @@ spec:
for v in parameter.volumeMounts.secret {
{
mountPath: v.mountPath
name: v.name
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
] | []
@@ -47,7 +56,10 @@ spec:
for v in parameter.volumeMounts.emptyDir {
{
mountPath: v.mountPath
name: v.name
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
] | []
@@ -56,7 +68,10 @@ spec:
for v in parameter.volumeMounts.hostPath {
{
mountPath: v.mountPath
name: v.name
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
] | []
@@ -119,6 +134,19 @@ spec:
},
] | []
}
volumesList: volumesArray.pvc + volumesArray.configMap + volumesArray.secret + volumesArray.emptyDir + volumesArray.hostPath
deDupVolumesArray: [
for val in [
for i, vi in volumesList {
for j, vj in volumesList if j < i && vi.name == vj.name {
_ignore: true
}
vi
},
] if val._ignore == _|_ {
val
},
]
output: {
apiVersion: "apps/v1"
kind: "Deployment"
@@ -262,7 +290,7 @@ spec:
}
if parameter["volumeMounts"] != _|_ {
volumes: volumesArray.pvc + volumesArray.configMap + volumesArray.secret + volumesArray.emptyDir + volumesArray.hostPath
volumes: deDupVolumesArray
}
}
}
@@ -375,6 +403,7 @@ spec:
pvc?: [...{
name: string
mountPath: string
subPath?: string
// +usage=The name of the PVC
claimName: string
}]
@@ -382,6 +411,7 @@ spec:
configMap?: [...{
name: string
mountPath: string
subPath?: string
defaultMode: *420 | int
cmName: string
items?: [...{
@@ -394,6 +424,7 @@ spec:
secret?: [...{
name: string
mountPath: string
subPath?: string
defaultMode: *420 | int
secretName: string
items?: [...{
@@ -406,12 +437,14 @@ spec:
emptyDir?: [...{
name: string
mountPath: string
subPath?: string
medium: *"" | "Memory"
}]
// +usage=Mount HostPath type volume
hostPath?: [...{
name: string
mountPath: string
subPath?: string
path: string
}]
}

View File

@@ -217,7 +217,6 @@ spec:
- "--max-workflow-step-error-retry-times={{ .Values.workflow.step.errorRetryTimes }}"
- "--feature-gates=EnableSuspendOnFailure={{- .Values.workflow.enableSuspendOnFailure | toString -}}"
- "--feature-gates=AuthenticateApplication={{- .Values.authentication.enabled | toString -}}"
- "--feature-gates=LegacyComponentRevision={{- .Values.featureGates.enableLegacyComponentRevision | toString -}}"
{{ if .Values.authentication.enabled }}
{{ if .Values.authentication.withUser }}
- "--authentication-with-user"

View File

@@ -109,10 +109,6 @@ optimize:
disableResourceApplyDoubleCheck: false
enableResourceTrackerDeleteOnlyTrigger: true
##@param featureGates.enableLegacyComponentRevision if disabled, only component with rollout trait will create component revisions
featureGates:
enableLegacyComponentRevision: false
## @section MultiCluster parameters
## @param multicluster.enabled Whether to enable multi-cluster

View File

@@ -2198,17 +2198,6 @@ spec:
a context in annotation. - should mark "finish" phase in
status.conditions.'
properties:
mode:
description: WorkflowExecuteMode defines the mode of workflow
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
type: string
type: object
ref:
type: string
steps:
@@ -2236,13 +2225,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta
data of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow
step.
@@ -2289,13 +2271,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the
meta data of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the
workflow step.
@@ -2317,8 +2292,6 @@ spec:
properties:
type: object
x-kubernetes-preserve-unknown-fields: true
timeout:
type: string
type:
type: string
required:
@@ -2326,8 +2299,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:
@@ -4002,13 +3973,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of
a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -4053,13 +4017,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data
of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow
step.
@@ -4081,8 +4038,6 @@ spec:
properties:
type: object
x-kubernetes-preserve-unknown-fields: true
timeout:
type: string
type:
type: string
required:
@@ -4090,8 +4045,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:

View File

@@ -1009,17 +1009,6 @@ spec:
order, and each step: - will have a context in annotation. - should
mark "finish" phase in status.conditions.'
properties:
mode:
description: WorkflowExecuteMode defines the mode of workflow
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
type: string
type: object
ref:
type: string
steps:
@@ -1046,13 +1035,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of
a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -1097,13 +1079,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data
of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow
step.
@@ -1125,8 +1100,6 @@ spec:
properties:
type: object
x-kubernetes-preserve-unknown-fields: true
timeout:
type: string
type:
type: string
required:
@@ -1134,8 +1107,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:

View File

@@ -1,574 +0,0 @@
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
# Definition source cue file: vela-templates/definitions/internal/daemon.cue
apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
annotations:
definition.oam.dev/description: Describes daemonset services in Kubernetes.
name: daemon
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
schematic:
cue:
template: |
import (
"strconv"
)
mountsArray: {
pvc: *[
for v in parameter.volumeMounts.pvc {
{
mountPath: v.mountPath
name: v.name
}
},
] | []
configMap: *[
for v in parameter.volumeMounts.configMap {
{
mountPath: v.mountPath
name: v.name
}
},
] | []
secret: *[
for v in parameter.volumeMounts.secret {
{
mountPath: v.mountPath
name: v.name
}
},
] | []
emptyDir: *[
for v in parameter.volumeMounts.emptyDir {
{
mountPath: v.mountPath
name: v.name
}
},
] | []
hostPath: *[
for v in parameter.volumeMounts.hostPath {
{
mountPath: v.mountPath
if v.mountPropagation != _|_ {
mountPropagation: v.mountPropagation
}
name: v.name
if v.readOnly != _|_ {
readOnly: v.readOnly
}
}
},
] | []
}
volumesArray: {
pvc: *[
for v in parameter.volumeMounts.pvc {
{
name: v.name
persistentVolumeClaim: claimName: v.claimName
}
},
] | []
configMap: *[
for v in parameter.volumeMounts.configMap {
{
name: v.name
configMap: {
defaultMode: v.defaultMode
name: v.cmName
if v.items != _|_ {
items: v.items
}
}
}
},
] | []
secret: *[
for v in parameter.volumeMounts.secret {
{
name: v.name
secret: {
defaultMode: v.defaultMode
secretName: v.secretName
if v.items != _|_ {
items: v.items
}
}
}
},
] | []
emptyDir: *[
for v in parameter.volumeMounts.emptyDir {
{
name: v.name
emptyDir: medium: v.medium
}
},
] | []
hostPath: *[
for v in parameter.volumeMounts.hostPath {
{
name: v.name
hostPath: path: v.path
}
},
] | []
}
output: {
apiVersion: "apps/v1"
kind: "DaemonSet"
spec: {
selector: matchLabels: "app.oam.dev/component": context.name
template: {
metadata: {
labels: {
if parameter.labels != _|_ {
parameter.labels
}
if parameter.addRevisionLabel {
"app.oam.dev/revision": context.revision
}
"app.oam.dev/name": context.appName
"app.oam.dev/component": context.name
}
if parameter.annotations != _|_ {
annotations: parameter.annotations
}
}
spec: {
containers: [{
name: context.name
image: parameter.image
if parameter["port"] != _|_ && parameter["ports"] == _|_ {
ports: [{
containerPort: parameter.port
}]
}
if parameter["ports"] != _|_ {
ports: [ for v in parameter.ports {
{
containerPort: v.port
protocol: v.protocol
if v.name != _|_ {
name: v.name
}
if v.name == _|_ {
name: "port-" + strconv.FormatInt(v.port, 10)
}
}}]
}
if parameter["imagePullPolicy"] != _|_ {
imagePullPolicy: parameter.imagePullPolicy
}
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
if parameter["env"] != _|_ {
env: parameter.env
}
if context["config"] != _|_ {
env: context.config
}
if parameter["cpu"] != _|_ {
resources: {
limits: cpu: parameter.cpu
requests: cpu: parameter.cpu
}
}
if parameter["memory"] != _|_ {
resources: {
limits: memory: parameter.memory
requests: memory: parameter.memory
}
}
if parameter["volumes"] != _|_ && parameter["volumeMounts"] == _|_ {
volumeMounts: [ for v in parameter.volumes {
{
mountPath: v.mountPath
name: v.name
}}]
}
if parameter["volumeMounts"] != _|_ {
volumeMounts: mountsArray.pvc + mountsArray.configMap + mountsArray.secret + mountsArray.emptyDir + mountsArray.hostPath
}
if parameter["livenessProbe"] != _|_ {
livenessProbe: parameter.livenessProbe
}
if parameter["readinessProbe"] != _|_ {
readinessProbe: parameter.readinessProbe
}
}]
if parameter["hostAliases"] != _|_ {
// +patchKey=ip
hostAliases: parameter.hostAliases
}
if parameter["imagePullSecrets"] != _|_ {
imagePullSecrets: [ for v in parameter.imagePullSecrets {
name: v
},
]
}
if parameter["volumes"] != _|_ && parameter["volumeMounts"] == _|_ {
volumes: [ for v in parameter.volumes {
{
name: v.name
if v.type == "pvc" {
persistentVolumeClaim: claimName: v.claimName
}
if v.type == "configMap" {
configMap: {
defaultMode: v.defaultMode
name: v.cmName
if v.items != _|_ {
items: v.items
}
}
}
if v.type == "secret" {
secret: {
defaultMode: v.defaultMode
secretName: v.secretName
if v.items != _|_ {
items: v.items
}
}
}
if v.type == "emptyDir" {
emptyDir: medium: v.medium
}
}
}]
}
if parameter["volumeMounts"] != _|_ {
volumes: volumesArray.pvc + volumesArray.configMap + volumesArray.secret + volumesArray.emptyDir + volumesArray.hostPath
}
}
}
}
}
exposePorts: [
for v in parameter.ports if v.expose == true {
port: v.port
targetPort: v.port
if v.name != _|_ {
name: v.name
}
if v.name == _|_ {
name: "port-" + strconv.FormatInt(v.port, 10)
}
},
]
outputs: {
if len(exposePorts) != 0 {
webserviceExpose: {
apiVersion: "v1"
kind: "Service"
metadata: name: context.name
spec: {
selector: "app.oam.dev/component": context.name
ports: exposePorts
type: parameter.exposeType
}
}
}
}
parameter: {
// +usage=Specify the labels in the workload
labels?: [string]: string
// +usage=Specify the annotations in the workload
annotations?: [string]: string
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Specify image pull policy for your service
imagePullPolicy?: "Always" | "Never" | "IfNotPresent"
// +usage=Specify image pull secrets for your service
imagePullSecrets?: [...string]
// +ignore
// +usage=Deprecated field, please use ports instead
// +short=p
port?: int
// +usage=Which ports do you want customer traffic sent to, defaults to 80
ports?: [...{
// +usage=Number of port to expose on the pod's IP address
port: int
// +usage=Name of the port
name?: string
// +usage=Protocol for port. Must be UDP, TCP, or SCTP
protocol: *"TCP" | "UDP" | "SCTP"
// +usage=Specify if the port should be exposed
expose: *false | bool
}]
// +ignore
// +usage=Specify what kind of Service you want. options: "ClusterIP", "NodePort", "LoadBalancer", "ExternalName"
exposeType: *"ClusterIP" | "NodePort" | "LoadBalancer" | "ExternalName"
// +ignore
// +usage=If addRevisionLabel is true, the revision label will be added to the underlying pods
addRevisionLabel: *false | bool
// +usage=Commands to run in the container
cmd?: [...string]
// +usage=Define arguments by using environment variables
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=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
cpu?: string
// +usage=Specifies the attributes of the memory resource required for the container.
memory?: string
volumeMounts?: {
// +usage=Mount PVC type volume
pvc?: [...{
name: string
mountPath: string
// +usage=The name of the PVC
claimName: string
}]
// +usage=Mount ConfigMap type volume
configMap?: [...{
name: string
mountPath: string
defaultMode: *420 | int
cmName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}]
// +usage=Mount Secret type volume
secret?: [...{
name: string
mountPath: string
defaultMode: *420 | int
secretName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}]
// +usage=Mount EmptyDir type volume
emptyDir?: [...{
name: string
mountPath: string
medium: *"" | "Memory"
}]
// +usage=Mount HostPath type volume
hostPath?: [...{
name: string
mountPath: string
mountPropagation?: "None" | "HostToContainer" | "Bidirectional"
path: string
readOnly?: bool
}]
}
// +usage=Deprecated field, use volumeMounts instead.
volumes?: [...{
name: string
mountPath: string
// +usage=Specify volume type, options: "pvc","configMap","secret","emptyDir"
type: "pvc" | "configMap" | "secret" | "emptyDir"
if type == "pvc" {
claimName: string
}
if type == "configMap" {
defaultMode: *420 | int
cmName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}
if type == "secret" {
defaultMode: *420 | int
secretName: string
items?: [...{
key: string
path: string
mode: *511 | int
}]
}
if type == "emptyDir" {
medium: *"" | "Memory"
}
}]
// +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
// +usage=Specify the hostAliases to add
hostAliases?: [...{
ip: string
hostnames: [...string]
}]
}
#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
host?: string
scheme?: *"HTTP" | string
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
}
status:
customStatus: |-
ready: {
replicas: *0 | int
} & {
if context.output.status.numberReady != _|_ {
replicas: context.output.status.numberReady
}
}
desired: {
replicas: *0 | int
} & {
if context.output.status.desiredNumberScheduled != _|_ {
replicas: context.output.status.desiredNumberScheduled
}
}
message: "Ready:\(ready.replicas)/\(desired.replicas)"
healthPolicy: |-
ready: {
replicas: *0 | int
} & {
if context.output.status.numberReady != _|_ {
replicas: context.output.status.numberReady
}
}
desired: {
replicas: *0 | int
} & {
if context.output.status.desiredNumberScheduled != _|_ {
replicas: context.output.status.desiredNumberScheduled
}
}
current: {
replicas: *0 | int
} & {
if context.output.status.currentNumberScheduled != _|_ {
replicas: context.output.status.currentNumberScheduled
}
}
updated: {
replicas: *0 | int
} & {
if context.output.status.updatedNumberScheduled != _|_ {
replicas: context.output.status.updatedNumberScheduled
}
}
generation: {
metadata: context.output.metadata.generation
observed: *0 | int
} & {
if context.output.status.observedGeneration != _|_ {
observed: context.output.status.observedGeneration
}
}
isHealth: (desired.replicas == ready.replicas) && (desired.replicas == updated.replicas) && (desired.replicas == current.replicas) && (generation.observed == generation.metadata || generation.observed > generation.metadata)
workload:
definition:
apiVersion: apps/v1
kind: DaemonSet
type: daemonsets.apps

View File

@@ -14,20 +14,21 @@ spec:
cue:
template: |
#K8sObject: {
resource?: string
group?: string
name?: string
// +usage=The resource type for the Kubernetes objects
resource?: string
// +usage=The group name for the Kubernetes objects
group?: string
// +usage=If specified, fetch the Kubernetes objects with the name, exclusive to labelSelector
name?: string
// +usage=If specified, fetch the Kubernetes objects from the namespace. Otherwise, fetch from the application's namespace.
namespace?: string
cluster?: string
// +usage=If specified, fetch the Kubernetes objects from the cluster. Otherwise, fetch from the local cluster.
cluster?: string
// +usage=If specified, fetch the Kubernetes objects according to the label selector, exclusive to name
labelSelector?: [string]: string
...
}
output: {
if len(parameter.objects) > 0 {
parameter.objects[0]
}
...
}
output: parameter.objects[0]
outputs: {
for i, v in parameter.objects {
if i > 0 {
@@ -35,7 +36,12 @@ spec:
}
}
}
parameter: objects: [...#K8sObject]
parameter: {
// +usage=If specified, application will fetch native Kubernetes objects according to the object description
objects?: [...#K8sObject]
// +usage=If specified, the objects in the urls will be loaded.
urls?: [...string]
}
status:
customStatus: |-
if context.output.apiVersion == "apps/v1" && context.output.kind == "Deployment" {

View File

@@ -64,6 +64,9 @@ spec:
{
name: "pvc-" + v.name
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
}
}
},
@@ -73,6 +76,9 @@ spec:
{
name: "configmap-" + v.name
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
}
},
] | []
@@ -103,6 +109,9 @@ spec:
{
name: "secret-" + v.name
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
}
},
] | []
@@ -133,6 +142,9 @@ spec:
{
name: "emptydir-" + v.name
mountPath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
}
},
] | []
@@ -141,12 +153,28 @@ spec:
{
name: "pvc-" + v.name
devicePath: v.mountPath
if v.subPath != _|_ {
subPath: v.subPath
}
}
},
] | []
volumesList: pvcVolumesList + configMapVolumesList + secretVolumesList + emptyDirVolumesList
deDupVolumesArray: [
for val in [
for i, vi in volumesList {
for j, vj in volumesList if j < i && vi.name == vj.name {
_ignore: true
}
vi
},
] if val._ignore == _|_ {
val
},
]
patch: spec: template: spec: {
// +patchKey=name
volumes: pvcVolumesList + configMapVolumesList + secretVolumesList + emptyDirVolumesList
volumes: deDupVolumesArray
containers: [{
// +patchKey=name
@@ -234,6 +262,7 @@ spec:
name: string
mountOnly: *false | bool
mountPath: string
subPath?: string
volumeMode: *"Filesystem" | string
volumeName?: string
accessModes: *["ReadWriteOnce"] | [...string]
@@ -275,6 +304,7 @@ spec:
configMapKey: string
}]
mountPath?: string
subPath?: string
defaultMode: *420 | int
readOnly: *false | bool
data?: {...}
@@ -298,6 +328,7 @@ spec:
secretKey: string
}]
mountPath?: string
subPath?: string
defaultMode: *420 | int
readOnly: *false | bool
stringData?: {...}
@@ -313,6 +344,7 @@ spec:
emptyDir?: [...{
name: string
mountPath: string
subPath?: string
medium: *"" | "Memory"
}]
}

View File

@@ -20,7 +20,10 @@ spec:
for v in parameter.volumeMounts.pvc {
{
mountPath: v.mountPath
name: v.name
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
] | []
@@ -29,7 +32,10 @@ spec:
for v in parameter.volumeMounts.configMap {
{
mountPath: v.mountPath
name: v.name
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
] | []
@@ -38,7 +44,10 @@ spec:
for v in parameter.volumeMounts.secret {
{
mountPath: v.mountPath
name: v.name
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
] | []
@@ -47,7 +56,10 @@ spec:
for v in parameter.volumeMounts.emptyDir {
{
mountPath: v.mountPath
name: v.name
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
] | []
@@ -56,7 +68,10 @@ spec:
for v in parameter.volumeMounts.hostPath {
{
mountPath: v.mountPath
name: v.name
if v.subPath != _|_ {
subPath: v.subPath
}
name: v.name
}
},
] | []
@@ -119,6 +134,19 @@ spec:
},
] | []
}
volumesList: volumesArray.pvc + volumesArray.configMap + volumesArray.secret + volumesArray.emptyDir + volumesArray.hostPath
deDupVolumesArray: [
for val in [
for i, vi in volumesList {
for j, vj in volumesList if j < i && vi.name == vj.name {
_ignore: true
}
vi
},
] if val._ignore == _|_ {
val
},
]
output: {
apiVersion: "apps/v1"
kind: "Deployment"
@@ -262,7 +290,7 @@ spec:
}
if parameter["volumeMounts"] != _|_ {
volumes: volumesArray.pvc + volumesArray.configMap + volumesArray.secret + volumesArray.emptyDir + volumesArray.hostPath
volumes: deDupVolumesArray
}
}
}
@@ -375,6 +403,7 @@ spec:
pvc?: [...{
name: string
mountPath: string
subPath?: string
// +usage=The name of the PVC
claimName: string
}]
@@ -382,6 +411,7 @@ spec:
configMap?: [...{
name: string
mountPath: string
subPath?: string
defaultMode: *420 | int
cmName: string
items?: [...{
@@ -394,6 +424,7 @@ spec:
secret?: [...{
name: string
mountPath: string
subPath?: string
defaultMode: *420 | int
secretName: string
items?: [...{
@@ -406,12 +437,14 @@ spec:
emptyDir?: [...{
name: string
mountPath: string
subPath?: string
medium: *"" | "Memory"
}]
// +usage=Mount HostPath type volume
hostPath?: [...{
name: string
mountPath: string
subPath?: string
path: string
}]
}

View File

@@ -36,7 +36,6 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/auth"
ctrlClient "github.com/oam-dev/kubevela/pkg/client"
@@ -47,7 +46,6 @@ import (
"github.com/oam-dev/kubevela/pkg/controller/utils"
"github.com/oam-dev/kubevela/pkg/cue/packages"
_ "github.com/oam-dev/kubevela/pkg/monitor/metrics"
"github.com/oam-dev/kubevela/pkg/monitor/watcher"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
@@ -56,7 +54,8 @@ import (
"github.com/oam-dev/kubevela/pkg/utils/system"
"github.com/oam-dev/kubevela/pkg/utils/util"
oamwebhook "github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev"
wfTypes "github.com/oam-dev/kubevela/pkg/workflow/types"
"github.com/oam-dev/kubevela/pkg/workflow"
"github.com/oam-dev/kubevela/pkg/workflow/tasks/custom"
"github.com/oam-dev/kubevela/version"
)
@@ -142,9 +141,9 @@ func main() {
standardcontroller.AddOptimizeFlags()
standardcontroller.AddAdmissionFlags()
flag.IntVar(&resourcekeeper.MaxDispatchConcurrent, "max-dispatch-concurrent", 10, "Set the max dispatch concurrent number, default is 10")
flag.IntVar(&wfTypes.MaxWorkflowWaitBackoffTime, "max-workflow-wait-backoff-time", 60, "Set the max workflow wait backoff time, default is 60")
flag.IntVar(&wfTypes.MaxWorkflowFailedBackoffTime, "max-workflow-failed-backoff-time", 300, "Set the max workflow wait backoff time, default is 300")
flag.IntVar(&wfTypes.MaxWorkflowStepErrorRetryTimes, "max-workflow-step-error-retry-times", 10, "Set the max workflow step error retry times, default is 10")
flag.IntVar(&workflow.MaxWorkflowWaitBackoffTime, "max-workflow-wait-backoff-time", 60, "Set the max workflow wait backoff time, default is 60")
flag.IntVar(&workflow.MaxWorkflowFailedBackoffTime, "max-workflow-failed-backoff-time", 300, "Set the max workflow wait backoff time, default is 300")
flag.IntVar(&custom.MaxWorkflowStepErrorRetryTimes, "max-workflow-step-error-retry-times", 10, "Set the max workflow step error retry times, default is 10")
utilfeature.DefaultMutableFeatureGate.AddFlag(flag.CommandLine)
flag.Parse()
@@ -324,13 +323,6 @@ func main() {
}
klog.InfoS("Use storage driver", "storageDriver", os.Getenv(system.StorageDriverEnv))
klog.Info("Start the vela application monitor")
informer, err := mgr.GetCache().GetInformer(context.Background(), &v1beta1.Application{})
if err != nil {
klog.ErrorS(err, "Unable to get informer for application")
}
watcher.StartApplicationMetricsWatcher(informer)
klog.Info("Start the vela controller manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

View File

@@ -1,47 +0,0 @@
# Shared Resource
### Background
In KubeVela, by default, application **owns** resources.
It means that resources create by the application should only be controlled by the application that creates it.
So there are basically two requirements for application creating resources:
1. The resource must not exist before the application creating it. It exists, there will be a resource conflict error.
2. The resource is expected to be only manageable through its creator. "Others" should not be able to modify it or edit it.
While dispatching resources, the application will
1. Check if resource exists. If exists, check its labels.
If "app.oam.dev/name" and "app.oam.dev/namespace" equals to the application's name and namespace, it means this resource is previously created by the same application and the dispatching operation now will become an update operation.
The two labels identify the owner of the resource.
2. If resource exists, but no label found, then this resource is created before this application. At this time, the application will report a resource conflict error.
3. If resource exists, and the labels point to another application, then this resource is managed by other applications. At this time, the current application will also report a resource conflict error.
With these checks, different applications cannot manage the same resource.
### Usage
However, there are scenarios that these two requirements are not met. One of the scenarios is sharing across different Applications.
For example, each application wants to create a ConfigMap, but their ConfigMaps are the same.
To achieve that, KubeVela application could utilize the `shared-resource` policy to make it possible.
#### create
When one resource is created as sharing resource, one special annotation `app.oam.dev/shared-by` will be added to the resource.
It will record the "sharer" of the resource in time order. The application that firstly creates the resource will set its owner labels to itself.
Then it will add itself to the sharer annotation.
#### share
When another application comes and wants to share the resource, it will check if the resource is sharable, aka there is at least one sharer in the sharer annotation.
If it is sharable, it will add itself to the sharer annotation, but not modify the content of the resource.
#### delete
With this mechanism, only the owner of the resource can modify the resource (including updating and state-keeping). Other sharer can only see that resource.
When the owner of the resource is gone (application is deleted or do not use this resource anymore), it will give the owner of the application to the next sharer. If no sharer exists, it will finally delete that resource.
See the following figures for details.
![shared-resource-1](./shared-resource-1.png)
![shared-resource-2](./shared-resource-2.png)

File diff suppressed because it is too large Load Diff

View File

@@ -1,91 +0,0 @@
## How to share resources across applications
Sometimes, you may want different applications to share the same resource.
For example, you might have various applications that needs the same namespace to exist.
In this case, you can use the `shared-resource` policy to declare which resources should be shared.
### Usage
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app1
spec:
components:
- name: ns1
type: k8s-objects
properties:
objects:
- apiVersion: v1
kind: Namespace
metadata:
name: example
- name: cm1
type: k8s-objects
properties:
objects:
- apiVersion: v1
kind: ConfigMap
metadata:
name: cm1
namespace: example
data:
key: value1
policies:
- name: shared-resource
type: shared-resource
properties:
rules:
- selector:
resourceTypes: ["Namespace"]
```
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app2
spec:
components:
- name: ns2
type: k8s-objects
properties:
objects:
- apiVersion: v1
kind: Namespace
metadata:
name: example
- name: cm2
type: k8s-objects
properties:
objects:
- apiVersion: v1
kind: ConfigMap
metadata:
name: cm2
namespace: example
data:
key: value2
policies:
- name: shared-resource
type: shared-resource
properties:
rules:
- selector:
resourceTypes: ["Namespace"]
```
The above two applications will dispatch the same namespace "example".
They will create two different ConfigMap inside namespace "example" respectively.
Both application use the `shared-resource` policy and declared the namespace resource as shared.
In this way, there will be no conflict for creating the same namespace.
If the `shared-resource` policy is not used, the second application will report error after it finds that the namespace "example" is managed by the first application.
The namespace will only be recycled when both applications are removed.
### Working Detail
One of the problem for sharing resource is that what will happen if different application holds different configuration for the shared resource.
In the `shared-resource` policy, all sharers will be recorded by time order. The first sharer will be able to write the resource while other sharers can only read it. After the first sharer is deleted, it will give the control of the resource to the next sharer. If no sharer is handling it, the resource will be finally removed.

View File

@@ -25,3 +25,7 @@ spec:
- name: my-mount
mountPath: /test
claimName: myclaim
- name: my-mount
mountPath: /test2
subPath: /sub
claimName: myclaim

View File

@@ -16,8 +16,9 @@ spec:
pvc:
- name: test1
mountPath: /test/mount/pvc
- name: test2
- name: test1
mountPath: /test/mount2/pvc
subPath: /sub
configMap:
- name: test1
mountPath: /test/mount/cm

View File

@@ -83,7 +83,7 @@ component-pod-view{appName=demo,appNs=default,cluster=prod,clusterNs=default,nam
#### describe
Query the pods detail information
Query the pods detail infomation
#### parameter

View File

@@ -1,130 +0,0 @@
# Steps with if
Every step can specify a `if`, you can use the `if` to determine whether the step should be executed or not.
## Always
If you want to execute the step no matter what, for example, send a notification after the component is deployed even it's failed, you can use the `if` with the value `always` like:
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: if-always-with-err
namespace: default
spec:
components:
- name: err-component
type: k8s-objects
properties:
objects:
- err: "error case"
workflow:
steps:
- name: apply-err-comp
type: apply-component
properties:
component: err-component
- name: notification
type: notification
if: always
properties:
slack:
url:
value: <your slack webhook url>
message:
text: always
```
## Custom Judgement
You can also write your own judgement logic to determine whether the step should be executed or not, note that the values of `if` will be executed as cue code. We support some built-in variables to use in `if`, they are:
* `status`: in this value, you can get the status of the step for judgement like `status.<step-name>.phase == "succeeded"`, or you can use the simplify way `status.<step-name>.succeeded`.
* `inputs`: in this value, you can get the inputs of the step for judgement like `inputs.<input-name> == "value"`.
### Status Example
If you want to control the step by the status of another step, you can follow the example:
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: if-timeout
namespace: default
spec:
components:
- name: comp-custom-timeout
type: webservice
properties:
image: crccheck/hello-world
port: 8000
workflow:
steps:
- name: suspend
timeout: 5s
type: suspend
- name: suspend2
# or `status.suspend.reason == "Timeout"`
if: status.suspend.timeout
type: suspend
timeout: 5s
- name: notification-1
type: notification
if: suspend.timeout
properties:
slack:
url:
value: <your slack webhook url>
message:
text: suspend is timeout
- name: notification-2
type: notification
if: status["notification-1"].succeeded
properties:
slack:
url:
value: <your slack webhook url>
message:
text: notification-1 is succeeded
```
### Inputs example
If you want to control the step by the inputs of another step, you can follow the example:
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: if-input
namespace: default
spec:
components:
- name: comp-custom-timeout
type: webservice
properties:
image: crccheck/hello-world
port: 8000
workflow:
steps:
- name: suspend
type: suspend
timeout: 5s
outputs:
- name: test
valueFrom: context.name + " message"
- name: notification
type: notification
inputs:
- from: test
parameterKey: slack.message.text
if: inputs.test == "if-input message"
properties:
slack:
url:
value: <your slack webhook url>
message:
text: from input
```

View File

@@ -1,62 +0,0 @@
# Timeout steps
Every step can specify a `timeout`, if the timeout expires and the step has not succeeded, the step will fail with the reason `Timeout`.
Here is an example:
```yaml
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app-with-timeout
namespace: default
spec:
components:
- name: comp
type: webservice
properties:
image: crccheck/hello-world
port: 8000
traits:
- type: scaler
properties:
replicas: 10
workflow:
steps:
- name: apply
timeout: 1m
type: apply-component
properties:
component: comp
- name: suspend
type: suspend
timeout: 5s
```
If the first step is succeeded in the time of `1m`, the second step will be executed. If the second step is not resumed in the time of `5s`, the suspend step will be failed with the reason `Timeout`, and the application will end up with the status of `WorkflowTerminated` like:
```yaml
status:
status: workflowTerminated
workflow:
...
finished: true
message: Terminated
mode: StepByStep
steps:
- firstExecuteTime: "2022-06-22T09:19:42Z"
id: gdcwh929ih
lastExecuteTime: "2022-06-22T09:20:08Z"
name: apply
phase: succeeded
type: apply-component
- firstExecuteTime: "2022-06-22T09:20:08Z"
id: rloz8axnju
lastExecuteTime: "2022-06-22T09:20:13Z"
name: suspend
phase: failed
reason: Timeout
type: suspend
suspend: false
terminated: true
```

View File

@@ -14,3 +14,10 @@ Edit a yaml file as `example.yaml`, then execute it with `vela up` command.
When executing the `step-group` step, the subSteps in the step group are executed in dag mode. The step group will only complete when all subSteps have been executed to completion.
SubStep has the same execution behavior as a normal step.

View File

@@ -22,10 +22,10 @@ import (
"strings"
"time"
"github.com/Netflix/go-expect"
v1 "k8s.io/api/core/v1"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
@@ -49,13 +49,13 @@ var _ = Describe("Addon Test", func() {
It("Enable addon test-addon", func() {
output, err := e2e.Exec("vela addon enable test-addon")
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring("enabled successfully."))
Expect(output).To(ContainSubstring("enabled Successfully."))
})
It("Upgrade addon test-addon", func() {
output, err := e2e.Exec("vela addon upgrade test-addon")
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring("enabled successfully."))
Expect(output).To(ContainSubstring("enabled Successfully."))
})
It("Disable addon test-addon", func() {
@@ -71,7 +71,7 @@ var _ = Describe("Addon Test", func() {
It("Enable addon with input", func() {
output, err := e2e.LongTimeExec("vela addon enable test-addon example=redis", 300*time.Second)
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring("enabled successfully."))
Expect(output).To(ContainSubstring("enabled Successfully."))
})
It("Disable addon test-addon", func() {
@@ -83,12 +83,6 @@ var _ = Describe("Addon Test", func() {
}, 60*time.Second).Should(Succeed())
})
It("Enable local addon with . as path", func() {
output, err := e2e.LongTimeExec("vela addon enable ../../e2e/addon/mock/testdata/sample/.", 600*time.Second)
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring("sample enabled successfully."))
})
It("Test Change default namespace can work", func() {
output, err := e2e.LongTimeExecWithEnv("vela addon list", 600*time.Second, []string{"DEFAULT_VELA_NS=test-vela"})
Expect(err).NotTo(HaveOccurred())
@@ -97,7 +91,7 @@ var _ = Describe("Addon Test", func() {
output, err = e2e.LongTimeExecWithEnv("vela addon enable test-addon", 600*time.Second, []string{"DEFAULT_VELA_NS=test-vela"})
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring("enabled successfully."))
Expect(output).To(ContainSubstring("enabled Successfully."))
Eventually(func(g Gomega) {
g.Expect(k8sClient.Get(context.Background(), types.NamespacedName{Name: "addon-test-addon", Namespace: "test-vela"}, &v1beta1.Application{})).Should(BeNil())
@@ -110,30 +104,6 @@ var _ = Describe("Addon Test", func() {
g.Expect(apierrors.IsNotFound(k8sClient.Get(context.Background(), types.NamespacedName{Name: "addon-test-addon", Namespace: "test-vela"}, &v1beta1.Application{}))).Should(BeTrue())
}, 60*time.Second).Should(Succeed())
})
It("Enable fluxcd-test-version whose version can't suit system requirements", func() {
output, err := e2e.InteractiveExec("vela addon enable fluxcd-test-version", func(c *expect.Console) {
_, err = c.SendLine("y")
Expect(err).NotTo(HaveOccurred())
})
Expect(output).To(ContainSubstring("enabled successfully"))
Expect(err).NotTo(HaveOccurred())
})
It("Disable addon fluxcd-test-version", func() {
output, err := e2e.LongTimeExec("vela addon disable fluxcd-test-version", 600*time.Second)
Expect(err).NotTo(HaveOccurred())
Expect(output).To(ContainSubstring("Successfully disable addon"))
})
It("Enable fluxcd-test-version whose version can't suit system requirements with 'n' input", func() {
output, err := e2e.InteractiveExec("vela addon enable fluxcd-test-version", func(c *expect.Console) {
_, err = c.SendLine("n")
Expect(err).NotTo(HaveOccurred())
})
Expect(output).To(ContainSubstring("you can try another version by command"))
Expect(err).NotTo(HaveOccurred())
})
})
Context("Addon registry test", func() {

View File

@@ -1,15 +0,0 @@
name: sample
version: 1.0.1
description: This is a test sample addon
icon: https://www.terraform.io/assets/images/logo-text-8c3ba8a6.svg
url: https://terraform.io/
tags: []
deployTo:
control_plane: true
runtime_cluster: false
dependencies: []
invisible: false

View File

@@ -1,3 +0,0 @@
parameter: {
example: *"default" | string
}

View File

@@ -1,26 +0,0 @@
apiVersion: v1
entries:
fluxcd-test-version:
- apiVersion: v2
appVersion: 1.16.0
description: A Helm chart for Kubernetes
name: fluxcd-test-version
type: application
urls:
- http://127.0.0.1:9098/helm/fluxcd-test-version-1.0.0.tgz
version: 1.0.0
annotations:
system.vela: ">=1.3.0"
system.kubernetes: ">=1.10.0"
- apiVersion: v2
appVersion: 1.16.0
description: A Helm chart for Kubernetes
name: fluxcd-test-version
type: application
urls:
- http://127.0.0.1:9098/helm/fluxcd-test-version-2.0.0.tgz
version: 2.0.0
annotations:
system.vela: ">=1.5.0"
system.kubernetes: ">=1.30.0"
generated: "2022-06-15T13:17:04.733573+08:00"

View File

@@ -39,7 +39,7 @@ var (
apiVersion: v1
data:
registries: '{ "KubeVela":{ "name": "KubeVela", "oss": { "end_point": "http://REGISTRY_ADDR",
"bucket": "" } }, "Test-Helm":{ "name": "Test-Helm", "helm": { "name":"", "password":"", "url": "http://HELM_ADDR"} } }'
"bucket": "" } } }'
kind: ConfigMap
metadata:
name: vela-addon-registry
@@ -59,7 +59,6 @@ func ApplyMockServerConfig() error {
cm := v1.ConfigMap{}
registryCmStr := strings.ReplaceAll(velaRegistry, "REGISTRY_ADDR", fmt.Sprintf("127.0.0.1:%d", Port))
registryCmStr = strings.ReplaceAll(registryCmStr, "HELM_ADDR", fmt.Sprintf("127.0.0.1:%d/helm", Port))
err = yaml.Unmarshal([]byte(registryCmStr), &cm)
if err != nil {

View File

@@ -22,7 +22,6 @@ import (
"fmt"
"html/template"
"io/fs"
"io/ioutil"
"log"
"net/http"
"path"
@@ -47,7 +46,6 @@ func main() {
log.Fatal("Apply mock server config to ConfigMap fail")
}
http.HandleFunc("/", ossHandler)
http.HandleFunc("/helm/", helmHandler)
err = http.ListenAndServe(fmt.Sprintf(":%d", utils.Port), nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
@@ -105,29 +103,6 @@ var ossHandler http.HandlerFunc = func(rw http.ResponseWriter, req *http.Request
}
}
var helmHandler http.HandlerFunc = func(rw http.ResponseWriter, req *http.Request) {
switch {
case strings.Contains(req.URL.Path, "index.yaml"):
file, err := ioutil.ReadFile("./e2e/addon/mock/testrepo/helm-repo/index.yaml")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
case strings.Contains(req.URL.Path, "fluxcd-test-version-1.0.0.tgz"):
file, err := ioutil.ReadFile("./e2e/addon/mock/testrepo/helm-repo/fluxcd-test-version-1.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
case strings.Contains(req.URL.Path, "fluxcd-test-version-2.0.0.tgz"):
file, err := ioutil.ReadFile("./e2e/addon/mock/testrepo/helm-repo/fluxcd-test-version-2.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
rw.Write(file)
}
}
func init() {
_ = fs.WalkDir(testData, "testdata", func(path string, d fs.DirEntry, err error) error {
path = strings.TrimPrefix(path, "testdata/")

View File

@@ -190,7 +190,7 @@ var ApplicationInitIntercativeCliContext = func(context string, appName string,
var ApplicationDeleteWithWaitOptions = func(context string, appName string) bool {
return ginkgo.Context(context, func() {
ginkgo.It("should print successful deletion information", func() {
cli := fmt.Sprintf("vela delete %s --wait -y", appName)
cli := fmt.Sprintf("vela delete %s --wait", appName)
output, err := e2e.ExecAndTerminate(cli)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(output).To(gomega.ContainSubstring("deleted"))
@@ -218,7 +218,7 @@ var ApplicationDeleteWithForceOptions = func(context string, appName string) boo
return k8sClient.Update(ctx, app)
}, time.Second*3, time.Millisecond*300).Should(gomega.BeNil())
cli := fmt.Sprintf("vela delete %s --force -y", appName)
cli := fmt.Sprintf("vela delete %s --force", appName)
output, err := e2e.LongTimeExec(cli, 3*time.Minute)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(output).To(gomega.ContainSubstring("timed out"))
@@ -230,7 +230,7 @@ var ApplicationDeleteWithForceOptions = func(context string, appName string) boo
g.Expect(k8sClient.Update(ctx, app)).Should(gomega.Succeed())
}, time.Second*5, time.Millisecond*300).Should(gomega.Succeed())
cli = fmt.Sprintf("vela delete %s --force -y", appName)
cli = fmt.Sprintf("vela delete %s --force", appName)
output, err = e2e.ExecAndTerminate(cli)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(output).To(gomega.ContainSubstring("deleted"))

View File

@@ -133,7 +133,7 @@ var (
WorkloadDeleteContext = func(context string, applicationName string) bool {
return ginkgo.Context(context, func() {
ginkgo.It("should print successful deletion information", func() {
cli := fmt.Sprintf("vela delete %s -y", applicationName)
cli := fmt.Sprintf("vela delete %s", applicationName)
output, err := Exec(cli)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
gomega.Expect(output).To(gomega.ContainSubstring("deleted from namespace"))

53
go.mod
View File

@@ -16,8 +16,6 @@ require (
github.com/barnettZQG/inject v0.0.1
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869
github.com/briandowns/spinner v1.11.1
github.com/chartmuseum/helm-push v0.10.2
github.com/cloudtty/cloudtty v0.2.0
github.com/containerd/containerd v1.5.13
github.com/coreos/go-oidc v2.1.0+incompatible
github.com/coreos/prometheus-operator v0.41.1
@@ -25,7 +23,7 @@ require (
github.com/davecgh/go-spew v1.1.1
github.com/deckarep/golang-set v1.7.1
github.com/emicklei/go-restful-openapi/v2 v2.3.0
github.com/emicklei/go-restful/v3 v3.8.0
github.com/emicklei/go-restful/v3 v3.0.0-rc2
github.com/evanphx/json-patch v4.12.0+incompatible
github.com/fatih/camelcase v1.0.0
github.com/fatih/color v1.13.0
@@ -48,7 +46,6 @@ require (
github.com/hashicorp/hcl/v2 v2.9.1
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174
github.com/imdario/mergo v0.3.12
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
github.com/kubevela/prism v1.4.1-0.20220613123457-94f1190f87c2
github.com/kyokomi/emoji v2.2.4+incompatible
github.com/mitchellh/hashstructure/v2 v2.0.1
@@ -59,7 +56,7 @@ require (
github.com/olekukonko/tablewriter v0.0.5
github.com/onsi/ginkgo v1.16.5
github.com/onsi/gomega v1.19.0
github.com/opencontainers/runc v1.1.3 // indirect
github.com/opencontainers/runc v1.0.3 // indirect
github.com/openkruise/kruise-api v1.1.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.11.0
@@ -76,7 +73,7 @@ require (
go.mongodb.org/mongo-driver v1.5.1
go.uber.org/zap v1.19.1
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
golang.org/x/tools v0.1.11-0.20220316014157-77aa08bb151a // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0
@@ -86,7 +83,7 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
gotest.tools v2.2.0+incompatible
helm.sh/helm/v3 v3.7.2
istio.io/client-go v1.13.4
istio.io/client-go v0.0.0-20210128182905-ee2edd059e02
k8s.io/api v0.23.6
k8s.io/apiextensions-apiserver v0.23.6
k8s.io/apimachinery v0.23.6
@@ -94,7 +91,6 @@ require (
k8s.io/cli-runtime v0.23.6
k8s.io/client-go v0.23.6
k8s.io/component-base v0.23.6
k8s.io/helm v2.17.0+incompatible
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.60.1
k8s.io/kube-aggregator v0.23.0
@@ -110,21 +106,7 @@ require (
)
require (
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/ghodss/yaml v1.0.0
github.com/gorilla/websocket v1.4.2
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/openkruise/rollouts v0.1.1-0.20220622054609-149e5a48da5e
github.com/xanzy/ssh-agent v0.3.0 // indirect
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
google.golang.org/protobuf v1.28.0 // indirect
)
require (
cloud.google.com/go/compute v1.7.0 // indirect
cloud.google.com/go/compute v1.6.1 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
@@ -164,8 +146,9 @@ require (
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/creack/pty v1.1.11 // indirect
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
github.com/cyphar/filepath-securejoin v0.2.2 // indirect
github.com/docker/cli v20.10.16+incompatible // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/docker/docker v20.10.16+incompatible // indirect
github.com/docker/docker-credential-helpers v0.6.4 // indirect
github.com/docker/go-connections v0.4.0 // indirect
@@ -183,6 +166,7 @@ require (
github.com/fluxcd/pkg/apis/meta v0.13.0 // indirect
github.com/fsnotify/fsnotify v1.5.1 // indirect
github.com/fvbommel/sortorder v1.0.1 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/go-errors/errors v1.0.1 // indirect
github.com/go-logr/zapr v1.2.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
@@ -206,6 +190,8 @@ require (
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
@@ -215,6 +201,7 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // 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.15.4 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/kr/pty v1.1.8 // indirect
@@ -267,6 +254,7 @@ 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
@@ -293,13 +281,16 @@ require (
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/sync v0.0.0-20220601150217-0de741cfad7f // indirect
golang.org/x/sys v0.0.0-20220624220833-87e55d714810 // indirect
golang.org/x/net v0.0.0-20220516155154-20f960328961 // indirect
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect
golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03 // indirect
google.golang.org/grpc v1.47.0 // indirect
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3 // indirect
google.golang.org/grpc v1.45.0 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/gorp.v1 v1.7.2 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.63.2 // indirect
@@ -308,8 +299,8 @@ require (
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
istio.io/api v0.0.0-20220512212136-561ffec82582 // indirect
istio.io/gogo-genproto v0.0.0-20211208193508-5ab4acc9eb1e // indirect
istio.io/api v0.0.0-20210128181506-0c4b8e54850f // indirect
istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a // indirect
oras.land/oras-go v0.4.0 // indirect
sigs.k8s.io/apiserver-network-proxy v0.0.30 // indirect
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.30 // indirect

141
go.sum
View File

@@ -34,9 +34,8 @@ cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+Y
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
cloud.google.com/go v0.102.0 h1:DAq3r8y4mDgyB/ZPJ9v/5VJNqjgJAxTn6ZYLlUywOu8=
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
@@ -48,14 +47,12 @@ cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTB
cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc=
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk=
cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/firestore v1.6.0/go.mod h1:afJwI0vaXwAG54kI7A//lP/lSPDkQORQuMkv56TxEPU=
cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
@@ -68,7 +65,6 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
contrib.go.opencensus.io/exporter/ocagent v0.6.0/go.mod h1:zmKjrJcdo0aYcVS7bmEeSEBLPA9YJp5bjrofdU3pIXs=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
@@ -161,7 +157,6 @@ github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZC
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/Masterminds/squirrel v1.5.2 h1:UiOEi2ZX4RCSkpiNDQN5kro/XIBpSRk9iTqdIRPzUXE=
github.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
@@ -182,7 +177,6 @@ github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg3
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
github.com/Microsoft/hcsshim v0.8.18/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim v0.8.24 h1:jP+GMeRXIR1sH1kG4lJr9ShmSjVrua5jmFZDtfYGkn4=
github.com/Microsoft/hcsshim v0.8.24/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg=
@@ -372,12 +366,9 @@ github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41
github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
github.com/charithe/durationcheck v0.0.8/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg=
github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg=
github.com/chartmuseum/helm-push v0.10.2 h1:vuzgu+j+2yKOpPtfF4ksD7RC9Y7wAwrHNpiWDnzAZzM=
github.com/chartmuseum/helm-push v0.10.2/go.mod h1:s6xTICU31jKdLkOXS+GgaR61E+oU4h8TWb1yZcHq8OE=
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU=
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
@@ -387,13 +378,10 @@ github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLI
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudtty/cloudtty v0.2.0 h1:QvDbb2hZl7nSfLDrKkbjIixjkW6seSVBX3N/GRmioyM=
github.com/cloudtty/cloudtty v0.2.0/go.mod h1:RRVb8fLrfpzjsLFqaUk74ouRvZ2drVCvSN3ZzidHju8=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -401,7 +389,6 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
@@ -433,7 +420,6 @@ github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
@@ -449,7 +435,6 @@ github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09Zvgq
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.2/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.4/go.mod h1:sx18RgvW6ABJ4iYUw7Q5x7bgFOAB9B6G7+yO0XBc4zw=
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
github.com/containerd/containerd v1.5.13 h1:XqvKw9i4P7/mFrC3TSM7yV5cwFZ9avXe6M3YANKnzEE=
github.com/containerd/containerd v1.5.13/go.mod h1:3AlCrzKROjIuP3JALsY14n8YtntaUDBu7vek+rPN5Vc=
@@ -546,9 +531,8 @@ github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/crossplane/crossplane-runtime v0.14.1-0.20210722005935-0b469fcc77cd h1:2ZdR/HyjXFIo6KxmM08jBLeiJs7GRdGmb6qPKQANGvI=
github.com/crossplane/crossplane-runtime v0.14.1-0.20210722005935-0b469fcc77cd/go.mod h1:0sB8XOV2zy1GdZvSMY0/5QzKQJUiNSek08wbAYHJbws=
github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
@@ -629,9 +613,8 @@ github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful-openapi/v2 v2.3.0 h1:tDgSCzQrkk4N+Isos0zGBYX/GTINjmQuP9BvITbEe38=
github.com/emicklei/go-restful-openapi/v2 v2.3.0/go.mod h1:bs67E3SEVgSmB3qDuRLqpS0NcpheqtsCCMhW2/jml1E=
github.com/emicklei/go-restful/v3 v3.0.0-rc2 h1:UkWzdUozgtjQzYuqSNQy+PuYxD4/DCzYucakgzWKolU=
github.com/emicklei/go-restful/v3 v3.0.0-rc2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/go-restful/v3 v3.8.0 h1:eCZ8ulSerjdAiaNpF7GxXIE7ZCMo1moN1qX+S609eVw=
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/emicklei/proto v1.6.15 h1:XbpwxmuOPrdES97FrSfpyy67SSCV/wBIKXqgJzh6hNw=
github.com/emicklei/proto v1.6.15/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A=
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
@@ -645,7 +628,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/esimonov/ifshort v1.0.2/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE=
@@ -914,7 +896,6 @@ github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblf
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godror/godror v0.24.2/go.mod h1:wZv/9vPiUib6tkoDl+AZ/QLf5YZgMravZ7jxH2eQWAE=
github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
@@ -1076,7 +1057,6 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/gax-go v2.0.2+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
@@ -1084,7 +1064,6 @@ github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pf
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
github.com/googleapis/gnostic v0.0.0-20170426233943-68f4ded48ba9/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
@@ -1095,7 +1074,6 @@ github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3i
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
github.com/googleapis/gnostic v0.5.5 h1:9fHAtK0uDfpveeqqo1hkEZJcFvYXAiCN3UutL8F9xHw=
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
github.com/gophercloud/gophercloud v0.0.0-20190126172459-c818fa66e4c8/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
@@ -1347,8 +1325,6 @@ github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHU
github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg=
github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c h1:N7A4JCA2G+j5fuFxCsJqjFU/sZe0mj8H0sSoSwbaikw=
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c/go.mod h1:Nn5wlyECw3iJrzi0AhIWg+AJUb4PlRQVW4/3XHH1LZA=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -1529,9 +1505,8 @@ github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/
github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.4.1 h1:1O+1cHA1aujwEwwVMa2Xm2l+gIpUHyd3+D+d7LZh1kM=
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.5.0 h1:2Ks8/r6lopsxWi9m58nlwjaeSzUX9iiL1vj5qB/9ObI=
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
@@ -1626,8 +1601,6 @@ github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvw
github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY=
@@ -1647,7 +1620,6 @@ github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDs
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
@@ -1670,8 +1642,8 @@ github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w=
github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
github.com/opencontainers/runc v1.0.3 h1:1hbqejyQWCJBvtKAfdO0b1FmaEf2z/bxnjqbARass5k=
github.com/opencontainers/runc v1.0.3/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
@@ -1682,12 +1654,8 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/openkruise/kruise-api v1.0.0/go.mod h1:kxV/UA/vrf/hz3z+kL21c0NOawC6K1ZjaKcJFgiOwsE=
github.com/openkruise/kruise-api v1.1.0 h1:ZRhV0FnxUp4XHc60YPkUqj2LJD4GRFB92qhtdgU6Zhc=
github.com/openkruise/kruise-api v1.1.0/go.mod h1:kxV/UA/vrf/hz3z+kL21c0NOawC6K1ZjaKcJFgiOwsE=
github.com/openkruise/rollouts v0.1.1-0.20220622054609-149e5a48da5e h1:jUMEDsA0OOpp0262pK8MV8M2glac+jIjx+q5Aydn6G0=
github.com/openkruise/rollouts v0.1.1-0.20220622054609-149e5a48da5e/go.mod h1:SORsT96ssCqMJYSVA90v6Z52utlV2jxPlyGh4czRfHA=
github.com/openshift/api v0.0.0-20210915110300-3cd8091317c4/go.mod h1:RsQCVJu4qhUawxxDP7pGlwU3IA4F01wYm3qKEu29Su8=
github.com/openshift/api v0.0.0-20211209135129-c58d9f695577/go.mod h1:DoslCwtqUpr3d/gsbq4ZlkaMEdYqKxuypsDjorcHhME=
github.com/openshift/build-machinery-go v0.0.0-20210115170933-e575b44a7a94/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE=
@@ -1880,7 +1848,6 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/securego/gosec/v2 v2.8.0/go.mod h1:hJZ6NT5TqoY+jmOsaxAV4cXoEdrMRLVaNPnSpUCvCZs=
github.com/securego/gosec/v2 v2.9.1/go.mod h1:oDcDLcatOJxkCGaCaq8lua1jTnYf6Sou4wdiJ1n4iHc=
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
@@ -2223,7 +2190,6 @@ go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
golang.org/x/arch v0.0.0-20180920145803-b19384d3c130/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
@@ -2400,17 +2366,13 @@ golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211215060638-4ddde0e984e9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220516155154-20f960328961 h1:+W/iTMPG0EL7aW+/atntZwZrvSRIj3m3yX414dSULUU=
golang.org/x/net v0.0.0-20220516155154-20f960328961/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e h1:TsQ7F31D3bUCLeqPT0u+yjp1guoArKaNKmCr22PYgTQ=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
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=
@@ -2432,10 +2394,8 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0=
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -2448,9 +2408,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180117170059-2c42eef0765b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -2579,20 +2538,16 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/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-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210817190340-bfb29a6856f2/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210915083310-ed5796bab164/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/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-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211110154304-99a53858aa08/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -2602,13 +2557,8 @@ golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a h1:N2T1jUrTQE9Re6TFF5PhvEHXHCguynGhKjWVsIUt5cY=
golang.org/x/sys v0.0.0-20220513210249-45d2b4557a2a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810 h1:rHZQSjJdAI4Xf5Qzeh2bBc5YJIkPFVM6oDtMFYmgws0=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -2779,10 +2729,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
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=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU=
gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY=
gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
@@ -2835,9 +2783,6 @@ google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/S
google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
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=
@@ -2905,7 +2850,6 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
@@ -2937,15 +2881,8 @@ google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2I
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3 h1:SeX3QUcBj3fciwnfPT9kt5gBhFy/FCZtYZ+I/RB8agc=
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03 h1:W70HjnmXFJm+8RNjOpIDYW2nKsSi/af0VvIZUtYkwuU=
google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -2964,6 +2901,7 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
@@ -2984,11 +2922,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.47.0 h1:9n77onPX5F3qfFCqjy9dhn8PbNQsIKeVU04J9G7umt8=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
@@ -3083,7 +3018,6 @@ gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
helm.sh/helm/v3 v3.7.0/go.mod h1:DajHtQTe8KrjNmvy5gxWkosFKaADrS3uRS5EkDtsmI4=
helm.sh/helm/v3 v3.7.2 h1:xn1OxcZEpgKpp4CCpPz1KKUyb9gAtTouXV2E3S8ChYQ=
helm.sh/helm/v3 v3.7.2/go.mod h1:UXuiAn0+FfBpqbiMuwWt8/aAKkfJvnWLBJ6f4HcFs0M=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -3097,12 +3031,12 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.2.0/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY=
honnef.co/go/tools v0.2.1/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY=
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
istio.io/api v0.0.0-20220512212136-561ffec82582 h1:AzLIET6ePAqxlWaXA6GOzapoRX1GRC6mZ8GY+cQIWYU=
istio.io/api v0.0.0-20220512212136-561ffec82582/go.mod h1:8ZZgyVgYrHhsFQarEgTfPnMGpdgTDZbxSjYhdwTUuAQ=
istio.io/client-go v1.13.4 h1:QJBFBkOaplyL/uBL7xo75mdE5G0i1uR6BR0u9/Wuo1E=
istio.io/client-go v1.13.4/go.mod h1:kM3WH/HCojq7BhCD894SZuaAXUKMswT+VQRaEEhTGj0=
istio.io/gogo-genproto v0.0.0-20211208193508-5ab4acc9eb1e h1:z2WI3y55w0K3c6hmarcp5EcOiP4vVpTBXA8nYstP+cE=
istio.io/gogo-genproto v0.0.0-20211208193508-5ab4acc9eb1e/go.mod h1:vJDAniIqryf/z///fgZqVPKJ7N2lBk7Gg8DCTB7oCfU=
istio.io/api v0.0.0-20210128181506-0c4b8e54850f h1:zUFsawgPj5oI9p5cf91YCExRlxLIVsEkIunN9ODUSJs=
istio.io/api v0.0.0-20210128181506-0c4b8e54850f/go.mod h1:88HN3o1fSD1jo+Z1WTLlJfMm9biopur6Ct9BFKjiB64=
istio.io/client-go v0.0.0-20210128182905-ee2edd059e02 h1:ZA8Y2gKkKtEeYuKfqlEzIBDfU4IE5uIAdsXDeD41T9w=
istio.io/client-go v0.0.0-20210128182905-ee2edd059e02/go.mod h1:oXMjFUWhxlReUSbg4i3GjKgOhSX1WgD68ZNlHQEcmQg=
istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a h1:w7zILua2dnYo9CxImhpNW4NE/8ZxEoc/wfBfHrhUhrE=
istio.io/gogo-genproto v0.0.0-20190930162913-45029607206a/go.mod h1:OzpAts7jljZceG4Vqi5/zXy/pOg1b209T3jb7Nv5wIs=
k8s.io/api v0.0.0-20190620084959-7cf5895f2711/go.mod h1:TBhBqb1AWbBQbW3XRusr7n7E4v2+5ZY8r8sAMnyFC5A=
k8s.io/api v0.0.0-20190813020757-36bff7324fb7/go.mod h1:3Iy+myeAORNCLgjd/Xu9ebwN7Vh59Bw0vh9jhoX+V58=
k8s.io/api v0.0.0-20190918155943-95b840bb6a1f/go.mod h1:uWuOHnjmNrtQomJrvEBg0c0HRNyQ+8KTEERVsK0PW48=
@@ -3114,6 +3048,7 @@ k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4=
k8s.io/api v0.17.5/go.mod h1:0zV5/ungglgy2Rlm3QK8fbxkXVs+BSJWpJP/+8gUVLY=
k8s.io/api v0.18.0-beta.2/go.mod h1:2oeNnWEqcSmaM/ibSh3t7xcIqbkGXhzZdn4ezV9T4m0=
k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8=
k8s.io/api v0.18.1/go.mod h1:3My4jorQWzSs5a+l7Ge6JBbIxChLnY8HnuT58ZWolss=
k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
k8s.io/api v0.18.3/go.mod h1:UOaMwERbqJMfeeeHc8XJKawj4P9TgDRnViIqqBeH2QA=
k8s.io/api v0.18.6/go.mod h1:eeyxr+cwCjMdLAmr2W3RyDI0VvTawSg/3RFFBEnmZGI=
@@ -3126,10 +3061,7 @@ k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s=
k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU=
k8s.io/api v0.21.3/go.mod h1:hUgeYHUbBp23Ue4qdX9tR8/ANi/g3ehylAqDn9NWVOg=
k8s.io/api v0.22.1/go.mod h1:bh13rkTp3F1XEaLGykbyRD2QaTTzPm0e/BMd8ptFONY=
k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8=
k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk=
k8s.io/api v0.22.4/go.mod h1:Rgs+9gIGYC5laXQSZZ9JqT5NevNgoGiOdVWi1BAB3qk=
k8s.io/api v0.22.6/go.mod h1:q1F7IfaNrbi/83ebLy3YFQYLjPSNyunZ/IXQxMmbwCg=
k8s.io/api v0.23.0/go.mod h1:8wmDdLBHBNxtOIytwLstXt5E9PddnZb0GaMcqsvDBpg=
k8s.io/api v0.23.1/go.mod h1:WfXnOnwSqNtG62Y1CdjoMxh7r7u9QXGCkA1u0na2jgo=
k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8=
@@ -3145,9 +3077,7 @@ k8s.io/apiextensions-apiserver v0.18.6/go.mod h1:lv89S7fUysXjLZO7ke783xOwVTm6lKi
k8s.io/apiextensions-apiserver v0.21.2/go.mod h1:+Axoz5/l3AYpGLlhJDfcVQzCerVYq3K3CvDMvw6X1RA=
k8s.io/apiextensions-apiserver v0.21.3/go.mod h1:kl6dap3Gd45+21Jnh6utCx8Z2xxLm8LGDkprcd+KbsE=
k8s.io/apiextensions-apiserver v0.22.1/go.mod h1:HeGmorjtRmRLE+Q8dJu6AYRoZccvCMsghwS8XTUYb2c=
k8s.io/apiextensions-apiserver v0.22.2/go.mod h1:2E0Ve/isxNl7tWLSUDgi6+cmwHi5fQRdwGVCxbC+KFA=
k8s.io/apiextensions-apiserver v0.22.4/go.mod h1:kH9lxD8dbJ+k0ZizGET55lFgdGjO8t45fgZnCVdZEpw=
k8s.io/apiextensions-apiserver v0.22.6/go.mod h1:wNsLwy8mfIkGThiv4Qq/Hy4qRazViKXqmH5pfYiRKyY=
k8s.io/apiextensions-apiserver v0.23.0/go.mod h1:xIFAEEDlAZgpVBl/1VSjGDmLoXAWRG40+GsWhKhAxY4=
k8s.io/apiextensions-apiserver v0.23.5/go.mod h1:ntcPWNXS8ZPKN+zTXuzYMeg731CP0heCTl6gYBxLcuQ=
k8s.io/apiextensions-apiserver v0.23.6 h1:v58cQ6Z0/GK1IXYr+oW0fnYl52o9LTY0WgoWvI8uv5Q=
@@ -3164,6 +3094,7 @@ k8s.io/apimachinery v0.17.2/go.mod h1:b9qmWdKlLuU9EBh+06BtLcSf/Mu89rWL33naRxs1uZ
k8s.io/apimachinery v0.17.5/go.mod h1:ioIo1G/a+uONV7Tv+ZmCbMG1/a3kVw5YcDdncd8ugQ0=
k8s.io/apimachinery v0.18.0-beta.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apimachinery v0.18.1/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
k8s.io/apimachinery v0.18.3/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
k8s.io/apimachinery v0.18.6/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
@@ -3176,9 +3107,7 @@ k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswP
k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM=
k8s.io/apimachinery v0.21.3/go.mod h1:H/IM+5vH9kZRNJ4l3x/fXP/5bOPJaVP/guptnZPeCFI=
k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
k8s.io/apimachinery v0.22.4/go.mod h1:yU6oA6Gnax9RrxGzVvPFFJ+mpnW6PBSqp0sx0I0HHW0=
k8s.io/apimachinery v0.22.6/go.mod h1:ZvVLP5iLhwVFg2Yx9Gh5W0um0DUauExbRhe+2Z8I1EU=
k8s.io/apimachinery v0.23.0/go.mod h1:fFCTTBKvKcwTPFzjlcxp91uPFZr+JA0FubU4fLzzFYc=
k8s.io/apimachinery v0.23.1/go.mod h1:SADt2Kl8/sttJ62RRsi9MIV4o8f5S3coArm0Iu3fBno=
k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM=
@@ -3198,10 +3127,7 @@ k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
k8s.io/apiserver v0.21.2/go.mod h1:lN4yBoGyiNT7SC1dmNk0ue6a5Wi6O3SWOIw91TsucQw=
k8s.io/apiserver v0.21.3/go.mod h1:eDPWlZG6/cCCMj/JBcEpDoK+I+6i3r9GsChYBHSbAzU=
k8s.io/apiserver v0.22.1/go.mod h1:2mcM6dzSt+XndzVQJX21Gx0/Klo7Aen7i0Ai6tIa400=
k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI=
k8s.io/apiserver v0.22.4/go.mod h1:38WmcUZiiy41A7Aty8/VorWRa8vDGqoUzDf2XYlku0E=
k8s.io/apiserver v0.22.4/go.mod h1:38WmcUZiiy41A7Aty8/VorWRa8vDGqoUzDf2XYlku0E=
k8s.io/apiserver v0.22.6/go.mod h1:OlL1rGa2kKWGj2JEXnwBcul/BwC9Twe95gm4ohtiIIs=
k8s.io/apiserver v0.23.0/go.mod h1:Cec35u/9zAepDPPFyT+UMrgqOCjgJ5qtfVJDxjZYmt4=
k8s.io/apiserver v0.23.1/go.mod h1:Bqt0gWbeM2NefS8CjWswwd2VNAKN6lUKR85Ft4gippY=
k8s.io/apiserver v0.23.5/go.mod h1:7wvMtGJ42VRxzgVI7jkbKvMbuCbVbgsWFT7RyXiRNTw=
@@ -3209,7 +3135,6 @@ k8s.io/apiserver v0.23.6 h1:p94LiXcsSnpSDIl4cv98liBuFKcaygSCNopFNfMg/Ac=
k8s.io/apiserver v0.23.6/go.mod h1:5PU32F82tfErXPmf7FXhd/UcuLfh97tGepjKUgJ2atg=
k8s.io/cli-runtime v0.0.0-20191214191754-e6dc6d5c8724/go.mod h1:wzlq80lvjgHW9if6MlE4OIGC86MDKsy5jtl9nxz/IYY=
k8s.io/cli-runtime v0.17.2/go.mod h1:aa8t9ziyQdbkuizkNLAw3qe3srSyWh9zlSB7zTqRNPI=
k8s.io/cli-runtime v0.22.1/go.mod h1:YqwGrlXeEk15Yn3em2xzr435UGwbrCw5x+COQoTYfoo=
k8s.io/cli-runtime v0.22.4/go.mod h1:x35r0ERHXr/MrbR1C6MPJxQ3xKG6+hXi9m2xLzlMPZA=
k8s.io/cli-runtime v0.23.6 h1:zvsGa4An+udUnznKSfD1Q17sETWHNOaMqYKHwHCvg+4=
k8s.io/cli-runtime v0.23.6/go.mod h1:0Z3VR/HRIFKiLzKIAkm1mPtcH98GT/fXu2IU0E4vFmw=
@@ -3223,6 +3148,7 @@ k8s.io/client-go v0.17.2/go.mod h1:QAzRgsa0C2xl4/eVpeVAZMvikCn8Nm81yqVx3Kk9XYI=
k8s.io/client-go v0.17.5/go.mod h1:S8uZpBpjJJdEH/fEyxcqg7Rn0P5jH+ilkgBHjriSmNo=
k8s.io/client-go v0.18.0-beta.2/go.mod h1:UvuVxHjKWIcgy0iMvF+bwNDW7l0mskTNOaOW1Qv5BMA=
k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8=
k8s.io/client-go v0.18.1/go.mod h1:iCikYRiXOj/yRRFE/aWqrpPtDt4P2JVWhtHkmESTcfY=
k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
k8s.io/client-go v0.18.3/go.mod h1:4a/dpQEvzAhT1BbuWW09qvIaGw6Gbu1gZYiQZIi1DMw=
k8s.io/client-go v0.18.6/go.mod h1:/fwtGLjYMS1MaM5oi+eXhKwG+1UHidUEXRh6cNsdO0Q=
@@ -3235,9 +3161,7 @@ k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs=
k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA=
k8s.io/client-go v0.21.3/go.mod h1:+VPhCgTsaFmGILxR/7E1N0S+ryO010QBeNCv5JwRGYU=
k8s.io/client-go v0.22.1/go.mod h1:BquC5A4UOo4qVDUtoc04/+Nxp1MeHcVc1HJm1KmG8kk=
k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U=
k8s.io/client-go v0.22.4/go.mod h1:Yzw4e5e7h1LNHA4uqnMVrpEpUs1hJOiuBsJKIlRCHDA=
k8s.io/client-go v0.22.6/go.mod h1:TffU4AV2idZGeP+g3kdFZP+oHVHWPL1JYFySOALriw0=
k8s.io/client-go v0.23.0/go.mod h1:hrDnpnK1mSr65lHHcUuIZIXDgEbzc7/683c6hyG4jTA=
k8s.io/client-go v0.23.1/go.mod h1:6QSI8fEuqD4zgFK0xbdwfB/PthBsIxCJMa3s17WlcO0=
k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4=
@@ -3253,13 +3177,10 @@ k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRV
k8s.io/code-generator v0.18.6/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
k8s.io/code-generator v0.20.0/go.mod h1:UsqdF+VX4PU2g46NC2JRs4gc+IfrctnwHb76RNbWHJg=
k8s.io/code-generator v0.20.10/go.mod h1:i6FmG+QxaLxvJsezvZp0q/gAEzzOz3U53KFibghWToU=
k8s.io/code-generator v0.20.10/go.mod h1:i6FmG+QxaLxvJsezvZp0q/gAEzzOz3U53KFibghWToU=
k8s.io/code-generator v0.21.2/go.mod h1:8mXJDCB7HcRo1xiEQstcguZkbxZaqeUOrO9SsicWs3U=
k8s.io/code-generator v0.21.3/go.mod h1:K3y0Bv9Cz2cOW2vXUrNZlFbflhuPvuadW6JdnN6gGKo=
k8s.io/code-generator v0.22.1/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
k8s.io/code-generator v0.22.2/go.mod h1:eV77Y09IopzeXOJzndrDyCI88UBok2h6WxAlBwpxa+o=
k8s.io/code-generator v0.22.4/go.mod h1:qjYl54pQ/emhkT0UxbufbREYJMWsHNNV/jSVwhYZQGw=
k8s.io/code-generator v0.22.6/go.mod h1:iOZwYADSgFPNGWfqHFfg1V0TNJnl1t0WyZluQp4baqU=
k8s.io/code-generator v0.23.0/go.mod h1:vQvOhDXhuzqiVfM/YHp+dmg10WDZCchJVObc9MvowsE=
k8s.io/code-generator v0.23.1/go.mod h1:V7yn6VNTCWW8GqodYCESVo95fuiEg713S8B7WacWZDA=
k8s.io/code-generator v0.23.5/go.mod h1:S0Q1JVA+kSzTI1oUvbKAxZY/DYbA/ZUb4Uknog12ETk=
@@ -3280,15 +3201,12 @@ k8s.io/component-base v0.20.10/go.mod h1:ZKOEin1xu68aJzxgzl5DZSp5J1IrjAOPlPN90/t
k8s.io/component-base v0.21.2/go.mod h1:9lvmIThzdlrJj5Hp8Z/TOgIkdfsNARQ1pT+3PByuiuc=
k8s.io/component-base v0.21.3/go.mod h1:kkuhtfEHeZM6LkX0saqSK8PbdO7A0HigUngmhhrwfGQ=
k8s.io/component-base v0.22.1/go.mod h1:0D+Bl8rrnsPN9v0dyYvkqFfBeAd4u7n77ze+p8CMiPo=
k8s.io/component-base v0.22.2/go.mod h1:5Br2QhI9OTe79p+TzPe9JKNQYvEKbq9rTJDWllunGug=
k8s.io/component-base v0.22.4/go.mod h1:MrSaQy4a3tFVViff8TZL6JHYSewNCLshZCwHYM58v5A=
k8s.io/component-base v0.22.6/go.mod h1:ngHLefY4J5fq2fApNdbWyj4yh0lvw36do4aAjNN8rc8=
k8s.io/component-base v0.23.0/go.mod h1:DHH5uiFvLC1edCpvcTDV++NKULdYYU6pR9Tt3HIKMKI=
k8s.io/component-base v0.23.1/go.mod h1:6llmap8QtJIXGDd4uIWJhAq0Op8AtQo6bDW2RrNMTeo=
k8s.io/component-base v0.23.5/go.mod h1:c5Nq44KZyt1aLl0IpHX82fhsn84Sb0jjzwjpcA42bY0=
k8s.io/component-base v0.23.6 h1:8dhVZ4VrRcNdV2EGjl8tj8YOHwX6ysgCGMJ2Oyy0NW8=
k8s.io/component-base v0.23.6/go.mod h1:FGMPeMrjYu0UZBSAFcfloVDplj9IvU+uRMTOdE23Fj0=
k8s.io/component-helpers v0.22.1/go.mod h1:QvBcDbX+qU5I2tMZABBF5fRwAlQwiv771IGBHK9WYh4=
k8s.io/component-helpers v0.22.4/go.mod h1:A50qTyczDFbhZDifIfS2zFrHuPk9UNOWPpvNZ+3RSIs=
k8s.io/component-helpers v0.23.6/go.mod h1:kgvl6wvnYg9oebklLPpbW8UhvAZ9Qds26/RANEbny/8=
k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
@@ -3302,8 +3220,6 @@ k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/helm v2.17.0+incompatible h1:Bpn6o1wKLYqKM3+Osh8e+1/K2g/GsQJ4F4yNF2+deao=
k8s.io/helm v2.17.0+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI=
k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
k8s.io/klog v0.3.1/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
@@ -3334,17 +3250,14 @@ k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAG
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 h1:E3J9oCLlaobFUqsjG9DfKbP2BmgwBL2p7pn0A3dG9W4=
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
k8s.io/kubectl v0.0.0-20191219154910-1528d4eea6dd/go.mod h1:9ehGcuUGjXVZh0qbYSB0vvofQw2JQe6c6cO0k4wu/Oo=
k8s.io/kubectl v0.22.1/go.mod h1:mjAOgEbMNMtZWxnfM6jd+nPjPsaoLqO5xanc78WcSbw=
k8s.io/kubectl v0.22.4/go.mod h1:ok2qRT6y2Gy4+y+mniJVyUMKeBHP4OWS9Rdtf/QTM5I=
k8s.io/kubectl v0.23.6 h1:ajzrqj88GqlH/gpscMCts+mKNeSJprpkWJEHO8CR2Ss=
k8s.io/kubectl v0.23.6/go.mod h1:mMtJhc2QtQiSfvIQoMEUIjGHtZuP4uxMy/ees6j6zx8=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/metrics v0.0.0-20191214191643-6b1944c9f765/go.mod h1:5V7rewilItwK0cz4nomU0b3XCcees2Ka5EBYWS1HBeM=
k8s.io/metrics v0.22.1/go.mod h1:i/ZNap89UkV1gLa26dn7fhKAdheJaKy+moOqJbiif7E=
k8s.io/metrics v0.22.4/go.mod h1:6F/iwuYb1w2QDCoHkeMFLf4pwHBcYKLm4mPtVHKYrIw=
k8s.io/metrics v0.23.6 h1:GH9tTTq7l6DNhzFsLW3Q3xG1LWEk/VT853T6r1mo3uI=
k8s.io/metrics v0.23.6/go.mod h1:Fm9VzVMZ7KVEEeLStF2y3XogfcDwpGyI15o1xB6PbYk=
@@ -3362,7 +3275,6 @@ k8s.io/utils v0.0.0-20210707171843-4b05e18ac7d9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
k8s.io/utils v0.0.0-20210722164352-7f3ee0f31471/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20211208161948-7d6a63dca704/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
@@ -3406,7 +3318,6 @@ sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2
sigs.k8s.io/controller-runtime v0.6.2/go.mod h1:vhcq/rlnENJ09SIRp3EveTaZ0yqH526hjf9iJdbUJ/E=
sigs.k8s.io/controller-runtime v0.9.2/go.mod h1:TxzMCHyEUpaeuOiZx/bIdc2T81vfs/aKdvJt9wuu0zk=
sigs.k8s.io/controller-runtime v0.9.5/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA=
sigs.k8s.io/controller-runtime v0.10.3/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY=
sigs.k8s.io/controller-runtime v0.11.0/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA=
sigs.k8s.io/controller-runtime v0.11.1/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA=
sigs.k8s.io/controller-runtime v0.11.2 h1:H5GTxQl0Mc9UjRJhORusqfJCIjBO8UtUxGggCwL1rLA=
@@ -3447,11 +3358,7 @@ sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/structured-merge-diff/v4 v4.2.0/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 h1:bKCqE9GvQ5tiVHn5rfn1r+yao3aLQEaLzkkmAkf+A6Y=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=

View File

@@ -2198,17 +2198,6 @@ spec:
a context in annotation. - should mark "finish" phase in
status.conditions.'
properties:
mode:
description: WorkflowExecuteMode defines the mode of workflow
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
type: string
type: object
ref:
type: string
steps:
@@ -2236,13 +2225,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta
data of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow
step.
@@ -2289,13 +2271,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the
meta data of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the
workflow step.
@@ -2317,8 +2292,6 @@ spec:
properties:
type: object
timeout:
type: string
type:
type: string
required:
@@ -2326,8 +2299,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:
@@ -4002,13 +3973,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of
a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -4053,13 +4017,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data
of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow
step.
@@ -4081,8 +4038,6 @@ spec:
properties:
type: object
timeout:
type: string
type:
type: string
required:
@@ -4090,8 +4045,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:

View File

@@ -1010,17 +1010,6 @@ spec:
order, and each step: - will have a context in annotation. - should
mark "finish" phase in status.conditions.'
properties:
mode:
description: WorkflowExecuteMode defines the mode of workflow
execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
type: string
type: object
ref:
type: string
steps:
@@ -1047,13 +1036,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of
a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -1098,13 +1080,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data
of a workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow
step.
@@ -1126,8 +1101,6 @@ spec:
properties:
type: object
timeout:
type: string
type:
type: string
required:
@@ -1135,8 +1108,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:

View File

@@ -57,13 +57,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of a workflow
step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -107,13 +100,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of a
workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -133,8 +119,6 @@ spec:
properties:
type: object
timeout:
type: string
type:
type: string
required:
@@ -142,8 +126,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:
@@ -159,16 +141,6 @@ spec:
openAPIV3Schema:
description: Workflow defines workflow steps and other attributes
properties:
mode:
description: WorkflowExecuteMode defines the mode of workflow execution
properties:
steps:
description: WorkflowMode describes the mode of workflow
type: string
subSteps:
description: WorkflowMode describes the mode of workflow
type: string
type: object
ref:
type: string
steps:
@@ -194,13 +166,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of a workflow
step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -244,13 +209,6 @@ spec:
- parameterKey
type: object
type: array
meta:
description: WorkflowStepMeta contains the meta data of a
workflow step
properties:
alias:
type: string
type: object
name:
description: Name is the unique name of the workflow step.
type: string
@@ -270,8 +228,6 @@ spec:
properties:
type: object
timeout:
type: string
type:
type: string
required:
@@ -279,8 +235,6 @@ spec:
- type
type: object
type: array
timeout:
type: string
type:
type: string
required:

View File

@@ -60,10 +60,7 @@ KUSTOMIZE_VERSION ?= 4.5.4
KUSTOMIZE = $(shell pwd)/bin/kustomize
.PHONY: kustomize
kustomize:
ifneq (, $(shell kustomize version | grep $(KUSTOMIZE_VERSION)))
KUSTOMIZE=$(shell which kustomize)
else ifneq (, $(shell $(KUSTOMIZE) version | grep $(KUSTOMIZE_VERSION)))
else
ifeq (, $(shell $(KUSTOMIZE) version | grep $(KUSTOMIZE_VERSION)))
@{ \
set -eo pipefail ;\
echo "installing kustomize-v$(KUSTOMIZE_VERSION) into $(shell pwd)/bin" ;\

View File

@@ -36,10 +36,10 @@ import (
cueyaml "cuelang.org/go/encoding/yaml"
"github.com/Masterminds/semver/v3"
"github.com/google/go-github/v32/github"
prismclusterv1alpha1 "github.com/kubevela/prism/pkg/apis/cluster/v1alpha1"
"github.com/pkg/errors"
"github.com/xanzy/go-gitlab"
"golang.org/x/oauth2"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/chartutil"
appsv1 "k8s.io/api/apps/v1"
@@ -50,7 +50,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
k8syaml "k8s.io/apimachinery/pkg/runtime/serializer/yaml"
types2 "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
"k8s.io/client-go/util/retry"
@@ -71,10 +70,8 @@ import (
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/utils"
addonutil "github.com/oam-dev/kubevela/pkg/utils/addon"
"github.com/oam-dev/kubevela/pkg/utils/apply"
"github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/oam-dev/kubevela/pkg/velaql"
version2 "github.com/oam-dev/kubevela/version"
)
@@ -97,9 +94,6 @@ const (
// DefSchemaName is the addon definition schemas dir name
DefSchemaName string = "schemas"
// ViewDirName is the addon views dir name
ViewDirName string = "views"
// AddonParameterDataKey is the key of parameter in addon args secrets
AddonParameterDataKey string = "addonParameterDataKey"
@@ -197,7 +191,7 @@ type Pattern struct {
}
// Patterns is the file pattern that the addon should be in
var Patterns = []Pattern{{Value: ReadmeFileName}, {Value: MetadataFileName}, {Value: TemplateFileName}, {Value: ParameterFileName}, {IsDir: true, Value: ResourcesDirName}, {IsDir: true, Value: DefinitionsDirName}, {IsDir: true, Value: DefSchemaName}, {IsDir: true, Value: ViewDirName}}
var Patterns = []Pattern{{Value: ReadmeFileName}, {Value: MetadataFileName}, {Value: TemplateFileName}, {Value: ParameterFileName}, {IsDir: true, Value: ResourcesDirName}, {IsDir: true, Value: DefinitionsDirName}, {IsDir: true, Value: DefSchemaName}}
// GetPatternFromItem will check if the file path has a valid pattern, return empty string if it's invalid.
// AsyncReader is needed to calculate relative path
@@ -312,7 +306,6 @@ func GetInstallPackageFromReader(r AsyncReader, meta *SourceMeta, uiData *UIData
TemplateFileName: readTemplate,
ResourcesDirName: readResFile,
DefSchemaName: readDefSchemaFile,
ViewDirName: readViewFile,
}
ptItems := ClassifyItemByPattern(meta, r)
@@ -415,24 +408,6 @@ func readDefFile(a *UIData, reader AsyncReader, readPath string) error {
return nil
}
// readViewFile read single view file
func readViewFile(a *InstallPackage, reader AsyncReader, readPath string) error {
b, err := reader.ReadFile(readPath)
if err != nil {
return err
}
filename := path.Base(readPath)
switch filepath.Ext(filename) {
case ".cue":
a.CUEViews = append(a.CUEViews, ElementFile{Data: b, Name: filepath.Base(readPath)})
case ".yaml", ".yml":
a.YAMLViews = append(a.YAMLViews, ElementFile{Data: b, Name: filepath.Base(readPath)})
default:
// skip other file formats
}
return nil
}
func readMetadata(a *UIData, reader AsyncReader, readPath string) error {
b, err := reader.ReadFile(readPath)
if err != nil {
@@ -612,9 +587,6 @@ func renderResources(addon *InstallPackage, args map[string]interface{}) ([]comm
for _, tmpl := range addon.CUETemplates {
comp, err := renderCUETemplate(tmpl, addon.Parameters, args, addon.Meta)
if err != nil && strings.Contains(err.Error(), "var(path=output) not exist") {
continue
}
if err != nil {
return nil, NewAddonError(fmt.Sprintf("fail to render cue template %s", err.Error()))
}
@@ -639,7 +611,7 @@ func formatAppFramework(addon *InstallPackage) *v1beta1.Application {
if app.Spec.Components == nil {
app.Spec.Components = []common2.ApplicationComponent{}
}
app.Name = addonutil.Addon2AppName(addon.Name)
app.Name = Convert2AppName(addon.Name)
// force override the namespace defined vela with DefaultVelaNS,this value can be modified by Env
app.SetNamespace(types.DefaultKubeVelaNS)
if app.Labels == nil {
@@ -655,26 +627,24 @@ func checkDeployClusters(ctx context.Context, k8sClient client.Client, args map[
if len(deployClusters) == 0 || k8sClient == nil {
return nil, nil
}
clusters, err := prismclusterv1alpha1.NewClusterClient(k8sClient).List(ctx)
vcs, err := multicluster.ListVirtualClusters(ctx, k8sClient)
if err != nil {
return nil, errors.Wrap(err, "fail to get registered cluster")
return nil, err
}
clusterNames := sets.String{}
if len(clusters.Items) != 0 {
for _, cluster := range clusters.Items {
clusterNames.Insert(cluster.Name)
}
}
var res []string
for _, c := range deployClusters {
c = strings.TrimSpace(c)
if c == "" {
continue
}
if !clusterNames.Has(c) {
var found bool
for _, vc := range vcs {
if c == vc.Name {
found = true
break
}
}
if !found {
return nil, errors.Errorf("cluster %s not exist", c)
}
res = append(res, c)
@@ -742,10 +712,7 @@ func RenderApp(ctx context.Context, addon *InstallPackage, k8sClient client.Clie
if app.Spec.Policies == nil {
app.Spec.Policies = []v1beta1.AppPolicy{}
}
body, err := json.Marshal(map[string][]string{types.ClustersArg: deployClusters})
if err != nil {
return nil, err
}
body, _ := json.Marshal(map[string][]string{types.ClustersArg: deployClusters})
app.Spec.Policies = append(app.Spec.Policies, v1beta1.AppPolicy{
Name: "specified-addon-clusters",
Type: v1alpha1.TopologyPolicyType,
@@ -799,7 +766,7 @@ func RenderApp(ctx context.Context, addon *InstallPackage, k8sClient client.Clie
func RenderDefinitions(addon *InstallPackage, config *rest.Config) ([]*unstructured.Unstructured, error) {
defObjs := make([]*unstructured.Unstructured, 0)
// No matter runtime mode or control mode, definition only needs to control plane k8s.
// No matter runtime mode or control mode , definition only needs to control plane k8s.
for _, def := range addon.Definitions {
obj, err := renderObject(def)
if err != nil {
@@ -839,26 +806,6 @@ func RenderDefinitionSchema(addon *InstallPackage) ([]*unstructured.Unstructured
return schemaConfigmaps, nil
}
// RenderViews will render views in addons.
func RenderViews(addon *InstallPackage) ([]*unstructured.Unstructured, error) {
views := make([]*unstructured.Unstructured, 0)
for _, view := range addon.YAMLViews {
obj, err := renderObject(view)
if err != nil {
return nil, err
}
views = append(views, obj)
}
for _, view := range addon.CUEViews {
obj, err := renderCUEView(view)
if err != nil {
return nil, err
}
views = append(views, obj)
}
return views, nil
}
func allocateDomainForAddon(ctx context.Context, k8sClient client.Client) ([]ObservabilityEnvironment, error) {
secrets, err := multicluster.ListExistingClusterSecrets(ctx, k8sClient)
if err != nil {
@@ -1003,20 +950,6 @@ func renderSchemaConfigmap(elem ElementFile) (*unstructured.Unstructured, error)
return util.Object2Unstructured(cm)
}
func renderCUEView(elem ElementFile) (*unstructured.Unstructured, error) {
name, err := utils.GetFilenameFromLocalOrRemote(elem.Name)
if err != nil {
return nil, err
}
cm, err := velaql.ParseViewIntoConfigMap(elem.Data, name)
if err != nil {
return nil, err
}
return util.Object2Unstructured(*cm)
}
// renderCUETemplate will return a component from cue template
func renderCUETemplate(elem ElementFile, parameters string, args map[string]interface{}, metadata Meta) (*common2.ApplicationComponent, error) {
bt, err := json.Marshal(args)
@@ -1067,6 +1000,14 @@ func renderCUETemplate(elem ElementFile, parameters string, args map[string]inte
return &comp, err
}
const addonAppPrefix = "addon-"
const addonSecPrefix = "addon-secret-"
// Convert2AppName -
func Convert2AppName(name string) string {
return addonAppPrefix + name
}
// RenderArgsSecret render addon enable argument to secret
func RenderArgsSecret(addon *InstallPackage, args map[string]interface{}) *unstructured.Unstructured {
argsByte, err := json.Marshal(args)
@@ -1076,7 +1017,7 @@ func RenderArgsSecret(addon *InstallPackage, args map[string]interface{}) *unstr
sec := v1.Secret{
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Secret"},
ObjectMeta: metav1.ObjectMeta{
Name: addonutil.Addon2SecName(addon.Name),
Name: Convert2SecName(addon.Name),
Namespace: types.DefaultKubeVelaNS,
},
Data: map[string][]byte{
@@ -1110,6 +1051,11 @@ func FetchArgsFromSecret(sec *v1.Secret) (map[string]interface{}, error) {
return res, nil
}
// Convert2SecName generate addon argument secret name
func Convert2SecName(name string) string {
return addonSecPrefix + name
}
// Installer helps addon enable, dependency-check, dispatch resources
type Installer struct {
ctx context.Context
@@ -1150,8 +1096,7 @@ func (h *Installer) enableAddon(addon *InstallPackage) error {
if !h.skipVersionValidate {
err = checkAddonVersionMeetRequired(h.ctx, addon.SystemRequirements, h.cli, h.dc)
if err != nil {
version := h.getAddonVersionMeetSystemRequirement(addon.Name)
return VersionUnMatchError{addonName: addon.Name, err: err, userSelectedAddonVersion: addon.Version, availableVersion: version}
return VersionUnMatchError{addonName: addon.Name, err: err}
}
}
@@ -1222,7 +1167,7 @@ func (h *Installer) installDependency(addon *InstallPackage) error {
for _, dep := range addon.Dependencies {
err := h.cli.Get(h.ctx, client.ObjectKey{
Namespace: types.DefaultKubeVelaNS,
Name: addonutil.Addon2AppName(dep.Name),
Name: Convert2AppName(dep.Name),
}, &app)
if err == nil {
continue
@@ -1251,7 +1196,7 @@ func (h *Installer) checkDependency(addon *InstallPackage) ([]string, error) {
for _, dep := range addon.Dependencies {
err := h.cli.Get(h.ctx, client.ObjectKey{
Namespace: types.DefaultKubeVelaNS,
Name: addonutil.Addon2AppName(dep.Name),
Name: Convert2AppName(dep.Name),
}, &app)
if err == nil {
continue
@@ -1308,11 +1253,6 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
return errors.Wrap(err, "render addon definitions' schema fail")
}
views, err := RenderViews(addon)
if err != nil {
return errors.Wrap(err, "render addon views fail")
}
if err := passDefInAppAnnotation(defs, app); err != nil {
return errors.Wrapf(err, "cannot pass definition to addon app's annotation")
}
@@ -1337,14 +1277,6 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
}
}
for _, view := range views {
addOwner(view, app)
err = h.apply.Apply(h.ctx, view, apply.DisableUpdateAnnotation())
if err != nil {
return err
}
}
if h.args != nil && len(h.args) > 0 {
sec := RenderArgsSecret(addon, h.args)
addOwner(sec, app)
@@ -1393,27 +1325,6 @@ func (h *Installer) continueOrRestartWorkflow() error {
return nil
}
// getAddonVersionMeetSystemRequirement return the addon's latest version which meet the system requirements
func (h *Installer) getAddonVersionMeetSystemRequirement(addonName string) string {
if h.r != nil && IsVersionRegistry(*h.r) {
versionedRegistry := BuildVersionedRegistry(h.r.Name, h.r.Helm.URL, &common.HTTPOption{
Username: h.r.Helm.Username,
Password: h.r.Helm.Password,
})
versions, err := versionedRegistry.GetAddonAvailableVersion(addonName)
if err != nil {
return ""
}
for _, version := range versions {
req := LoadSystemRequirements(version.Annotations)
if checkAddonVersionMeetRequired(h.ctx, req, h.cli, h.dc) == nil {
return version.Version
}
}
}
return ""
}
func addOwner(child *unstructured.Unstructured, app *v1beta1.Application) {
child.SetOwnerReferences(append(child.GetOwnerReferences(),
*metav1.NewControllerRef(app, v1beta1.ApplicationKindVersionKind)))
@@ -1427,7 +1338,7 @@ func determineAddonAppName(ctx context.Context, cli client.Client, addonName str
return "", err
}
// if the app still not exist, use addon-{addonName}
return addonutil.Addon2AppName(addonName), nil
return Convert2AppName(addonName), nil
}
return app.Name, nil
}
@@ -1436,7 +1347,7 @@ func determineAddonAppName(ctx context.Context, cli client.Client, addonName str
// if not find will try to get 1.1 legacy addon related app by using NamespacedName(vela-system, `addonName`)
func FetchAddonRelatedApp(ctx context.Context, cli client.Client, addonName string) (*v1beta1.Application, error) {
app := &v1beta1.Application{}
if err := cli.Get(ctx, types2.NamespacedName{Namespace: types.DefaultKubeVelaNS, Name: addonutil.Addon2AppName(addonName)}, app); err != nil {
if err := cli.Get(ctx, types2.NamespacedName{Namespace: types.DefaultKubeVelaNS, Name: Convert2AppName(addonName)}, app); err != nil {
if !apierrors.IsNotFound(err) {
return nil, err
}
@@ -1575,8 +1486,32 @@ func fetchVelaCoreImageTag(ctx context.Context, k8sClient client.Client) (string
// PackageAddon package vela addon directory into a helm chart compatible archive and return its absolute path
func PackageAddon(addonDictPath string) (string, error) {
meta := &Meta{}
metaData, err := ioutil.ReadFile(filepath.Clean(filepath.Join(addonDictPath, MetadataFileName)))
if err != nil {
return "", err
}
err = yaml.Unmarshal(metaData, meta)
if err != nil {
return "", err
}
chartFile := &chart.Metadata{
Name: meta.Name,
Description: meta.Description,
// define Vela addon's type to be library in order to prevent installation of a common chart. Please refer to https://helm.sh/docs/topics/library_charts/
Type: "library",
Version: meta.Version,
AppVersion: meta.Version,
APIVersion: chart.APIVersionV2,
Icon: meta.Icon,
Home: meta.URL,
Keywords: meta.Tags,
}
// save the Chart.yaml file in order to be compatible with helm chart
err := MakeChartCompatible(addonDictPath, true)
err = chartutil.SaveChartfile(filepath.Join(addonDictPath, chartutil.ChartfileName), chartFile)
if err != nil {
return "", err
}

View File

@@ -39,7 +39,6 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/oam/util"
addonutil "github.com/oam-dev/kubevela/pkg/utils/addon"
"github.com/oam-dev/kubevela/pkg/utils/apply"
)
@@ -253,7 +252,7 @@ var _ = Describe("Test addon util func", func() {
secArgs := v1.Secret{
TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Secret"},
ObjectMeta: metav1.ObjectMeta{
Name: addonutil.Addon2SecName("test-addon-old-args"),
Name: Convert2SecName("test-addon-old-args"),
Namespace: types.DefaultKubeVelaNS,
},
StringData: map[string]string{
@@ -379,23 +378,6 @@ var _ = Describe("test enable addon in local dir", func() {
})
})
var _ = Describe("test enable addon which applies the views independently", func() {
BeforeEach(func() {
app := v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Namespace: "vela-system", Name: "addon-test-view"}}
Expect(k8sClient.Delete(ctx, &app)).Should(SatisfyAny(BeNil(), util.NotFoundMatcher{}))
})
It("test enable addon which applies the views independently", func() {
ctx := context.Background()
err := EnableAddonByLocalDir(ctx, "test-view", "./testdata/test-view", 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-test-view"}, &app)).Should(BeNil())
configMap := v1.ConfigMap{}
Expect(k8sClient.Get(ctx, types2.NamespacedName{Namespace: "vela-system", Name: "pod-view"}, &configMap)).Should(BeNil())
})
})
const (
appYaml = `apiVersion: core.oam.dev/v1beta1
kind: Application

View File

@@ -22,7 +22,6 @@ import (
"encoding/xml"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
@@ -50,7 +49,6 @@ import (
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/oam"
addonutil "github.com/oam-dev/kubevela/pkg/utils/addon"
version2 "github.com/oam-dev/kubevela/version"
)
@@ -114,29 +112,6 @@ var ossHandler http.HandlerFunc = func(rw http.ResponseWriter, req *http.Request
}
}
var helmHandler http.HandlerFunc = func(writer http.ResponseWriter, request *http.Request) {
switch {
case strings.Contains(request.URL.Path, "index.yaml"):
files, err := ioutil.ReadFile("./testdata/multiversion-helm-repo/index.yaml")
if err != nil {
_, _ = writer.Write([]byte(err.Error()))
}
writer.Write(files)
case strings.Contains(request.URL.Path, "fluxcd-1.0.0.tgz"):
files, err := ioutil.ReadFile("./testdata/multiversion-helm-repo/fluxcd-1.0.0.tgz")
if err != nil {
_, _ = writer.Write([]byte(err.Error()))
}
writer.Write(files)
case strings.Contains(request.URL.Path, "fluxcd-2.0.0.tgz"):
files, err := ioutil.ReadFile("./testdata/multiversion-helm-repo/fluxcd-2.0.0.tgz")
if err != nil {
_, _ = writer.Write([]byte(err.Error()))
}
writer.Write(files)
}
}
var ctx = context.Background()
func testReaderFunc(t *testing.T, reader AsyncReader) {
@@ -315,30 +290,6 @@ func TestRenderDefinitions(t *testing.T) {
assert.Nil(t, app.Spec.Workflow)
}
func TestRenderViews(t *testing.T) {
addonDeployToRuntime := viewAddon
addonDeployToRuntime.Meta.DeployTo = &DeployTo{
DisableControlPlane: false,
RuntimeCluster: false,
}
views, err := RenderViews(&addonDeployToRuntime)
assert.NoError(t, err)
assert.Equal(t, len(views), 2)
view := views[0]
assert.Equal(t, view.GetKind(), "ConfigMap")
assert.Equal(t, view.GetAPIVersion(), "v1")
assert.Equal(t, view.GetNamespace(), types.DefaultKubeVelaNS)
assert.Equal(t, view.GetName(), "cloud-resource-view")
view = views[1]
assert.Equal(t, view.GetKind(), "ConfigMap")
assert.Equal(t, view.GetAPIVersion(), "v1")
assert.Equal(t, view.GetNamespace(), types.DefaultKubeVelaNS)
assert.Equal(t, view.GetName(), "pod-view")
}
func TestRenderK8sObjects(t *testing.T) {
addonMultiYaml := multiYamlAddon
addonMultiYaml.Meta.DeployTo = &DeployTo{
@@ -442,7 +393,7 @@ func TestGetAddonStatus4Observability(t *testing.T) {
addonSecret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: addonutil.Addon2SecName(ObservabilityAddon),
Name: Convert2SecName(ObservabilityAddon),
Namespace: types.DefaultKubeVelaNS,
},
Data: map[string][]byte{},
@@ -497,22 +448,6 @@ func TestGetAddonStatus4Observability(t *testing.T) {
assert.Equal(t, addonStatus.AddonPhase, enabled)
}
func TestGetAddonVersionMeetSystemRequirement(t *testing.T) {
server := httptest.NewServer(helmHandler)
defer server.Close()
i := &Installer{
r: &Registry{
Helm: &HelmSource{
URL: server.URL,
},
},
}
version := i.getAddonVersionMeetSystemRequirement("fluxcd-no-requirements")
assert.Equal(t, version, "1.0.0")
version = i.getAddonVersionMeetSystemRequirement("not-exist")
assert.Equal(t, version, "")
}
var baseAddon = InstallPackage{
Meta: Meta{
Name: "test-render-cue-definition-addon",
@@ -542,24 +477,6 @@ var multiYamlAddon = InstallPackage{
},
}
var viewAddon = InstallPackage{
Meta: Meta{
Name: "test-render-view-addon",
},
YAMLViews: []ElementFile{
{
Data: testYAMLView,
Name: "cloud-resource-view",
},
},
CUEViews: []ElementFile{
{
Data: testCUEView,
Name: "pod-view",
},
},
}
var testCueDef = `annotations: {
type: "trait"
annotations: {}
@@ -638,125 +555,6 @@ spec:
- containerPort: 80
`
var testYAMLView = `
apiVersion: "v1"
kind: "ConfigMap"
metadata:
name: "cloud-resource-view"
namespace: "vela-system"
data:
template: |
import (
"vela/ql"
)
parameter: {
appName: string
appNs: string
}
resources: ql.#ListResourcesInApp & {
app: {
name: parameter.appName
namespace: parameter.appNs
filter: {
"apiVersion": "terraform.core.oam.dev/v1beta1"
"kind": "Configuration"
}
withStatus: true
}
}
status: {
if resources.err == _|_ {
"cloud-resources": [ for i, resource in resources.list {
resource.object
}]
}
if resources.err != _|_ {
error: resources.err
}
}
`
var testCUEView = `
import (
"vela/ql"
)
parameter: {
name: string
namespace: string
cluster: *"" | string
}
pod: ql.#Read & {
value: {
apiVersion: "v1"
kind: "Pod"
metadata: {
name: parameter.name
namespace: parameter.namespace
}
}
cluster: parameter.cluster
}
eventList: ql.#SearchEvents & {
value: {
apiVersion: "v1"
kind: "Pod"
metadata: pod.value.metadata
}
cluster: parameter.cluster
}
podMetrics: ql.#Read & {
cluster: parameter.cluster
value: {
apiVersion: "metrics.k8s.io/v1beta1"
kind: "PodMetrics"
metadata: {
name: parameter.name
namespace: parameter.namespace
}
}
}
status: {
if pod.err == _|_ {
containers: [ for container in pod.value.spec.containers {
name: container.name
image: container.image
resources: {
if container.resources.limits != _|_ {
limits: container.resources.limits
}
if container.resources.requests != _|_ {
requests: container.resources.requests
}
if podMetrics.err == _|_ {
usage: {for containerUsage in podMetrics.value.containers {
if containerUsage.name == container.name {
cpu: containerUsage.usage.cpu
memory: containerUsage.usage.memory
}
}}
}
}
if pod.value.status.containerStatuses != _|_ {
status: {for containerStatus in pod.value.status.containerStatuses if containerStatus.name == container.name {
state: containerStatus.state
restartCount: containerStatus.restartCount
}}
}
}]
if eventList.err == _|_ {
events: eventList.list
}
}
if pod.err != _|_ {
error: pod.err
}
}
`
func TestRenderApp4Observability(t *testing.T) {
k8sClient := fake.NewClientBuilder().Build()
testcases := []struct {
@@ -843,13 +641,6 @@ func TestGetPatternFromItem(t *testing.T) {
gitItemName := "parameter.cue"
gitItemType := FileType
gitItemPath := "addons/terraform/resources/parameter.cue"
viewOSSR := localReader{
dir: "./testdata/test-view",
name: "test-view",
}
viewPath := filepath.Join("./testdata/test-view/views/pod-view.cue", "pod-view.cue")
testCases := []struct {
caseName string
item Item
@@ -875,17 +666,6 @@ func TestGetPatternFromItem(t *testing.T) {
meetPattern: "resources/parameter.cue",
r: gitR,
},
{
caseName: "views case",
item: OSSItem{
tp: FileType,
path: viewPath,
name: "pod-view.cue",
},
root: "test-view",
meetPattern: "views",
r: viewOSSR,
},
}
for _, tc := range testCases {
res := GetPatternFromItem(tc.item, tc.r, tc.root)
@@ -1166,36 +946,6 @@ func TestReadDefFile(t *testing.T) {
assert.True(t, len(uiData.Definitions) == 1)
}
// Test readDefFile only accept .cue
func TestReadViewFile(t *testing.T) {
// setup test data
testAddonName := "test-view"
testAddonDir := fmt.Sprintf("./testdata/%s", testAddonName)
reader := localReader{dir: testAddonDir, name: testAddonName}
metas, err := reader.ListAddonMeta()
testAddonMeta := metas[testAddonName]
assert.NoError(t, err)
// run test
var addon = &InstallPackage{}
ptItems := ClassifyItemByPattern(&testAddonMeta, reader)
items := ptItems[ViewDirName]
for _, it := range items {
err := readViewFile(addon, reader, reader.RelativePath(it))
if err != nil {
assert.NoError(t, err)
}
}
notExistErr := readViewFile(addon, reader, "not-exist.cue")
assert.Error(t, notExistErr)
// verify
assert.True(t, len(addon.CUEViews) == 1)
assert.True(t, len(addon.YAMLViews) == 1)
}
func TestRenderCUETemplate(t *testing.T) {
fileDate, err := os.ReadFile("./testdata/example/resources/configmap.cue")
assert.NoError(t, err)
@@ -1228,10 +978,6 @@ func TestPackageAddon(t *testing.T) {
archiver, err := PackageAddon(validAddonDict)
assert.NoError(t, err)
assert.Equal(t, filepath.Join(pwd, "example-1.0.1.tgz"), archiver)
// Remove generated package after tests
defer func() {
_ = os.RemoveAll(filepath.Join(pwd, "example-1.0.1.tgz"))
}()
invalidAddonDict := "./testdata"
archiver, err = PackageAddon(invalidAddonDict)
@@ -1244,19 +990,3 @@ func TestPackageAddon(t *testing.T) {
assert.Equal(t, "", archiver)
}
func TestGenerateAnnotation(t *testing.T) {
meta := Meta{SystemRequirements: &SystemRequirements{
VelaVersion: ">1.4.0",
KubernetesVersion: ">1.20.0",
}}
res := generateAnnotation(&meta)
assert.Equal(t, res[velaSystemRequirement], ">1.4.0")
assert.Equal(t, res[kubernetesSystemRequirement], ">1.20.0")
meta = Meta{}
meta.SystemRequirements = &SystemRequirements{KubernetesVersion: ">=1.20.1"}
res = generateAnnotation(&meta)
assert.Equal(t, res[velaSystemRequirement], "")
assert.Equal(t, res[kubernetesSystemRequirement], ">=1.20.1")
}

View File

@@ -1,378 +0,0 @@
/*
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 addon
import (
"fmt"
"os"
"path"
"regexp"
"strings"
"github.com/fatih/color"
"cuelang.org/go/cue"
"cuelang.org/go/cue/format"
"cuelang.org/go/encoding/gocode/gocodec"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/utils"
)
// CreateAddonFromHelmChart creates an addon scaffold from a Helm Chart, with a Helm component inside
func CreateAddonFromHelmChart(addonName, addonPath, helmRepoURL, chartName, chartVersion string) error {
if len(addonName) == 0 || len(helmRepoURL) == 0 || len(chartName) == 0 || len(chartVersion) == 0 {
return fmt.Errorf("addon addonPath, helm URL, chart name, and chart verion should not be empty")
}
// Currently, we do not check whether the Helm Chart actually exists, because it is just a scaffold.
// The user can still edit it after creation.
// Also, if the user is offline, we cannot check whether the Helm Chart exists.
// TODO(charlie0129): check whether the Helm Chart exists (if the user wants)
// Make sure url is valid
isValidURL := utils.IsValidURL(helmRepoURL)
if !isValidURL {
return fmt.Errorf("invalid helm repo url %s", helmRepoURL)
}
err := preAddonCreation(addonName, addonPath)
if err != nil {
return err
}
// Create files like template.yaml, README.md, and etc.
err = createFilesFromHelmChart(addonName, addonPath, helmRepoURL, chartName, chartVersion)
if err != nil {
return fmt.Errorf("cannot create addon files: %w", err)
}
postAddonCreation(addonPath)
return nil
}
// CreateAddonSample creates an empty addon scaffold, with some required files
func CreateAddonSample(addonName, addonPath string) error {
if len(addonName) == 0 || len(addonPath) == 0 {
return fmt.Errorf("addon name and addon path should not be empty")
}
err := preAddonCreation(addonName, addonPath)
if err != nil {
return err
}
err = createSampleFiles(addonName, addonPath)
if err != nil {
return err
}
postAddonCreation(addonPath)
return nil
}
// preAddonCreation is executed before creating an addon scaffold
// It makes sure that user-provided info is valid.
func preAddonCreation(addonName, addonPath string) error {
if len(addonName) == 0 || len(addonPath) == 0 {
return fmt.Errorf("addon name and addonPath should not be empty")
}
// Make sure addon name is valid
err := CheckAddonName(addonName)
if err != nil {
return err
}
// Create dirs
err = createAddonDirs(addonPath)
if err != nil {
return fmt.Errorf("cannot create addon structure: %w", err)
}
return nil
}
// postAddonCreation is after before creating an addon scaffold
// It prints some instructions to get started.
func postAddonCreation(addonPath string) {
fmt.Println("Scaffold created in directory " +
color.New(color.Bold).Sprint(addonPath) + ". What to do next:\n" +
"- Check out our guide on how to build your own addon: " +
color.BlueString("https://kubevela.io/docs/platform-engineers/addon/intro") + "\n" +
"- Review and edit what we have generated in " + color.New(color.Bold).Sprint(addonPath) + "\n" +
"- To enable the addon, run: " +
color.New(color.FgGreen).Sprint("vela") + color.GreenString(" addon enable ") + color.New(color.Bold, color.FgGreen).Sprint(addonPath))
}
// CheckAddonName checks if an addon name is valid
func CheckAddonName(addonName string) error {
if len(addonName) == 0 {
return fmt.Errorf("addon name should not be empty")
}
// Make sure addonName only contains lowercase letters, dashes, and numbers, e.g. some-addon
re := regexp.MustCompile(`^[a-z\d]+(-[a-z\d]+)*$`)
if !re.MatchString(addonName) {
return fmt.Errorf("addon name should only cocntain lowercase letters, dashes, and numbers, e.g. some-addon")
}
return nil
}
// createFilesFromHelmChart creates the file structure for a Helm Chart addon,
// including template.yaml, readme.md, metadata.yaml, and <addon-nam>.cue.
func createFilesFromHelmChart(addonName, addonPath, helmRepoURL, chartName, chartVersion string) error {
// Generate template.yaml with an empty Application
applicationTemplate := v1beta1.Application{
TypeMeta: v1.TypeMeta{
APIVersion: v1beta1.SchemeGroupVersion.String(),
Kind: "Application",
},
ObjectMeta: v1.ObjectMeta{
Name: addonName,
Namespace: types.DefaultKubeVelaNS,
},
}
applicationTemplateBytes, err := yaml.Marshal(applicationTemplate)
if err != nil {
return err
}
// Generate metadata.yaml with `fluxcd` as a dependency because we are using helm.
// However, this may change in the future, possibly with `argocd`.
metadataTemplate := Meta{
Name: addonName,
Version: chartVersion,
Description: "An addon for KubeVela.",
Tags: []string{chartVersion},
Dependencies: []*Dependency{{Name: "fluxcd"}},
}
metadataTemplateBytes, err := yaml.Marshal(metadataTemplate)
if err != nil {
return err
}
// Write template.yaml, readme.md, and metadata.yaml
err = writeRequiredFiles(addonPath,
applicationTemplateBytes,
[]byte(strings.ReplaceAll(readmeTemplate, "ADDON_NAME", addonName)),
metadataTemplateBytes)
if err != nil {
return err
}
// Write addonName.cue, containing the helm chart
addonResourcePath := path.Join(addonPath, ResourcesDirName, addonName+".cue")
resourceTmpl := HelmCUETemplate{}
resourceTmpl.Output.Type = "helm"
resourceTmpl.Output.Properties.RepoType = "helm"
resourceTmpl.Output.Properties.URL = helmRepoURL
resourceTmpl.Output.Properties.Chart = chartName
resourceTmpl.Output.Properties.Version = chartVersion
err = writeHelmCUETemplate(resourceTmpl, addonResourcePath)
if err != nil {
return err
}
return nil
}
// createSampleFiles creates the file structure for an empty addon
func createSampleFiles(addonName, addonPath string) error {
// Generate metadata.yaml
metadataTemplate := Meta{
Name: addonName,
Version: "1.0.0",
Description: "An addon for KubeVela.",
Tags: []string{},
Dependencies: []*Dependency{},
}
metadataTemplateBytes, err := yaml.Marshal(metadataTemplate)
if err != nil {
return err
}
// Generate template.yaml
applicationTemplate := v1beta1.Application{
TypeMeta: v1.TypeMeta{
APIVersion: v1beta1.SchemeGroupVersion.String(),
Kind: "Application",
},
ObjectMeta: v1.ObjectMeta{
Name: addonName,
Namespace: types.DefaultKubeVelaNS,
},
}
applicationTemplateBytes, err := yaml.Marshal(applicationTemplate)
if err != nil {
return err
}
err = writeRequiredFiles(addonPath,
applicationTemplateBytes,
[]byte(strings.ReplaceAll(readmeTemplate, "ADDON_NAME", addonName)),
metadataTemplateBytes)
if err != nil {
return err
}
return nil
}
// writeRequiredFiles creates required files for an addon,
// including template.yaml, readme.md, and metadata.yaml
func writeRequiredFiles(addonPath string, tmplContent, readmeContent, metadataContent []byte) error {
// Write template.yaml
templateFilePath := path.Join(addonPath, TemplateFileName)
err := os.WriteFile(templateFilePath,
tmplContent,
0644)
if err != nil {
return fmt.Errorf("cannot write %s: %w", templateFilePath, err)
}
// Write README.md
readmeFilePath := path.Join(addonPath, ReadmeFileName)
err = os.WriteFile(readmeFilePath,
readmeContent,
0644)
if err != nil {
return fmt.Errorf("cannot write %s: %w", readmeFilePath, err)
}
// Write metadata.yaml
metadataFilePath := path.Join(addonPath, MetadataFileName)
err = os.WriteFile(metadataFilePath,
metadataContent,
0644)
if err != nil {
return fmt.Errorf("cannot write %s: %w", metadataFilePath, err)
}
return nil
}
// createAddonDirs creates the directory structure for an addon
func createAddonDirs(addonDir string) error {
// Make sure addonDir is pointing to an empty directory, or does not exist at all
// so that we can create it later
_, err := os.Stat(addonDir)
if !os.IsNotExist(err) {
emptyDir, err := utils.IsEmptyDir(addonDir)
if err != nil {
return fmt.Errorf("we can't create directory %s. Make sure the name has not already been taken and you have the proper rights to write to it", addonDir)
}
if !emptyDir {
return fmt.Errorf("directory %s is not empty. To avoid any data loss, please manually delete it first, then try again", addonDir)
}
// Now we are sure addonPath is en empty dir, delete it
err = os.Remove(addonDir)
if err != nil {
return err
}
}
// nolint:gosec
err = os.MkdirAll(addonDir, 0755)
if err != nil {
return err
}
dirs := []string{
path.Join(addonDir, ResourcesDirName),
path.Join(addonDir, DefinitionsDirName),
path.Join(addonDir, DefSchemaName),
}
for _, dir := range dirs {
// nolint:gosec
err = os.MkdirAll(dir, 0755)
if err != nil {
return err
}
}
return nil
}
// writeHelmCUETemplate writes a cue, with a helm component inside, intended as addon resource
func writeHelmCUETemplate(tmpl HelmCUETemplate, filePath string) error {
r := cue.Runtime{}
v, err := gocodec.New(&r, nil).Decode(tmpl)
if err != nil {
return err
}
// Use `output` value
v = v.Lookup("output")
// Format output
bs, err := format.Node(v.Syntax())
if err != nil {
return err
}
// Append "output: " to the beginning of the string, like "output: {}"
bs = append([]byte("output: "), bs...)
err = os.WriteFile(filePath, bs, 0644)
if err != nil {
return fmt.Errorf("cannot write %s: %w", filePath, err)
}
return nil
}
// HelmCUETemplate is a template for a helm component .cue in an addon
type HelmCUETemplate struct {
Output struct {
Type string `json:"type"`
Properties struct {
RepoType string `json:"repoType"`
URL string `json:"url"`
Chart string `json:"chart"`
Version string `json:"version"`
} `json:"properties"`
} `json:"output"`
}
const (
readmeTemplate = "# ADDON_NAME\n" +
"\n" +
"This is an addon template. Check how to build your own addon: https://kubevela.net/docs/platform-engineers/addon/intro\n" +
"\n" +
"## Directory Structure\n" +
"\n" +
"- `template.yaml`: contains the basic app, you can add some component and workflow to meet your requirements. Other files in `resources/` and `definitions/` will be rendered as Components and appended in `spec.components`\n" +
"- `metadata.yaml`: contains addon metadata information.\n" +
"- `definitions/`: contains the X-Definition yaml/cue files. These file will be rendered as KubeVela Component in `template.yaml`\n" +
"- `resources/`:\n" +
" - `parameter.cue` to expose parameters. It will be converted to JSON schema and rendered in UI forms.\n" +
" - All other files will be rendered as KubeVela Components. It can be one of the two types:\n" +
" - YAML file that contains only one resource. This will be rendered as a `raw` component\n" +
" - CUE template file that can read user input as `parameter.XXX` as defined `parameter.cue`.\n" +
" Basically the CUE template file will be combined with `parameter.cue` to render a resource.\n" +
" **You can specify the type and trait in this format**\n" +
""
)

View File

@@ -1,171 +0,0 @@
/*
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 addon
import (
"os"
"path"
"testing"
"gotest.tools/assert"
)
func TestCheckAddonName(t *testing.T) {
var err error
err = CheckAddonName("")
assert.ErrorContains(t, err, "should not be empty")
invalidNames := []string{
"-addon",
"addon-",
"Caps",
"=",
".",
}
for _, name := range invalidNames {
err = CheckAddonName(name)
assert.ErrorContains(t, err, "should only")
}
validNames := []string{
"addon-name",
"3-addon-name",
"addon-name-3",
"addon",
}
for _, name := range validNames {
err = CheckAddonName(name)
assert.NilError(t, err)
}
}
func TestWriteHelmCUETemplate(t *testing.T) {
resourceTmpl := HelmCUETemplate{}
resourceTmpl.Output.Type = "helm"
resourceTmpl.Output.Properties.RepoType = "helm"
resourceTmpl.Output.Properties.URL = "https://charts.bitnami.com/bitnami"
resourceTmpl.Output.Properties.Chart = "bitnami/nginx"
resourceTmpl.Output.Properties.Version = "12.0.4"
err := writeHelmCUETemplate(resourceTmpl, "test.cue")
assert.NilError(t, err)
defer func() {
_ = os.Remove("test.cue")
}()
data, err := os.ReadFile("test.cue")
assert.NilError(t, err)
expected := `output: {
type: "helm"
properties: {
url: "https://charts.bitnami.com/bitnami"
repoType: "helm"
chart: "bitnami/nginx"
version: "12.0.4"
}
}`
assert.Equal(t, string(data), expected)
}
func TestCreateAddonFromHelmChart(t *testing.T) {
err := CreateAddonFromHelmChart("", "", "", "bitnami/nginx", "12.0.4")
assert.ErrorContains(t, err, "should not be empty")
checkFiles := func(base string) {
fileList := []string{
"definitions",
path.Join("resources", base+".cue"),
"schemas",
MetadataFileName,
ReadmeFileName,
TemplateFileName,
}
for _, file := range fileList {
_, err = os.Stat(path.Join(base, file))
assert.NilError(t, err)
}
}
// Empty dir already exists
_ = os.MkdirAll("test-addon", 0755)
err = CreateAddonFromHelmChart("test-addon", "./test-addon", "https://charts.bitnami.com/bitnami", "bitnami/nginx", "12.0.4")
checkFiles("test-addon")
defer func() {
_ = os.RemoveAll("test-addon")
}()
// Non-empty dir already exists
err = CreateAddonFromHelmChart("test-addon", "test-addon", "https://charts.bitnami.com/bitnami", "bitnami/nginx", "12.0.4")
assert.ErrorContains(t, err, "not empty")
// Name already taken
err = os.WriteFile("already-taken", []byte{}, 0644)
assert.NilError(t, err)
defer func() {
_ = os.Remove("already-taken")
}()
err = CreateAddonFromHelmChart("already-taken", "already-taken", "https://charts.bitnami.com/bitnami", "bitnami/nginx", "12.0.4")
assert.ErrorContains(t, err, "can't create")
// Invalid addon name
err = CreateAddonFromHelmChart("/", "./a", "https://charts.bitnami.com/bitnami", "bitnami/nginx", "12.0.4")
assert.ErrorContains(t, err, "should only")
// Invalid URL
err = CreateAddonFromHelmChart("invalid-url", "invalid-url", "invalid-url", "bitnami/nginx", "12.0.4")
assert.ErrorContains(t, err, "invalid helm repo url")
}
func TestCreateAddonSample(t *testing.T) {
checkFiles := func(base string) {
fileList := []string{
"definitions",
"resources",
"schemas",
MetadataFileName,
ReadmeFileName,
TemplateFileName,
}
for _, file := range fileList {
_, err := os.Stat(path.Join(base, file))
assert.NilError(t, err)
}
}
// Normal creation
err := CreateAddonSample("test-addon", "test-addon")
assert.NilError(t, err)
checkFiles("test-addon")
// Non-empty dir already exists
err = CreateAddonSample("test-addon", "test-addon")
assert.ErrorContains(t, err, "directory")
defer func() {
_ = os.RemoveAll("test-addon")
}()
err = CreateAddonSample("", "")
assert.ErrorContains(t, err, "empty")
}
func TestPreAddonCreation(t *testing.T) {
err := preAddonCreation("", "")
assert.ErrorContains(t, err, "empty")
err = preAddonCreation("=", "a")
assert.ErrorContains(t, err, "name")
}

View File

@@ -55,24 +55,8 @@ func WrapErrRateLimit(err error) error {
type VersionUnMatchError struct {
err error
addonName string
// userSelectedAddonVersion is the version of the addon which is selected to install by user
userSelectedAddonVersion string
// availableVersion is the latest available addon's version which suits system requirements
availableVersion string
}
// GetAvailableVersion load addon's available version from the err
func (v VersionUnMatchError) GetAvailableVersion() (string, error) {
if v.availableVersion == "" {
return "", fmt.Errorf("%s don't exist available version meet system requirement", v.addonName)
}
return v.availableVersion, nil
}
func (v VersionUnMatchError) Error() string {
if v.availableVersion != "" {
return fmt.Sprintf("fail to install %s version of %s, because %s.\nInstall %s(v%s) which is the latest version that suits current version requirements", v.userSelectedAddonVersion, v.addonName, v.err, v.addonName, v.availableVersion)
}
return fmt.Sprintf("fail to install %s version of %s, because %s", v.userSelectedAddonVersion, v.addonName, v.err)
return fmt.Sprintf("addon %s system requirement miss match: %v", v.addonName, v.err)
}

View File

@@ -1,43 +0,0 @@
/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package addon
import (
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestError(t *testing.T) {
err := &VersionUnMatchError{}
assert.False(t, strings.Contains(err.Error(), "which is the latest version that suits current version requirements"))
err = &VersionUnMatchError{availableVersion: "1.0.0"}
assert.Contains(t, err.Error(), "which is the latest version that suits current version requirements")
}
func TestGetAvailableVersion(t *testing.T) {
unMatchErr := &VersionUnMatchError{availableVersion: "1.0.0"}
version, err := unMatchErr.GetAvailableVersion()
assert.Empty(t, err)
assert.Equal(t, version, "1.0.0")
unMatchErr = &VersionUnMatchError{}
version, err = unMatchErr.GetAvailableVersion()
assert.NotEmpty(t, err)
assert.Equal(t, version, "")
}

BIN
pkg/addon/example-1.0.1.tgz Normal file

Binary file not shown.

View File

@@ -36,7 +36,6 @@ import (
"github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam"
addonutil "github.com/oam-dev/kubevela/pkg/utils/addon"
"github.com/oam-dev/kubevela/pkg/utils/apply"
"github.com/oam-dev/kubevela/pkg/utils/common"
)
@@ -163,7 +162,7 @@ func GetAddonStatus(ctx context.Context, cli client.Client, name string) (Status
// Get addon parameters
var sec v1.Secret
err = cli.Get(ctx, client.ObjectKey{Namespace: types.DefaultKubeVelaNS, Name: addonutil.Addon2SecName(name)}, &sec)
err = cli.Get(ctx, client.ObjectKey{Namespace: types.DefaultKubeVelaNS, Name: Convert2SecName(name)}, &sec)
if err != nil {
// Not found error can be ignored. Others can't.
if !apierrors.IsNotFound(err) {
@@ -187,7 +186,7 @@ func GetAddonStatus(ctx context.Context, cli client.Client, name string) (Status
sec v1.Secret
domain string
)
if err = cli.Get(ctx, client.ObjectKey{Namespace: types.DefaultKubeVelaNS, Name: addonutil.Addon2SecName(name)}, &sec); err != nil {
if err = cli.Get(ctx, client.ObjectKey{Namespace: types.DefaultKubeVelaNS, Name: Convert2SecName(name)}, &sec); err != nil {
klog.ErrorS(err, "failed to get observability secret")
addonStatus.AddonPhase = enabling
addonStatus.InstalledVersion = ""

View File

@@ -1,299 +0,0 @@
/*
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 addon
import (
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
cm "github.com/chartmuseum/helm-push/pkg/chartmuseum"
cmhelm "github.com/chartmuseum/helm-push/pkg/helm"
"github.com/fatih/color"
helmrepo "helm.sh/helm/v3/pkg/repo"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// PushCmd is the command object to initiate a push command to ChartMuseum
type PushCmd struct {
ChartName string
AppVersion string
ChartVersion string
RepoName string
Username string
Password string
AccessToken string
AuthHeader string
ContextPath string
ForceUpload bool
UseHTTP bool
CaFile string
CertFile string
KeyFile string
InsecureSkipVerify bool
Out io.Writer
Timeout int64
KeepChartMetadata bool
// We need it to search in addon registries.
// If you use URL, instead of registry names, then it is not needed.
Client client.Client
}
// Push pushes addons (i.e. Helm Charts) to ChartMuseum.
// It will package the addon into a Helm Chart if necessary.
func (p *PushCmd) Push(ctx context.Context) error {
var repo *cmhelm.Repo
var err error
// Get the user specified Helm repo
repo, err = GetHelmRepo(ctx, p.Client, p.RepoName)
if err != nil {
return err
}
// Make the addon dir a Helm Chart
// The user can decide if they want Chart.yaml be in sync with addon metadata.yaml
// By default, it will recreate Chart.yaml according to addon metadata.yaml
err = MakeChartCompatible(p.ChartName, !p.KeepChartMetadata)
// `Not a directory` errors are ignored, that's fine,
// since .tgz files are also supported.
if err != nil && !strings.Contains(err.Error(), "is not a directory") {
return err
}
// Get chart from a directory or .tgz package
chart, err := cmhelm.GetChartByName(p.ChartName)
if err != nil {
return err
}
// Override chart version using specified version
if p.ChartVersion != "" {
chart.SetVersion(p.ChartVersion)
}
// Override app version using specified version
if p.AppVersion != "" {
chart.SetAppVersion(p.AppVersion)
}
// Override username and password using specified values
username := repo.Config.Username
password := repo.Config.Password
if p.Username != "" {
username = p.Username
}
if p.Password != "" {
password = p.Password
}
// Unset accessToken if repo credentials are provided
if username != "" && password != "" {
p.AccessToken = ""
}
// In case the repo is stored with cm:// protocol,
// (if that's somehow possible with KubeVela addon registries)
// use http instead,
// otherwise keep as it-is.
var url string
if p.UseHTTP {
url = strings.Replace(repo.Config.URL, "cm://", "http://", 1)
} else {
url = strings.Replace(repo.Config.URL, "cm://", "https://", 1)
}
cmClient, err := cm.NewClient(
cm.URL(url),
cm.Username(username),
cm.Password(password),
cm.AccessToken(p.AccessToken),
cm.AuthHeader(p.AuthHeader),
cm.ContextPath(p.ContextPath),
cm.CAFile(p.CaFile),
cm.CertFile(p.CertFile),
cm.KeyFile(p.KeyFile),
cm.InsecureSkipVerify(p.InsecureSkipVerify),
cm.Timeout(p.Timeout),
)
if err != nil {
return err
}
// Use a temporary dir to hold packaged .tgz Charts
tmp, err := ioutil.TempDir("", "helm-push-")
if err != nil {
return err
}
defer func(path string) {
_ = os.RemoveAll(path)
}(tmp)
// Package Chart into .tgz packages for uploading to ChartMuseum
chartPackagePath, err := cmhelm.CreateChartPackage(chart, tmp)
if err != nil {
return err
}
_, _ = fmt.Fprintf(os.Stderr, "Pushing %s to %s... ",
color.New(color.Bold).Sprintf(filepath.Base(chartPackagePath)),
formatRepoNameAndURL(p.RepoName, repo.Config.URL),
)
// Push Chart to ChartMuseum
resp, err := cmClient.UploadChartPackage(chartPackagePath, p.ForceUpload)
if err != nil {
return err
}
return handlePushResponse(resp)
}
// GetHelmRepo searches for a Helm repo by name.
// By saying name, it can actually be a URL or a name.
// If a URL is provided, a temp repo object is returned.
// If a name is provided, we will try to find it in local addon registries (only Helm type).
func GetHelmRepo(ctx context.Context, c client.Client, repoName string) (*cmhelm.Repo, error) {
var repo *cmhelm.Repo
var err error
// If RepoName looks like a URL (https / http), just create a temp repo object.
// We do not look for it in local addon registries.
if regexp.MustCompile(`^https?://`).MatchString(repoName) {
repo, err = cmhelm.TempRepoFromURL(repoName)
if err != nil {
return nil, err
}
return repo, nil
}
// Otherwise, search for in it in the local addon registries.
ds := NewRegistryDataStore(c)
registries, err := ds.ListRegistries(ctx)
if err != nil {
return nil, err
}
var matchedEntry *helmrepo.Entry
// Search for the target repo name in addon registries
for _, reg := range registries {
// We are only interested in Helm registries.
if reg.Helm == nil {
continue
}
if reg.Name == repoName {
matchedEntry = &helmrepo.Entry{
Name: reg.Name,
URL: reg.Helm.URL,
Username: reg.Helm.Username,
Password: reg.Helm.Password,
}
break
}
}
if matchedEntry == nil {
return nil, fmt.Errorf("we cannot find Helm repository %s. Make sure you hava added it using `vela addon registry add` and it is a Helm repository", repoName)
}
// Use the repo found locally.
repo = &cmhelm.Repo{ChartRepository: &helmrepo.ChartRepository{Config: matchedEntry}}
return repo, nil
}
// SetFieldsFromEnv sets fields in PushCmd from environment variables
func (p *PushCmd) SetFieldsFromEnv() {
if v, ok := os.LookupEnv("HELM_REPO_USERNAME"); ok && p.Username == "" {
p.Username = v
}
if v, ok := os.LookupEnv("HELM_REPO_PASSWORD"); ok && p.Password == "" {
p.Password = v
}
if v, ok := os.LookupEnv("HELM_REPO_ACCESS_TOKEN"); ok && p.AccessToken == "" {
p.AccessToken = v
}
if v, ok := os.LookupEnv("HELM_REPO_AUTH_HEADER"); ok && p.AuthHeader == "" {
p.AuthHeader = v
}
if v, ok := os.LookupEnv("HELM_REPO_CONTEXT_PATH"); ok && p.ContextPath == "" {
p.ContextPath = v
}
if v, ok := os.LookupEnv("HELM_REPO_USE_HTTP"); ok {
p.UseHTTP, _ = strconv.ParseBool(v)
}
if v, ok := os.LookupEnv("HELM_REPO_CA_FILE"); ok && p.CaFile == "" {
p.CaFile = v
}
if v, ok := os.LookupEnv("HELM_REPO_CERT_FILE"); ok && p.CertFile == "" {
p.CertFile = v
}
if v, ok := os.LookupEnv("HELM_REPO_KEY_FILE"); ok && p.KeyFile == "" {
p.KeyFile = v
}
if v, ok := os.LookupEnv("HELM_REPO_INSECURE"); ok {
p.InsecureSkipVerify, _ = strconv.ParseBool(v)
}
}
// handlePushResponse checks response from ChartMuseum
func handlePushResponse(resp *http.Response) error {
if resp.StatusCode != 201 && resp.StatusCode != 202 {
_, _ = fmt.Fprintf(os.Stderr, "%s\n", color.RedString("Failed"))
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
return getChartMuseumError(b, resp.StatusCode)
}
_, _ = fmt.Fprintf(os.Stderr, "%s\n", color.GreenString("Done"))
return nil
}
// getChartMuseumError checks error messages from the response
func getChartMuseumError(b []byte, code int) error {
var er struct {
Error string `json:"error"`
}
err := json.Unmarshal(b, &er)
if err != nil || er.Error == "" {
return fmt.Errorf("%d: could not properly parse response JSON: %s", code, string(b))
}
return fmt.Errorf("%d: %s", code, er.Error)
}
func formatRepoNameAndURL(name, url string) string {
if name == "" || regexp.MustCompile(`^https?://`).MatchString(name) {
return color.BlueString(url)
}
return fmt.Sprintf("%s(%s)",
color.New(color.Bold).Sprintf(name),
color.BlueString(url),
)
}

View File

@@ -1,203 +0,0 @@
/*
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 addon
import (
"context"
"crypto/rand"
"crypto/tls"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/helm/pkg/tlsutil"
)
var _ = Describe("Addon push command", func() {
var (
testTarballPath = "testdata/charts/sample-1.0.1.tgz"
testServerCertPath = "testdata/tls/server.crt"
testServerKeyPath = "testdata/tls/server.key"
testServerCAPath = "testdata/tls/server_ca.crt"
testClientCAPath = "testdata/tls/client_ca.crt"
testClientCertPath = "testdata/tls/client.crt"
testClientKeyPath = "testdata/tls/client.key"
)
var (
statusCode int
body string
tmp string
)
var p *PushCmd
var ts *httptest.Server
var err error
var ds RegistryDataStore
setArgsAndRun := func(args []string) error {
p = &PushCmd{}
p.Client = k8sClient
p.Out = os.Stdout
p.ChartName = args[0]
p.RepoName = args[1]
p.SetFieldsFromEnv()
return p.Push(context.TODO())
}
AfterEach(func() {
ts.Close()
_ = os.RemoveAll(tmp)
err = ds.DeleteRegistry(context.TODO(), "helm-push-test")
Expect(err).To(Succeed())
})
Context("plain old HTTP Server", func() {
BeforeEach(func() {
statusCode = 201
body = "{\"success\": true}"
ts = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(statusCode)
w.Write([]byte(body))
}))
// Create new Helm home w/ test repo
tmp, err = ioutil.TempDir("", "helm-push-test")
Expect(err).To(Succeed())
// Add our helm repo to addon registry
ds = NewRegistryDataStore(k8sClient)
err = ds.AddRegistry(context.TODO(), Registry{
Name: "helm-push-test",
Helm: &HelmSource{
URL: ts.URL,
},
})
Expect(err).To(Succeed())
_ = os.Setenv("HELM_REPO_USERNAME", "myuser")
_ = os.Setenv("HELM_REPO_PASSWORD", "mypass")
_ = os.Setenv("HELM_REPO_CONTEXT_PATH", "/x/y/z")
})
It("Not enough args", func() {
err = setArgsAndRun([]string{"", ""})
Expect(err).ShouldNot(Succeed(), "expecting error with missing args, instead got nil")
})
It("Bad chart path", func() {
args := []string{"/this/this/not/a/chart", "helm-push-test"}
err = setArgsAndRun(args)
Expect(err).ShouldNot(Succeed(), "expecting error with bad chart path, instead got nil")
})
It("Bad repo name", func() {
args := []string{testTarballPath, "this-is-not-a-valid-repo"}
err = setArgsAndRun(args)
Expect(err).ShouldNot(Succeed(), "expecting error with bad repo name, instead got nil")
})
It("Valid tar, repo name", func() {
args := []string{testTarballPath, "helm-push-test"}
err = setArgsAndRun(args)
Expect(err).Should(Succeed())
})
It("Valid tar, repo URL", func() {
args := []string{testTarballPath, ts.URL}
err = setArgsAndRun(args)
Expect(err).Should(Succeed())
})
It("Trigger 409, already exists", func() {
statusCode = 409
body = "{\"error\": \"package already exists\"}"
args := []string{testTarballPath, "helm-push-test"}
err = setArgsAndRun(args)
Expect(err).ShouldNot(Succeed(), "expecting error with 409, instead got nil")
})
It("Unable to parse JSON response body", func() {
statusCode = 500
body = "duiasnhioasd"
args := []string{testTarballPath, "helm-push-test"}
err = setArgsAndRun(args)
Expect(err).ShouldNot(Succeed(), "expecting error with bad response body, instead got nil")
})
})
Context("TLS Enabled Server", func() {
BeforeEach(func() {
statusCode = 201
body = "{\"success\": true}"
ts = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(statusCode)
_, _ = w.Write([]byte(body))
}))
serverCert, err := tls.LoadX509KeyPair(testServerCertPath, testServerKeyPath)
Expect(err).To(Succeed(), "failed to load certificate and key")
clientCaCertPool, err := tlsutil.CertPoolFromFile(testClientCAPath)
Expect(err).To(Succeed(), "load server CA file failed")
ts.TLS = &tls.Config{
ClientCAs: clientCaCertPool,
ClientAuth: tls.RequireAndVerifyClientCert,
Certificates: []tls.Certificate{serverCert},
Rand: rand.Reader,
}
ts.StartTLS()
// Create new Helm home w/ test repo
tmp, err = ioutil.TempDir("", "helm-push-test")
Expect(err).To(Succeed())
// Add our helm repo to addon registry
ds = NewRegistryDataStore(k8sClient)
err = ds.AddRegistry(context.TODO(), Registry{
Name: "helm-push-test",
Helm: &HelmSource{
URL: ts.URL,
},
})
Expect(err).To(Succeed())
_ = os.Setenv("HELM_REPO_USERNAME", "myuser")
_ = os.Setenv("HELM_REPO_PASSWORD", "mypass")
_ = os.Setenv("HELM_REPO_CONTEXT_PATH", "/x/y/z")
})
It("no cert provided", func() {
_ = os.Unsetenv("HELM_REPO_CA_FILE")
_ = os.Unsetenv("HELM_REPO_CERT_FILE")
_ = os.Unsetenv("HELM_REPO_KEY_FILE")
args := []string{testTarballPath, "helm-push-test"}
err = setArgsAndRun(args)
Expect(err).ShouldNot(Succeed(), "expected non nil error but got nil when run cmd without certificate option")
})
It("with cert", func() {
_ = os.Setenv("HELM_REPO_CA_FILE", testServerCAPath)
_ = os.Setenv("HELM_REPO_CERT_FILE", testClientCertPath)
_ = os.Setenv("HELM_REPO_KEY_FILE", testClientKeyPath)
args := []string{testTarballPath, "helm-push-test"}
err = setArgsAndRun(args)
Expect(err).Should(Succeed())
})
})
})

Binary file not shown.

View File

@@ -1,36 +0,0 @@
apiVersion: v1
entries:
fluxcd:
- apiVersion: v2
appVersion: 1.16.0
description: A Helm chart for Kubernetes
name: fluxcd
type: application
urls:
- http://127.0.0.1:18083/multi/fluxcd-1.0.0.tgz
version: 1.0.0
annotations:
system.vela: ">=1.3.0"
system.kubernetes: ">=1.10.0"
- apiVersion: v2
appVersion: 1.16.0
description: A Helm chart for Kubernetes
name: fluxcd
type: application
urls:
- http://127.0.0.1:18083/multi/fluxcd-2.0.0.tgz
version: 2.0.0
annotations:
system.vela: ">=1.4.0"
system.kubernetes: ">=1.20.0"
fluxcd-no-requirements:
- apiVersion: v2
appVersion: 1.16.0
description: A Helm chart for Kubernetes
name: fluxcd
type: application
urls:
- http://127.0.0.1:18083/multi/fluxcd-1.0.0.tgz
version: 1.0.0
annotations:
generated: "2022-06-15T13:17:04.733573+08:00"

View File

@@ -1,15 +0,0 @@
name: test-view
version: 1.0.0
description: test
icon: https://www.terraform.io/assets/images/logo-text-8c3ba8a6.svg
url: https://terraform.io/
tags: []
deployTo:
controlPlane: true
runtimeCluster: false
dependencies: []
invisible: false

View File

@@ -1,37 +0,0 @@
apiVersion: "v1"
kind: "ConfigMap"
metadata:
name: "cloud-resource-view"
namespace: "vela-system"
data:
template: |
import (
"vela/ql"
)
parameter: {
appName: string
appNs: string
}
resources: ql.#ListResourcesInApp & {
app: {
name: parameter.appName
namespace: parameter.appNs
filter: {
"apiVersion": "terraform.core.oam.dev/v1beta1"
"kind": "Configuration"
}
withStatus: true
}
}
status: {
if resources.err == _|_ {
"cloud-resources": [ for i, resource in resources.list {
resource.object
}]
}
if resources.err != _|_ {
error: resources.err
}
}

View File

@@ -1,75 +0,0 @@
import (
"vela/ql"
)
parameter: {
name: string
namespace: string
cluster: *"" | string
}
pod: ql.#Read & {
value: {
apiVersion: "v1"
kind: "Pod"
metadata: {
name: parameter.name
namespace: parameter.namespace
}
}
cluster: parameter.cluster
}
eventList: ql.#SearchEvents & {
value: {
apiVersion: "v1"
kind: "Pod"
metadata: pod.value.metadata
}
cluster: parameter.cluster
}
podMetrics: ql.#Read & {
cluster: parameter.cluster
value: {
apiVersion: "metrics.k8s.io/v1beta1"
kind: "PodMetrics"
metadata: {
name: parameter.name
namespace: parameter.namespace
}
}
}
status: {
if pod.err == _|_ {
containers: [ for container in pod.value.spec.containers {
name: container.name
image: container.image
resources: {
if container.resources.limits != _|_ {
limits: container.resources.limits
}
if container.resources.requests != _|_ {
requests: container.resources.requests
}
if podMetrics.err == _|_ {
usage: {for containerUsage in podMetrics.value.containers {
if containerUsage.name == container.name {
cpu: containerUsage.usage.cpu
memory: containerUsage.usage.memory
}
}}
}
}
if pod.value.status.containerStatuses != _|_ {
status: {for containerStatus in pod.value.status.containerStatuses if containerStatus.name == container.name {
state: containerStatus.state
restartCount: containerStatus.restartCount
}}
}
}]
if eventList.err == _|_ {
events: eventList.list
}
}
if pod.err != _|_ {
error: pod.err
}
}

View File

@@ -1,30 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFHjCCAwagAwIBAgIUVh0GhVN5oZJUfbbKiS9XIH722WowDQYJKoZIhvcNAQEL
BQAwTDELMAkGA1UEBhMCICAxCjAIBgNVBAgMASAxCjAIBgNVBAcMASAxCjAIBgNV
BAoMASAxGTAXBgNVBAMMEEhFTE1DTElFTlRDRVJUQ0EwHhcNMjEwMTAyMDkwNTQ1
WhcNMzAxMjMxMDkwNTQ1WjBGMQswCQYDVQQGEwIgIDEKMAgGA1UECAwBIDEKMAgG
A1UEBwwBIDEKMAgGA1UECgwBIDETMBEGA1UEAwwKSEVMTUNMSUVOVDCCAiIwDQYJ
KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMYC80vkz8mK/cvzvr5x3Ua//2kAV2pd
sJyA4ujFr6KRvqd1Hk9N6V5WbbE7VnYWQ51P5Gx40iv0lzHhzC93t5wHxjIOXYLE
uZqpeJMJBSTJnHz12A6b9lAnhW3psFBfAU4lsi+u4zimLXJTQw+ONKWsyW2C2ZXs
IVpNusg75exMUwFaklCxB0Ib+AH3nH0fs56J7GZwJNokftcB3Op1qx9XAIQAk0dJ
PRnrzZBQ9xp/WHtNdRgTnvJcDab8noI4oeTrLAU3yAFEAHUUxMMPgdpEe61cLbHT
xxATH70zf6v95KpCQN2LvdNsjgcUmPRjNy7pjL+0sSBhmBYHPVvpXnkZdbF2C804
EYGIYrmNRXcSEOQxQOCSiYr9BSQUWK1wC0xRZGrAMQQ/fzda0lfYlkr3guq7DPG1
2ZCNEc80vZ1YjRjApWQoA+xOOwujJYJLI3XFG+t0/w/sB5f4slXrKwBHP0BxSw4p
I0ab0PeY9GmI5l704QmBgQF5u/mh7tdSR0najj6IkwEyG85UMufyUyaggQHvwTeN
DLP2ItLyshyCA9JB/mnHoEbarUgsgV5/sPQqgMdqYUnPcInuQyz/sTVD7x8YOxI6
xo0o+pnNuN9jMaT2pDQ2+IYzBQihdDNxgxPtS9aZyXE2yUcpiGFtBn4qWMKlOs5y
1Mu0bXunR6hnAgMBAAEwDQYJKoZIhvcNAQELBQADggIBAKGvPoNmC0d3UwcRdS+x
6MY4S2nryyclVmen5s9aSEkVqPoDSxH6O5L/1eOblj0BlS8K6budcgseAkJrvw8+
ZYFXdKBpFninbHv4IySjWupE9rH+rSquNVQrZYK6ZHzfpW5dBfeHEJgyzJNRcu6i
7ySUbBYraL7CHgJKNR2b38WrIGBKeYkkmb3gEIteq79XhZpSWLxc4OUArVNtzTed
v+5oqZImmAvaCrlRRd7/aCkQFsNzbQ7AJfZnPNrZz7A4mkV1yVRFBRMrllJFc6mH
kCv5Hm77GmVtXaZuYnQE0AqpkX8TLACDER+MfP8KwURje14nBqsng1kr4YOUUMyb
SyVPKtM5b/CCGt3BhX80kyy7unfwK/avDuuFaRcq59zEvfD1XuWtMwc/xaw5gXDi
vqo7jLEpFnEC7PdnU8hK8POZnJESdAG8aZGXDy+tPvYQ2DqEXjLc/7FXMhverbLV
b6LuSOOrTff4HM5eQ517TVJNB+MmSosEOC2mH62lu7gEXpM45UI4UelmJTTP+7cy
LbUaxjs/ff6kA1RhbQVWR0cZyw89Pj73mrbjg6knVKzIw8lU3pTQXhwaVbp8HIzT
zN+i8h7W3WuSjwjx4tzmUcCobzjJFKZJbM54EaAXdgSj/x541o6BSFm/IsZ9a81j
waDb9wYoG3nZtVb/OYDUFU7Z
-----END CERTIFICATE-----

View File

@@ -1,52 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDGAvNL5M/Jiv3L
876+cd1Gv/9pAFdqXbCcgOLoxa+ikb6ndR5PTeleVm2xO1Z2FkOdT+RseNIr9Jcx
4cwvd7ecB8YyDl2CxLmaqXiTCQUkyZx89dgOm/ZQJ4Vt6bBQXwFOJbIvruM4pi1y
U0MPjjSlrMltgtmV7CFaTbrIO+XsTFMBWpJQsQdCG/gB95x9H7OeiexmcCTaJH7X
AdzqdasfVwCEAJNHST0Z682QUPcaf1h7TXUYE57yXA2m/J6COKHk6ywFN8gBRAB1
FMTDD4HaRHutXC2x08cQEx+9M3+r/eSqQkDdi73TbI4HFJj0Yzcu6Yy/tLEgYZgW
Bz1b6V55GXWxdgvNOBGBiGK5jUV3EhDkMUDgkomK/QUkFFitcAtMUWRqwDEEP383
WtJX2JZK94LquwzxtdmQjRHPNL2dWI0YwKVkKAPsTjsLoyWCSyN1xRvrdP8P7AeX
+LJV6ysARz9AcUsOKSNGm9D3mPRpiOZe9OEJgYEBebv5oe7XUkdJ2o4+iJMBMhvO
VDLn8lMmoIEB78E3jQyz9iLS8rIcggPSQf5px6BG2q1ILIFef7D0KoDHamFJz3CJ
7kMs/7E1Q+8fGDsSOsaNKPqZzbjfYzGk9qQ0NviGMwUIoXQzcYMT7UvWmclxNslH
KYhhbQZ+KljCpTrOctTLtG17p0eoZwIDAQABAoICAHSyiHDSCSPepnTs0h2rPZ3U
ydI4QUyOqueRjilhWIGXI6XNgG98m2zdwwgQ0IQH2xF7ZEQJcNQ28mSTjqLrC2sJ
qeUWUkYfasOb3VPKnR1xNKjwusThZekXYavFbgPv+fT0gm9XwtJAHcijCYLBbIW3
r366/0E8SOvPo6UeqAL7eG/z0Qd9TanIkgGWzMNxS4rD/m7g6NcnaxmMH4aOkquF
uugQ7ru0ji4Yqq3DCd6z7pG8tKXb6nErj2A6wbA9cCxZ7TemCFm2mg5mjw/ms8DP
W5RwHv4OseLnYm0/TJ8wovM02MW49ccE0y+ZFAvz7THYsvrIoxtSaS+SVLc2clYh
2L+mOo7KpBX9zL2JY8l2wMUcmukr5zKs7gvqN/lAZvR6bafYiBN5pTzWvMWUFwCU
p1EaSIVeccduhTf72tRzpo2W5IDH2XY9209P1ZBzuGgKl+McPcwnx2KnAh91NdtP
ZfN+6cbRDrQY3JsJe8MeYyvpIkHaRXl3sf6rO0VFT4brymWhejzMBko7Qu1EXfVj
8pyAgepE9DqybS0HG5GYm1Mj6VotHNDQXwvLWZgjFsCmaXuwpRZIEUrqzoZaATS4
qJOTIwdfahruz+3qD+2jiaFPScaLIXInijAnkRco0Xkp49+/FlObkN/VghCAb1XI
wL/38/Ecei2sJGzCT5UBAoIBAQD4scFUejzhOUPafImJRWSMM73QkZU/hE49na6l
XMvFOC+6cRQeN3wMezguAjnetqEBrmTBkax/gL0nsuXYmEQmd4r+GAx5FUHXQIE2
LzDulvMjVeVSA6vpCtbjC7UoAs5J8B18pr5EfoFTfCU5d0BsU0XBBPwdeRUyP4pB
e9JXvPWOYzpzBC8d5eMsuRuj1M78BUJJmaxDLdGcBLER3UrTnaaurY+kD+/ryxLx
sT9sWHW0i8jZB9PaDVY8Nvvu0gZsD/gH2U56o6UFotZjQ0P90v7HLTTCvncZGNCH
PB70mEd7IVGW/FoDRKa2gQ+19Q41VspMOho2wum7EGVbxSqDAoIBAQDL1AwidJRV
qLoqzkBpleY7I2GR5BFgfHHZswMqPS8iBXPAgdoXXtWaWs6huGMB9LyMJ2ot6Vm9
THw49XTpfUKeEwAYwVx6y3h3tfJHY4ugXGR+kOi75bOCwHMmX/UFnSmu00DUNY9Y
F+eXi2kiCsHcDkIOOYONIQgVJLDuzlLQaFAWLktFEXu23izkylaLgLd/UEQVF1p1
/yAHIs1UXeGqtTRGxbrP2HdL44GD805lHbf1JcM4Q5Gn7BcWn+ivQewS2jF8MGH1
QbK8ncbZZmQfOUnCKXAmi/IyVojLGVWkT1GsTNC1qfiKcqELFsMrgoykeVKJcNfC
Ci4THpDXhHVNAoIBABvdVssPUyjtEKQ3VfWyd7yZw4fN+AoA2f9fXoUaq54yWG6s
YtOr5dNELxxAlZlVnx6gGpvxpYE3vHnpOoWVMfWZaVJlAWjDr/fdO10F1pa1BRMN
eb9BuA5Jb6BK3IZaIiD4rWUdDa6A+h6Ph2Az81zvy53/3/uxaGWT5vrFU+EOw/ir
N45RhrHz4wtMxkMKAhMMx8uVU07HoHe5stlMkSi6vkVOHw0D2B70RvAbqv6Jvs52
5w8iKGODIQloI7wzfhK3i1PdzkRBd6j1AM5oaALVlERe1U2Ip7GBLUQpwVIoicHL
Dug66B77ny5NsaPyjB//1HTMAcnm9udFxAWPRt8CggEBAKt5QpQh+0Bs5+FnDm1F
PCD4TPcNJUlEqAr7PGhmfKZka9LB6xXKJGzsg/UtR623lH9cEUl6jJJiLAdHCAn9
5PNTDLvGv+RWFIyxNpe0ORy5XZnUktawEWqoOLdJ9rm4U/7NnjZosKTtx1mIYPPQ
lPJp1ExfOjqaVVBkQ61DSgwmFWnznEMIyEk5dA8t4c0OhlDG19/ee63U6b7XGmIl
cNnKA6aeZeDBPOtNBAJbx9HtRHsqP6evwHPCfFH+SSRXkyDxCrxtf5tyn8lp+oWe
TBCwg0qizcS/6wtKHV6ve4r1Z8JKBTMvQPZIJQ9NIPgTpfogTr1tfzWwlr5i8ns8
5ekCggEBAIKMkEtdRWR1dlWByh82Dro5fL/mTMGgF4BJJyiuuKpdzInmhWaMhhSV
BL7gnFuxWkIn1h7RhgiVNiyMF1toQOdvF5ipuMWaCa3cZRIUAAgKkJxl1PfqDkMr
koEHbLz726gry3iQqyraDFrLpF4aLy4QaofUDU5HIsqbm5EecmQJ2tRzltGT5idL
aFVcOXBIqd/isRSGyGdvKiTBnI8/qCXHBmWSuC/2wUBsqfcsktLGOSLvmG+FSJzF
wDH7U1GFYnTG34IlZnjaJEoh+5xy6rHVDEW7aX8Jy+kr/Zc8qSWH+73y2Hs2/T5i
vLWbseIYBACDyFxccjU78/a70FZmSmQ=
-----END PRIVATE KEY-----

View File

@@ -1,32 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFeTCCA2GgAwIBAgIUR/7hT0+Kju66vSp9UuBk/c0vdoAwDQYJKoZIhvcNAQEL
BQAwTDELMAkGA1UEBhMCICAxCjAIBgNVBAgMASAxCjAIBgNVBAcMASAxCjAIBgNV
BAoMASAxGTAXBgNVBAMMEEhFTE1DTElFTlRDRVJUQ0EwHhcNMjEwMTAyMDkwNTQ1
WhcNMzAxMjMxMDkwNTQ1WjBMMQswCQYDVQQGEwIgIDEKMAgGA1UECAwBIDEKMAgG
A1UEBwwBIDEKMAgGA1UECgwBIDEZMBcGA1UEAwwQSEVMTUNMSUVOVENFUlRDQTCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMzrmoo1onmXMzRCbAzt0j1I
HFWQfW8T7kuBwoo5tO5fHKoWOg6ztnsX4TjXA2q3NXPCUFcuzp3L1xmgwVUm6iBc
TDMAUmbOVFXQWQWUSi9YGMkTvQrjqyO+eY1tfnh6ZxiF29T92XDVAH8O9mHwsfMQ
8g3Bn6of86o8cchQ2kM1n9kKs58MdWaKlFQAOnKDdDX8C9E39GcWrtcAASDOHAOm
UYMhIAY3fw/yuuSgxDRcuYuN8jp6cNYgNoiMidFrgDdkeky+Y2n1RQMWsT2GoC2S
6ZV1//7Awnbny8MCdT74LTQ9bN2j/4KfwLTwE5EwCOmf0MrnYeVSK6fIWFGPzJhs
eeGwykTgPazkcCJkSIQGQkgSQON7U1XdsiCj5r4tUDfSXSteAPad0dYvEIwBUkpd
i+MaPE1oC4D6I3ye7LkhfBbzwzx7vYRjDh/fxA6ZH/hRkE+JW7tLEUDM6EXeMhKL
JoUMYVKn5gypbpwItmbVyfhjlh31e+11dz0xk+2iBRbL3t2b67mjvao9LJl+PLP/
Pk9NbX8bAGtsMFKSyHAumUzy5CDYhK7dVPPdUvKTiH57kExScsIZe0+zuzcT/sx1
z57yb8xPh+IoN8HPJYz6wpFEn00rmUprELUjZTtHgZE7st+GIP+oEj31BgRmrFIy
mLIjgblZxoFTCWFe6trtAgMBAAGjUzBRMB0GA1UdDgQWBBQT8nXy1NvG/E8KvGD/
aoadNdL+BjAfBgNVHSMEGDAWgBQT8nXy1NvG/E8KvGD/aoadNdL+BjAPBgNVHRMB
Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQB8nYSII0pXbhld3pOIarYOiYTo
5aOIOZaUHxgJk9EqNMkZUDX0EeKnFSwigtERfUza4APCM36+m3m58Rq7hzFCdoit
/sTuH0ez3Cne8H3tnr8aaXZRU+As857PS5xE6v29NwwRBGdSensCEk+IgZxkxjnS
6p0oSZza0+yrCwQOJJbdSQ/qJHwPdN+oTuW0yMbt83AR1ycUkic5LcXneieaTdUr
PGbzXD5tTC7thl+0h/EtoqfFdAiFDSR4B0lPdOJw64xhDMk952FB2MSFd0HLZNbc
dwYEjCYMqiDXCpXeL4vvPyxN8bzQrCpeSc2hdV+55ejMdaJMBGXNCfdROx8LhoSi
0G63F1Bex0R5vpUHlCALvldg0B5ZhLJ3t+O8O7rj2fTlhfNqSa6b7tSn5UlkWp9F
/AZxzENo25LVi8/7A8x/Defdl2Dq4JHaEtdHpROfLPPYe0H8zSHTTOnUlrKjNSSK
NIZOETD4hvxKg2ZcZZUyt5tSo31yzFJS8tF8HqE6RK/dt407fM53rTOuY5PEa1f0
/RwVf7b2hjgkTf7+uFeslbBZxdkO1CzE44XBmWaFf4kZFVdl06eQ8uE70MfIkmb5
VDcLz6zf6YE4jm7nUMowZ93/C+OrdUAq6qZOFgcwfrdMr1MJ/z82hCIfTRRSyM57
RfQSytf5T17r5K+yWg==
-----END CERTIFICATE-----

View File

@@ -1,30 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFMzCCAxugAwIBAgIUQGMSwNP26VEf81fG96Gw+p8XDHkwDQYJKoZIhvcNAQEL
BQAwTDELMAkGA1UEBhMCICAxCjAIBgNVBAgMASAxCjAIBgNVBAcMASAxCjAIBgNV
BAoMASAxGTAXBgNVBAMMEEhFTE1TRVJWRVJDRVJUQ0EwHhcNMjEwMTAyMDkwNTQz
WhcNMzAxMjMxMDkwNTQzWjBGMQswCQYDVQQGEwIgIDEKMAgGA1UECAwBIDEKMAgG
A1UEBwwBIDEKMAgGA1UECgwBIDETMBEGA1UEAwwKSEVMTVNFUlZFUjCCAiIwDQYJ
KoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPz8Vr/uPHsmAevay7q/myV4tDrjuIj
xjaIwLTlyngq6tWCFr7zXczYJXYY83rvkTVN0oBMkqev7ZlRy1Q5A8FuTEeKnMuv
kRYEn5I8EF2pUP7rY+Gbn6dS63Jh7+wj2g3HwJ+9RzAnzpvNfh6ZbGxZ2I7ALTWU
KUVpJljkDJO6+HyON7geh6R/mFDsq3v6n+giywr3pp37hqDueKYoyBt7WJ+2D2IH
tlxS5eRDoygpZAiiXhSRoGGZ2oS2jevVhnTkHqzS21zNd11WiXtpe0Yu78+cwiqB
iON7Zy5oWVVF+Og1buLkPslVgxg5BJSbfcs5D6cbVreoJFFM9uaJGhjE1PTlci8C
wYJGgdKULP1bcHpbdnz2G8ZIz0xuOwhlThWHdEzh++Vst/UlpRGRkuLxEC34jsJw
XoRt0WMNeakYQzIbWJtkHCA1CCMrfm+Rzuxh+KfwVHMz9J8fv6thdXQcV/tqMKbN
zzEHi3/2lUJeMvS2bibXeWHfiEOlXzIwTPJs4cwwi9PkhfGXWz6XwgIaMfsS8fOS
l5m5s8vFbEHTh3HUQ1J7njc6AFslv5c/5IYeG+sa5ObWsllYt1pTWVTW9sZsHn8s
kGcjxA3SeH/8tjeAMXbnHIEca7Q9UmTlDilb2BL3TreVdckZUIbIvwmftB+Xh5Mt
XQQhBTZZhnAzAgMBAAGjEzARMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZIhvcNAQEL
BQADggIBAE1sejJ6SWRzL8udWxfITdqgqlw+Ci8+K2BYwgBd5vJun+us0oommzl6
ogkJyeytdRx1RdnqQi2Gucz4+HS2FJsXsWjNc7S7TCKj7QGt8O6WQQGPxYD6Ypn8
2q8HHjuPS3aa3w1sID1DxDBjWnDFnz27bF1Fhb7eq51oRJVyXIb8+ip8uoxF0lkR
1ges0h3SSYRz7gvu3t4dDeUiTyttV0yWDk7yWOEZyUxRqYgKJXmu2nFkeOnyiof5
IyjhdQR4XrR6mWZChJT3WtDNGvTTX1uUfMP35fc4YiENzNUzqGcbBVjaJNl1HzlE
Xzi6tkZFnF+T0I7Av/sIlsCL7L/nqqRDXb7yEGG+bY2N9K1Wwkn2WrdrApwbE32N
jV/3wY6oOtgmDaWoc4FOgzI250Y0SyVaAQlN+LvR7EPLJrGA+/6LaCiOMkaDT/JZ
0YtIynvjHVL9gThtrWU/BBe8OzN3tXaxJNMdY2OxSyJEYBEyHDBNluIk1pmJcsRA
KQ5p5vS3sBj9kZAeka0W59emv3n08/IS1svAGxlJa+gSFJTBe9XQJcD8f0kSy+8x
4OAMfFVYrKsQryyS7fRepCTy/niAETp8w/n21cXMCkwMRAFPI9DXx8vEMubDt9dx
NWKOk0Juc2XKIL3Z+IUqUiRopJ7iXyfwsb+8ctcyNcnYT8iaF7f/
-----END CERTIFICATE-----

View File

@@ -1,52 +0,0 @@
-----BEGIN PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDD8/Fa/7jx7JgH
r2su6v5sleLQ647iI8Y2iMC05cp4KurVgha+813M2CV2GPN675E1TdKATJKnr+2Z
UctUOQPBbkxHipzLr5EWBJ+SPBBdqVD+62Phm5+nUutyYe/sI9oNx8CfvUcwJ86b
zX4emWxsWdiOwC01lClFaSZY5AyTuvh8jje4Hoekf5hQ7Kt7+p/oIssK96ad+4ag
7nimKMgbe1iftg9iB7ZcUuXkQ6MoKWQIol4UkaBhmdqEto3r1YZ05B6s0ttczXdd
Vol7aXtGLu/PnMIqgYjje2cuaFlVRfjoNW7i5D7JVYMYOQSUm33LOQ+nG1a3qCRR
TPbmiRoYxNT05XIvAsGCRoHSlCz9W3B6W3Z89hvGSM9MbjsIZU4Vh3RM4fvlbLf1
JaURkZLi8RAt+I7CcF6EbdFjDXmpGEMyG1ibZBwgNQgjK35vkc7sYfin8FRzM/Sf
H7+rYXV0HFf7ajCmzc8xB4t/9pVCXjL0tm4m13lh34hDpV8yMEzybOHMMIvT5IXx
l1s+l8ICGjH7EvHzkpeZubPLxWxB04dx1ENSe543OgBbJb+XP+SGHhvrGuTm1rJZ
WLdaU1lU1vbGbB5/LJBnI8QN0nh//LY3gDF25xyBHGu0PVJk5Q4pW9gS9063lXXJ
GVCGyL8Jn7Qfl4eTLV0EIQU2WYZwMwIDAQABAoICAHcpa8a46BFGnZVe2cFoalxC
MfJ2rSdcNfeH5hib/Spifvhj6c0pVgtyDiXpOneyJA3US4R2DGEpHUY1dX68RUpl
9sEyy/MZyxMmsJtPJ2ytwHGlV9Ikv0wTotamNC7YBoyGwt7hTd889enNZzrYdhTV
9lmpCFUiyo5JSWaZGATmmKG2IrA28KnaZhggNJBqcr/KGMuMmqhMAyzumDQDbN05
f0Vwg55LrlwqlV7guuF7eje99ZRwkqWH2FkIYvndmayP5Q+YEoo28LW0IFsKZErj
1DXe0DzlFQexTaftERZIPPuJMuuLfZsWA2jBk8WDYVYqVxh6CZwaBivir+q1yUXi
SzQB8XBfttpHpfXS6jQ9N18NbC/QvfyP67qDpK4f29sOLhfshIldxrPqPLQRwD6q
oQJ0UhhAjEcjeGITFScfGrt5HYqBR8R8DhcuoklseqBewOKYhOaV6ibiHz+G39Df
3hJAfFZLqXybvOxrx1d7Dr69Gr/9tws7rmK8hTPoIXE+7+jqLZ1fRY+3CorASbXW
JNZeR9VLAruFwfIc6NphftdsUf2MjwuafkLptafAWUFqhm9lpomNwBC3EgBCYg9b
4U57ASFO3kA858d6OKMqxh8+Ja6gFTEtiXxu2e+TAn4nz+HV442URMgU88wH1Fv/
pa29LdmJ+F9q4B2YPq+BAoIBAQDjtCz4CIILmjXghQ/m0lzPrgfc7uF4/dwBGkP+
HW+UQlyvvSgBHcsOG8DH4J1pF5yN3Q/Hh2pvz/7NcIu+5+gEpgkNA5sJtYIkF2tI
QnKp7zzfoODLcRI5sQKZxWUenLLaJ5UlRNyjtGGuZQnZ5fmuT7yzE4gZJwe8dMqS
Qp/gVdFB8GcXo1tEhOsKJYNxqHfeiB73fUOoGX3ovuNtumiw6/6M5rAx4hQXrpR+
p4jiida+cXPqYxrazRLpjvZOuQXwB6+6aSqMAj0Xmyq2HVPkxZjRz5yBmH99Lgr6
vGkNjcgKyzdWP8wTG/CUyzAX4+NEgrfdMZcrSIz2DflTRaohAoIBAQDcTbEXUqoy
Kgw2TFMb8JtvxMidXf0EMLo7u2OuPEomz8+lSLLbudL6NhYriDZzm69alNzrt1et
R587YQytI+l3MOvuc8+HmC6ouP5PRGpEND0FikU25xwz9GsFw8sFJbWbw6zsbYnN
MolTJ1wRH8AYqlWF/AV6H62IzNnU5P4+ThgbtkL5sxhiHVIqHsMbyykIz6o3MOJP
FWcvkIkg9fRAsxu+1DAdOr4IMJISEP5opy1M4nqA4KnSfhX+f7CLZqCYibYl1Xiz
hSoQ1fvUA7o1qMrzKJbtGlhsfcsFAiOVga7bxU2R1rFJyKXgfhYwYnec3k12nBXU
308abAbFClfTAoIBAQCXKX6M7oD+mNJZiZxD3LUWfe7kYYU3YDfUV455vSrcnq2P
USCklRW++Pei+V8mbDFXEEEwcZpcPhVmZueuxZ+Grn7lr9YVvPR3Z0CmSM58N8EO
qGtzQ04ZFISodp2pk9c78fkWM7/RwabzMko26HA3ouGfdEDuibWeC16LeEVQlUgE
4UZfL+gf9alfJAY9xtxE09LS88qdZsbqYwbySkTD5vcmrOKdSvuRuSkFZ8z8rwrr
hL+yAzbJuEhs2qZzHmttrHyhYL2JEtdhu3XATnnqLq9D4fKBKi7AeHd7eua2w7/g
QoYq8NFWgj7VWIpF4dh3G9xZsFktt800b5RsDpxhAoIBAAqvrhZuiRjz1zHPE/z3
9+I9Dmorw/kvD+mT1mr+O66USANBeoOUCPrgIsUrz1BeTew76ld4xkT+g2fS9lVz
t4BznA4uCfQO2ryOdK+NpwX17rvVEDRwk3qlsYdPDwsJ4DxVCo9RZOzSNb0V3K5r
9tp7cLiWGAHrhXRsU2izTu3gxeSaO7d3C4i+2Vx3r4kqmqv1vtD8iw3BAQdaoHw7
0gRNa9we2NKiJdOp33wG3QBgk572IXEc9L/kI9b7hKnOaZ3cmDxPlZJHtFmqt5N6
Ns8hh+6xmliX/ZANrgppJya6aqv4byHS4zisBffUxejE7f5q/iDxw1FXH7QtZ0qp
jMcCggEBAIgJy5OX5leqQpOqx8lzRq1t0nJhIeLcDFkooWrMyyfrZAFaaqgP7jkX
iR31M+h9w57aYNwK3nXLg1b9GxCxs6WIgJpnM8UW1uQy8TBn6TMEEAyhnmjhMg6K
pz3o1gTJ+2SVQ6uNRrk9SL8DGDvUhgY+VuuuCpbLI1S5e/ryUpvsNG7ucs2K19nT
7l0fT30KspD1yTzQvBH9uh/opZWEYowFziaBsAVcYis+TP8bBLA8MurEECw3ztcV
/sQa5pD7wQfRs0MUL10wgcj+FbDiFTcxgCpfu2WHnstY2CGleBegrqJ/Ky4c4JQa
EzEE4ZKHWvLxZ2aFpwgVVBgVv0q7xbk=
-----END PRIVATE KEY-----

View File

@@ -1,32 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIFeTCCA2GgAwIBAgIUEUxeJXnV2hjeuSvl99tONAWFtPEwDQYJKoZIhvcNAQEL
BQAwTDELMAkGA1UEBhMCICAxCjAIBgNVBAgMASAxCjAIBgNVBAcMASAxCjAIBgNV
BAoMASAxGTAXBgNVBAMMEEhFTE1TRVJWRVJDRVJUQ0EwHhcNMjEwMTAyMDkwNTQw
WhcNMzAxMjMxMDkwNTQwWjBMMQswCQYDVQQGEwIgIDEKMAgGA1UECAwBIDEKMAgG
A1UEBwwBIDEKMAgGA1UECgwBIDEZMBcGA1UEAwwQSEVMTVNFUlZFUkNFUlRDQTCC
AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMD+TGmj+RveoUTh3Kjym+Fe
aI5gJIRHj76/bSL0n6oApXeHV7c576NtihDWLq9CPiGAoYo38I4AKO8nH35ifDl5
uPeaqoczbXc7Jr1liLfq7uQ/ZpPK4LvnmkeWJwb/iFZc1lPC1KGR76Sf5NVXDHfp
xuGau6ExCah+ng3NbpvUcQ+fLPJ2OuS/hVkQNO+GqALYxiFObv0VyMSpg+WKh7p7
AioidJPTLQa3a1NK09SYZD4kjAxErIxoX2xTFcsPcS4fuoTgbvLHubT7mOamTD6+
E1c/1EzcyzLuh2BHqcjkzQhWVMa8VX2mjPGqTdykZYrbsp9sTInqytWxp47dcZhw
fUE7RikEPj33Oj5AJ9DSxaka24tZstraaaxF0VSgegzIPu37c762n2x3luX3Iwsg
6yodhAYtnl+pVvjmqbOJ7eEfAIPU44cHDvyHmPIBFspmBIP/NqgrD548rgEC5Jrl
X/DKsOJYln7Czf5RumRTlFGea2A3oYBizhcLOMxv0BalpWmpNS14iKwN3h1KXDFK
inPvnknQTveKQ/ZkvayDJoc5l49W2Igz5uM0jwCV7/n8yI/l9N1DRUrMiOdpLWPA
n6G6PC91JG6BoHFOKAzxJru19gq1wi7knZF/3EinqRrUZqt2AUT5EM0MPhx7G7Dl
7uAsZAMXVNDHbjrEpiZPAgMBAAGjUzBRMB0GA1UdDgQWBBRJ/z9FE6IUNCxTsjCZ
vmM36ruK4TAfBgNVHSMEGDAWgBRJ/z9FE6IUNCxTsjCZvmM36ruK4TAPBgNVHRMB
Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQCQzHHn8LAGIRHEng/zFrL39Izv
8/LOWmPpAX9uJU1sxyafw7MmappBaK6nRdDble9zC66UQKYXOvuXS7O6aIh9MWv6
42ThvFaNWhNRa2bZyMWRlGzT3bOKw1G8TM4TYRA73jm6gfGADPi0po3vGI9PUlsT
lQ5yuR5Vno7VorZ0kGOAu0skH/7X8UIhhIZONCpWnPMoBsQS+iHgjHjqBF1IkY+3
pPBCe+WPj4NqE3Roz60dabO29PiPEjITrFWyuSFPtyvA9XReJIc758SznheOn0X9
pfzvU9MQeqNwtVx7s7mkcB60TX+w3Ey2auKLulG44gEt1rvbjs/n/isJ8CfAAI23
S0wJvPcvc1iZ5QiftXiYIP7t8TqVKVItt6h+vyHsAkUZv/CGC3SGXhxva//3sbbT
gRiBxci6dNzGO5a0Br1z7MNvaRSMRGqog2szX2Jkx2WhxLtuv+jd8IzJcrmb5X7v
VmSFGdklIxeGG/y95d+VgOl9WURvQi+VuiOIouvG0TG7KNnZkp6jF7vMwp206CjB
f38ReS5TANI1QTZbY5HC/HDl1KIHE9II7KKQJBxLsOlUgoZnGtWJviUeq8JH0pCM
YYGU0aKWrTRqexl/kA8P8R+nmnGys3iVdOUMSp38nOrkJ8GLnDOYVB5Z7E5J8cis
6IJa1euccl1ArgxBbg==
-----END CERTIFICATE-----

View File

@@ -48,9 +48,6 @@ type InstallPackage struct {
// Definitions and CUEDefinitions are converted as OAM X-Definitions, they will only in control plane cluster
Definitions []ElementFile `json:"definitions"`
CUEDefinitions []ElementFile `json:"CUEDefinitions"`
// YAMLViews and CUEViews are the instances of velaql, they will only in control plane cluster
YAMLViews []ElementFile `json:"YAMLViews"`
CUEViews []ElementFile `json:"CUEViews"`
// DefSchemas are UI schemas read by VelaUX, it will only be installed in control plane clusters
DefSchemas []ElementFile `json:"defSchemas,omitempty"`

View File

@@ -19,15 +19,8 @@ package addon
import (
"context"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chartutil"
"sigs.k8s.io/yaml"
errors "github.com/pkg/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -243,144 +236,3 @@ type InstallOption func(installer *Installer)
func SkipValidateVersion(installer *Installer) {
installer.skipVersionValidate = true
}
// IsAddonDir validates an addon directory.
// It checks required files like metadata.yaml and template.yaml
func IsAddonDir(dirName string) (bool, error) {
if fi, err := os.Stat(dirName); err != nil {
return false, err
} else if !fi.IsDir() {
return false, errors.Errorf("%q is not a directory", dirName)
}
// Load metadata.yaml
metadataYaml := filepath.Join(dirName, MetadataFileName)
if _, err := os.Stat(metadataYaml); os.IsNotExist(err) {
return false, errors.Errorf("no %s exists in directory %q", MetadataFileName, dirName)
}
metadataYamlContent, err := ioutil.ReadFile(filepath.Clean(metadataYaml))
if err != nil {
return false, errors.Errorf("cannot read %s in directory %q", MetadataFileName, dirName)
}
// Check metadata.yaml contents
metadataContent := new(Meta)
if err := yaml.Unmarshal(metadataYamlContent, &metadataContent); err != nil {
return false, err
}
if metadataContent == nil {
return false, errors.Errorf("metadata (%s) missing", MetadataFileName)
}
if metadataContent.Name == "" {
return false, errors.Errorf("addon name is empty")
}
if metadataContent.Version == "" {
return false, errors.Errorf("addon version is empty")
}
// Load template.yaml
templateYaml := filepath.Join(dirName, TemplateFileName)
if _, err := os.Stat(templateYaml); os.IsNotExist(err) {
return false, errors.Errorf("no %s exists in directory %q", TemplateFileName, dirName)
}
templateYamlContent, err := ioutil.ReadFile(filepath.Clean(templateYaml))
if err != nil {
return false, errors.Errorf("cannot read %s in directory %q", TemplateFileName, dirName)
}
// Check template.yaml contents
templateContent := new(v1beta1.Application)
if err := yaml.Unmarshal(templateYamlContent, &templateContent); err != nil {
return false, err
}
if templateContent == nil {
return false, errors.Errorf("chart metadata (%s) missing", TemplateFileName)
}
return true, nil
}
// MakeChartCompatible makes an addon directory compatible with Helm Charts.
// It essentially creates a Chart.yaml file in it (if it doesn't already have one).
// If overwrite is true, a Chart.yaml will always be created.
func MakeChartCompatible(addonDir string, overwrite bool) error {
// Check if it is an addon dir
isAddonDir, err := IsAddonDir(addonDir)
if !isAddonDir {
return fmt.Errorf("%s is not an addon dir: %w", addonDir, err)
}
// Check if the addon dir has valid Chart.yaml in it.
// No need to handle error here.
// If it doesn't contain a valid Chart.yaml (thus errors), we will create it later.
isChartDir, _ := chartutil.IsChartDir(addonDir)
// Only when it is already a Helm Chart, and we don't want to overwrite Chart.yaml,
// we do nothing.
if isChartDir && !overwrite {
return nil
}
// Creating Chart.yaml.
chartMeta, err := generateChartMetadata(addonDir)
if err != nil {
return err
}
err = chartutil.SaveChartfile(filepath.Join(addonDir, chartutil.ChartfileName), chartMeta)
if err != nil {
return err
}
return nil
}
// generateChartMetadata generates a Chart.yaml file (chart.Metadata) from an addon metadata file (metadata.yaml).
// It is mostly used to package an addon into a Helm Chart.
func generateChartMetadata(addonDirPath string) (*chart.Metadata, error) {
// Load addon metadata.yaml
meta := &Meta{}
metaData, err := ioutil.ReadFile(filepath.Clean(filepath.Join(addonDirPath, MetadataFileName)))
if err != nil {
return nil, err
}
err = yaml.Unmarshal(metaData, meta)
if err != nil {
return nil, err
}
// Generate Chart.yaml from metadata.yaml
chartMeta := &chart.Metadata{
Name: meta.Name,
Description: meta.Description,
// Define Vela addon's type to be library in order to prevent installation of a common chart.
// Please refer to https://helm.sh/docs/topics/library_charts/
Type: "library",
Version: meta.Version,
AppVersion: meta.Version,
APIVersion: chart.APIVersionV2,
Icon: meta.Icon,
Home: meta.URL,
Keywords: meta.Tags,
}
annotation := generateAnnotation(meta)
if len(annotation) != 0 {
chartMeta.Annotations = annotation
}
return chartMeta, nil
}
// generateAnnotation generate addon annotation info for chart.yaml, will recorded in index.yaml in helm repo
func generateAnnotation(meta *Meta) map[string]string {
res := map[string]string{}
if meta.SystemRequirements != nil {
if len(meta.SystemRequirements.VelaVersion) != 0 {
res[velaSystemRequirement] = meta.SystemRequirements.VelaVersion
}
if len(meta.SystemRequirements.KubernetesVersion) != 0 {
res[kubernetesSystemRequirement] = meta.SystemRequirements.KubernetesVersion
}
}
return res
}

View File

@@ -18,13 +18,9 @@ package addon
import (
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
"helm.sh/helm/v3/pkg/chartutil"
"github.com/stretchr/testify/assert"
. "github.com/onsi/ginkgo"
@@ -158,119 +154,6 @@ func TestUsingAddonInfo(t *testing.T) {
assert.Equal(t, true, strings.Contains(res, "Please delete them before disabling the addon"))
}
func TestIsAddonDir(t *testing.T) {
var isAddonDir bool
var err error
var meta *Meta
var metaYaml []byte
// Non-existent dir
isAddonDir, err = IsAddonDir("non-existent-dir")
assert.Equal(t, isAddonDir, false)
assert.Error(t, err)
// Not a directory (a file)
isAddonDir, err = IsAddonDir(filepath.Join("testdata", "local", "metadata.yaml"))
assert.Equal(t, isAddonDir, false)
assert.Contains(t, err.Error(), "not a directory")
// No metadata.yaml
isAddonDir, err = IsAddonDir(".")
assert.Equal(t, isAddonDir, false)
assert.Contains(t, err.Error(), "exists in directory")
// Empty metadata.yaml
err = os.MkdirAll(filepath.Join("testdata", "testaddon"), 0700)
assert.NoError(t, err)
defer func() {
os.RemoveAll(filepath.Join("testdata", "testaddon"))
}()
err = os.WriteFile(filepath.Join("testdata", "testaddon", MetadataFileName), []byte{}, 0644)
assert.NoError(t, err)
isAddonDir, err = IsAddonDir(filepath.Join("testdata", "testaddon"))
assert.Equal(t, isAddonDir, false)
assert.Contains(t, err.Error(), "missing")
// Empty addon name
meta = &Meta{}
metaYaml, err = yaml.Marshal(meta)
assert.NoError(t, err)
err = os.WriteFile(filepath.Join("testdata", "testaddon", MetadataFileName), metaYaml, 0644)
assert.NoError(t, err)
isAddonDir, err = IsAddonDir(filepath.Join("testdata", "testaddon"))
assert.Equal(t, isAddonDir, false)
assert.Contains(t, err.Error(), "addon name is empty")
// Empty addon version
meta = &Meta{
Name: "name",
}
metaYaml, err = yaml.Marshal(meta)
assert.NoError(t, err)
err = os.WriteFile(filepath.Join("testdata", "testaddon", MetadataFileName), metaYaml, 0644)
assert.NoError(t, err)
isAddonDir, err = IsAddonDir(filepath.Join("testdata", "testaddon"))
assert.Equal(t, isAddonDir, false)
assert.Contains(t, err.Error(), "addon version is empty")
// No template.yaml
meta = &Meta{
Name: "name",
Version: "1.0.0",
}
metaYaml, err = yaml.Marshal(meta)
assert.NoError(t, err)
err = os.WriteFile(filepath.Join("testdata", "testaddon", MetadataFileName), metaYaml, 0644)
assert.NoError(t, err)
isAddonDir, err = IsAddonDir(filepath.Join("testdata", "testaddon"))
assert.Equal(t, isAddonDir, false)
assert.Contains(t, err.Error(), "exists in directory")
// Empty template.yaml
err = os.WriteFile(filepath.Join("testdata", "testaddon", TemplateFileName), []byte{}, 0644)
assert.NoError(t, err)
isAddonDir, err = IsAddonDir(filepath.Join("testdata", "testaddon"))
assert.Equal(t, isAddonDir, false)
assert.Contains(t, err.Error(), "missing")
// Pass all checks
err = CreateAddonSample("testaddon2", filepath.Join("testdata", "testaddon2"))
assert.NoError(t, err)
defer func() {
_ = os.RemoveAll(filepath.Join("testdata", "testaddon2"))
}()
isAddonDir, err = IsAddonDir(filepath.Join("testdata", "testaddon2"))
assert.Equal(t, isAddonDir, true)
assert.NoError(t, err)
}
func TestMakeChart(t *testing.T) {
var err error
// Not a addon dir
err = MakeChartCompatible(".", true)
assert.Contains(t, err.Error(), "not an addon dir")
// Valid addon dir
err = CreateAddonSample("testaddon2", filepath.Join("testdata", "testaddon"))
assert.NoError(t, err)
defer func() {
_ = os.RemoveAll(filepath.Join("testdata", "testaddon"))
}()
err = MakeChartCompatible(filepath.Join("testdata", "testaddon"), true)
assert.NoError(t, err)
isChartDir, err := chartutil.IsChartDir(filepath.Join("testdata", "testaddon"))
assert.NoError(t, err)
assert.Equal(t, isChartDir, true)
// Already a chart dir
err = MakeChartCompatible(filepath.Join("testdata", "testaddon"), false)
assert.NoError(t, err)
isChartDir, err = chartutil.IsChartDir(filepath.Join("testdata", "testaddon"))
assert.NoError(t, err)
assert.Equal(t, isChartDir, true)
}
const (
compDefYaml = `
apiVersion: core.oam.dev/v1beta1

View File

@@ -20,23 +20,18 @@ import (
"bytes"
"context"
"fmt"
"sort"
"github.com/Masterminds/semver/v3"
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/repo"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/oam-dev/kubevela/pkg/utils/helm"
)
const (
// velaSystemRequirement is the vela version requirement annotation key
velaSystemRequirement = `system.vela`
// kubernetesSystemRequirement is the kubernetes requirement annotation key
kubernetesSystemRequirement = `system.kubernetes`
"helm.sh/helm/v3/pkg/chart/loader"
"helm.sh/helm/v3/pkg/repo"
)
// VersionedRegistry is the interface of support version registry
@@ -45,7 +40,6 @@ type VersionedRegistry interface {
GetAddonUIData(ctx context.Context, addonName, version string) (*UIData, error)
GetAddonInstallPackage(ctx context.Context, addonName, version string) (*InstallPackage, error)
GetDetailedAddon(ctx context.Context, addonName, version string) (*WholeAddonPackage, error)
GetAddonAvailableVersion(addonName string) ([]*repo.ChartVersion, error)
}
// BuildVersionedRegistry is build versioned addon registry
@@ -105,11 +99,6 @@ func (i *versionedRegistry) GetDetailedAddon(ctx context.Context, addonName, ver
return wholePackage, nil
}
// GetAddonAvailableVersion will return all available versions of the addon which is loaded from the registry, and the version are sorted from last to first
func (i versionedRegistry) GetAddonAvailableVersion(addonName string) ([]*repo.ChartVersion, error) {
return i.loadAddonVersions(addonName)
}
func (i *versionedRegistry) resolveAddonListFromIndex(repoName string, index *repo.IndexFile) []*UIData {
var res []*UIData
for addonName, versions := range index.Entries {
@@ -168,25 +157,11 @@ func (i versionedRegistry) loadAddon(ctx context.Context, name, version string)
}
addonPkg.AvailableVersions = availableVersions
addonPkg.RegistryName = i.name
addonPkg.Meta.SystemRequirements = LoadSystemRequirements(addonVersion.Annotations)
return addonPkg, nil
}
return nil, fmt.Errorf("cannot fetch addon package")
}
// loadAddonVersions Load all available versions of the addon
func (i versionedRegistry) loadAddonVersions(addonName string) ([]*repo.ChartVersion, error) {
versions, err := i.h.ListVersions(i.url, addonName, false, i.Opts)
if err != nil {
return nil, err
}
if len(versions) == 0 {
return nil, ErrNotExist
}
sort.Sort(sort.Reverse(versions))
return versions, nil
}
func loadAddonPackage(addonName string, files []*loader.BufferedFile) (*WholeAddonPackage, error) {
mr := MemoryReader{Name: addonName, Files: files}
metas, err := mr.ListAddonMeta()
@@ -237,18 +212,3 @@ func chooseVersion(specifiedVersion string, versions []*repo.ChartVersion) (*rep
}
return addonVersion, availableVersions
}
// LoadSystemRequirements load the system version requirements from the addon's meta file
func LoadSystemRequirements(anno map[string]string) *SystemRequirements {
if len(anno) == 0 {
return nil
}
req := &SystemRequirements{}
if _, ok := anno[velaSystemRequirement]; ok {
req.VelaVersion = anno[velaSystemRequirement]
}
if _, ok := anno[kubernetesSystemRequirement]; ok {
req.KubernetesVersion = anno[kubernetesSystemRequirement]
}
return req
}

View File

@@ -23,7 +23,6 @@ import (
"io/ioutil"
"log"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
@@ -31,17 +30,15 @@ import (
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/repo"
"github.com/stretchr/testify/assert"
"github.com/oam-dev/kubevela/pkg/utils/common"
"github.com/oam-dev/kubevela/pkg/utils/helm"
"github.com/stretchr/testify/assert"
)
func TestVersionRegistry(t *testing.T) {
go func() {
http.HandleFunc("/", versionedHandler)
http.HandleFunc("/authReg", basicAuthVersionedHandler)
http.HandleFunc("/multi/", multiVersionHandler)
err := http.ListenAndServe(fmt.Sprintf(":%d", 18083), nil)
if err != nil {
log.Fatal("Setup server error:", err)
@@ -101,38 +98,6 @@ func TestVersionRegistry(t *testing.T) {
assert.NotEmpty(t, addonWholePackage.RegistryName)
testListUIData(t)
mr := BuildVersionedRegistry("multiversion-helm-repo", "http://127.0.0.1:18083/multi", nil)
addons, err = mr.ListAddon()
assert.NoError(t, err)
assert.Equal(t, len(addons), 2)
addonUIData, err = mr.GetAddonUIData(context.Background(), "fluxcd", "2.0.0")
assert.NoError(t, err)
assert.NotEmpty(t, addonUIData.Definitions)
assert.NotEmpty(t, addonUIData.Icon)
assert.Equal(t, addonUIData.Version, "2.0.0")
addonsInstallPackage, err = mr.GetAddonInstallPackage(context.Background(), "fluxcd", "1.0.0")
assert.NoError(t, err)
assert.NotEmpty(t, addonsInstallPackage)
assert.NotEmpty(t, addonsInstallPackage.YAMLTemplates)
assert.NotEmpty(t, addonsInstallPackage.DefSchemas)
assert.NotEmpty(t, addonsInstallPackage.SystemRequirements.VelaVersion, "1.3.0")
assert.NotEmpty(t, addonsInstallPackage.SystemRequirements.KubernetesVersion, "1.10.0")
addonWholePackage, err = mr.GetDetailedAddon(context.Background(), "fluxcd", "1.0.0")
assert.NoError(t, err)
assert.NotEmpty(t, addonWholePackage)
assert.NotEmpty(t, addonWholePackage.YAMLTemplates)
assert.NotEmpty(t, addonWholePackage.DefSchemas)
assert.NotEmpty(t, addonWholePackage.RegistryName)
assert.Equal(t, addonWholePackage.RegistryName, "multiversion-helm-repo")
version, err := mr.GetAddonAvailableVersion("fluxcd")
assert.NoError(t, err)
assert.Equal(t, len(version), 2)
assert.Equal(t, addonWholePackage.SystemRequirements.VelaVersion, ">=1.3.0")
assert.Equal(t, addonWholePackage.SystemRequirements.KubernetesVersion, ">=1.10.0")
}
@@ -207,66 +172,3 @@ var basicAuthVersionedHandler http.HandlerFunc = func(writer http.ResponseWriter
writer.Write(files)
}
}
var multiVersionHandler http.HandlerFunc = func(writer http.ResponseWriter, request *http.Request) {
switch {
case strings.Contains(request.URL.Path, "index.yaml"):
files, err := ioutil.ReadFile("./testdata/multiversion-helm-repo/index.yaml")
if err != nil {
_, _ = writer.Write([]byte(err.Error()))
}
writer.Write(files)
case strings.Contains(request.URL.Path, "fluxcd-1.0.0.tgz"):
files, err := ioutil.ReadFile("./testdata/multiversion-helm-repo/fluxcd-1.0.0.tgz")
if err != nil {
_, _ = writer.Write([]byte(err.Error()))
}
writer.Write(files)
case strings.Contains(request.URL.Path, "fluxcd-2.0.0.tgz"):
files, err := ioutil.ReadFile("./testdata/multiversion-helm-repo/fluxcd-2.0.0.tgz")
if err != nil {
_, _ = writer.Write([]byte(err.Error()))
}
writer.Write(files)
}
}
func TestLoadSystemRequirements(t *testing.T) {
req := LoadSystemRequirements(map[string]string{velaSystemRequirement: ">=1.3.0", kubernetesSystemRequirement: ">=1.10.0"})
assert.Equal(t, req.VelaVersion, ">=1.3.0")
assert.Equal(t, req.KubernetesVersion, ">=1.10.0")
req = LoadSystemRequirements(nil)
assert.Empty(t, req)
req = LoadSystemRequirements(map[string]string{kubernetesSystemRequirement: ">=1.10.0"})
assert.Equal(t, req.KubernetesVersion, ">=1.10.0")
req = LoadSystemRequirements(map[string]string{velaSystemRequirement: ">=1.4.0"})
assert.Equal(t, req.VelaVersion, ">=1.4.0")
}
func TestLoadAddonVersions(t *testing.T) {
server := httptest.NewServer(multiVersionHandler)
defer server.Close()
mr := &versionedRegistry{
name: "multiversion-helm-repo",
url: server.URL,
h: helm.NewHelperWithCache(),
Opts: nil,
}
versions, err := mr.loadAddonVersions("not-exist")
assert.Error(t, err)
assert.Equal(t, err, ErrNotExist)
assert.Equal(t, len(versions), 0)
mr = &versionedRegistry{
name: "multiversion-helm-repo",
url: server.URL,
h: helm.NewHelperWithCache(),
Opts: nil,
}
versions, err = mr.loadAddonVersions("not-exist")
assert.Error(t, err)
assert.Equal(t, len(versions), 0)
}

View File

@@ -101,16 +101,6 @@ func (a *Application) IsSynced() bool {
return false
}
// IsReadOnly is readonly app
// Only the source is inner, the app is readonly
func (a *Application) IsReadOnly() bool {
if a.Labels == nil {
return false
}
sot := a.Labels[LabelSourceOfTruth]
return sot == FromInner
}
// ClusterSelector cluster selector
type ClusterSelector struct {
Name string `json:"name"`

View File

@@ -50,9 +50,7 @@ const (
FromCR = "from-k8s-resource"
// FromUX means the data source of truth is from velaux data store
FromUX = "from-velaux"
// FromInner means the data source of truth is from KubeVela inner usage
// the configuration that don't want to be synced
// the addon application should be synced, but set to readonly mode
// FromInner means the data source of truth is from KubeVela inner usage, such as addon or configuration that don't want to be synced
FromInner = "from-inner-system"
)

View File

@@ -22,7 +22,6 @@ import (
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
)
@@ -96,26 +95,3 @@ func DeleteApplicationEnvPolicies(ctx context.Context, store datastore.DataStore
}
return nil
}
// GetApplicationRevision get the application revision
// If the version is empty, will query the latest revision of the application
func GetApplicationRevision(ctx context.Context, store datastore.DataStore, appName, version string) (*model.ApplicationRevision, error) {
ar := &model.ApplicationRevision{AppPrimaryKey: appName}
if version != "" {
ar.Version = version
}
revisions, err := store.List(ctx, ar, &datastore.ListOptions{
Page: 1,
PageSize: 1,
SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}},
})
if err != nil || len(revisions) == 0 {
return nil, bcode.ErrApplicationRevisionNotExist
}
latestRevisionRaw := revisions[0]
latestRevision, ok := latestRevisionRaw.(*model.ApplicationRevision)
if !ok {
return nil, errors.New("convert application revision error")
}
return latestRevision, nil
}

View File

@@ -46,7 +46,6 @@ import (
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam"
addonutil "github.com/oam-dev/kubevela/pkg/utils/addon"
"github.com/oam-dev/kubevela/pkg/utils/apply"
velaerr "github.com/oam-dev/kubevela/pkg/utils/errors"
)
@@ -221,7 +220,7 @@ func (u *addonServiceImpl) StatusAddon(ctx context.Context, name string) (*apis.
var sec v1.Secret
err = u.kubeClient.Get(ctx, client.ObjectKey{
Namespace: types.DefaultKubeVelaNS,
Name: addonutil.Addon2SecName(name),
Name: pkgaddon.Convert2SecName(name),
}, &sec)
if err != nil && !errors2.IsNotFound(err) {
return nil, bcode.ErrAddonSecretGet
@@ -446,7 +445,7 @@ func (u *addonServiceImpl) UpdateAddon(ctx context.Context, name string, args ap
// check addon application whether exist
err := u.kubeClient.Get(ctx, client.ObjectKey{
Namespace: types.DefaultKubeVelaNS,
Name: addonutil.Addon2AppName(name),
Name: pkgaddon.Convert2AppName(name),
}, &app)
if err != nil {
return err

View File

@@ -29,6 +29,7 @@ import (
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/selection"
"k8s.io/apimachinery/pkg/types"
@@ -93,7 +94,7 @@ type ApplicationService interface {
DetailRevision(ctx context.Context, appName, revisionName string) (*apisv1.DetailRevisionResponse, error)
Statistics(ctx context.Context, app *model.Application) (*apisv1.ApplicationStatisticsResponse, error)
ListRecords(ctx context.Context, appName string) (*apisv1.ListWorkflowRecordsResponse, error)
CompareApp(ctx context.Context, app *model.Application, compareReq apisv1.AppCompareReq) (*apisv1.AppCompareResponse, error)
CompareAppWithLatestRevision(ctx context.Context, app *model.Application, compareReq apisv1.AppCompareReq) (*apisv1.AppCompareResponse, error)
ResetAppToLatestRevision(ctx context.Context, appName string) (*apisv1.AppResetResponse, error)
DryRunAppOrRevision(ctx context.Context, app *model.Application, dryRunReq apisv1.AppDryRunReq) (*apisv1.AppDryRunResponse, error)
CreateApplicationTrigger(ctx context.Context, app *model.Application, req apisv1.CreateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error)
@@ -295,23 +296,6 @@ func (c *applicationServiceImpl) GetApplicationStatus(ctx context.Context, appmo
return &app.Status, nil
}
// GetApplicationStatus get application CR from controller cluster
func (c *applicationServiceImpl) GetApplicationCRInEnv(ctx context.Context, appmodel *model.Application, envName string) (*v1beta1.Application, error) {
var app v1beta1.Application
env, err := c.EnvService.GetEnv(ctx, envName)
if err != nil {
return nil, err
}
err = c.KubeClient.Get(ctx, types.NamespacedName{Namespace: env.Namespace, Name: appmodel.GetAppNameForSynced()}, &app)
if err != nil {
if apierrors.IsNotFound(err) {
return nil, nil
}
return nil, err
}
return &app, nil
}
// GetApplicationCR get application CR in cluster
func (c *applicationServiceImpl) GetApplicationCR(ctx context.Context, appModel *model.Application) (*v1beta1.ApplicationList, error) {
var apps v1beta1.ApplicationList
@@ -646,7 +630,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
// TODO: rollback to handle all the error case
// step1: Render oam application
version := utils.GenerateVersion("")
oamApp, err := c.renderOAMApplication(ctx, app, req.WorkflowName, "", version)
oamApp, err := c.renderOAMApplication(ctx, app, req.WorkflowName, version)
if err != nil {
return nil, err
}
@@ -787,7 +771,7 @@ func (c *applicationServiceImpl) syncConfigs4Application(ctx context.Context, ap
return nil
}
func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appModel *model.Application, reqWorkflowName, envName, version string) (*v1beta1.Application, error) {
func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appModel *model.Application, reqWorkflowName, version string) (*v1beta1.Application, error) {
// Priority 1 uses the requested workflow as release .
// Priority 2 uses the default workflow as release .
var workflow *model.Workflow
@@ -803,15 +787,10 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
return nil, err
}
}
if workflow != nil {
envName = workflow.EnvName
if workflow == nil || workflow.EnvName == "" {
return nil, bcode.ErrWorkflowNotExist
}
envbinding, err := c.EnvBindingService.GetEnvBinding(ctx, appModel, envName)
if err != nil {
return nil, err
}
env, err := c.EnvService.GetEnv(ctx, envName)
env, err := c.EnvService.GetEnv(ctx, workflow.EnvName)
if err != nil {
return nil, err
}
@@ -820,20 +799,14 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
labels[key] = value
}
labels[oam.AnnotationAppName] = appModel.Name
// To take over the application
labels[model.LabelSourceOfTruth] = model.FromUX
deployAppName := envbinding.AppDeployName
if deployAppName == "" {
deployAppName = appModel.Name
}
var app = &v1beta1.Application{
TypeMeta: metav1.TypeMeta{
Kind: "Application",
APIVersion: "core.oam.dev/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Name: deployAppName,
Name: appModel.Name,
Namespace: env.Namespace,
Labels: labels,
Annotations: map[string]string{
@@ -914,25 +887,25 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
}
app.Spec.Policies = append(app.Spec.Policies, appPolicy)
}
if workflow != nil {
app.Annotations[oam.AnnotationWorkflowName] = workflow.Name
var steps []v1beta1.WorkflowStep
for _, step := range workflow.Steps {
var workflowStep = v1beta1.WorkflowStep{
Name: step.Name,
Type: step.Type,
Inputs: step.Inputs,
Outputs: step.Outputs,
}
if step.Properties != nil {
workflowStep.Properties = step.Properties.RawExtension()
}
steps = append(steps, workflowStep)
app.Annotations[oam.AnnotationWorkflowName] = workflow.Name
var steps []v1beta1.WorkflowStep
for _, step := range workflow.Steps {
var workflowStep = v1beta1.WorkflowStep{
Name: step.Name,
Type: step.Type,
Inputs: step.Inputs,
Outputs: step.Outputs,
}
app.Spec.Workflow = &v1beta1.Workflow{
Steps: steps,
if step.Properties != nil {
workflowStep.Properties = step.Properties.RawExtension()
}
steps = append(steps, workflowStep)
}
app.Spec.Workflow = &v1beta1.Workflow{
Steps: steps,
}
return app, nil
}
@@ -1396,101 +1369,50 @@ func (c *applicationServiceImpl) Statistics(ctx context.Context, app *model.Appl
}, nil
}
// CompareApp compare application
func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model.Application, compareReq apisv1.AppCompareReq) (*apisv1.AppCompareResponse, error) {
var base, compareTarget *v1beta1.Application
var err error
var envNameByRevision string
switch {
case compareReq.CompareLatestWithRunning != nil:
base, err = c.renderOAMApplication(ctx, appModel, "", compareReq.CompareLatestWithRunning.Env, "")
if err != nil {
log.Logger.Errorf("failed to build the latest application %s", err.Error())
break
}
case compareReq.CompareRevisionWithRunning != nil || compareReq.CompareRevisionWithLatest != nil:
var revision = ""
if compareReq.CompareRevisionWithRunning != nil {
revision = compareReq.CompareRevisionWithRunning.Revision
}
if compareReq.CompareRevisionWithLatest != nil {
revision = compareReq.CompareRevisionWithLatest.Revision
}
base, envNameByRevision, err = c.getAppModelFromRevision(ctx, appModel.Name, revision)
if err != nil {
log.Logger.Errorf("failed to get the app model from the revision %s", err.Error())
break
}
// CompareAppWithLatestRevision compare application with last revision
func (c *applicationServiceImpl) CompareAppWithLatestRevision(ctx context.Context, appModel *model.Application, compareReq apisv1.AppCompareReq) (*apisv1.AppCompareResponse, error) {
var reqWorkflowName string
if compareReq.Env != "" {
reqWorkflowName = repository.ConvertWorkflowName(compareReq.Env)
}
newApp, err := c.renderOAMApplication(ctx, appModel, reqWorkflowName, "")
if err != nil {
return nil, err
}
ignoreSomeParams(newApp)
newAppBytes, err := yaml.Marshal(newApp)
if err != nil {
return nil, err
}
switch {
case compareReq.CompareLatestWithRunning != nil || compareReq.CompareRevisionWithRunning != nil:
var envName string
if compareReq.CompareLatestWithRunning != nil {
envName = compareReq.CompareLatestWithRunning.Env
}
if compareReq.CompareRevisionWithRunning != nil {
envName = envNameByRevision
}
if envName == "" {
break
}
compareTarget, err = c.GetApplicationCRInEnv(ctx, appModel, envName)
if err != nil {
log.Logger.Errorf("failed to query the application CR %s", err.Error())
break
}
case compareReq.CompareRevisionWithLatest != nil:
compareTarget, err = c.renderOAMApplication(ctx, appModel, "", envNameByRevision, "")
if err != nil {
log.Logger.Errorf("failed to build the latest application %s", err.Error())
break
oldApp, err := c.getAppFromLatestRevision(ctx, appModel.Name, compareReq.Env, "")
if err != nil {
if errors.Is(err, bcode.ErrApplicationRevisionNotExist) {
return &apisv1.AppCompareResponse{IsDiff: false, NewAppYAML: string(newAppBytes)}, nil
}
return nil, err
}
var baseAppBytes, targetAppBytes []byte
if base != nil {
ignoreSomeParams(base)
baseAppBytes, err = yaml.Marshal(base)
if err != nil {
return nil, err
}
ignoreSomeParams(oldApp)
oldAppBytes, err := yaml.Marshal(oldApp)
if err != nil {
return nil, err
}
if compareTarget != nil {
ignoreSomeParams(compareTarget)
targetAppBytes, err = yaml.Marshal(compareTarget)
if err != nil {
return nil, err
}
}
compareResponse := &apisv1.AppCompareResponse{IsDiff: true, BaseAppYAML: string(baseAppBytes), TargetAppYAML: string(targetAppBytes)}
if base == nil || compareTarget == nil {
return compareResponse, nil
}
args := common2.Args{
Schema: common2.Scheme,
}
_ = args.SetConfig(c.KubeConfig)
args.SetClient(c.KubeClient)
diffResult, buff, err := compare(ctx, args, compareTarget, base)
diffResult, buff, err := compare(ctx, args, newApp, oldApp)
if err != nil {
log.Logger.Errorf("fail to compare the app %s", err.Error())
compareResponse.IsDiff = false
return compareResponse, nil
return &apisv1.AppCompareResponse{IsDiff: false, NewAppYAML: string(newAppBytes), OldAppYAML: string(oldAppBytes)}, err
}
compareResponse.IsDiff = diffResult.DiffType != ""
compareResponse.DiffReport = buff.String()
return compareResponse, nil
return &apisv1.AppCompareResponse{IsDiff: diffResult.DiffType != "", DiffReport: buff.String(), NewAppYAML: string(newAppBytes), OldAppYAML: string(oldAppBytes)}, nil
}
// ResetAppToLatestRevision reset app's component to last revision
func (c *applicationServiceImpl) ResetAppToLatestRevision(ctx context.Context, appName string) (*apisv1.AppResetResponse, error) {
targetApp, _, err := c.getAppModelFromRevision(ctx, appName, "")
targetApp, err := c.getAppFromLatestRevision(ctx, appName, "", "")
if err != nil {
return nil, err
}
@@ -1502,12 +1424,16 @@ func (c *applicationServiceImpl) DryRunAppOrRevision(ctx context.Context, appMod
var app *v1beta1.Application
var err error
if dryRunReq.DryRunType == "APP" {
app, err = c.renderOAMApplication(ctx, appModel, dryRunReq.Workflow, dryRunReq.Env, "")
var reqWorkflowName string
if dryRunReq.Env != "" {
reqWorkflowName = repository.ConvertWorkflowName(dryRunReq.Env)
}
app, err = c.renderOAMApplication(ctx, appModel, reqWorkflowName, "")
if err != nil {
return nil, err
}
} else {
app, _, err = c.getAppModelFromRevision(ctx, dryRunReq.AppName, dryRunReq.Version)
app, err = c.getAppFromLatestRevision(ctx, dryRunReq.AppName, dryRunReq.Env, dryRunReq.Version)
if err != nil {
return nil, err
}
@@ -1535,16 +1461,33 @@ func genWebhookToken() string {
return string(b)
}
func (c *applicationServiceImpl) getAppModelFromRevision(ctx context.Context, appName string, version string) (*v1beta1.Application, string, error) {
latestRevision, err := repository.GetApplicationRevision(ctx, c.Store, appName, version)
if err != nil {
return nil, "", err
func (c *applicationServiceImpl) getAppFromLatestRevision(ctx context.Context, appName string, envName string, version string) (*v1beta1.Application, error) {
ar := &model.ApplicationRevision{AppPrimaryKey: appName}
if envName != "" {
ar.EnvName = envName
}
if version != "" {
ar.Version = version
}
revisions, err := c.Store.List(ctx, ar, &datastore.ListOptions{
Page: 1,
PageSize: 1,
SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}},
})
if err != nil || len(revisions) == 0 {
return nil, bcode.ErrApplicationRevisionNotExist
}
latestRevisionRaw := revisions[0]
latestRevision, ok := latestRevisionRaw.(*model.ApplicationRevision)
if !ok {
return nil, errors.New("convert application revision error")
}
oldApp := &v1beta1.Application{}
if err := yaml.Unmarshal([]byte(latestRevision.ApplyAppConfig), oldApp); err != nil {
return nil, "", err
return nil, err
}
return oldApp, latestRevision.EnvName, nil
return oldApp, nil
}
func (c *applicationServiceImpl) resetApp(ctx context.Context, targetApp *v1beta1.Application) (*apisv1.AppResetResponse, error) {
@@ -1631,21 +1574,38 @@ func dryRunApplication(ctx context.Context, c common2.Args, app *v1beta1.Applica
return buff, err
}
dryRunOpt := dryrun.NewDryRunOption(newClient, config, dm, pd, objects)
comps, policies, err := dryRunOpt.ExecuteDryRun(ctx, app)
comps, err := dryRunOpt.ExecuteDryRun(ctx, app)
if err != nil {
return buff, fmt.Errorf("generate OAM objects %w", err)
}
if _, err = fmt.Fprintf(&buff, "---\n# Application(%s) \n---\n\n", app.Name); err != nil {
return buff, fmt.Errorf("fail to write to buff %w", err)
var components = make(map[string]*unstructured.Unstructured)
for _, comp := range comps {
components[comp.Name] = comp.StandardWorkload
}
buff.Write([]byte(fmt.Sprintf("---\n# Application(%s) \n---\n\n", app.Name)))
result, err := yaml.Marshal(app)
if err != nil {
return buff, fmt.Errorf("marshal app: %w", err)
return buff, errors.New("marshal app error")
}
buff.Write(result)
buff.WriteString("\n---\n")
if err = dryRunOpt.PrintDryRun(&buff, app.Name, comps, policies); err != nil {
return buff, err
buff.Write([]byte("\n---\n"))
for _, c := range comps {
buff.Write([]byte(fmt.Sprintf("---\n# Application(%s) -- Component(%s) \n---\n\n", app.Name, c.Name)))
result, err := yaml.Marshal(components[c.Name])
if err != nil {
return buff, errors.New("marshal result for component " + c.Name + " object in yaml format")
}
buff.Write(result)
buff.Write([]byte("\n---\n"))
for _, t := range c.Traits {
result, err := yaml.Marshal(t)
if err != nil {
return buff, errors.New("marshal result for component " + c.Name + " object in yaml format")
}
buff.Write(result)
buff.Write([]byte("\n---\n"))
}
buff.Write([]byte("\n"))
}
return buff, nil
}
@@ -1653,23 +1613,21 @@ func dryRunApplication(ctx context.Context, c common2.Args, app *v1beta1.Applica
// ignoreSomeParams ignore some parameters before comparing the app changes.
// ignore the workflow spec
func ignoreSomeParams(o *v1beta1.Application) {
var defaultApplication = v1beta1.Application{}
// only compare the spec without the workflow
defaultApplication.Spec = o.Spec
defaultApplication.Spec.Workflow = nil
defaultApplication.Name = o.Name
defaultApplication.Namespace = o.Namespace
sort.Slice(defaultApplication.Spec.Policies, func(i, j int) bool {
return defaultApplication.Spec.Policies[i].Name < defaultApplication.Spec.Policies[j].Name
})
sort.Slice(defaultApplication.Spec.Components, func(i, j int) bool {
return defaultApplication.Spec.Components[i].Name < defaultApplication.Spec.Components[j].Name
})
*o = defaultApplication
// set default
o.ResourceVersion = ""
o.Spec.Workflow = nil
newAnnotations := map[string]string{}
annotations := o.GetAnnotations()
for k, v := range annotations {
if k == oam.AnnotationDeployVersion || k == oam.AnnotationPublishVersion || k == "kubectl.kubernetes.io/last-applied-configuration" {
continue
}
newAnnotations[k] = v
}
o.SetAnnotations(newAnnotations)
}
func compare(ctx context.Context, c common2.Args, targetApp *v1beta1.Application, baseApp *v1beta1.Application) (*dryrun.DiffEntry, bytes.Buffer, error) {
func compare(ctx context.Context, c common2.Args, newApp *v1beta1.Application, oldApp *v1beta1.Application) (*dryrun.DiffEntry, bytes.Buffer, error) {
var buff = bytes.Buffer{}
_, err := c.GetClient()
if err != nil {
@@ -1693,7 +1651,7 @@ func compare(ctx context.Context, c common2.Args, targetApp *v1beta1.Application
return nil, buff, err
}
liveDiffOption := dryrun.NewLiveDiffOption(client, config, dm, pd, objs)
diffResult, err := liveDiffOption.DiffApps(ctx, baseApp, targetApp)
diffResult, err := liveDiffOption.DiffApps(ctx, newApp, oldApp)
if err != nil {
return nil, buff, err
}
@@ -1701,55 +1659,3 @@ func compare(ctx context.Context, c common2.Args, targetApp *v1beta1.Application
reportDiffOpt.PrintDiffReport(diffResult)
return diffResult, buff, nil
}
// NewTestApplicationService create the application service instance for testing
func NewTestApplicationService(ds datastore.DataStore, c client.Client, cfg *rest.Config) ApplicationService {
targetImpl := &targetServiceImpl{K8sClient: c, Store: ds}
envImpl := &envServiceImpl{KubeClient: c, Store: ds}
rbacService := &rbacServiceImpl{Store: ds}
userService := &userServiceImpl{Store: ds, RbacService: rbacService, SysService: systemInfoServiceImpl{Store: ds}}
projectService := &projectServiceImpl{
K8sClient: c,
Store: ds,
RbacService: rbacService,
TargetService: targetImpl,
UserService: userService,
EnvService: envImpl,
}
userService.ProjectService = projectService
envImpl.ProjectService = projectService
workflowService := &workflowServiceImpl{
Store: ds,
KubeClient: c,
Apply: apply.NewAPIApplicator(c),
EnvService: envImpl,
}
def := &definitionServiceImpl{KubeClient: c}
envbinding := &envBindingServiceImpl{
Store: ds,
WorkflowService: workflowService,
EnvService: envImpl,
DefinitionService: def,
KubeClient: c,
}
workflowService.EnvBindingService = envbinding
return &applicationServiceImpl{
Store: ds,
KubeClient: c,
KubeConfig: cfg,
Apply: apply.NewAPIApplicator(c),
WorkflowService: &workflowServiceImpl{
Store: ds,
KubeClient: c,
Apply: apply.NewAPIApplicator(c),
EnvService: envImpl,
EnvBindingService: envbinding,
},
EnvService: envImpl,
EnvBindingService: envbinding,
TargetService: targetImpl,
DefinitionService: def,
ProjectService: projectService,
UserService: userService,
}
}

View File

@@ -478,12 +478,8 @@ var _ = Describe("Test application service function", func() {
Expect(resp.Total).Should(Equal(int64(3)))
})
It("Test CompareApp function", func() {
check := func(compareResponse *v1.AppCompareResponse, isDiff bool) {
Expect(cmp.Diff(compareResponse.BaseAppYAML, "")).ShouldNot(BeEmpty())
Expect(cmp.Diff(compareResponse.TargetAppYAML, "")).ShouldNot(BeEmpty())
Expect(cmp.Diff(compareResponse.IsDiff, isDiff)).Should(BeEmpty())
}
It("Test CompareAppWithLatestRevision function", func() {
appModel, err := appService.GetApplication(context.TODO(), testApp)
Expect(err).Should(BeNil())
_, err = appService.Deploy(context.TODO(), appModel, v1.ApplicationDeployRequest{WorkflowName: repository.ConvertWorkflowName("app-dev")})
@@ -492,40 +488,23 @@ var _ = Describe("Test application service function", func() {
Expect(err).Should(BeNil())
By("compare when app not change, should return false")
compareResponse, err := appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithRunning: &v1.CompareRevisionWithRunningOption{},
})
compareResponse, err := appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{})
Expect(err).Should(BeNil())
check(compareResponse, false)
Expect(cmp.Diff(compareResponse.IsDiff, false)).Should(BeEmpty())
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithLatest: &v1.CompareRevisionWithLatestOption{},
})
By("compare when app not change and env not empty, should return false")
compareResponse, err = appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{Env: "app-dev"})
Expect(err).Should(BeNil())
check(compareResponse, false)
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-dev",
},
})
Expect(err).Should(BeNil())
check(compareResponse, false)
Expect(cmp.Diff(compareResponse.IsDiff, false)).Should(BeEmpty())
By("compare when app add env, not change, should return false")
_, err = envService.CreateEnv(context.TODO(), v1.CreateEnvRequest{Name: "app-prod", Namespace: "envnsprod", Targets: []string{defaultTarget}, Project: "app-prod"})
Expect(err).Should(BeNil())
_, err = envBindingService.CreateEnvBinding(context.TODO(), appModel, v1.CreateApplicationEnvbindingRequest{EnvBinding: v1.EnvBinding{Name: "app-prod"}})
Expect(err).Should(BeNil())
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-prod",
},
})
compareResponse, err = appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{})
Expect(err).Should(BeNil())
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
Expect(cmp.Diff(compareResponse.TargetAppYAML, "")).Should(BeEmpty())
Expect(cmp.Diff(compareResponse.BaseAppYAML, "")).ShouldNot(BeEmpty())
Expect(cmp.Diff(compareResponse.IsDiff, false)).Should(BeEmpty())
By("compare when app's env add target, should return true")
_, err = targetService.CreateTarget(context.TODO(), v1.CreateTargetRequest{Name: "dev-target1", Project: appModel.Project, Cluster: &v1.ClusterTarget{ClusterName: "local", Namespace: "dev-target1"}})
@@ -536,13 +515,9 @@ var _ = Describe("Test application service function", func() {
Targets: []string{defaultTarget, "dev-target1"},
})
Expect(err).Should(BeNil())
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-dev",
},
})
compareResponse, err = appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{})
Expect(err).Should(BeNil())
check(compareResponse, true)
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
By("compare when update app's trait, should return true")
// reset app config
@@ -554,21 +529,11 @@ var _ = Describe("Test application service function", func() {
Description: "description",
})
Expect(err).Should(BeNil())
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithLatest: &v1.CompareRevisionWithLatestOption{},
})
compareResponse, err = appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{})
Expect(err).Should(BeNil())
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-dev",
},
})
Expect(err).Should(BeNil())
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
By("compare when update component's target after app deployed ,should return true")
By("compare when update component's target after app deployed ,should return ture")
// reset app config
_, err = appService.ResetAppToLatestRevision(context.TODO(), testApp)
Expect(err).Should(BeNil())
@@ -580,49 +545,9 @@ var _ = Describe("Test application service function", func() {
Properties: &newProperties,
})
Expect(err).Should(BeNil())
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithLatest: &v1.CompareRevisionWithLatestOption{},
})
compareResponse, err = appService.CompareAppWithLatestRevision(context.TODO(), appModel, v1.AppCompareReq{})
Expect(err).Should(BeNil())
check(compareResponse, true)
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-dev",
},
})
Expect(err).Should(BeNil())
check(compareResponse, true)
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithRunning: &v1.CompareRevisionWithRunningOption{},
})
Expect(err).Should(BeNil())
check(compareResponse, false)
By("compare when changed the application CR, should return true")
appCR, err := appService.GetApplicationCRInEnv(context.TODO(), appModel, "app-dev")
Expect(err).Should(BeNil())
appCR.Spec.Components[0].Properties = &runtime.RawExtension{Raw: []byte("{\"exposeType\":\"NodePort\",\"image\":\"nginx:222\",\"imagePullPolicy\":\"Always\"}")}
err = k8sClient.Update(context.TODO(), appCR)
Expect(err).Should(BeNil())
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareRevisionWithRunning: &v1.CompareRevisionWithRunningOption{},
})
Expect(err).Should(BeNil())
check(compareResponse, true)
compareResponse, err = appService.CompareApp(context.TODO(), appModel, v1.AppCompareReq{
CompareLatestWithRunning: &v1.CompareLatestWithRunningOption{
Env: "app-dev",
},
})
Expect(err).Should(BeNil())
check(compareResponse, true)
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
err = envBindingService.ApplicationEnvRecycle(context.TODO(), &model.Application{Name: testApp}, &model.EnvBinding{Name: "app-dev"})
Expect(err).Should(BeNil())
})

View File

@@ -1,373 +0,0 @@
/*
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 service
import (
"bytes"
"context"
"fmt"
"io"
"os"
"strconv"
"strings"
"time"
v1alpha1 "github.com/cloudtty/cloudtty/pkg/apis/cloudshell/v1alpha1"
"github.com/ghodss/yaml"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/tools/clientcmd/api"
"sigs.k8s.io/controller-runtime/pkg/client"
kubevelatypes "github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/auth"
)
const (
// DefaultCloudShellPathPrefix the default prefix
DefaultCloudShellPathPrefix = "/view/cloudshell"
// DefaultCloudShellCommand the init command when open the TTY connection
DefaultCloudShellCommand = "bash"
// DefaultLabelKey the default label key for the cloud shell
DefaultLabelKey = "oam.dev/cloudshell"
// StatusFailed means there is an error when creating the required resources, should retry.
StatusFailed = "Failed"
// StatusPreparing means the required resource is created, waiting until the environment is ready.
StatusPreparing = "Preparing"
// StatusCompleted means the environment is ready.
StatusCompleted = "Completed"
// CAFilePathInCluster the CA file path when the server running in cluster.
CAFilePathInCluster = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
// ServerAddressInCluster the kubernetes server address in cluster.
ServerAddressInCluster = "https://kubernetes.default:443"
)
// CloudShellService provide the cloud shell feature
type CloudShellService interface {
Prepare(ctx context.Context) (*apisv1.CloudShellPrepareResponse, error)
GetCloudShellEndpoint(ctx context.Context) (string, error)
}
// GenerateKubeConfig generate the kubeconfig for the cloudshell
type GenerateKubeConfig func(ctx context.Context, cli kubernetes.Interface, cfg *api.Config, writer io.Writer, options ...auth.KubeConfigGenerateOption) (*api.Config, error)
type cloudShellServiceImpl struct {
KubeClient client.Client `inject:"kubeClient"`
KubeConfig *rest.Config `inject:"kubeConfig"`
UserService UserService `inject:""`
ProjectService ProjectService `inject:""`
RBACService RBACService `inject:""`
TargetService TargetService `inject:""`
EnvService EnvService `inject:""`
GenerateKubeConfig GenerateKubeConfig
}
// NewCloudShellService create the instance of the cloud shell service
func NewCloudShellService() CloudShellService {
return &cloudShellServiceImpl{
GenerateKubeConfig: auth.GenerateKubeConfig,
}
}
// Prepare prepare the cloud shell environment for the user
func (c *cloudShellServiceImpl) Prepare(ctx context.Context) (*apisv1.CloudShellPrepareResponse, error) {
res := &apisv1.CloudShellPrepareResponse{}
var userName string
if user := ctx.Value(&apisv1.CtxKeyUser); user != nil {
if u, ok := user.(string); ok {
userName = u
}
}
if userName == "" {
return nil, bcode.ErrUnauthorized
}
ctx, cancel := context.WithTimeout(ctx, time.Second*20)
defer cancel()
var cloudShell v1alpha1.CloudShell
var shouldCreate bool
if err := c.KubeClient.Get(ctx, types.NamespacedName{Namespace: kubevelatypes.DefaultKubeVelaNS, Name: makeUserCloudShellName(userName)}, &cloudShell); err != nil {
if apierrors.IsNotFound(err) {
shouldCreate = true
} else {
if meta.IsNoMatchError(err) {
return nil, bcode.ErrCloudShellAddonNotEnabled
}
return res, err
}
}
if shouldCreate {
if err := c.prepareKubeConfig(ctx); err != nil {
return res, fmt.Errorf("failed to prepare the kubeconfig for the user: %w", err)
}
new, err := c.newCloudShell(ctx)
if err != nil {
return res, err
}
if err := c.KubeClient.Create(ctx, new); err != nil {
if meta.IsNoMatchError(err) {
return nil, bcode.ErrCloudShellAddonNotEnabled
}
return res, err
}
res.Status = StatusPreparing
} else {
if cloudShell.Status.Phase == v1alpha1.PhaseFailed {
if err := c.KubeClient.Delete(ctx, &cloudShell); err != nil {
log.Logger.Errorf("failed to clear the failed cloud shell:%s", err.Error())
}
res.Status = StatusFailed
}
if cloudShell.Status.Phase == v1alpha1.PhaseReady {
res.Status = StatusCompleted
} else {
res.Status = StatusPreparing
res.Message = fmt.Sprintf("The phase is %s", cloudShell.Status.Phase)
}
}
return res, nil
}
func (c *cloudShellServiceImpl) GetCloudShellEndpoint(ctx context.Context) (string, error) {
var userName string
if user := ctx.Value(&apisv1.CtxKeyUser); user != nil {
if u, ok := user.(string); ok {
userName = u
}
}
if userName == "" {
return "", bcode.ErrUnauthorized
}
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
var cloudShell v1alpha1.CloudShell
if err := c.KubeClient.Get(ctx, types.NamespacedName{Namespace: kubevelatypes.DefaultKubeVelaNS, Name: makeUserCloudShellName(userName)}, &cloudShell); err != nil {
if meta.IsNoMatchError(err) {
return "", bcode.ErrCloudShellAddonNotEnabled
}
if apierrors.IsNotFound(err) {
return "", bcode.ErrCloudShellNotInit
}
return "", err
}
return cloudShell.Status.AccessURL, nil
}
// prepareKubeConfig prepare the user's kubeconfig
func (c *cloudShellServiceImpl) prepareKubeConfig(ctx context.Context) error {
var userName string
if user := ctx.Value(&apisv1.CtxKeyUser); user != nil {
if u, ok := user.(string); ok {
userName = u
}
}
if userName == "" {
return bcode.ErrUnauthorized
}
user, _ := c.UserService.GetUser(ctx, userName)
if user == nil {
return bcode.ErrUnauthorized
}
projects, err := c.ProjectService.ListUserProjects(ctx, userName)
if err != nil {
return err
}
var groups []string
for _, p := range projects {
permissions, err := c.RBACService.GetUserPermissions(ctx, user, p.Name, false)
var readOnly bool
if err != nil {
log.Logger.Errorf("failed to get the user permissions %s", err.Error())
readOnly = true
} else {
readOnly = checkReadOnly(p.Name, permissions)
}
if readOnly {
// TODO:(@barnettZQG) there needs a method to revoke the privileges
if err := c.managePrivilegesForUser(ctx, p.Name, true, userName, false); err != nil {
log.Logger.Errorf("failed to privileges the user %s", err.Error())
}
} else {
groups = append(groups, utils.KubeVelaProjectGroupPrefix+p.Name)
}
}
if utils.StringsContain(user.UserRoles, "admin") {
groups = append(groups, utils.KubeVelaAdminGroupPrefix+"admin")
}
cli, err := kubernetes.NewForConfig(c.KubeConfig)
if err != nil {
return err
}
cfg, err := clientcmd.NewDefaultPathOptions().GetStartingConfig()
if err != nil {
return err
}
if len(cfg.Clusters) == 0 {
caFromServiceAccount, err := os.ReadFile(CAFilePathInCluster)
if err != nil {
log.Logger.Errorf("failed to read the ca file from the service account dir,%s", err.Error())
return err
}
cfg.Clusters = map[string]*api.Cluster{
"local": {
CertificateAuthorityData: caFromServiceAccount,
Server: ServerAddressInCluster,
},
}
}
for k := range cfg.Clusters {
cfg.Clusters[k].Server = ServerAddressInCluster
}
buffer := bytes.NewBuffer(nil)
cfg, err = c.GenerateKubeConfig(ctx, cli, cfg, buffer, auth.KubeConfigWithIdentityGenerateOption(auth.Identity{
User: userName,
Groups: groups,
}))
if err != nil {
log.Logger.Errorf("failed to generate the kube config:%s Message: %s", err.Error(), strings.ReplaceAll(buffer.String(), "\n", "\t"))
return err
}
bs, err := clientcmd.Write(*cfg)
if err != nil {
return err
}
cm := corev1.ConfigMap{}
cm.Name = makeUserConfigName(userName)
cm.Namespace = kubevelatypes.DefaultKubeVelaNS
cm.Labels = map[string]string{
DefaultLabelKey: "kubeconfig",
}
identityByte, _ := yaml.Marshal(auth.Identity{
User: userName,
Groups: groups,
})
cm.Data = map[string]string{
"config": string(bs),
"identity": string(identityByte),
}
// mount the token for requesting the API
if tokenV := ctx.Value(&apisv1.CtxKeyToken); tokenV != nil {
if u, ok := tokenV.(string); ok {
cm.Data["token"] = u
}
}
var exist = &corev1.ConfigMap{}
if c.KubeClient.Get(ctx, types.NamespacedName{Namespace: kubevelatypes.DefaultKubeVelaNS, Name: cm.Name}, exist) == nil {
if exist.Data == nil {
cm.Data = map[string]string{}
}
exist.Data["config"] = string(bs)
return c.KubeClient.Update(ctx, &cm)
}
return c.KubeClient.Create(ctx, &cm)
}
func makeUserConfigName(userName string) string {
return fmt.Sprintf("users-%s-kubeconfig", userName)
}
func makeUserCloudShellName(userName string) string {
return fmt.Sprintf("users-%s", userName)
}
func (c *cloudShellServiceImpl) newCloudShell(ctx context.Context) (*v1alpha1.CloudShell, error) {
var userName string
if user := ctx.Value(&apisv1.CtxKeyUser); user != nil {
if u, ok := user.(string); ok {
userName = u
}
}
if userName == "" {
return nil, bcode.ErrUnauthorized
}
var cs v1alpha1.CloudShell
cs.Name = fmt.Sprintf("users-%s", userName)
cs.Namespace = kubevelatypes.DefaultKubeVelaNS
cs.Labels = map[string]string{
DefaultLabelKey: "cloudshell",
}
cs.Spec.ConfigmapName = makeUserConfigName(userName)
cs.Spec.RunAsUser = userName
// only one client and exit on disconnection
once, _ := strconv.ParseBool(os.Getenv("CLOUDSHELL_ONCE"))
cs.Spec.Once = once
cs.Spec.Cleanup = true
// A cloudshell instance can live for a maximum of 60 minutes.
cs.Spec.Ttl = 60 * 60
cs.Spec.CommandAction = DefaultCloudShellCommand
cs.Spec.ExposeMode = v1alpha1.ExposureServiceClusterIP
cs.Spec.PathPrefix = DefaultCloudShellPathPrefix
return &cs, nil
}
func checkReadOnly(projectName string, permissions []*model.Permission) bool {
ra := &RequestResourceAction{}
ra.SetResourceWithName("project:{projectName}/application:*", func(name string) string {
return projectName
})
ra.SetActions([]string{"deploy"})
return !ra.Match(permissions)
}
// managePrivilegesForUser grant or revoke privileges for a user
func (c *cloudShellServiceImpl) managePrivilegesForUser(ctx context.Context, projectName string, readOnly bool, userName string, revoke bool) error {
targets, err := c.TargetService.ListTargets(ctx, 0, 0, projectName)
if err != nil {
log.Logger.Infof("failed to list the targets by the project name %s :%s", projectName, err.Error())
}
var authPDs []auth.PrivilegeDescription
for _, t := range targets.Targets {
authPDs = append(authPDs, &auth.ScopedPrivilege{Cluster: t.Cluster.ClusterName, Namespace: t.Cluster.Namespace, ReadOnly: readOnly})
}
envs, err := c.EnvService.ListEnvs(ctx, 0, 0, apisv1.ListEnvOptions{Project: projectName})
if err != nil {
log.Logger.Infof("failed to list the envs by the project name %s :%s", projectName, err.Error())
}
for _, e := range envs.Envs {
authPDs = append(authPDs, &auth.ApplicationPrivilege{Cluster: kubevelatypes.ClusterLocalName, Namespace: e.Namespace, ReadOnly: readOnly})
}
identity := &auth.Identity{User: userName}
writer := &bytes.Buffer{}
f, msg := auth.GrantPrivileges, "GrantPrivileges"
if revoke {
f, msg = auth.RevokePrivileges, "RevokePrivileges"
}
if err := f(ctx, c.KubeClient, authPDs, identity, writer); err != nil {
return err
}
log.Logger.Debugf("%s: %s", msg, writer.String())
return nil
}

View File

@@ -1,216 +0,0 @@
/*
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 service
import (
"context"
"io"
"io/ioutil"
"time"
v1alpha1 "github.com/cloudtty/cloudtty/pkg/apis/cloudshell/v1alpha1"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"sigs.k8s.io/yaml"
kubevelatypes "github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/auth"
)
var _ = Describe("Test cloudshell service function", func() {
var (
ds datastore.DataStore
cloudShellService *cloudShellServiceImpl
userService *userServiceImpl
projectService *projectServiceImpl
err error
database string
)
BeforeEach(func() {
database = "cloudshell-test-kubevela"
ds, err = NewDatastore(datastore.Config{Type: "kubeapi", Database: database})
Expect(err).Should(Succeed())
envService := &envServiceImpl{
Store: ds,
KubeClient: k8sClient,
}
userService = &userServiceImpl{
Store: ds,
SysService: &systemInfoServiceImpl{Store: ds},
ProjectService: projectService,
}
projectService = &projectServiceImpl{
Store: ds,
RbacService: &rbacServiceImpl{
Store: ds,
},
TargetService: &targetServiceImpl{
Store: ds,
K8sClient: k8sClient,
},
EnvService: envService,
UserService: userService,
}
userService.ProjectService = projectService
userService.RbacService = projectService.RbacService
envService.ProjectService = projectService
cloudShellService = &cloudShellServiceImpl{
KubeClient: k8sClient,
KubeConfig: cfg,
ProjectService: projectService,
TargetService: &targetServiceImpl{
Store: ds,
K8sClient: k8sClient,
},
EnvService: envService,
UserService: userService,
RBACService: projectService.RbacService,
GenerateKubeConfig: func(ctx context.Context, cli kubernetes.Interface, cfg *clientcmdapi.Config, writer io.Writer, options ...auth.KubeConfigGenerateOption) (*clientcmdapi.Config, error) {
return &clientcmdapi.Config{}, nil
},
}
})
It("test prepareKubeConfig", func() {
err = userService.Init(context.TODO())
Expect(err).Should(BeNil())
err = projectService.Init(context.TODO())
Expect(err).Should(BeNil())
By("test the developer users")
_, err = userService.CreateUser(context.TODO(), apisv1.CreateUserRequest{Name: "test-dev", Password: "test"})
Expect(err).Should(BeNil())
_, err = projectService.AddProjectUser(context.TODO(), "default", apisv1.AddProjectUserRequest{
UserName: "test-dev",
UserRoles: []string{"app-developer"},
})
Expect(err).Should(BeNil())
permissions, err := projectService.RbacService.GetUserPermissions(context.TODO(), &model.User{Name: "test-dev"}, "default", false)
Expect(err).Should(BeNil())
Expect(checkReadOnly("default", permissions)).Should(BeFalse())
ctx := context.WithValue(context.TODO(), &apisv1.CtxKeyUser, "test-dev")
err = cloudShellService.prepareKubeConfig(ctx)
Expect(err).Should(BeNil())
var rb rbacv1.RoleBinding
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "kubevela:writer:application:binding", Namespace: "default"}, &rb)
Expect(err).Should(BeNil())
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "kubevela:writer:binding", Namespace: "default"}, &rb)
Expect(err).Should(BeNil())
By("test the viewer users")
_, err = userService.CreateUser(context.TODO(), apisv1.CreateUserRequest{Name: "test-viewer", Password: "test"})
Expect(err).Should(BeNil())
_, err = projectService.AddProjectUser(context.TODO(), "default", apisv1.AddProjectUserRequest{
UserName: "test-viewer",
UserRoles: []string{"project-viewer"},
})
Expect(err).Should(BeNil())
permissions, err = projectService.RbacService.GetUserPermissions(ctx, &model.User{Name: "test-viewer"}, "default", false)
Expect(err).Should(BeNil())
Expect(checkReadOnly("default", permissions)).Should(BeTrue())
ctx = context.WithValue(context.TODO(), &apisv1.CtxKeyUser, "test-viewer")
err = cloudShellService.prepareKubeConfig(ctx)
Expect(err).Should(BeNil())
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "kubevela:reader:application:binding", Namespace: "default"}, &rb)
Expect(err).Should(BeNil())
Expect(len(rb.Subjects)).Should(Equal(1))
Expect(rb.Subjects[0].Name).Should(Equal("test-viewer"))
Expect(rb.Subjects[0].Kind).Should(Equal("User"))
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "kubevela:reader:binding", Namespace: "default"}, &rb)
Expect(err).Should(BeNil())
By("test the administrator users")
_, err = userService.CreateUser(context.TODO(), apisv1.CreateUserRequest{Name: "admin-test", Password: "test", Roles: []string{"admin"}})
Expect(err).Should(BeNil())
ctx = context.WithValue(context.TODO(), &apisv1.CtxKeyUser, "admin-test")
err = cloudShellService.prepareKubeConfig(ctx)
Expect(err).Should(BeNil())
var cm corev1.ConfigMap
err = k8sClient.Get(context.TODO(), types.NamespacedName{Namespace: kubevelatypes.DefaultKubeVelaNS, Name: makeUserConfigName("admin-test")}, &cm)
Expect(err).Should(BeNil())
Expect(len(cm.Data["identity"]) > 0).Should(BeTrue())
var identity auth.Identity
err = yaml.Unmarshal([]byte(cm.Data["identity"]), &identity)
Expect(err).Should(BeNil())
Expect(utils.StringsContain(identity.Groups, utils.KubeVelaAdminGroupPrefix+"admin")).Should(BeTrue())
})
It("test prepare", func() {
By("With not CRD")
_, err = userService.CreateUser(context.TODO(), apisv1.CreateUserRequest{Name: "test", Password: "test"})
Expect(err).Should(BeNil())
ctx := context.WithValue(context.TODO(), &apisv1.CtxKeyUser, "test")
_, err := cloudShellService.Prepare(ctx)
Expect(err).ShouldNot(BeNil())
Expect(err.Error()).Should(Equal(bcode.ErrCloudShellAddonNotEnabled.Error()))
cloudshellCRDBytes, err := ioutil.ReadFile("./testdata/cloudshell-crd.yaml")
Expect(err).Should(BeNil())
crd := apiextensionsv1.CustomResourceDefinition{}
Expect(yaml.Unmarshal(cloudshellCRDBytes, &crd)).Should(BeNil())
Expect(k8sClient.Create(context.TODO(), &crd)).Should(BeNil())
time.Sleep(2 * time.Second)
re, err := cloudShellService.Prepare(ctx)
Expect(err).Should(BeNil())
Expect(re.Status).Should(Equal(StatusPreparing))
var cloudShell v1alpha1.CloudShell
err = k8sClient.Get(ctx, types.NamespacedName{Namespace: kubevelatypes.DefaultKubeVelaNS, Name: makeUserCloudShellName("test")}, &cloudShell)
Expect(err).Should(BeNil())
cloudShell.Status.Phase = v1alpha1.PhaseReady
cloudShell.Status.AccessURL = "10.10.1.1:8765"
err = k8sClient.Status().Update(context.Background(), &cloudShell)
Expect(err).Should(BeNil())
re, err = cloudShellService.Prepare(ctx)
Expect(err).Should(BeNil())
Expect(re.Status).Should(Equal(StatusCompleted))
endpoint, err := cloudShellService.GetCloudShellEndpoint(ctx)
Expect(err).Should(BeNil())
Expect(endpoint).Should(Equal("10.10.1.1:8765"))
})
})

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