Compare commits

..

195 Commits

Author SHA1 Message Date
Hongchao Deng
92a887c1dc Merge pull request #1831 from wonderflow/fixdev
add application  controller to caps which can be disabled and remove appdeployment
2021-06-22 02:34:12 -07:00
天元
b3eaea0912 add application controller to caps which can be disabled and remove appdeployment 2021-06-22 16:51:16 +08:00
yangsoon
e320a4b027 add more options for vela-controller (#1769)
* add more option for controller

1. add ConcurrentReconciles for setting the concurrent reconcile number of the controller
2. add DependCheckWait for setting the time to wait for ApplicationConfiguration's dependent-resource ready

* fix test

* add controller reference
2021-06-08 10:30:00 +08:00
wyike
a534c17e8a cp oam pr 329 (#1742)
fix Ci
2021-06-01 18:32:31 +08:00
wyike
7bcf469e8c add long wait as controller args (#1739)
* add long wait as controller args

* fix golint error

* fix ci workflow add git submodles

fix test

* add submodle for Ci
2021-06-01 17:40:15 +08:00
Jianbo Sun
64f07ebd33 Merge pull request #1528 from wonderflow/cp-xxx
update github token
2021-04-19 14:18:09 +08:00
天元
9e0a86212c fix ci 2021-04-19 13:44:59 +08:00
天元
c15a631b9a update github token 2021-04-19 11:22:52 +08:00
Jianbo Sun
df8fb9369b Merge pull request #1185 from wangyikewxgm/cp1172
Cherry pick pr 1172 to release-0.3 branch
2021-03-12 18:58:29 +08:00
wangyike
222906ece0 try to solve failed test 2021-03-12 17:58:51 +08:00
wangyike
ca8aa01c95 cp1172
delete useless test

fix ci error
2021-03-12 17:34:43 +08:00
Jianbo Sun
4cf4fdff30 align workload/trait definition schema with v0.2.2 spec (#1175) 2021-03-11 18:46:02 -08:00
Jianbo Sun
2648f6d100 Merge pull request #1162 from wangyikewxgm/fix-dryrun
fix vela system dryrun command cannot get namespaced definition
2021-03-11 15:25:10 +08:00
Jianbo Sun
3bc014bc8c Merge pull request #1169 from legendtkl/release-0.3
fix arm64 build failed
2021-03-11 10:25:09 +08:00
Weiping Cai
bb9f5402b3 fix arm64 build failed and block our release pipeline
Signed-off-by: Weiping Cai <weiping.cai@daocloud.io>
2021-03-10 22:44:08 +08:00
wangyike
1d3307002c fix dryrun use namespace 2021-03-09 17:18:44 +08:00
Jianbo Sun
37bd952486 Merge pull request #1156 from wangyikewxgm/cp1085
cherry-pick  pr 1085 to release-0.3
2021-03-09 10:55:10 +08:00
wangyike
5c33598fe9 modify controller,webhook,api,chart
solve failed test

add compatibility test for old crd

add app ns for cli

modify compatibility test

solve compatibility problem

add testing for  GetDefinition func with cluster scope CRD

generate code for compatibility-test

move testdata generate to makefile

optimize ci pipeline for compatibility-test
2021-03-09 10:10:48 +08:00
Jianbo Sun
54e806a94c Merge pull request #1152 from yangsoon/fix-workflow
cherry-pick(#1143) delete image after e2e test
2021-03-08 11:48:58 +08:00
yangsoon
740b85c6e1 fix issue #1140 delete image after e2e test 2021-03-08 11:24:42 +08:00
Jianbo Sun
8ceb64d16c Merge pull request #1136 from wonderflow/fixgc
fix garbage collection for apply once force model
2021-03-05 10:51:21 +08:00
天元
5bf11d4142 fix revision enable workload check and prevent GC if replica>0 2021-03-04 18:05:17 +08:00
天元
0229ac775b reduce reconcile too frequency, error will requeue automatically 2021-03-04 16:00:45 +08:00
Jianbo Sun
52e3893bf3 Merge pull request #1114 from wonderflow/fix1
update CRD and fix workload not create first time
2021-03-01 17:58:11 +08:00
天元
419afd27b5 update CRD and fix workload not create first time 2021-03-01 15:05:19 +08:00
Jianbo Sun
52550bb7b5 parent override child when annotation/labels conflicts && one revision will apply once only in force mode && AC.status CRD updated (#1109)
* when annotation/labels passthrough from parent to child conflicts, the parent will override the child.
e.g. 1) AC will override its component/workload; 2) workload will override child-resource; 3) AC will override its trait

* apply once only force will block workload apply when revision not changed even ac generation updated
2021-02-28 22:38:18 -08:00
Jianbo Sun
d6f3f995cd Merge pull request #1111 from captainroy-hy/chp-1041
cherry-pick(1041&1036) fix unit test
2021-02-26 18:57:10 +08:00
roy wang
dc6ab6b8d6 fix unstable unit test
Signed-off-by: roywang <seiwy2010@gmail.com>
2021-02-26 19:18:15 +09:00
roywang
613f1f9b53 quick fix unstable unit test
Signed-off-by: roywang <seiwy2010@gmail.com>
2021-02-26 18:46:10 +09:00
Jianbo Sun
eefc72b0c6 Merge pull request #1099 from captainroy-hy/ut-apply-once
add unit test
2021-02-26 10:26:09 +08:00
Jianbo Sun
1ac66bb3e4 fix component custom revison loop infinitely create revision (#1101) 2021-02-24 23:50:45 -08:00
roywang
ac6d6d1a73 add unit test
Signed-off-by: roywang <seiwy2010@gmail.com>
2021-02-25 02:59:19 +09:00
Jianbo Sun
46f7472bd5 fix apply only once observedGeneration should mark after meet all dependency requirements && add log for apply only once (#1094) 2021-02-24 01:13:27 -08:00
Jianbo Sun
d872430b08 Merge pull request #1095 from wonderflow/cherryp
cherry-pick: remove go-header package dependency
2021-02-23 20:10:30 +08:00
天元
9d2cf16141 remove go-header package dependency 2021-02-23 19:14:57 +08:00
Jianbo Sun
8c9fab1aa1 Merge pull request #1096 from wonderflow/ci
enable CI for release-*
2021-02-23 19:12:44 +08:00
天元
e213779235 enable CI for release-* 2021-02-23 17:53:49 +08:00
Jianbo Sun
e4bf16b618 Merge pull request #1034 from oam-dev/master
merge master to release-0.3 align with v0.3.3
2021-02-07 17:49:09 +08:00
Jianbo Sun
f6d2e76102 Merge pull request #1032 from wangkai1994/fix/cap_error_message
fix cap error message
2021-02-07 17:30:27 +08:00
wangkai1994
58bd00f137 fix cap error message, 2021-02-07 17:09:36 +08:00
Dylan
abe01d2add fix: update CR's status with retry.RetryOnConflict (#1015) 2021-02-06 23:08:22 -08:00
Jianbo Sun
aabd1e399a Merge pull request #1020 from zzxwill/app-creation-ui
Implement application creation page
2021-02-07 10:27:53 +08:00
Jianbo Sun
12cc22b5c4 Merge pull request #838 from captainroy-hy/force-apply-once-only
implement ApplyOnceOnlyForce
2021-02-06 13:14:23 +08:00
roy wang
47ab481eee implement ApplyOnceOnlyForce
add unit test

Signed-off-by: roy wang <seiwy2010@gmail.com>
2021-02-06 12:58:32 +09:00
Ryan Zhang
b564e0ef26 add more code to complete the rollout plan (#1024) 2021-02-05 12:08:19 -08:00
zzxwill
1119d1b529 fix lint issue 2021-02-05 17:55:16 +08:00
zzxwill
8af08075df Implement application creation page
To fix #680
2021-02-05 17:48:27 +08:00
Jianbo Sun
4b06961e6f Merge pull request #1014 from wonderflow/definition
move template out from extension to spec.template
2021-02-05 15:51:44 +08:00
天元
96a589b098 move template out from extension 2021-02-05 14:45:30 +08:00
Jianbo Sun
258bdd7b76 Merge pull request #1017 from resouer/doc
Update the details of the doc
2021-02-05 13:49:57 +08:00
Jianbo Sun
1f5223267b Merge pull request #1021 from zzxwill/dashboard-build
Revert package management and build tool to npm
2021-02-05 12:21:11 +08:00
Jianbo Sun
c24169e42d Merge pull request #1000 from ryanzhang-oss/rollout-controller
Cloneset rollout
2021-02-05 12:06:22 +08:00
zzxwill
9230e5c181 Revert package management and build tool to npm
As yarn failed to build and start the dashboard most
of time, revert the tool to npm
2021-02-05 11:31:37 +08:00
Ryan Zhang
10bf5739ca fix lint 2021-02-04 17:11:04 -08:00
Ryan Zhang
15020660c9 cloneset controller draft 2021-02-04 17:01:22 -08:00
Harry Zhang
cd971063f8 Update the details of the doc 2021-02-04 14:26:21 -08:00
Jianbo Sun
b6f10bb1fa Merge pull request #975 from leejanee/app-status
display trait status information with customized style
2021-02-04 20:22:19 +08:00
天元
868e0925d4 move health check and status out of extention 2021-02-04 17:56:20 +08:00
Jianbo Sun
f2bd881d27 Merge pull request #1012 from dylandee/fix-redundant-docker-image-push
remove redundant image push operation
2021-02-04 16:37:57 +08:00
Dylan
ea306dac5e remove redundant image push operation 2021-02-04 16:15:43 +08:00
Jianbo Sun
a761e75c01 Merge pull request #994 from zzxwill/fix-openAPIV3Schema-validatation
Fix openAPIV3Schema validation issue
2021-02-04 14:15:45 +08:00
天元
87e52bb349 add demo, test and refine code 2021-02-04 14:14:52 +08:00
Jianbo Sun
dc8358f910 Merge pull request #1008 from resouer/doc
Fix doc detail
2021-02-04 08:46:23 +08:00
Jianbo Sun
26a7e57d6e Merge pull request #1009 from vnzongzna/patch-1
Fix link in APIServer-Catalog Examples
2021-02-04 08:45:27 +08:00
Vaibhav Kaushik
026d5f6446 Minor fix for APIServe-Catalog Doc 2021-02-04 02:26:54 +05:30
Vaibhav Kaushik
26aa3eceae Fix link in APIServer-Catalog Examples 2021-02-04 02:13:25 +05:30
Harry Zhang
966a773195 Fix doc detail 2021-02-03 10:04:43 -08:00
zzxwill
5aea4c4baa Fix openAPIV3Schema validatation issue
Legacy crd charts/vela-core/crds/standard.oam.dev_routes.yaml could not
be applied to old Kubernetes clusters like 1.15.12.
Fix #993
2021-02-03 22:20:39 +08:00
Zheng Xi Zhou
51860cf11a Fix wrong target directory name for artifathub.io (#1004) 2021-02-03 19:51:34 +08:00
Jianbo Sun
90d82c38e9 Merge pull request #1001 from captainroy-hy/sync-cap-bug-fix
fix cannot sync trait without definitionRef
2021-02-03 19:47:27 +08:00
roy wang
2375e019bd fix cannot sync trait without definitionRef
Signed-off-by: roy wang <seiwy2010@gmail.com>
2021-02-03 20:29:11 +09:00
Zheng Xi Zhou
fb15b43914 Fix issue: artifacthub-repo.yml not uploaded to repo (#1003)
* Fix issue: artifacthub-repo.yml not uploaded to repo

* Update .github/workflows/registry.yml

Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>
2021-02-03 19:03:08 +08:00
天元
829d230427 remove unused client side trait checker 2021-02-03 18:19:51 +08:00
天元
f310665fe0 implement vela status in application CRD controller and refactor the health check code 2021-02-03 18:13:47 +08:00
Kai
dafbbbb606 mark vela install as deprecated (#989)
* mark `vela install` as deprecated

* refactor vela install to helm install

* refactor vela install to helm install

fix

* Update pkg/commands/system.go

Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>

* Update pkg/commands/system.go

Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>

* Update README.md

* Update CONTRIBUTING.md

Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>

* Update _sidebar.md

* Update README.md

* revert

Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>
2021-02-03 16:14:58 +08:00
Jianbo Sun
2524a3e5fb Merge pull request #943 from captainroy-hy/webhook-no-traitdef
validating webhook for TraitDefinition
2021-02-03 14:50:17 +08:00
Zheng Xi Zhou
dd04402a28 Build KubeVela legacy chart (#983)
* Build KubeVela legacy chart

Also pushed it to oss bucket
fix #528

* remvoe flag `--devel`

* make it explictly to modify values.yaml for legacy chart
2021-02-03 14:27:04 +08:00
roy wang
62611896e1 validating webhook for TraitDefinition
add unit test

fix lint issues

Signed-off-by: roy wang <seiwy2010@gmail.com>
2021-02-03 14:46:24 +09:00
Jianbo Sun
8186b174ba Merge pull request #991 from captainroy-hy/ac-webhook-td
use dummy trait definition in appconfig webhook
2021-02-03 09:58:47 +08:00
Lei Zhang (Harry)
b99a4b619c Merge pull request #960 from resouer/dev
Explain KubeVela
2021-02-02 11:33:30 -08:00
Lei Zhang (Harry)
5ae47074d1 Update docs/en/platform-engineers/overview.md
Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>
2021-02-02 10:32:01 -08:00
Lei Zhang (Harry)
5a2305b83e Update docs/en/platform-engineers/overview.md
Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>
2021-02-02 10:31:50 -08:00
Lei Zhang (Harry)
78a145fa74 Update docs/en/platform-engineers/overview.md
Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>
2021-02-02 10:31:30 -08:00
roywang
02f214b766 use dummy trait definition in appconfig webhook
Signed-off-by: roywang <seiwy2010@gmail.com>
2021-02-02 22:58:16 +09:00
lj176172
dd6810314e status app 2021-02-02 21:23:01 +08:00
Jianbo Sun
2efeec8a8e Merge pull request #990 from 96RadhikaJadhav/fixing-wrong-chart-name
Fixed wrong chart name
2021-02-02 17:41:44 +08:00
96RadhikaJadhav
671c73a070 Fixed wrong chart name 2021-02-02 14:20:11 +05:30
Zheng Xi Zhou
942115a1c3 Set KubeVela as verified publisher of ArtifactHub (#986)
* Set KubeVeal as verified publisher of ArtifactHub

Set KubeVela team as a verified publisher of Artifacthub,
Add README to the repo and add helm badge in github readme

To impleted #977

* Update hack/artifacthub/artifacthub-repo.yml

Co-authored-by: Ryan Zhang <yangzhangrice@hotmail.com>

* Update hack/artifacthub/artifacthub-repo.yml

Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>

* add more owners

* add README to chart

Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>
Co-authored-by: Ryan Zhang <yangzhangrice@hotmail.com>
2021-02-02 15:37:40 +08:00
Holger Protzek
f737379738 Added ingressClass to route trait (#947)
* Added ingressClass to route trait

* typo

Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>

* run make reviewable

* fixed ingress test

Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>
2021-02-02 09:52:20 +08:00
Jianbo Sun
e5a9721fa5 Merge pull request #985 from zzxwill/capability-show
Change "vela show" function name
2021-02-02 09:51:23 +08:00
zzxwill
86db8de125 Change "vela show" function name
Also updated help vela help message
2021-02-01 19:48:34 +08:00
Ryan Zhang
7f64974701 This PR spells out the rollout states (#972)
* add rollout state transition:

* address comments
2021-02-01 17:40:59 +08:00
Jianbo Sun
9c64afa1f6 Merge pull request #982 from wonderflow/fix
bump #981 into release-0.3
2021-02-01 14:53:02 +08:00
Hongchao Deng
18f184d57c Merge pull request #981 from wonderflow/fix
fix pull image error
2021-01-31 21:57:37 -08:00
天元
b80bacf65d fix version 2021-02-01 13:19:33 +08:00
Jianbo Sun
c96a92475d Merge pull request #974 from wonderflow/reg
minor change for CI name
2021-01-29 18:40:21 +08:00
天元
316b438674 minor change for CI name 2021-01-29 18:24:38 +08:00
Jianbo Sun
104f0827dc Merge pull request #958 from captainroy-hy/static-check-action
add staticcheck CI action
2021-01-29 18:14:56 +08:00
Jianbo Sun
0a81696315 Merge pull request #973 from wonderflow/testmaster
manually create release and automatically upload artifacts
2021-01-29 17:44:33 +08:00
roy wang
93ae8a9099 fix staticcheck issues
add staticcheck CI action

add staticcheck in Makefile

Signed-off-by: roywang <seiwy2010@gmail.com>
2021-01-29 18:42:03 +09:00
天元
ed436d4e6d merge chart and docker publish into registry 2021-01-29 17:12:18 +08:00
天元
e5e71dbc25 change from create release by github robot to manuelly
automatically upload artifacts after manually released
2021-01-29 17:11:58 +08:00
Jianbo Sun
af61a81828 Merge pull request #971 from wonderflow/fixc
fix inner containerizedworkload not work
2021-01-29 16:28:52 +08:00
天元
b88309a333 fix inner containerizedworkload not work 2021-01-29 15:51:29 +08:00
Jianbo Sun
c41bd241ce update kubevela installation guide (#955)
* update kubevela installation guide

* adress comments

* Update docs/en/install.md

Co-authored-by: Hongchao Deng <hongchaodeng1@gmail.com>

* Update docs/en/install.md

Co-authored-by: Hongchao Deng <hongchaodeng1@gmail.com>

* remove line

* address comments

Co-authored-by: Hongchao Deng <hongchaodeng1@gmail.com>
2021-01-29 15:46:58 +08:00
Jianbo Sun
5c188dd9cc Merge pull request #952 from wonderflow/removecode
remove unused dependency installation
2021-01-29 14:58:57 +08:00
Jianbo Sun
66fb99954e fix quick start guide as we don't have route trait installed as default (#954)
* fix quick start guide as we don't have route trait installed as default

* add a description for ingress trait
2021-01-29 14:56:38 +08:00
Jianbo Sun
f39660c286 Merge pull request #953 from wonderflow/svcd
deprecate unused vela commands
2021-01-29 13:48:31 +08:00
Jianbo Sun
07e16d9f8a Merge pull request #967 from wonderflow/arm64
build linux/arm64 cli command
2021-01-29 13:47:27 +08:00
Jianbo Sun
2abcb44ee2 Merge pull request #937 from wonderflow/outputs
allow multiple outputs for workloaddefintion
2021-01-29 12:39:36 +08:00
天元
d2ce5856a6 adress comment 2021-01-29 12:38:23 +08:00
天元
bed609e192 build linux/arm64 cli command 2021-01-29 12:18:38 +08:00
天元
6922f7cfab fix ci 2021-01-29 11:39:44 +08:00
天元
aed2494875 allow multiple outputs for workloaddefintion 2021-01-29 11:39:44 +08:00
天元
10076f8516 trait name should not contain dummy when traitdefinition not found 2021-01-29 11:39:44 +08:00
Jianbo Sun
a8b4004e3b Merge pull request #965 from captainroy-hy/not-depend-defref
allow traitDefinition to omit definitionRef
2021-01-29 11:36:22 +08:00
Lei Zhang (Harry)
d1c93ed90c Update docs/en/platform-engineers/overview.md
Co-authored-by: Zheng Xi Zhou <zzxwill@gmail.com>
2021-01-28 19:22:08 -08:00
Jianbo Sun
a042b6b43d Merge pull request #963 from ryanzhang-oss/appDeployment-structure
further develop appDeployment controller
2021-01-29 11:19:59 +08:00
Jianbo Sun
130827629b Merge pull request #962 from allenhaozi/feat/update-del-app-prompt-msg
update delete app prompt information
2021-01-29 11:18:23 +08:00
mahao
82cdb615c0 update delete app prompt information
Signed-off-by: mahao <allenhaozi@gmail.com>
2021-01-29 11:00:44 +08:00
roy wang
7629399683 allow traitDefinition to omit definitionRef
Signed-off-by: roy wang <seiwy2010@gmail.com>
2021-01-29 11:31:03 +09:00
Ryan Zhang
ad496b132a further develop appDeployment controller 2021-01-28 17:59:31 -08:00
Harry Zhang
ef5d3c35c6 Explain KubeVela 2021-01-28 12:30:25 -08:00
Zheng Xi Zhou
2a943c9429 Using Terraform as IaC module in KubeVela (#863)
* Integrate Terraform into KubeVela

Integrated Terrafrom into KubeVela to enable it to deploy
infrastruce resouces by `vela up`

* extend Terraform modules/files as WorkloadDefinition

stop printing terraform log to console

Support one workload consumes two cloud services

Refactor Terraform plugin based on Application Object

add testcase

* refactor code per reviewer's comments

fix rebase issue

* find lost code back

* refactor code to make the modification as little as to that of branch master

* remove blank lines from imports
2021-01-28 18:36:52 +08:00
天元
52aed26b96 update docs 2021-01-28 15:21:04 +08:00
天元
61c256a97c remove unused dependency installation as we have reduce 3rd party dependency , they will be installed as capability from registry 2021-01-28 14:55:25 +08:00
天元
8dbad9e8c1 remove relevant test code 2021-01-28 14:54:09 +08:00
天元
3e8f0b3299 remove vela <trait> command 2021-01-28 14:45:55 +08:00
天元
c1a14a70f5 remove vela comp deploy 2021-01-28 14:41:41 +08:00
just-do1
0a6065d7d0 [#929] Modification to comand vela show WORKLOAD_TYPE or TRAIT (#948)
* [#929] Modification to comand vela show WORKLOAD_TYPE or TRAIT

* update the describetion of --web

* [#929] update --web describtion

* update the doc of check-ref-doc.md
2021-01-28 12:28:47 +08:00
Jianbo Sun
fa58501a97 remove 3rd party dependency from default installation (#946)
* remove 3rd party dependency from default installation

* fix CI
2021-01-27 18:29:42 -08:00
Zheng Xi Zhou
aa03e9c9d4 OpenAPI: Application creation based on Application object (#924)
* OpenAPI: Application creation based on Application object

Implemented Application creation OpenAPI based on new Application object
To #913

* fix e2e problems

* fix import issue
2021-01-28 10:15:26 +08:00
Jaime Zhang
4d00ad78ae #884 #830 complete the trait info when it is applied to * (#890)
* #884 complete the trait info when it is applied to *

* add unit test for trait print which applied to *

* code optimization

* code optimization to go standard

* summarize all 'applies to' content to *
2021-01-27 19:57:47 +08:00
Ryan Zhang
5b26575c16 Merge pull request #945 from wonderflow/charts
Upload vela core chart to alibaba cloud oss for every release and master commit
2021-01-27 01:24:13 -08:00
天元
cf60e72fe9 use the number version 2021-01-27 17:02:10 +08:00
天元
a2707395e9 force push to cloud 2021-01-27 16:37:16 +08:00
天元
a420785dc2 add repo url 2021-01-27 16:32:58 +08:00
天元
ccf47a2189 fix no config 2021-01-27 16:20:55 +08:00
天元
3d98b94fd8 upload charts to alibaba cloud oss bucket 2021-01-27 16:17:23 +08:00
Ryan Zhang
6adb91fb50 Merge pull request #940 from ryanzhang-oss/appDeployment
Add rollout annotation logic in application
2021-01-27 00:14:40 -08:00
Jianbo Sun
d27aa77753 Merge pull request #938 from wonderflow/updatedep
upgrade github.com/stretchr/testify try fix CI
2021-01-27 15:06:58 +08:00
Ryan Zhang
462be588af address comments and fix CI 2021-01-26 20:47:56 -08:00
Ryan Zhang
c85bbe1ae2 add rolling annotation to the application 2021-01-26 00:29:49 -08:00
Ryan Zhang
a257f6e60c application controller ignore annotation 2021-01-26 00:03:53 -08:00
Ryan Zhang
0e987a08b6 Merge pull request #934 from wonderflow/cert-manager
support vela install with helm args and make cert-manager optional
2021-01-25 23:35:56 -08:00
Jianbo Sun
206d343785 Merge pull request #927 from ryanzhang-oss/appdeployment-controller
some initial code for app deployment controller/webhook
2021-01-26 15:24:00 +08:00
天元
1cf1e6c064 upgrade github.com/stretchr/testify try fix CI 2021-01-26 15:00:43 +08:00
Jianbo Sun
c1f50d622b Merge pull request #936 from kqzh/master
fix condition err always nil
2021-01-26 14:49:29 +08:00
Ryan Zhang
e664831ff6 application deployment 2021-01-25 22:17:35 -08:00
kqzh
3a73221661 fix err always nil 2021-01-26 13:58:10 +08:00
Jianbo Sun
97f45ae859 code refactor (#935)
* code refactor

* update boilerplate.go.txt
2021-01-26 10:26:41 +08:00
天元
4cd9a70cfe support vela install with helm args and make cert-manager optional 2021-01-25 19:16:18 +08:00
Weiping Cai
75ecf2f301 support env and config storage driver (#850)
* support env and config storage driver

Signed-off-by: Weiping Cai <weiping.cai@daocloud.io>

* use driver.LocalDriverName to replace  str

Signed-off-by: Weiping Cai <weiping.cai@daocloud.io>
2021-01-25 16:26:42 +08:00
Hongchao Deng
77642f069a Merge pull request #926 from hongchaodeng/design-update
* update APIServer + Catalog design

- add application creation workflow
- make application adaptable to multiple env and clusters
- add module into catalog package format and adapt to helm/terraform
2021-01-24 19:32:23 -08:00
Hongchao Deng
2720028e2a comment 2021-01-24 19:11:36 -08:00
Jianbo Sun
72ee26dbb4 add advanced trait tutorial (#921)
* add advanced trait tutorial

* add more intersiting trait

* init container and patch

* add more traits

* node affinity

* addressing comment
2021-01-25 10:53:36 +08:00
Jianbo Sun
9173ff828f Merge pull request #930 from leejanee/dry-run
Add dry-run command
2021-01-23 12:28:03 +08:00
Hongchao Deng
62ec540fcf update 2021-01-22 13:35:54 -08:00
lj176172
f6a3ade584 lint 2021-01-22 19:17:49 +08:00
lj176172
be49ea092b application dry-run 2021-01-22 19:05:55 +08:00
Hongchao Deng
b173224212 update APIServer + Catalog design
- add application creation workflow
- make application adaptable to multiple env and clusters
- add module into catalog package format and adapt to helm/terraform
2021-01-22 00:24:30 -08:00
Jianbo Sun
c71eea7f90 Merge pull request #923 from zeed-w-beez/master
happy new year
2021-01-22 12:37:08 +08:00
zeed-w-beez
5b1a55b58b happy new year
Use variable-year in copyrights.
2021-01-22 11:25:21 +08:00
Zheng Xi Zhou
eba7049f39 Add Getdefinition OpenAPI in Restful-api docs (#917)
Added Getdefinition api docs and update email contact
2021-01-22 10:20:22 +08:00
Jianbo Sun
65706f401b Merge pull request #857 from captainroy-hy/refactor-apply
using 3-way-merge-patch instead of "json merge patch for workload" and "update for trait"
2021-01-21 18:42:00 +08:00
roywang
59a6ef5140 implement util/apply with three-way diff
add/fix unit tests

fix e2e tests

update doc & add unit test

Signed-off-by: roy wang <seiwy2010@gmail.com>
2021-01-21 18:05:29 +09:00
Jianbo Sun
1fcd4ca55e Merge pull request #920 from ryanzhang-oss/app-deployment-controller
refactor application controller
2021-01-21 16:52:00 +08:00
Ryan Zhang
d74dbb4fda refactor application controller 2021-01-21 00:34:04 -08:00
Jianbo Sun
b6edd4bc7e Merge pull request #916 from resouer/dev
Fix ref doc guide
2021-01-21 14:04:18 +08:00
Harry Zhang
879c6c8878 Fix ref doc guide 2021-01-20 21:22:49 -08:00
Hongchao Deng
c722f561b0 Merge pull request #901 from zzxwill/ref-docs
Add `Writing Appfile` based on capability references docs
2021-01-20 19:20:32 -08:00
Jianbo Sun
0b5052ad91 Merge pull request #912 from resouer/dev
Update the concept doc to reflect app crd
2021-01-21 10:52:04 +08:00
Jianbo Sun
4661297ca5 Merge pull request #902 from ryanzhang-oss/rollout-structure
Rollout code framework
2021-01-21 10:02:37 +08:00
Harry Zhang
87cc86dde2 Update the concept doc to reflect app crd 2021-01-20 17:33:20 -08:00
Ryan Zhang
adbe1f9368 add the rollout code framework 2021-01-20 13:08:00 -08:00
Zheng Xi Zhou
f0d8bd078b address comments
Co-authored-by: Jianbo Sun <wonderflow.sun@gmail.com>
2021-01-20 15:56:20 +08:00
zzxwill
78b86d84b6 Add Writing Appfile based on capability references docs
Introduced `vela show` with and without flag `--no-website`, and
official site to help setting properties for workload types and
traits.
2021-01-20 15:56:20 +08:00
Jianbo Sun
ba4374dc27 Merge pull request #900 from sunny0826/docs
update docs
2021-01-20 15:35:13 +08:00
guoxudong
806c396264 update docs 2021-01-20 13:37:43 +08:00
Jianbo Sun
721ca9ff92 Merge pull request #886 from zzxwill/ref-docs
Generate the reference doc for a workload type or trait in the local host website and in a table style on Cli console
2021-01-20 10:34:03 +08:00
Ryan Zhang
023d24d392 draft 2021-01-19 15:50:38 -08:00
zzxwill
a674174cda add more unittest 2021-01-19 21:56:26 +08:00
zzxwill
48f3ed94b7 convert configuration files to variables
open the exact reference doc link for a capability

add option `--no-website` to support display reference docs on console
2021-01-19 15:16:40 +08:00
Jianbo Sun
47f35e6d62 Merge pull request #861 from rain18/health
feature: add healthcheck policy for workload and trait by cue template
2021-01-19 13:23:58 +08:00
zhangrun.zr
f55dd467b9 feature: add healthcheck policy for workload and trait by cue template
Signed-off-by: zhangrun.zr <zhangrun.zr@alibaba-inc.com>
2021-01-19 13:03:05 +08:00
Ryan Zhang
7524aeee31 Merge pull request #852 from rain18/task
feature: add http task for application cue template
2021-01-18 20:11:59 -08:00
Hongchao Deng
cb368c2f8c roadmap: add template, rewrite 2020 winter, add 2021 spring (#891)
* roadmap: add template, rewrite 2020 winter, add 2021 spring

Signed-off-by: Hongchao Deng <hongchaodeng1@gmail.com>

* Update docs/en/roadmap/2020-12-roadmap.md

Co-authored-by: Zheng Xi Zhou <zzxwill@gmail.com>

* update

Signed-off-by: Hongchao Deng <hongchaodeng1@gmail.com>

Co-authored-by: Zheng Xi Zhou <zzxwill@gmail.com>
2021-01-19 09:57:27 +08:00
Jianbo Sun
64c560583e Merge pull request #894 from captainroy-hy/fix-unstable-ut-4
fix unstable unit test
2021-01-19 09:55:33 +08:00
roy wang
580056b209 fix unstable unit test
Signed-off-by: roy wang <seiwy2010@gmail.com>
2021-01-18 18:59:58 +09:00
zhangrun.zr
2706e63743 fix: use httptest instead of echo and rename context
Signed-off-by: zhangrun.zr <zhangrun.zr@alibaba-inc.com>
2021-01-18 15:52:22 +08:00
zzxwill
3546001bf6 Generate a local site to host all reference docs
By Cli `vela reference` to generate reference docs for all workload
types and traits, and host them in a local website.

To fix #880
2021-01-18 12:18:15 +08:00
Jianbo Sun
40aa97363e Merge pull request #787 from ryanzhang-oss/rollout
rollout CRD API Spec
2021-01-18 11:01:59 +08:00
Ryan Zhang
f6345534e6 fix field name 2021-01-15 19:19:32 -08:00
Ryan Zhang
df32d4b1ba update rollout CRD spec 2021-01-15 19:19:32 -08:00
zhangrun.zr
732d8f76d3 feature: add http task for application cue template
Signed-off-by: zhangrun.zr <zhangrun.zr@alibaba-inc.com>
2021-01-15 19:20:39 +08:00
440 changed files with 20948 additions and 11759 deletions

View File

@@ -5,6 +5,8 @@ on:
branches: [ master ]
pull_request:
branches: [master]
workflow_dispatch: {}
defaults:
run:
working-directory: ./dashboard

View File

@@ -1,56 +0,0 @@
name: Publish to Registry
on:
push:
branches:
- master
tags:
- "v*"
jobs:
update:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Get the version
id: get_version
run: |
VERSION=${GITHUB_REF#refs/tags/}
if [[ ${GITHUB_REF} == "refs/heads/master" ]]; then
VERSION=latest
fi
echo ::set-output name=VERSION::${VERSION}
- name: Get git revision
id: vars
shell: bash
run: |
echo "::set-output name=git_revision::$(git rev-parse --short HEAD)"
- name: Login ghcr.io
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.CR_PAT }}
- name: Login docker.io
uses: docker/login-action@v1
with:
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- uses: docker/build-push-action@v2
name: Build & Pushing
with:
context: .
file: Dockerfile
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 }}
tags: |-
ghcr.io/${{ github.repository }}/vela-core:${{ steps.get_version.outputs.VERSION }}
docker.io/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}

View File

@@ -7,7 +7,9 @@ on:
- release-*
workflow_dispatch: {}
pull_request:
branches: [master]
branches:
- master
- release-*
env:
# Common versions
@@ -62,11 +64,50 @@ jobs:
flags: unittests
name: codecov-umbrella
compatibility-test:
runs-on: ubuntu-20.04
steps:
- name: Set up Go 1.14
uses: actions/setup-go@v1
with:
go-version: ${{ env.GO_VERSION }}
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- name: Cache Go Dependencies
uses: actions/cache@v2
with:
path: .work/pkg
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-pkg-
- name: Install ginkgo
run: |
sudo apt-get install -y golang-ginkgo-dev
- name: Setup Kind Cluster
uses: engineerd/setup-kind@v0.5.0
with:
version: ${{ env.KIND_VERSION }}
- name: install Kubebuilder
uses: wonderflow/kubebuilder-action@v1.1
- name: Run Make compatibility-test
run: make compatibility-test
- name: Clean up testdata
run: make compatibility-testdata-cleanup
e2e-tests:
runs-on: aliyun
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v2
with:
submodules: true
- name: Setup Go
uses: actions/setup-go@v2
@@ -77,7 +118,7 @@ jobs:
run: |
go get -v -t -d ./...
- name: Setup Kind Cluster
- name: Setup Kind
uses: engineerd/setup-kind@v0.5.0
with:
version: ${{ env.KIND_VERSION }}
@@ -114,6 +155,29 @@ jobs:
- name: Run e2e tests
run: make e2e-test
- name: Cleanup image
if: ${{ always() }}
run: make image-cleanup
staticcheck:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: true
- name: Cache Go Dependencies
uses: actions/cache@v2
with:
path: .work/pkg
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
restore-keys: ${{ runner.os }}-pkg-
- name: Static Check
run: go run honnef.co/go/tools/cmd/staticcheck -- ./...
lint:
runs-on: ubuntu-20.04
@@ -164,4 +228,4 @@ jobs:
run: go install golang.org/x/tools/cmd/goimports && make fmt
- name: Check Diff
run: make check-diff
run: make check-diff

122
.github/workflows/registry.yml vendored Normal file
View File

@@ -0,0 +1,122 @@
name: Registry
on:
push:
branches:
- master
tags:
- "v*"
workflow_dispatch: {}
env:
BUCKET: kubevelacharts
ENDPOINT: oss-cn-hangzhou.aliyuncs.com
ACCESS_KEY: ${{ secrets.OSS_ACCESS_KEY }}
ACCESS_KEY_SECRET: ${{ secrets.OSS_ACCESS_KEY_SECRET }}
ARTIFACT_HUB_REPOSITORY_ID: ${{ secrets.ARTIFACT_HUB_REPOSITORY_ID }}
jobs:
publish-images:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Get the version
id: get_version
run: |
VERSION=${GITHUB_REF#refs/tags/}
if [[ ${GITHUB_REF} == "refs/heads/master" ]]; then
VERSION=latest
fi
echo ::set-output name=VERSION::${VERSION}
- name: Get git revision
id: vars
shell: bash
run: |
echo "::set-output name=git_revision::$(git rev-parse --short HEAD)"
- name: Login ghcr.io
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login docker.io
uses: docker/login-action@v1
with:
registry: docker.io
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- uses: docker/build-push-action@v2
name: Build & Pushing
with:
context: .
file: Dockerfile
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 }}
tags: |-
ghcr.io/${{ github.repository }}/vela-core:${{ steps.get_version.outputs.VERSION }}
docker.io/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
publish-charts:
env:
HELM_CHARTS_DIR: charts
HELM_CHART: charts/vela-core
LEGACY_HELM_CHART: legacy/charts/vela-core-legacy
LOCAL_OSS_DIRECTORY: .oss/
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@master
- name: Get the version
id: get_version
run: |
VERSION=${GITHUB_REF#refs/tags/}
if [[ ${GITHUB_REF} == "refs/heads/master" ]]; then
VERSION=latest
fi
echo ::set-output name=VERSION::${VERSION}
- name: Get git revision
id: vars
shell: bash
run: |
echo "::set-output name=git_revision::$(git rev-parse --short HEAD)"
- name: Install Helm
uses: azure/setup-helm@v1
with:
version: v3.4.0
- name: Prepare legacy chart
run: |
rsync -r $LEGACY_HELM_CHART $HELM_CHARTS_DIR
rsync -r $HELM_CHART/* $LEGACY_HELM_CHART --exclude=Chart.yaml --exclude=crds
- name: Tag helm chart image
run: |
version=${{ steps.get_version.outputs.VERSION }}
sed -i "s/latest/$version/g" $HELM_CHART/values.yaml
sed -i "s/latest/$version/g" $LEGACY_HELM_CHART/values.yaml
number=${version#"v"}
sed -i "s/0.1.0/$number/g" $HELM_CHART/Chart.yaml
sed -i "s/0.1.0/$number/g" $LEGACY_HELM_CHART/Chart.yaml
- name: Install ossutil
run: wget http://gosspublic.alicdn.com/ossutil/1.7.0/ossutil64 && chmod +x ossutil64 && mv ossutil64 ossutil
- name: Configure Alibaba Cloud OSSUTIL
run: ./ossutil --config-file .ossutilconfig config -i ${ACCESS_KEY} -k ${ACCESS_KEY_SECRET} -e ${ENDPOINT} -c .ossutilconfig
- name: sync cloud to local
run: ./ossutil --config-file .ossutilconfig sync oss://$BUCKET/core $LOCAL_OSS_DIRECTORY
- name: add artifacthub stuff to the repo
run: |
rsync docs/en/install.md $HELM_CHART/README.md
rsync docs/en/install.md $LEGACY_HELM_CHART/README.md
sed -i "s/ARTIFACT_HUB_REPOSITORY_ID/$ARTIFACT_HUB_REPOSITORY_ID/g" hack/artifacthub/artifacthub-repo.yml
rsync hack/artifacthub/artifacthub-repo.yml $LOCAL_OSS_DIRECTORY
- name: Package helm charts
run: |
helm package $HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm package $LEGACY_HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm repo index --url https://$BUCKET.$ENDPOINT/core $LOCAL_OSS_DIRECTORY
- name: sync local to cloud
run: ./ossutil --config-file .ossutilconfig sync $LOCAL_OSS_DIRECTORY oss://$BUCKET/core -f

View File

@@ -4,10 +4,10 @@ on:
push:
tags:
- "v*"
workflow_dispatch: {}
jobs:
build:
name: Build
publish-cli:
runs-on: ubuntu-latest
env:
VELA_VERSION: ${{ github.ref }}
@@ -41,58 +41,55 @@ jobs:
run: make cross-build
- name: Run compress binary
run: make compress
- name: Create Release
id: create_release
uses: actions/create-release@v1
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ github.ref }}
- name: Upload Linux tar.gz
- name: Get release
id: get_release
uses: bruceadams/get-release@v1.2.2
- name: Upload Linux amd64 tar.gz
uses: actions/upload-release-asset@v1.0.2
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./_bin/vela-linux-amd64.tar.gz
asset_name: vela-${{ steps.get_version.outputs.VERSION }}-linux-amd64.tar.gz
asset_content_type: binary/octet-stream
- name: Upload Linux zip
- name: Upload Linux amd64 zip
uses: actions/upload-release-asset@v1.0.2
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./_bin/vela-linux-amd64.zip
asset_name: vela-${{ steps.get_version.outputs.VERSION }}-linux-amd64.zip
asset_content_type: binary/octet-stream
- name: Upload MacOS tar.gz
uses: actions/upload-release-asset@v1.0.2
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./_bin/vela-darwin-amd64.tar.gz
asset_name: vela-${{ steps.get_version.outputs.VERSION }}-darwin-amd64.tar.gz
asset_content_type: binary/octet-stream
- name: Upload MacOS zip
uses: actions/upload-release-asset@v1.0.2
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./_bin/vela-darwin-amd64.zip
asset_name: vela-${{ steps.get_version.outputs.VERSION }}-darwin-amd64.zip
asset_content_type: binary/octet-stream
- name: Upload Windows tar.gz
uses: actions/upload-release-asset@v1.0.2
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./_bin/vela-windows-amd64.tar.gz
asset_name: vela-${{ steps.get_version.outputs.VERSION }}-windows-amd64.tar.gz
asset_content_type: binary/octet-stream
- name: Upload Windows zip
uses: actions/upload-release-asset@v1.0.2
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./_bin/vela-windows-amd64.zip
asset_name: vela-${{ steps.get_version.outputs.VERSION }}-windows-amd64.zip
asset_content_type: binary/octet-stream
- name: Upload Checksums
uses: actions/upload-release-asset@v1.0.2
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
upload_url: ${{ steps.get_release.outputs.upload_url }}
asset_path: ./_bin/sha256sums.txt
asset_name: sha256sums.txt
asset_content_type: text/plain

View File

@@ -74,7 +74,7 @@ make core-run
This command will run controller locally, it will use your local KubeConfig which means you need to have a k8s cluster
locally. If you don't have a one, we suggest that you could setup up a cluster with [kind](https://kind.sigs.k8s.io/).
When you're developing `vela-core`, make sure the controller installed by `vela install` is not running.
When you're developing `vela-core`, make sure the controller installed by helm chart is not running.
Otherwise, it will conflict with your local running controller.
You can check and uninstall it by using helm.

View File

@@ -37,12 +37,12 @@ endif
all: build
# Run tests
test: vet lint
test: vet lint staticcheck
go test -race -coverprofile=coverage.txt -covermode=atomic ./pkg/... ./cmd/...
@$(OK) unit-tests pass
# Build manager binary
build: fmt vet lint
build: fmt vet lint staticcheck
go run hack/chart/generate.go
go build -o bin/vela -ldflags ${LDFLAGS} cmd/vela/main.go
git checkout cmd/vela/fake/chart_source.go
@@ -74,7 +74,7 @@ generate-source:
cross-build:
go run hack/chart/generate.go
GO111MODULE=on CGO_ENABLED=0 $(GOX) -ldflags $(LDFLAGS) -parallel=3 -output="_bin/{{.OS}}-{{.Arch}}/vela" -osarch='$(TARGETS)' ./cmd/vela/
GO111MODULE=on CGO_ENABLED=0 $(GOX) -ldflags $(LDFLAGS) -parallel=2 -output="_bin/{{.OS}}-{{.Arch}}/vela" -osarch='$(TARGETS)' ./cmd/vela/
compress:
( \
@@ -102,10 +102,13 @@ fmt: goimports installcue
vet:
go vet ./...
staticcheck: staticchecktool
$(STATICCHECK) ./...
lint: golangci
$(GOLANGCILINT) run ./...
reviewable: manifests fmt vet lint
reviewable: manifests fmt vet lint staticcheck
go mod tidy
# Execute auto-gen code commands and ensure branch is clean.
@@ -122,7 +125,7 @@ docker-push:
docker push ${IMG}
e2e-setup:
bin/vela install --image-pull-policy IfNotPresent --image-repo vela-core-test --image-tag $(GIT_COMMIT)
bin/vela install --set installCertManager=true --image-pull-policy IfNotPresent --image-repo vela-core-test --image-tag $(GIT_COMMIT) --depend-check-wait 10s
ginkgo version
ginkgo -v -r e2e/setup
kubectl wait --for=condition=Ready pod -l app.kubernetes.io/name=vela-core,app.kubernetes.io/instance=kubevela -n vela-system --timeout=600s
@@ -141,11 +144,28 @@ e2e-test:
CGO_ENABLED=0 go test -timeout 1h -count=1 -v -tags 'integration' ./test/integration
@$(OK) tests pass
compatibility-test: vet lint staticcheck generate-compatibility-testdata
# Run compatibility test with old crd
COMPATIBILITY_TEST=TRUE go test -race ./pkg/...
@$(OK) compatibility-test pass
generate-compatibility-testdata:
mkdir -p ./test/compatibility-test/testdata
go run ./test/compatibility-test/convert/main.go ./charts/vela-core/crds ./test/compatibility-test/testdata
compatibility-testdata-cleanup:
rm -f ./test/compatibility-test/testdata/*
e2e-cleanup:
# Clean up
rm -rf ~/.vela
image-cleanup:
# Delete Docker image
ifneq ($(shell docker images -q vela-core-test:$(GIT_COMMIT)),)
docker image rm -f vela-core-test:$(GIT_COMMIT)
endif
# load docker image to the kind cluster
kind-load:
docker build -t vela-core-test:$(GIT_COMMIT) .
@@ -187,7 +207,7 @@ manifests:
go generate $(foreach t,pkg apis,./$(t)/...)
./hack/vela-templates/gen_definitions.sh
GOLANGCILINT_VERSION ?= v1.29.0
GOLANGCILINT_VERSION ?= v1.31.0
HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
HOSTARCH := $(shell uname -m)
ifeq ($(HOSTARCH),x86_64)
@@ -207,6 +227,19 @@ else
GOLANGCILINT=$(shell which golangci-lint)
endif
.PHONY: staticchecktool
staticchecktool:
ifeq (, $(shell which staticcheck))
@{ \
set -e ;\
echo 'installing honnef.co/go/tools/cmd/staticcheck ' ;\
GO111MODULE=off go get honnef.co/go/tools/cmd/staticcheck ;\
}
STATICCHECK=$(GOBIN)/staticcheck
else
STATICCHECK=$(shell which staticcheck)
endif
.PHONY: goimports
goimports:
ifeq (, $(shell which goimports))
@@ -233,7 +266,7 @@ endif
start-dashboard:
go run pkg/server/main/startAPIServer.go &
cd dashboard && yarn && yarn start && cd ..
cd dashboard && npm install && npm start && cd ..
swagger-gen:
$(GOBIN)/swag init -g server/route.go -d pkg/ -o pkg/server/docs/

View File

@@ -6,6 +6,7 @@
[![Releases](https://img.shields.io/github/release/oam-dev/kubevela/all.svg?style=flat-square)](https://github.com/oam-dev/kubevela/releases)
[![TODOs](https://img.shields.io/endpoint?url=https://api.tickgit.com/badge?repo=github.com/oam-dev/kubevela)](https://www.tickgit.com/browse?repo=github.com/oam-dev/kubevela)
[![Twitter](https://img.shields.io/twitter/url?style=social&url=https%3A%2F%2Ftwitter.com%2Foam_dev)](https://twitter.com/oam_dev)
[![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/kubevela)](https://artifacthub.io/packages/search?repo=kubevela)
![alt](docs/resources/KubeVela-03.png)

View File

@@ -17,21 +17,47 @@ limitations under the License.
package v1alpha2
import (
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
)
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// ApplicationDeploymentSpec defines the desired state of ApplicationDeployment
// ApplicationDeploymentSpec defines how to describe an upgrade between different application
type ApplicationDeploymentSpec struct {
// TODO add spec here
// TargetApplicationName contains the name of the application that we need to upgrade to.
// We assume that an application is immutable, thus the name alone is suffice
TargetApplicationName string `json:"targetApplicationName"`
// SourceApplicationName contains the name of the application that we need to upgrade from.
// it can be empty only when it's the first time to deploy the application
SourceApplicationName string `json:"sourceApplicationName,omitempty"`
// The list of component to upgrade in the application.
// We only support single component application so far
// TODO: (RZ) Support multiple components in an application
// +optional
ComponentList []string `json:"componentList,omitempty"`
// RolloutPlan is the details on how to rollout the resources
RolloutPlan v1alpha1.RolloutPlan `json:"rolloutPlan"`
// RevertOnDelete revert the rollout when the rollout CR is deleted, default is false
// It will remove the target application from the kubernetes
// +optional
RevertOnDelete *bool `json:"revertOnDelete,omitempty"`
}
// ApplicationDeploymentStatus defines the observed state of ApplicationDeployment
type ApplicationDeploymentStatus struct {
// TODO add status field here
runtimev1alpha1.ConditionedStatus `json:",inline"`
v1alpha1.RolloutStatus `json:",inline"`
// LastTargetApplicationName contains the name of the application that we upgraded to
// We will restart the rollout if this is not the same as the spec
LastTargetApplicationName string `json:"lastTargetApplicationName"`
// LastSourceApplicationName contains the name of the application that we need to upgrade from.
// We will restart the rollout if this is not the same as the spec
LastSourceApplicationName string `json:"lastSourceApplicationName,omitempty"`
}
// ApplicationDeployment is the Schema for the ApplicationDeployment API

View File

@@ -30,10 +30,14 @@ import (
type ApplicationPhase string
const (
// ApplicationRollingOut means the app is in the middle of rolling out
ApplicationRollingOut ApplicationPhase = "rollingOut"
// ApplicationRendering means the app is rendering
ApplicationRendering ApplicationPhase = "rendering"
// ApplicationRunning means the app finished rendering and applied result to the cluster
ApplicationRunning ApplicationPhase = "running"
// ApplicationHealthChecking means the app finished rendering and applied result to the cluster, but still unhealthy
ApplicationHealthChecking ApplicationPhase = "healthChecking"
)
// AppStatus defines the observed state of Application
@@ -47,6 +51,24 @@ type AppStatus struct {
// Components record the related Components created by Application Controller
Components []runtimev1alpha1.TypedReference `json:"components,omitempty"`
// Services record the status of the application services
Services []ApplicationComponentStatus `json:"services,omitempty"`
}
// ApplicationComponentStatus record the health status of App component
type ApplicationComponentStatus struct {
Name string `json:"name"`
Healthy bool `json:"healthy"`
Message string `json:"message,omitempty"`
Traits []ApplicationTraitStatus `json:"traits,omitempty"`
}
// ApplicationTraitStatus records the trait health status
type ApplicationTraitStatus struct {
Type string `json:"type"`
Healthy bool `json:"healthy"`
Message string `json:"message,omitempty"`
}
// ApplicationTrait defines the trait of application
@@ -99,3 +121,13 @@ type ApplicationList struct {
metav1.ListMeta `json:"metadata,omitempty"`
Items []Application `json:"items"`
}
// GetComponent get the component from the application based on its workload type
func (app *Application) GetComponent(workloadType string) *ApplicationComponent {
for _, c := range app.Spec.Components {
if c.WorkloadType == workloadType {
return &c
}
}
return nil
}

View File

@@ -0,0 +1,52 @@
package v1alpha2
import (
"reflect"
"testing"
)
func TestApplication_GetComponent(t *testing.T) {
ac1 := ApplicationComponent{
Name: "ac1",
WorkloadType: "type1",
}
ac2 := ApplicationComponent{
Name: "ac2",
WorkloadType: "type2",
}
tests := map[string]struct {
app *Application
componentName string
want *ApplicationComponent
}{
"test get one": {
app: &Application{
Spec: ApplicationSpec{
Components: []ApplicationComponent{
ac1, ac2,
},
},
},
componentName: ac1.WorkloadType,
want: &ac1,
},
"test get none": {
app: &Application{
Spec: ApplicationSpec{
Components: []ApplicationComponent{
ac2,
},
},
},
componentName: ac1.WorkloadType,
want: nil,
},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
if got := tt.app.GetComponent(tt.componentName); !reflect.DeepEqual(got, tt.want) {
t.Errorf("GetComponent() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -24,6 +24,20 @@ import (
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
)
// CUE defines the encapsulation in CUE format
type CUE struct {
// Template defines the abstraction template data of the capability, it will replace the old CUE template in extension field.
// Template is a required field if CUE is defined in Capability Definition.
Template string `json:"template"`
}
// Schematic defines the encapsulation of this capability(workload/trait/scope),
// the encapsulation can be defined in different ways, e.g. CUE/HCL(terraform)/KUBE(K8s Object)/HELM, etc...
type Schematic struct {
CUE *CUE `json:"cue,omitempty"`
// TODO(wonderflow): support HCL(terraform)/KUBE(K8s Object)/HELM here.
}
// A DefinitionReference refers to a CustomResourceDefinition by name.
type DefinitionReference struct {
// Name of the referenced CustomResourceDefinition.
@@ -64,12 +78,35 @@ type WorkloadDefinitionSpec struct {
// +optional
PodSpecPath string `json:"podSpecPath,omitempty"`
// Status defines the custom health policy and status message for workload
// +optional
Status *Status `json:"status,omitempty"`
// Template defines the abstraction template data of the workload, it will replace the old template in extension field.
// the data format depends on templateType, by default it's CUE
// +optional
Template string `json:"template,omitempty"`
// Schematic defines the data format and template of the encapsulation of the workload
// +optional
Schematic *Schematic `json:"schematic,omitempty"`
// Extension is used for extension needs by OAM platform builders
// +optional
// +kubebuilder:pruning:PreserveUnknownFields
Extension *runtime.RawExtension `json:"extension,omitempty"`
}
// Status defines the loop back status of the abstraction by using CUE template
type Status struct {
// CustomStatus defines the custom status message that could display to user
// +optional
CustomStatus string `json:"customStatus,omitempty"`
// HealthPolicy defines the health check policy for the abstraction
// +optional
HealthPolicy string `json:"healthPolicy,omitempty"`
}
// +kubebuilder:object:root=true
// A WorkloadDefinition registers a kind of Kubernetes custom resource as a
@@ -77,7 +114,7 @@ type WorkloadDefinitionSpec struct {
// is used to validate the schema of the workload when it is embedded in an OAM
// Component.
// +kubebuilder:printcolumn:JSONPath=".spec.definitionRef.name",name=DEFINITION-NAME,type=string
// +kubebuilder:resource:scope=Cluster,categories={crossplane,oam}
// +kubebuilder:resource:scope=Namespaced,categories={crossplane,oam}
type WorkloadDefinition struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -126,6 +163,14 @@ type TraitDefinitionSpec struct {
// +optional
ConflictsWith []string `json:"conflictsWith,omitempty"`
// Schematic defines the data format and template of the encapsulation of the trait
// +optional
Schematic *Schematic `json:"schematic,omitempty"`
// Status defines the custom health policy and status message for trait
// +optional
Status *Status `json:"status,omitempty"`
// Extension is used for extension needs by OAM platform builders
// +optional
// +kubebuilder:pruning:PreserveUnknownFields
@@ -139,7 +184,7 @@ type TraitDefinitionSpec struct {
// to validate the schema of the trait when it is embedded in an OAM
// ApplicationConfiguration.
// +kubebuilder:printcolumn:JSONPath=".spec.definitionRef.name",name=DEFINITION-NAME,type=string
// +kubebuilder:resource:scope=Cluster,categories={crossplane,oam}
// +kubebuilder:resource:scope=Namespaced,categories={crossplane,oam}
type TraitDefinition struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -181,7 +226,7 @@ type ScopeDefinitionSpec struct {
// to validate the schema of the scope when it is embedded in an OAM
// ApplicationConfiguration.
// +kubebuilder:printcolumn:JSONPath=".spec.definitionRef.name",name=DEFINITION-NAME,type=string
// +kubebuilder:resource:scope=Cluster,categories={crossplane,oam}
// +kubebuilder:resource:scope=Namespaced,categories={crossplane,oam}
type ScopeDefinition struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@@ -374,6 +419,16 @@ type WorkloadTrait struct {
// Message will allow controller to leave some additional information for this trait
Message string `json:"message,omitempty"`
// AppliedGeneration indicates the generation observed by the appConfig controller.
// The same field is also recorded in the annotations of traits.
// A trait is possible to be deleted from cluster after created.
// This field is useful to track the observed generation of traits after they are
// deleted.
AppliedGeneration int64 `json:"appliedGeneration,omitempty"`
// DependencyUnsatisfied notify does the trait has dependency unsatisfied
DependencyUnsatisfied bool `json:"dependencyUnsatisfied,omitempty"`
}
// A ScopeStatus represents the state of a scope.
@@ -401,6 +456,12 @@ type WorkloadStatus struct {
// ComponentRevisionName of current component
ComponentRevisionName string `json:"componentRevisionName,omitempty"`
// DependencyUnsatisfied notify does the workload has dependency unsatisfied
DependencyUnsatisfied bool `json:"dependencyUnsatisfied,omitempty"`
// AppliedComponentRevision indicates the applied component revision name of this workload
AppliedComponentRevision string `json:"appliedComponentRevision,omitempty"`
// Reference to a workload created by an ApplicationConfiguration.
Reference runtimev1alpha1.TypedReference `json:"workloadRef,omitempty"`

View File

@@ -109,6 +109,14 @@ var (
ApplicationKindVersionKind = SchemeGroupVersion.WithKind(ApplicationKind)
)
// Application type metadata.
var (
ApplicationDeploymentKind = reflect.TypeOf(ApplicationDeployment{}).Name()
ApplicationDeploymentGroupKind = schema.GroupKind{Group: Group, Kind: ApplicationDeploymentKind}.String()
ApplicationDeploymentKindAPIVersion = ApplicationKind + "." + SchemeGroupVersion.String()
ApplicationDeploymentKindVersionKind = SchemeGroupVersion.WithKind(ApplicationDeploymentKind)
)
func init() {
SchemeBuilder.Register(&WorkloadDefinition{}, &WorkloadDefinitionList{})
SchemeBuilder.Register(&TraitDefinition{}, &TraitDefinitionList{})

View File

@@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
Copyright 2020 The KubeVela Authors.
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.
@@ -34,6 +34,13 @@ func (in *AppStatus) DeepCopyInto(out *AppStatus) {
*out = make([]v1alpha1.TypedReference, len(*in))
copy(*out, *in)
}
if in.Services != nil {
in, out := &in.Services, &out.Services
*out = make([]ApplicationComponentStatus, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppStatus.
@@ -103,6 +110,26 @@ func (in *ApplicationComponent) DeepCopy() *ApplicationComponent {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ApplicationComponentStatus) DeepCopyInto(out *ApplicationComponentStatus) {
*out = *in
if in.Traits != nil {
in, out := &in.Traits, &out.Traits
*out = make([]ApplicationTraitStatus, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationComponentStatus.
func (in *ApplicationComponentStatus) DeepCopy() *ApplicationComponentStatus {
if in == nil {
return nil
}
out := new(ApplicationComponentStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ApplicationConfiguration) DeepCopyInto(out *ApplicationConfiguration) {
*out = *in
@@ -264,7 +291,7 @@ func (in *ApplicationDeployment) DeepCopyInto(out *ApplicationDeployment) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
out.Spec = in.Spec
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
@@ -321,6 +348,17 @@ func (in *ApplicationDeploymentList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ApplicationDeploymentSpec) DeepCopyInto(out *ApplicationDeploymentSpec) {
*out = *in
if in.ComponentList != nil {
in, out := &in.ComponentList, &out.ComponentList
*out = make([]string, len(*in))
copy(*out, *in)
}
in.RolloutPlan.DeepCopyInto(&out.RolloutPlan)
if in.RevertOnDelete != nil {
in, out := &in.RevertOnDelete, &out.RevertOnDelete
*out = new(bool)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationDeploymentSpec.
@@ -336,7 +374,7 @@ func (in *ApplicationDeploymentSpec) DeepCopy() *ApplicationDeploymentSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ApplicationDeploymentStatus) DeepCopyInto(out *ApplicationDeploymentStatus) {
*out = *in
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
in.RolloutStatus.DeepCopyInto(&out.RolloutStatus)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationDeploymentStatus.
@@ -419,6 +457,21 @@ func (in *ApplicationTrait) DeepCopy() *ApplicationTrait {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ApplicationTraitStatus) DeepCopyInto(out *ApplicationTraitStatus) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationTraitStatus.
func (in *ApplicationTraitStatus) DeepCopy() *ApplicationTraitStatus {
if in == nil {
return nil
}
out := new(ApplicationTraitStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CPUResources) DeepCopyInto(out *CPUResources) {
*out = *in
@@ -435,6 +488,21 @@ func (in *CPUResources) DeepCopy() *CPUResources {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CUE) DeepCopyInto(out *CUE) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CUE.
func (in *CUE) DeepCopy() *CUE {
if in == nil {
return nil
}
out := new(CUE)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ChildResourceKind) DeepCopyInto(out *ChildResourceKind) {
*out = *in
@@ -1503,6 +1571,26 @@ func (in *Revision) DeepCopy() *Revision {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Schematic) DeepCopyInto(out *Schematic) {
*out = *in
if in.CUE != nil {
in, out := &in.CUE, &out.CUE
*out = new(CUE)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Schematic.
func (in *Schematic) DeepCopy() *Schematic {
if in == nil {
return nil
}
out := new(Schematic)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ScopeDefinition) DeepCopyInto(out *ScopeDefinition) {
*out = *in
@@ -1612,6 +1700,21 @@ func (in *SecretKeySelector) DeepCopy() *SecretKeySelector {
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Status) DeepCopyInto(out *Status) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Status.
func (in *Status) DeepCopy() *Status {
if in == nil {
return nil
}
out := new(Status)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TCPSocketProbe) DeepCopyInto(out *TCPSocketProbe) {
*out = *in
@@ -1699,6 +1802,16 @@ func (in *TraitDefinitionSpec) DeepCopyInto(out *TraitDefinitionSpec) {
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.Schematic != nil {
in, out := &in.Schematic, &out.Schematic
*out = new(Schematic)
(*in).DeepCopyInto(*out)
}
if in.Status != nil {
in, out := &in.Status, &out.Status
*out = new(Status)
**out = **in
}
if in.Extension != nil {
in, out := &in.Extension, &out.Extension
*out = new(runtime.RawExtension)
@@ -1847,6 +1960,16 @@ func (in *WorkloadDefinitionSpec) DeepCopyInto(out *WorkloadDefinitionSpec) {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Status != nil {
in, out := &in.Status, &out.Status
*out = new(Status)
**out = **in
}
if in.Schematic != nil {
in, out := &in.Schematic, &out.Schematic
*out = new(Schematic)
(*in).DeepCopyInto(*out)
}
if in.Extension != nil {
in, out := &in.Extension, &out.Extension
*out = new(runtime.RawExtension)

View File

@@ -12,7 +12,7 @@
//go:generate go run -tags generate sigs.k8s.io/controller-tools/cmd/controller-gen object:headerFile=../hack/boilerplate.go.txt paths=./... crd:trivialVersions=true output:artifacts:config=../legacy/charts/vela-core-legacy/crds
//go:generate go run ../legacy/convert/main.go ../legacy/charts/vela-core-legacy/crds
//go:generate go run ../hack/crd/update.go ../charts/vela-core/crds/
//go:generate go run ../hack/crd/update.go ../charts/vela-core/crds/standard.oam.dev_podspecworkloads.yaml
package apis

View File

@@ -1,122 +0,0 @@
/*
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 (
"github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// Protocol defines network protocols supported for things like container ports.
type Protocol string
// TriggerType defines the type of trigger
type TriggerType string
// Autoscaler is the Schema for the autoscalers API
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories={oam}
type Autoscaler struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec AutoscalerSpec `json:"spec"`
Status AutoscalerStatus `json:"status,omitempty"`
}
// SetConditions set condition for CR status
func (as *Autoscaler) SetConditions(c ...v1alpha1.Condition) {
as.Status.SetConditions(c...)
}
// GetCondition get condition from CR status
func (as *Autoscaler) GetCondition(conditionType v1alpha1.ConditionType) v1alpha1.Condition {
return as.Status.GetCondition(conditionType)
}
// GetWorkloadReference get workload reference
func (as *Autoscaler) GetWorkloadReference() v1alpha1.TypedReference {
return as.Spec.WorkloadReference
}
// SetWorkloadReference set workload reference
func (as *Autoscaler) SetWorkloadReference(reference v1alpha1.TypedReference) {
as.Spec.WorkloadReference = reference
}
// Trigger defines the trigger of Autoscaler
type Trigger struct {
// Name is the trigger name, if not set, it will be automatically generated and make it globally unique
Name string `json:"name,omitempty"`
// Type allows value in [cpu/memory/storage/ephemeral-storage、cron、pps、qps/rps、custom]
Type TriggerType `json:"type"`
// Condition set the condition when to trigger scaling
Condition map[string]string `json:"condition"`
}
// AutoscalerSpec defines the desired state of Autoscaler
type AutoscalerSpec struct {
// MinReplicas is the minimal replicas
// +optional
MinReplicas *int32 `json:"minReplicas,omitempty"`
// MinReplicas is the maximal replicas
// +optional
MaxReplicas *int32 `json:"maxReplicas,omitempty"`
// Triggers lists all triggers
Triggers []Trigger `json:"triggers"`
// TargetWorkload specify the workload which is going to be scaled,
// it could be WorkloadReference or the child resource of it
TargetWorkload TargetWorkload `json:"targetWorkload,omitempty"`
// WorkloadReference marks the owner of the workload
WorkloadReference runtimev1alpha1.TypedReference `json:"workloadRef,omitempty"`
}
// TargetWorkload holds the a reference to the scale target Object
type TargetWorkload struct {
Name string `json:"name"`
// +optional
APIVersion string `json:"apiVersion,omitempty"`
// +optional
Kind string `json:"kind,omitempty"`
}
// AutoscalerStatus defines the observed state of Autoscaler
type AutoscalerStatus struct {
runtimev1alpha1.ConditionedStatus `json:",inline"`
}
// +kubebuilder:object:root=true
// AutoscalerList contains a list of Autoscaler
type AutoscalerList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Autoscaler `json:"items"`
}
func init() {
SchemeBuilder.Register(&Autoscaler{}, &AutoscalerList{})
}

View File

@@ -24,9 +24,16 @@ import (
"sigs.k8s.io/controller-runtime/pkg/scheme"
)
const (
// GroupName of the CRDs
GroupName = "standard.oam.dev"
// Version of the group of CRDs
Version = "v1alpha1"
)
var (
// SchemeGroupVersion is group version used to register these objects
SchemeGroupVersion = schema.GroupVersion{Group: "standard.oam.dev", Version: "v1alpha1"}
SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: Version}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}

View File

@@ -1,121 +0,0 @@
/*
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 (
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"github.com/oam-dev/kubevela/pkg/oam"
)
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// MetricsTraitSpec defines the desired state of MetricsTrait
type MetricsTraitSpec struct {
// An endpoint to be monitored by a ServiceMonitor.
ScrapeService ScapeServiceEndPoint `json:"scrapeService"`
// WorkloadReference to the workload whose metrics needs to be exposed
WorkloadReference runtimev1alpha1.TypedReference `json:"workloadRef,omitempty"`
}
// ScapeServiceEndPoint defines a scrapeable endpoint serving Prometheus metrics.
type ScapeServiceEndPoint struct {
// The format of the metrics data,
// The default and only supported format is "prometheus" for now
Format string `json:"format,omitempty"`
// Number or name of the port to access on the pods targeted by the service.
// The default is discovered automatically from podTemplate, metricTrait will create a service for the workload
TargetPort intstr.IntOrString `json:"port,omitempty"`
// Route service traffic to pods with label keys and values matching this
// The default is discovered automatically from podTemplate.
// If no podTemplate, use the labels specified here, or use the labels of the workload
TargetSelector map[string]string `json:"selector,omitempty"`
// HTTP path to scrape for metrics.
// default is /metrics
// +optional
Path string `json:"path,omitempty"`
// Scheme at which metrics should be scraped
// The default and only supported scheme is "http"
// +optional
Scheme string `json:"scheme,omitempty"`
// The default is true
// +optional
Enabled *bool `json:"enabled,omitempty"`
}
// MetricsTraitStatus defines the observed state of MetricsTrait
type MetricsTraitStatus struct {
runtimev1alpha1.ConditionedStatus `json:",inline"`
// ServiceMonitorName managed by this trait
ServiceMonitorName string `json:"serviceMonitorName,omitempty"`
// Port is the real port monitoring
Port intstr.IntOrString `json:"port,omitempty"`
// SelectorLabels is the real labels selected
SelectorLabels map[string]string `json:"selectorLabels,omitempty"`
}
// +kubebuilder:object:root=true
// MetricsTrait is the Schema for the metricstraits API
// +kubebuilder:resource:categories={oam}
// +kubebuilder:subresource:status
type MetricsTrait struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec MetricsTraitSpec `json:"spec"`
Status MetricsTraitStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// MetricsTraitList contains a list of MetricsTrait
type MetricsTraitList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []MetricsTrait `json:"items"`
}
func init() {
SchemeBuilder.Register(&MetricsTrait{}, &MetricsTraitList{})
}
var _ oam.Trait = &MetricsTrait{}
// SetConditions for set CR condition
func (tr *MetricsTrait) SetConditions(c ...runtimev1alpha1.Condition) {
tr.Status.SetConditions(c...)
}
// GetCondition for get CR condition
func (tr *MetricsTrait) GetCondition(c runtimev1alpha1.ConditionType) runtimev1alpha1.Condition {
return tr.Status.GetCondition(c)
}
// GetWorkloadReference of this MetricsTrait.
func (tr *MetricsTrait) GetWorkloadReference() runtimev1alpha1.TypedReference {
return tr.Spec.WorkloadReference
}
// SetWorkloadReference of this MetricsTrait.
func (tr *MetricsTrait) SetWorkloadReference(r runtimev1alpha1.TypedReference) {
tr.Spec.WorkloadReference = r
}

View File

@@ -0,0 +1,242 @@
package v1alpha1
import (
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
"k8s.io/apimachinery/pkg/util/intstr"
)
// RolloutStrategyType defines strategies for pods rollout
type RolloutStrategyType string
const (
// IncreaseFirstRolloutStrategyType indicates that we increase the target resources first
IncreaseFirstRolloutStrategyType RolloutStrategyType = "IncreaseFirst"
// DecreaseFirstRolloutStrategyType indicates that we decrease the source resources first
DecreaseFirstRolloutStrategyType RolloutStrategyType = "DecreaseFirst"
)
// HookType can be pre, post or during rollout
type HookType string
const (
// InitializeRolloutHook execute webhook during the rollout initializing phase
InitializeRolloutHook HookType = "initialize-rollout"
// PreBatchRolloutHook execute webhook before each batch rollout
PreBatchRolloutHook HookType = "pre-batch-rollout"
// PostBatchRolloutHook execute webhook after each batch rollout
PostBatchRolloutHook HookType = "post-batch-rollout"
// FinalizeRolloutHook execute the webhook during the rollout finalizing phase
FinalizeRolloutHook HookType = "finalize-rollout"
)
// RollingState is the overall rollout state
type RollingState string
const (
// VerifyingState verify that the rollout setting is valid and the controller can locate both the
// target and the source
VerifyingState RollingState = "verifying"
// InitializingState rollout is initializing all the new resources
InitializingState RollingState = "initializing"
// RollingInBatchesState rolling out
RollingInBatchesState RollingState = "rollingInBatches"
// FinalisingState finalize the rolling, possibly clean up the old resources, adjust traffic
FinalisingState RollingState = "finalising"
// RolloutSucceedState rollout successfully completed to match the desired target state
RolloutSucceedState RollingState = "rolloutSucceed"
// RolloutFailedState rollout is failed, the target replica is not reached
// we can not move forward anymore
// we will let the client to decide when or whether to revert
RolloutFailedState RollingState = "rolloutFailed"
)
// BatchRollingState is the sub state when the rollout is on the fly
type BatchRollingState string
const (
// BatchInitializingState still rolling the batch, the batch rolling is not completed yet
BatchInitializingState BatchRollingState = "batchInitializing"
// BatchInRollingState still rolling the batch, the batch rolling is not completed yet
BatchInRollingState BatchRollingState = "batchInRolling"
// BatchVerifyingState verifying if the application is ready to roll.
BatchVerifyingState BatchRollingState = "batchVerifying"
// BatchRolloutFailedState indicates that the batch didn't get the manual or automatic approval
BatchRolloutFailedState BatchRollingState = "batchVerifyFailed"
// BatchFinalizingState indicates that all the pods in the are available, we can move on to the next batch
BatchFinalizingState BatchRollingState = "batchFinalizing"
// BatchReadyState indicates that all the pods in the are upgraded and its state is ready
BatchReadyState BatchRollingState = "batchReady"
)
// RolloutPlan fines the details of the rollout plan
type RolloutPlan struct {
// RolloutStrategy defines strategies for the rollout plan
// +optional
RolloutStrategy *RolloutStrategyType `json:"rolloutStrategy,omitempty"`
// The size of the target resource. The default is the same
// as the size of the source resource.
// +optional
TargetSize *int32 `json:"targetSize,omitempty"`
// The number of batches, default = 1
// mutually exclusive to RolloutBatches
// +optional
NumBatches *int32 `json:"numBatches,omitempty"`
// The exact distribution among batches.
// mutually exclusive to NumBatches.
// The total number cannot exceed the targetSize or the size of the source resource
// We will IGNORE the last batch's replica field if it's a percentage since round errors can lead to inaccurate sum
// We highly recommend to leave the last batch's replica field empty
// +optional
RolloutBatches []RolloutBatch `json:"rolloutBatches,omitempty"`
// All pods in the batches up to the batchPartition (included) will have
// the target resource specification while the rest still have the source resource
// This is designed for the operators to manually rollout
// Default is the the number of batches which will rollout all the batches
// +optional
BatchPartition *int32 `json:"lastBatchToRollout,omitempty"`
// Paused the rollout, default is false
// +optional
Paused bool `json:"paused,omitempty"`
// RolloutWebhooks provide a way for the rollout to interact with an external process
// +optional
RolloutWebhooks []RolloutWebhook `json:"rolloutWebhooks,omitempty"`
// CanaryMetric provides a way for the rollout process to automatically check certain metrics
// before complete the process
// +optional
CanaryMetric []CanaryMetric `json:"canaryMetric,omitempty"`
}
// RolloutBatch is used to describe how the each batch rollout should be
type RolloutBatch struct {
// Replicas is the number of pods to upgrade in this batch
// it can be an absolute number (ex: 5) or a percentage of total pods
// we will ignore the percentage of the last batch to just fill the gap
// +optional
// it is mutually exclusive with the PodList field
Replicas intstr.IntOrString `json:"replicas,omitempty"`
// The list of Pods to get upgraded
// +optional
// it is mutually exclusive with the Replicas field
PodList []string `json:"podList,omitempty"`
// MaxUnavailable is the max allowed number of pods that is unavailable
// during the upgrade. We will mark the batch as ready as long as there are less
// or equal number of pods unavailable than this number.
// default = 0
// +optional
MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty"`
// The wait time, in seconds, between instances upgrades, default = 0
// +optional
InstanceInterval *int32 `json:"instanceInterval,omitempty"`
// RolloutWebhooks provides a way for the batch rollout to interact with an external process
// +optional
BatchRolloutWebhooks []RolloutWebhook `json:"batchRolloutWebhooks,omitempty"`
// CanaryMetric provides a way for the batch rollout process to automatically check certain metrics
// before moving to the next batch
// +optional
CanaryMetric []CanaryMetric `json:"canaryMetric,omitempty"`
}
// RolloutWebhook holds the reference to external checks used for canary analysis
type RolloutWebhook struct {
// Type of this webhook
Type HookType `json:"type"`
// Name of this webhook
Name string `json:"name"`
// URL address of this webhook
URL string `json:"url"`
// Request timeout for this webhook
Timeout string `json:"timeout,omitempty"`
// Metadata (key-value pairs) for this webhook
// +optional
Metadata *map[string]string `json:"metadata,omitempty"`
}
// RolloutWebhookPayload holds the info and metadata sent to webhooks
type RolloutWebhookPayload struct {
// ResourceRef refers to the resource we are operating on
ResourceRef *runtimev1alpha1.TypedReference `json:"resourceRef"`
// RolloutRef refers to the rollout that is controlling the rollout
RolloutRef *runtimev1alpha1.TypedReference `json:"rolloutRef"`
// Metadata (key-value pairs) are the extra data send to this webhook
Metadata map[string]string `json:"metadata,omitempty"`
}
// CanaryMetric holds the reference to metrics used for canary analysis
type CanaryMetric struct {
// Name of the metric
Name string `json:"name"`
// Interval represents the windows size
Interval string `json:"interval,omitempty"`
// Range value accepted for this metric
// +optional
MetricsRange *MetricsExpectedRange `json:"metricsRange,omitempty"`
// TemplateRef references a metric template object
// +optional
TemplateRef *runtimev1alpha1.TypedReference `json:"templateRef,omitempty"`
}
// MetricsExpectedRange defines the range used for metrics validation
type MetricsExpectedRange struct {
// Minimum value
// +optional
Min *intstr.IntOrString `json:"min,omitempty"`
// Maximum value
// +optional
Max *intstr.IntOrString `json:"max,omitempty"`
}
// RolloutStatus defines the observed state of a rollout plan
type RolloutStatus struct {
// Conditions represents the latest available observations of a CloneSet's current state.
runtimev1alpha1.ConditionedStatus `json:",inline"`
// NewPodTemplateIdentifier is a string that uniquely represent the new pod template
// each workload type could use different ways to identify that so we cannot compare between resources
NewPodTemplateIdentifier string `json:"targetGeneration,omitempty"`
// lastAppliedPodTemplateIdentifier is a string that uniquely represent the last pod template
// each workload type could use different ways to identify that so we cannot compare between resources
// We update this field only after a successful rollout
LastAppliedPodTemplateIdentifier string `json:"lastAppliedPodTemplateIdentifier,omitempty"`
// RollingState is the Rollout State
RollingState RollingState `json:"rollingState"`
// BatchRollingState only meaningful when the Status is rolling
// +optional
BatchRollingState BatchRollingState `json:"batchRollingState"`
// The current batch the rollout is working on/blocked
// it starts from 0
CurrentBatch int32 `json:"currentBatch"`
// UpgradedReplicas is the number of Pods upgraded by the rollout controller
UpgradedReplicas int32 `json:"upgradedReplicas"`
// UpgradedReplicas is the number of Pods upgraded by the rollout controller that have a Ready Condition.
UpgradedReadyReplicas int32 `json:"upgradedReadyReplicas"`
}

View File

@@ -0,0 +1,298 @@
package v1alpha1
import (
"fmt"
"time"
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
)
// RolloutEvent is used to describe the events during rollout
type RolloutEvent string
const (
// RollingFailedEvent indicates that we encountered an unexpected error during upgrading and can't be retried
RollingFailedEvent RolloutEvent = "RollingFailedEvent"
// RollingRetriableFailureEvent indicates that we encountered an unexpected but retriable error
RollingRetriableFailureEvent RolloutEvent = "RollingRetriableFailureEvent"
// RollingSpecVerifiedEvent indicates that we have successfully verified that the rollout spec
RollingSpecVerifiedEvent RolloutEvent = "RollingSpecVerifiedEvent"
// RollingInitializedEvent indicates that we have finished initializing all the workload resources
RollingInitializedEvent RolloutEvent = "RollingInitializedEvent"
// AllBatchFinishedEvent indicates that all batches are upgraded
AllBatchFinishedEvent RolloutEvent = "AllBatchFinishedEvent"
// RollingFinalizedEvent indicates that we have finalized the rollout which includes but not
// limited to the resource garbage collection
RollingFinalizedEvent RolloutEvent = "AllBatchFinishedEvent"
// InitializedOneBatchEvent indicates that we have successfully rolled out one batch
InitializedOneBatchEvent RolloutEvent = "InitializedOneBatchEvent"
// FinishedOneBatchEvent indicates that we have successfully rolled out one batch
FinishedOneBatchEvent RolloutEvent = "FinishedOneBatchEvent"
// BatchRolloutContinueEvent indicates that we need to continue to upgrade the pods in the batch
BatchRolloutContinueEvent RolloutEvent = "BatchRolloutContinueEvent"
// BatchRolloutVerifyingEvent indicates that we are waiting for the approval of resume one batch
BatchRolloutVerifyingEvent RolloutEvent = "BatchRolloutVerifyingEvent"
// OneBatchAvailableEvent indicates that the batch resource is considered available
// this events comes after we have examine the pod readiness check and traffic shifting if needed
OneBatchAvailableEvent RolloutEvent = "OneBatchAvailable"
// BatchRolloutApprovedEvent indicates that we got the approval manually
BatchRolloutApprovedEvent RolloutEvent = "BatchRolloutApprovedEvent"
// BatchRolloutFailedEvent indicates that we are waiting for the approval of the
BatchRolloutFailedEvent RolloutEvent = "BatchRolloutFailedEvent"
// WorkloadModifiedEvent indicates that the res
WorkloadModifiedEvent RolloutEvent = "WorkloadModifiedEvent"
)
// These are valid conditions of the rollout.
const (
// RolloutSpecVerified indicates that the rollout spec matches the resource we have in the cluster
RolloutSpecVerified runtimev1alpha1.ConditionType = "RolloutSpecVerified"
// RolloutInitialized means all the needed initialization work is done
RolloutInitialized runtimev1alpha1.ConditionType = "Initialized"
// RolloutInProgress means we are upgrading resources.
RolloutInProgress runtimev1alpha1.ConditionType = "Ready"
// RolloutSucceed means that the rollout is done.
RolloutSucceed runtimev1alpha1.ConditionType = "Succeed"
// BatchInitialized
BatchInitialized runtimev1alpha1.ConditionType = "BatchInitialized"
// BatchInRolled
BatchInRolled runtimev1alpha1.ConditionType = "BatchInRolled"
// BatchVerified
BatchVerified runtimev1alpha1.ConditionType = "BatchVerified"
// BatchRolloutFailed
BatchRolloutFailed runtimev1alpha1.ConditionType = "BatchRolloutFailed"
// BatchFinalized
BatchFinalized runtimev1alpha1.ConditionType = "BatchFinalized"
// BatchReady
BatchReady runtimev1alpha1.ConditionType = "BatchReady"
)
// NewPositiveCondition creates a positive condition type
func NewPositiveCondition(condType runtimev1alpha1.ConditionType) runtimev1alpha1.Condition {
return runtimev1alpha1.Condition{
Type: condType,
Status: v1.ConditionTrue,
LastTransitionTime: metav1.NewTime(time.Now()),
}
}
// NewNegativeCondition creates a false condition type
func NewNegativeCondition(condType runtimev1alpha1.ConditionType, message string) runtimev1alpha1.Condition {
return runtimev1alpha1.Condition{
Type: condType,
Status: v1.ConditionFalse,
LastTransitionTime: metav1.NewTime(time.Now()),
Message: message,
}
}
const invalidRollingStateTransition = "the rollout state transition from `%s` state with `%s` is invalid"
const invalidBatchRollingStateTransition = "the batch rolling state transition from `%s` state with `%s` is invalid"
func (r *RolloutStatus) getRolloutConditionType() runtimev1alpha1.ConditionType {
// figure out which condition type should we put in the condition depends on its state
switch r.RollingState {
case VerifyingState:
return RolloutSpecVerified
case InitializingState:
return RolloutInitialized
case RollingInBatchesState:
switch r.BatchRollingState {
case BatchInitializingState:
return BatchInitialized
case BatchVerifyingState:
return BatchVerified
case BatchFinalizingState:
return BatchFinalized
case BatchReadyState:
return BatchReady
default:
return RolloutInProgress
}
case FinalisingState:
return RolloutSucceed
default:
return RolloutSucceed
}
}
// RolloutRetry is a special state transition since we need an error message
func (r *RolloutStatus) RolloutRetry(reason string) {
// we can still retry, no change on the state
r.SetConditions(NewNegativeCondition(r.getRolloutConditionType(), reason))
}
// RolloutFailed is a special state transition since we need an error message
func (r *RolloutStatus) RolloutFailed(reason string) {
// set the condition first which depends on the state
r.SetConditions(NewNegativeCondition(r.getRolloutConditionType(), reason))
r.RollingState = RolloutFailedState
}
// StateTransition is the center place to do rollout state transition
// it returns an error if the transition is invalid
// it changes the coming rollout state if it's valid
func (r *RolloutStatus) StateTransition(event RolloutEvent) {
rollingState := r.RollingState
batchRollingState := r.BatchRollingState
defer klog.InfoS("try to execute a rollout state transition",
"pre rolling state", rollingState,
"pre batch rolling state", batchRollingState,
"post rolling state", r.RollingState,
"post batch rolling state", r.BatchRollingState)
// we have special transition for these two types of event
if event == RollingFailedEvent || event == RollingRetriableFailureEvent {
panic(fmt.Errorf(invalidRollingStateTransition, rollingState, event))
}
switch rollingState {
case VerifyingState:
if event == RollingSpecVerifiedEvent {
r.RollingState = InitializingState
r.SetConditions(NewPositiveCondition(r.getRolloutConditionType()))
return
}
panic(fmt.Errorf(invalidRollingStateTransition, rollingState, event))
case InitializingState:
if event == RollingInitializedEvent {
r.RollingState = RollingInBatchesState
r.SetConditions(NewPositiveCondition(r.getRolloutConditionType()))
return
}
panic(fmt.Errorf(invalidRollingStateTransition, rollingState, event))
case RollingInBatchesState:
r.batchStateTransition(event)
return
case FinalisingState:
if event == RollingFinalizedEvent {
r.RollingState = RolloutSucceedState
r.SetConditions(NewPositiveCondition(r.getRolloutConditionType()))
return
}
panic(fmt.Errorf(invalidRollingStateTransition, rollingState, event))
case RolloutSucceedState:
if event == WorkloadModifiedEvent {
r.RollingState = VerifyingState
r.SetConditions(NewPositiveCondition(r.getRolloutConditionType()))
return
}
if event == RollingFinalizedEvent {
// no op
return
}
panic(fmt.Errorf(invalidRollingStateTransition, rollingState, event))
case RolloutFailedState:
if event == WorkloadModifiedEvent {
r.RollingState = VerifyingState
r.SetConditions(NewPositiveCondition(r.getRolloutConditionType()))
return
}
if event == RollingFailedEvent {
// no op
return
}
panic(fmt.Errorf(invalidRollingStateTransition, rollingState, event))
default:
panic(fmt.Errorf("invalid rolling state %s", rollingState))
}
}
// batchStateTransition handles the state transition when the rollout is in action
func (r *RolloutStatus) batchStateTransition(event RolloutEvent) {
batchRollingState := r.BatchRollingState
if event == BatchRolloutFailedEvent {
r.BatchRollingState = BatchRolloutFailedState
r.RollingState = RolloutFailedState
r.SetConditions(NewNegativeCondition(r.getRolloutConditionType(), "failed"))
return
}
switch batchRollingState {
case BatchInitializingState:
if event == InitializedOneBatchEvent {
r.BatchRollingState = BatchInRollingState
return
}
panic(fmt.Errorf(invalidBatchRollingStateTransition, batchRollingState, event))
case BatchInRollingState:
if event == BatchRolloutContinueEvent {
// no op
return
}
if event == BatchRolloutVerifyingEvent {
r.BatchRollingState = BatchVerifyingState
r.SetConditions(NewPositiveCondition(r.getRolloutConditionType()))
return
}
panic(fmt.Errorf(invalidBatchRollingStateTransition, batchRollingState, event))
case BatchVerifyingState:
if event == OneBatchAvailableEvent {
r.BatchRollingState = BatchFinalizingState
r.SetConditions(NewPositiveCondition(r.getRolloutConditionType()))
return
}
if event == BatchRolloutVerifyingEvent {
// no op
return
}
panic(fmt.Errorf(invalidBatchRollingStateTransition, batchRollingState, event))
case BatchFinalizingState:
if event == FinishedOneBatchEvent {
r.BatchRollingState = BatchReadyState
r.SetConditions(NewPositiveCondition(r.getRolloutConditionType()))
return
}
if event == AllBatchFinishedEvent {
// transition out of the batch loop
r.RollingState = FinalisingState
r.SetConditions(NewPositiveCondition(r.getRolloutConditionType()))
return
}
panic(fmt.Errorf(invalidBatchRollingStateTransition, batchRollingState, event))
case BatchReadyState:
if event == BatchRolloutApprovedEvent {
r.BatchRollingState = BatchInitializingState
r.SetConditions(NewPositiveCondition(r.getRolloutConditionType()))
return
}
panic(fmt.Errorf(invalidBatchRollingStateTransition, batchRollingState, event))
default:
panic(fmt.Errorf("invalid batch rolling state %s", batchRollingState))
}
}

View File

@@ -0,0 +1,71 @@
package v1alpha1
import (
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/oam-dev/kubevela/pkg/oam"
)
// RolloutTraitSpec defines the desired state of RolloutTrait
type RolloutTraitSpec struct {
// TargetRef references a target resource that contains the newer version
// of the software. We assumed that new resource already exists.
// This is the only resource we work on if the resource is a stateful resource (cloneset/statefulset)
TargetRef runtimev1alpha1.TypedReference `json:"targetRef"`
// SourceRef references the list of resources that contains the older version
// of the software. We assume that it's the first time to deploy when we cannot find any source.
// +optional
SourceRef []runtimev1alpha1.TypedReference `json:"sourceRef,omitempty"`
// RolloutPlan is the details on how to rollout the resources
RolloutPlan RolloutPlan `json:"rolloutPlan"`
}
// RolloutTrait is the Schema for the RolloutTrait API
// +kubebuilder:object:root=true
// +genclient
// +kubebuilder:subresource:status
type RolloutTrait struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec RolloutTraitSpec `json:"spec,omitempty"`
Status RolloutStatus `json:"status,omitempty"`
}
// RolloutTraitList contains a list of RolloutTrait
// +kubebuilder:object:root=true
// +genclient
type RolloutTraitList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []RolloutTrait `json:"items"`
}
func init() {
SchemeBuilder.Register(&RolloutTrait{}, &RolloutTraitList{})
}
var _ oam.Trait = &RolloutTrait{}
// SetConditions for set CR condition
func (tr *RolloutTrait) SetConditions(c ...runtimev1alpha1.Condition) {
tr.Status.SetConditions(c...)
}
// GetCondition for get CR condition
func (tr *RolloutTrait) GetCondition(c runtimev1alpha1.ConditionType) runtimev1alpha1.Condition {
return tr.Status.GetCondition(c)
}
// GetWorkloadReference of this MetricsTrait.
func (tr *RolloutTrait) GetWorkloadReference() runtimev1alpha1.TypedReference {
return tr.Spec.TargetRef
}
// SetWorkloadReference of this MetricsTrait.
func (tr *RolloutTrait) SetWorkloadReference(r runtimev1alpha1.TypedReference) {
tr.Spec.TargetRef = r
}

View File

@@ -1,162 +0,0 @@
/*
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 (
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"github.com/oam-dev/kubevela/pkg/oam"
)
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// RouteSpec defines the desired state of Route
type RouteSpec struct {
// WorkloadReference to the workload whose metrics needs to be exposed
WorkloadReference runtimev1alpha1.TypedReference `json:"workloadRef,omitempty"`
// Host is the host of the route
Host string `json:"host"`
// TLS indicate route trait will create SSL secret using cert-manager with specified issuer
// If this is nil, route trait will use a selfsigned issuer
TLS *TLS `json:"tls,omitempty"`
// Rules contain multiple rules of route
Rules []Rule `json:"rules,omitempty"`
// Provider indicate which ingress controller implementation the route trait will use, by default it's nginx-ingress
Provider string `json:"provider,omitempty"`
}
// Rule defines to route rule
type Rule struct {
// Name will become the suffix of underlying ingress created by this rule, if not, will use index as suffix.
Name string `json:"name,omitempty"`
// Path is location Path, default for "/"
Path string `json:"path,omitempty"`
// RewriteTarget will rewrite request from Path to RewriteTarget path.
RewriteTarget string `json:"rewriteTarget,omitempty"`
// CustomHeaders pass a custom list of headers to the backend service.
CustomHeaders map[string]string `json:"customHeaders,omitempty"`
// DefaultBackend will become the ingress default backend if the backend is not available
DefaultBackend *runtimev1alpha1.TypedReference `json:"defaultBackend,omitempty"`
// Backend indicate how to connect backend service
// If it's nil, will auto discovery
Backend *Backend `json:"backend,omitempty"`
}
// TLS defines certificate issuer and type for mTLS configuration
type TLS struct {
IssuerName string `json:"issuerName,omitempty"`
// Type indicate the issuer is ClusterIssuer or Issuer(namespace issuer), by default, it's Issuer
// +kubebuilder:default:=Issuer
Type IssuerType `json:"type,omitempty"`
}
// IssuerType defines the type of issuer
type IssuerType string
const (
// ClusterIssuer is a cluster level type of issuer
ClusterIssuer IssuerType = "ClusterIssuer"
// NamespaceIssuer is the default one
NamespaceIssuer IssuerType = "Issuer"
)
// Backend defines backend configure for route trait.
// Route will automatically discover podSpec and label for BackendService.
// If BackendService is already set, discovery won't work.
// If BackendService is not set, the discovery mechanism will work.
type Backend struct {
// ReadTimeout used for setting read timeout duration for backend service, the unit is second.
ReadTimeout int `json:"readTimeout,omitempty"`
// SendTimeout used for setting send timeout duration for backend service, the unit is second.
SendTimeout int `json:"sendTimeout,omitempty"`
// BackendService specifies the backend K8s service and port, it's optional
BackendService *BackendServiceRef `json:"backendService,omitempty"`
}
// BackendServiceRef specifies the backend K8s service and port, if specified, the two fields are all required
type BackendServiceRef struct {
// Port allow you direct specify backend service port.
Port intstr.IntOrString `json:"port"`
// ServiceName allow you direct specify K8s service for backend service.
ServiceName string `json:"serviceName"`
}
// RouteStatus defines the observed state of Route
type RouteStatus struct {
Ingresses []runtimev1alpha1.TypedReference `json:"ingresses,omitempty"`
Service *runtimev1alpha1.TypedReference `json:"service,omitempty"`
Status string `json:"status,omitempty"`
runtimev1alpha1.ConditionedStatus `json:",inline"`
}
// Route is the Schema for the routes API
// +kubebuilder:object:root=true
// +kubebuilder:resource:categories={oam}
// +kubebuilder:subresource:status
type Route struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec RouteSpec `json:"spec,omitempty"`
Status RouteStatus `json:"status,omitempty"`
}
// RouteList contains a list of Route
// +kubebuilder:object:root=true
type RouteList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Route `json:"items"`
}
func init() {
SchemeBuilder.Register(&Route{}, &RouteList{})
}
var _ oam.Trait = &Route{}
// SetConditions set condition for CR status
func (r *Route) SetConditions(c ...runtimev1alpha1.Condition) {
r.Status.SetConditions(c...)
}
// GetCondition get condition from CR status
func (r *Route) GetCondition(c runtimev1alpha1.ConditionType) runtimev1alpha1.Condition {
return r.Status.GetCondition(c)
}
// GetWorkloadReference of this Route Trait.
func (r *Route) GetWorkloadReference() runtimev1alpha1.TypedReference {
return r.Spec.WorkloadReference
}
// SetWorkloadReference of this Route Trait.
func (r *Route) SetWorkloadReference(rt runtimev1alpha1.TypedReference) {
r.Spec.WorkloadReference = rt
}

View File

@@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
Copyright 2020 The KubeVela Authors.
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.
@@ -23,249 +23,55 @@ package v1alpha1
import (
corev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
runtime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/intstr"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Autoscaler) DeepCopyInto(out *Autoscaler) {
func (in *CanaryMetric) DeepCopyInto(out *CanaryMetric) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Autoscaler.
func (in *Autoscaler) DeepCopy() *Autoscaler {
if in == nil {
return nil
if in.MetricsRange != nil {
in, out := &in.MetricsRange, &out.MetricsRange
*out = new(MetricsExpectedRange)
(*in).DeepCopyInto(*out)
}
out := new(Autoscaler)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Autoscaler) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AutoscalerList) DeepCopyInto(out *AutoscalerList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Autoscaler, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoscalerList.
func (in *AutoscalerList) DeepCopy() *AutoscalerList {
if in == nil {
return nil
}
out := new(AutoscalerList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *AutoscalerList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AutoscalerSpec) DeepCopyInto(out *AutoscalerSpec) {
*out = *in
if in.MinReplicas != nil {
in, out := &in.MinReplicas, &out.MinReplicas
*out = new(int32)
**out = **in
}
if in.MaxReplicas != nil {
in, out := &in.MaxReplicas, &out.MaxReplicas
*out = new(int32)
**out = **in
}
if in.Triggers != nil {
in, out := &in.Triggers, &out.Triggers
*out = make([]Trigger, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
out.TargetWorkload = in.TargetWorkload
out.WorkloadReference = in.WorkloadReference
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoscalerSpec.
func (in *AutoscalerSpec) DeepCopy() *AutoscalerSpec {
if in == nil {
return nil
}
out := new(AutoscalerSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AutoscalerStatus) DeepCopyInto(out *AutoscalerStatus) {
*out = *in
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AutoscalerStatus.
func (in *AutoscalerStatus) DeepCopy() *AutoscalerStatus {
if in == nil {
return nil
}
out := new(AutoscalerStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Backend) DeepCopyInto(out *Backend) {
*out = *in
if in.BackendService != nil {
in, out := &in.BackendService, &out.BackendService
*out = new(BackendServiceRef)
if in.TemplateRef != nil {
in, out := &in.TemplateRef, &out.TemplateRef
*out = new(corev1alpha1.TypedReference)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Backend.
func (in *Backend) DeepCopy() *Backend {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CanaryMetric.
func (in *CanaryMetric) DeepCopy() *CanaryMetric {
if in == nil {
return nil
}
out := new(Backend)
out := new(CanaryMetric)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *BackendServiceRef) DeepCopyInto(out *BackendServiceRef) {
func (in *MetricsExpectedRange) DeepCopyInto(out *MetricsExpectedRange) {
*out = *in
out.Port = in.Port
if in.Min != nil {
in, out := &in.Min, &out.Min
*out = new(intstr.IntOrString)
**out = **in
}
if in.Max != nil {
in, out := &in.Max, &out.Max
*out = new(intstr.IntOrString)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BackendServiceRef.
func (in *BackendServiceRef) DeepCopy() *BackendServiceRef {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsExpectedRange.
func (in *MetricsExpectedRange) DeepCopy() *MetricsExpectedRange {
if in == nil {
return nil
}
out := new(BackendServiceRef)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MetricsTrait) DeepCopyInto(out *MetricsTrait) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsTrait.
func (in *MetricsTrait) DeepCopy() *MetricsTrait {
if in == nil {
return nil
}
out := new(MetricsTrait)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *MetricsTrait) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MetricsTraitList) DeepCopyInto(out *MetricsTraitList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]MetricsTrait, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsTraitList.
func (in *MetricsTraitList) DeepCopy() *MetricsTraitList {
if in == nil {
return nil
}
out := new(MetricsTraitList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *MetricsTraitList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MetricsTraitSpec) DeepCopyInto(out *MetricsTraitSpec) {
*out = *in
in.ScrapeService.DeepCopyInto(&out.ScrapeService)
out.WorkloadReference = in.WorkloadReference
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsTraitSpec.
func (in *MetricsTraitSpec) DeepCopy() *MetricsTraitSpec {
if in == nil {
return nil
}
out := new(MetricsTraitSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *MetricsTraitStatus) DeepCopyInto(out *MetricsTraitStatus) {
*out = *in
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
out.Port = in.Port
if in.SelectorLabels != nil {
in, out := &in.SelectorLabels, &out.SelectorLabels
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetricsTraitStatus.
func (in *MetricsTraitStatus) DeepCopy() *MetricsTraitStatus {
if in == nil {
return nil
}
out := new(MetricsTraitStatus)
out := new(MetricsExpectedRange)
in.DeepCopyInto(out)
return out
}
@@ -372,7 +178,124 @@ func (in *PodSpecWorkloadStatus) DeepCopy() *PodSpecWorkloadStatus {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Route) DeepCopyInto(out *Route) {
func (in *RolloutBatch) DeepCopyInto(out *RolloutBatch) {
*out = *in
out.Replicas = in.Replicas
if in.PodList != nil {
in, out := &in.PodList, &out.PodList
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.MaxUnavailable != nil {
in, out := &in.MaxUnavailable, &out.MaxUnavailable
*out = new(intstr.IntOrString)
**out = **in
}
if in.InstanceInterval != nil {
in, out := &in.InstanceInterval, &out.InstanceInterval
*out = new(int32)
**out = **in
}
if in.BatchRolloutWebhooks != nil {
in, out := &in.BatchRolloutWebhooks, &out.BatchRolloutWebhooks
*out = make([]RolloutWebhook, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.CanaryMetric != nil {
in, out := &in.CanaryMetric, &out.CanaryMetric
*out = make([]CanaryMetric, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutBatch.
func (in *RolloutBatch) DeepCopy() *RolloutBatch {
if in == nil {
return nil
}
out := new(RolloutBatch)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RolloutPlan) DeepCopyInto(out *RolloutPlan) {
*out = *in
if in.RolloutStrategy != nil {
in, out := &in.RolloutStrategy, &out.RolloutStrategy
*out = new(RolloutStrategyType)
**out = **in
}
if in.TargetSize != nil {
in, out := &in.TargetSize, &out.TargetSize
*out = new(int32)
**out = **in
}
if in.NumBatches != nil {
in, out := &in.NumBatches, &out.NumBatches
*out = new(int32)
**out = **in
}
if in.RolloutBatches != nil {
in, out := &in.RolloutBatches, &out.RolloutBatches
*out = make([]RolloutBatch, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.BatchPartition != nil {
in, out := &in.BatchPartition, &out.BatchPartition
*out = new(int32)
**out = **in
}
if in.RolloutWebhooks != nil {
in, out := &in.RolloutWebhooks, &out.RolloutWebhooks
*out = make([]RolloutWebhook, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.CanaryMetric != nil {
in, out := &in.CanaryMetric, &out.CanaryMetric
*out = make([]CanaryMetric, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutPlan.
func (in *RolloutPlan) DeepCopy() *RolloutPlan {
if in == nil {
return nil
}
out := new(RolloutPlan)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RolloutStatus) DeepCopyInto(out *RolloutStatus) {
*out = *in
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutStatus.
func (in *RolloutStatus) DeepCopy() *RolloutStatus {
if in == nil {
return nil
}
out := new(RolloutStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RolloutTrait) DeepCopyInto(out *RolloutTrait) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
@@ -380,18 +303,18 @@ func (in *Route) DeepCopyInto(out *Route) {
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Route.
func (in *Route) DeepCopy() *Route {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutTrait.
func (in *RolloutTrait) DeepCopy() *RolloutTrait {
if in == nil {
return nil
}
out := new(Route)
out := new(RolloutTrait)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *Route) DeepCopyObject() runtime.Object {
func (in *RolloutTrait) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
@@ -399,31 +322,31 @@ func (in *Route) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RouteList) DeepCopyInto(out *RouteList) {
func (in *RolloutTraitList) DeepCopyInto(out *RolloutTraitList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]Route, len(*in))
*out = make([]RolloutTrait, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteList.
func (in *RouteList) DeepCopy() *RouteList {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutTraitList.
func (in *RolloutTraitList) DeepCopy() *RolloutTraitList {
if in == nil {
return nil
}
out := new(RouteList)
out := new(RolloutTraitList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *RouteList) DeepCopyObject() runtime.Object {
func (in *RolloutTraitList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
@@ -431,154 +354,68 @@ func (in *RouteList) DeepCopyObject() runtime.Object {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RouteSpec) DeepCopyInto(out *RouteSpec) {
func (in *RolloutTraitSpec) DeepCopyInto(out *RolloutTraitSpec) {
*out = *in
out.WorkloadReference = in.WorkloadReference
if in.TLS != nil {
in, out := &in.TLS, &out.TLS
*out = new(TLS)
**out = **in
}
if in.Rules != nil {
in, out := &in.Rules, &out.Rules
*out = make([]Rule, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteSpec.
func (in *RouteSpec) DeepCopy() *RouteSpec {
if in == nil {
return nil
}
out := new(RouteSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RouteStatus) DeepCopyInto(out *RouteStatus) {
*out = *in
if in.Ingresses != nil {
in, out := &in.Ingresses, &out.Ingresses
out.TargetRef = in.TargetRef
if in.SourceRef != nil {
in, out := &in.SourceRef, &out.SourceRef
*out = make([]corev1alpha1.TypedReference, len(*in))
copy(*out, *in)
}
if in.Service != nil {
in, out := &in.Service, &out.Service
in.RolloutPlan.DeepCopyInto(&out.RolloutPlan)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutTraitSpec.
func (in *RolloutTraitSpec) DeepCopy() *RolloutTraitSpec {
if in == nil {
return nil
}
out := new(RolloutTraitSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RolloutWebhook) DeepCopyInto(out *RolloutWebhook) {
*out = *in
if in.Metadata != nil {
in, out := &in.Metadata, &out.Metadata
*out = new(map[string]string)
if **in != nil {
in, out := *in, *out
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutWebhook.
func (in *RolloutWebhook) DeepCopy() *RolloutWebhook {
if in == nil {
return nil
}
out := new(RolloutWebhook)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *RolloutWebhookPayload) DeepCopyInto(out *RolloutWebhookPayload) {
*out = *in
if in.ResourceRef != nil {
in, out := &in.ResourceRef, &out.ResourceRef
*out = new(corev1alpha1.TypedReference)
**out = **in
}
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteStatus.
func (in *RouteStatus) DeepCopy() *RouteStatus {
if in == nil {
return nil
}
out := new(RouteStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Rule) DeepCopyInto(out *Rule) {
*out = *in
if in.CustomHeaders != nil {
in, out := &in.CustomHeaders, &out.CustomHeaders
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.DefaultBackend != nil {
in, out := &in.DefaultBackend, &out.DefaultBackend
if in.RolloutRef != nil {
in, out := &in.RolloutRef, &out.RolloutRef
*out = new(corev1alpha1.TypedReference)
**out = **in
}
if in.Backend != nil {
in, out := &in.Backend, &out.Backend
*out = new(Backend)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule.
func (in *Rule) DeepCopy() *Rule {
if in == nil {
return nil
}
out := new(Rule)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ScapeServiceEndPoint) DeepCopyInto(out *ScapeServiceEndPoint) {
*out = *in
out.TargetPort = in.TargetPort
if in.TargetSelector != nil {
in, out := &in.TargetSelector, &out.TargetSelector
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
if in.Enabled != nil {
in, out := &in.Enabled, &out.Enabled
*out = new(bool)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScapeServiceEndPoint.
func (in *ScapeServiceEndPoint) DeepCopy() *ScapeServiceEndPoint {
if in == nil {
return nil
}
out := new(ScapeServiceEndPoint)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TLS) DeepCopyInto(out *TLS) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TLS.
func (in *TLS) DeepCopy() *TLS {
if in == nil {
return nil
}
out := new(TLS)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TargetWorkload) DeepCopyInto(out *TargetWorkload) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetWorkload.
func (in *TargetWorkload) DeepCopy() *TargetWorkload {
if in == nil {
return nil
}
out := new(TargetWorkload)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Trigger) DeepCopyInto(out *Trigger) {
*out = *in
if in.Condition != nil {
in, out := &in.Condition, &out.Condition
if in.Metadata != nil {
in, out := &in.Metadata, &out.Metadata
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
@@ -586,12 +423,12 @@ func (in *Trigger) DeepCopyInto(out *Trigger) {
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Trigger.
func (in *Trigger) DeepCopy() *Trigger {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RolloutWebhookPayload.
func (in *RolloutWebhookPayload) DeepCopy() *RolloutWebhookPayload {
if in == nil {
return nil
}
out := new(Trigger)
out := new(RolloutWebhookPayload)
in.DeepCopyInto(out)
return out
}

View File

@@ -18,12 +18,10 @@ package types
import (
"encoding/json"
"fmt"
"cuelang.org/go/cue"
"github.com/google/go-cmp/cmp"
"github.com/spf13/pflag"
"k8s.io/apimachinery/pkg/runtime"
)
// Source record the source of Capability
@@ -88,6 +86,14 @@ const (
TypeScope CapType = "scope"
)
// CapabilityCategory defines the category of a capability
type CapabilityCategory string
const (
// TerraformCategory means the capability is in Terraform format
TerraformCategory CapabilityCategory = "terraform"
)
// Parameter defines a parameter for cli from capability template
type Parameter struct {
Name string `json:"name"`
@@ -99,20 +105,6 @@ type Parameter struct {
Alias string `json:"alias,omitempty"`
}
// ConvertTemplateJSON2Object convert spec.extension to object
func ConvertTemplateJSON2Object(in *runtime.RawExtension) (Capability, error) {
var t Capability
var extension Capability
if in == nil || in.Raw == nil {
return t, fmt.Errorf("no template found")
}
err := json.Unmarshal(in.Raw, &extension)
if err == nil {
t = extension
}
return t, err
}
// SetFlagBy set cli flag from Parameter
func SetFlagBy(flags *pflag.FlagSet, v Parameter) {
name := v.Name

View File

@@ -1,6 +1,6 @@
apiVersion: v2
name: vela-core
description: A Helm chart for Kube Vela core
description: A Helm chart for KubeVela core
# A chart can be either an 'application' or a 'library' chart.
#

View File

@@ -380,12 +380,18 @@ spec:
items:
description: A WorkloadStatus represents the status of a workload.
properties:
appliedComponentRevision:
description: AppliedComponentRevision indicates the applied component revision name of this workload
type: string
componentName:
description: ComponentName that produced this workload.
type: string
componentRevisionName:
description: ComponentRevisionName of current component
type: string
dependencyUnsatisfied:
description: DependencyUnsatisfied notify does the workload has dependency unsatisfied
type: boolean
scopes:
description: Scopes associated with this workload.
items:
@@ -426,6 +432,13 @@ spec:
items:
description: A WorkloadTrait represents a trait associated with a workload and its status
properties:
appliedGeneration:
description: AppliedGeneration indicates the generation observed by the appConfig controller. The same field is also recorded in the annotations of traits. A trait is possible to be deleted from cluster after created. This field is useful to track the observed generation of traits after they are deleted.
format: int64
type: integer
dependencyUnsatisfied:
description: DependencyUnsatisfied notify does the trait has dependency unsatisfied
type: boolean
message:
description: Message will allow controller to leave some additional information for this trait
type: string

View File

@@ -32,11 +32,240 @@ spec:
metadata:
type: object
spec:
description: ApplicationDeploymentSpec defines the desired state of ApplicationDeployment
description: ApplicationDeploymentSpec defines how to describe an upgrade between different application
properties:
componentList:
description: 'The list of component to upgrade in the application. We only support single component application so far TODO: (RZ) Support multiple components in an application'
items:
type: string
type: array
revertOnDelete:
description: RevertOnDelete revert the rollout when the rollout CR is deleted, default is false It will remove the target application from the kubernetes
type: boolean
rolloutPlan:
description: RolloutPlan is the details on how to rollout the resources
properties:
canaryMetric:
description: CanaryMetric provides a way for the rollout process to automatically check certain metrics before complete the process
items:
description: CanaryMetric holds the reference to metrics used for canary analysis
properties:
interval:
description: Interval represents the windows size
type: string
metricsRange:
description: Range value accepted for this metric
properties:
max:
anyOf:
- type: integer
- type: string
description: Maximum value
x-kubernetes-int-or-string: true
min:
anyOf:
- type: integer
- type: string
description: Minimum value
x-kubernetes-int-or-string: true
type: object
name:
description: Name of the metric
type: string
templateRef:
description: TemplateRef references a metric template object
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- name
type: object
type: array
lastBatchToRollout:
description: All pods in the batches up to the batchPartition (included) will have the target resource specification while the rest still have the source resource This is designed for the operators to manually rollout Default is the the number of batches which will rollout all the batches
format: int32
type: integer
numBatches:
description: The number of batches, default = 1 mutually exclusive to RolloutBatches
format: int32
type: integer
paused:
description: Paused the rollout, default is false
type: boolean
rolloutBatches:
description: The exact distribution among batches. mutually exclusive to NumBatches. The total number cannot exceed the targetSize or the size of the source resource We will IGNORE the last batch's replica field if it's a percentage since round errors can lead to inaccurate sum We highly recommend to leave the last batch's replica field empty
items:
description: RolloutBatch is used to describe how the each batch rollout should be
properties:
batchRolloutWebhooks:
description: RolloutWebhooks provides a way for the batch rollout to interact with an external process
items:
description: RolloutWebhook holds the reference to external checks used for canary analysis
properties:
metadata:
additionalProperties:
type: string
description: Metadata (key-value pairs) for this webhook
type: object
name:
description: Name of this webhook
type: string
timeout:
description: Request timeout for this webhook
type: string
type:
description: Type of this webhook
type: string
url:
description: URL address of this webhook
type: string
required:
- name
- type
- url
type: object
type: array
canaryMetric:
description: CanaryMetric provides a way for the batch rollout process to automatically check certain metrics before moving to the next batch
items:
description: CanaryMetric holds the reference to metrics used for canary analysis
properties:
interval:
description: Interval represents the windows size
type: string
metricsRange:
description: Range value accepted for this metric
properties:
max:
anyOf:
- type: integer
- type: string
description: Maximum value
x-kubernetes-int-or-string: true
min:
anyOf:
- type: integer
- type: string
description: Minimum value
x-kubernetes-int-or-string: true
type: object
name:
description: Name of the metric
type: string
templateRef:
description: TemplateRef references a metric template object
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- name
type: object
type: array
instanceInterval:
description: The wait time, in seconds, between instances upgrades, default = 0
format: int32
type: integer
maxUnavailable:
anyOf:
- type: integer
- type: string
description: MaxUnavailable is the max allowed number of pods that is unavailable during the upgrade. We will mark the batch as ready as long as there are less or equal number of pods unavailable than this number. default = 0
x-kubernetes-int-or-string: true
podList:
description: The list of Pods to get upgraded it is mutually exclusive with the Replicas field
items:
type: string
type: array
replicas:
anyOf:
- type: integer
- type: string
description: 'Replicas is the number of pods to upgrade in this batch it can be an absolute number (ex: 5) or a percentage of total pods we will ignore the percentage of the last batch to just fill the gap it is mutually exclusive with the PodList field'
x-kubernetes-int-or-string: true
type: object
type: array
rolloutStrategy:
description: RolloutStrategy defines strategies for the rollout plan
type: string
rolloutWebhooks:
description: RolloutWebhooks provide a way for the rollout to interact with an external process
items:
description: RolloutWebhook holds the reference to external checks used for canary analysis
properties:
metadata:
additionalProperties:
type: string
description: Metadata (key-value pairs) for this webhook
type: object
name:
description: Name of this webhook
type: string
timeout:
description: Request timeout for this webhook
type: string
type:
description: Type of this webhook
type: string
url:
description: URL address of this webhook
type: string
required:
- name
- type
- url
type: object
type: array
targetSize:
description: The size of the target resource. The default is the same as the size of the source resource.
format: int32
type: integer
type: object
sourceApplicationName:
description: SourceApplicationName contains the name of the application that we need to upgrade from. it can be empty only when it's the first time to deploy the application
type: string
targetApplicationName:
description: TargetApplicationName contains the name of the application that we need to upgrade to. We assume that an application is immutable, thus the name alone is suffice
type: string
required:
- rolloutPlan
- targetApplicationName
type: object
status:
description: ApplicationDeploymentStatus defines the observed state of ApplicationDeployment
properties:
batchRollingState:
description: BatchRollingState only meaningful when the Status is rolling
type: string
conditions:
description: Conditions of the resource.
items:
@@ -65,6 +294,39 @@ spec:
- type
type: object
type: array
currentBatch:
description: The current batch the rollout is working on/blocked it starts from 0
format: int32
type: integer
lastAppliedPodTemplateIdentifier:
description: lastAppliedPodTemplateIdentifier is a string that uniquely represent the last pod template each workload type could use different ways to identify that so we cannot compare between resources We update this field only after a successful rollout
type: string
lastSourceApplicationName:
description: LastSourceApplicationName contains the name of the application that we need to upgrade from. We will restart the rollout if this is not the same as the spec
type: string
lastTargetApplicationName:
description: LastTargetApplicationName contains the name of the application that we upgraded to We will restart the rollout if this is not the same as the spec
type: string
rollingState:
description: RollingState is the Rollout State
type: string
targetGeneration:
description: NewPodTemplateIdentifier is a string that uniquely represent the new pod template each workload type could use different ways to identify that so we cannot compare between resources
type: string
upgradedReadyReplicas:
description: UpgradedReplicas is the number of Pods upgraded by the rollout controller that have a Ready Condition.
format: int32
type: integer
upgradedReplicas:
description: UpgradedReplicas is the number of Pods upgraded by the rollout controller
format: int32
type: integer
required:
- currentBatch
- lastTargetApplicationName
- rollingState
- upgradedReadyReplicas
- upgradedReplicas
type: object
type: object
served: true

View File

@@ -127,6 +127,37 @@ spec:
- type
type: object
type: array
services:
description: Services record the status of the application services
items:
description: ApplicationComponentStatus record the health status of App component
properties:
healthy:
type: boolean
message:
type: string
name:
type: string
traits:
items:
description: ApplicationTraitStatus records the trait health status
properties:
healthy:
type: boolean
message:
type: string
type:
type: string
required:
- healthy
- type
type: object
type: array
required:
- healthy
- name
type: object
type: array
status:
description: ApplicationPhase is a label for the condition of a application at the current time
type: string

View File

@@ -17,7 +17,7 @@ spec:
listKind: ScopeDefinitionList
plural: scopedefinitions
singular: scopedefinition
scope: Cluster
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.definitionRef.name

View File

@@ -17,7 +17,7 @@ spec:
listKind: TraitDefinitionList
plural: traitdefinitions
singular: traitdefinition
scope: Cluster
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.definitionRef.name
@@ -68,6 +68,29 @@ spec:
revisionEnabled:
description: Revision indicates whether a trait is aware of component revision
type: boolean
schematic:
description: Schematic defines the data format and template of the encapsulation of the trait
properties:
cue:
description: CUE defines the encapsulation in CUE format
properties:
template:
description: Template defines the abstraction template data of the capability, it will replace the old CUE template in extension field. Template is a required field if CUE is defined in Capability Definition.
type: string
required:
- template
type: object
type: object
status:
description: Status defines the custom health policy and status message for trait
properties:
customStatus:
description: CustomStatus defines the custom status message that could display to user
type: string
healthPolicy:
description: HealthPolicy defines the health check policy for the abstraction
type: string
type: object
workloadRefPath:
description: WorkloadRefPath indicates where/if a trait accepts a workloadRef object
type: string

View File

@@ -17,7 +17,7 @@ spec:
listKind: WorkloadDefinitionList
plural: workloaddefinitions
singular: workloaddefinition
scope: Cluster
scope: Namespaced
versions:
- additionalPrinterColumns:
- jsonPath: .spec.definitionRef.name
@@ -82,6 +82,32 @@ spec:
revisionLabel:
description: RevisionLabel indicates which label for underlying resources(e.g. pods) of this workload can be used by trait to create resource selectors(e.g. label selector for pods).
type: string
schematic:
description: Schematic defines the data format and template of the encapsulation of the workload
properties:
cue:
description: CUE defines the encapsulation in CUE format
properties:
template:
description: Template defines the abstraction template data of the capability, it will replace the old CUE template in extension field. Template is a required field if CUE is defined in Capability Definition.
type: string
required:
- template
type: object
type: object
status:
description: Status defines the custom health policy and status message for workload
properties:
customStatus:
description: CustomStatus defines the custom status message that could display to user
type: string
healthPolicy:
description: HealthPolicy defines the health check policy for the abstraction
type: string
type: object
template:
description: Template defines the abstraction template data of the workload, it will replace the old template in extension field. the data format depends on templateType, by default it's CUE
type: string
required:
- definitionRef
type: object

View File

@@ -1,143 +0,0 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.2.4
creationTimestamp: null
name: autoscalers.standard.oam.dev
spec:
group: standard.oam.dev
names:
categories:
- oam
kind: Autoscaler
listKind: AutoscalerList
plural: autoscalers
singular: autoscaler
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: Autoscaler is the Schema for the autoscalers API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: AutoscalerSpec defines the desired state of Autoscaler
properties:
maxReplicas:
description: MinReplicas is the maximal replicas
format: int32
type: integer
minReplicas:
description: MinReplicas is the minimal replicas
format: int32
type: integer
targetWorkload:
description: TargetWorkload specify the workload which is going to be scaled, it could be WorkloadReference or the child resource of it
properties:
apiVersion:
type: string
kind:
type: string
name:
type: string
required:
- name
type: object
triggers:
description: Triggers lists all triggers
items:
description: Trigger defines the trigger of Autoscaler
properties:
condition:
additionalProperties:
type: string
description: Condition set the condition when to trigger scaling
type: object
name:
description: Name is the trigger name, if not set, it will be automatically generated and make it globally unique
type: string
type:
description: Type allows value in [cpu/memory/storage/ephemeral-storage、cron、pps、qps/rps、custom]
type: string
required:
- condition
- type
type: object
type: array
workloadRef:
description: WorkloadReference marks the owner of the workload
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- triggers
type: object
status:
description: AutoscalerStatus defines the observed state of Autoscaler
properties:
conditions:
description: Conditions of the resource.
items:
description: A Condition that may apply to a resource.
properties:
lastTransitionTime:
description: LastTransitionTime is the last time this condition transitioned from one status to another.
format: date-time
type: string
message:
description: A Message containing details about this condition's last transition from one status to another, if any.
type: string
reason:
description: A Reason for this condition's last transition from one status to another.
type: string
status:
description: Status of this condition; is it currently True, False, or Unknown?
type: string
type:
description: Type of this condition. At most one of each condition type may apply to a resource at any point in time.
type: string
required:
- lastTransitionTime
- reason
- status
- type
type: object
type: array
type: object
required:
- spec
type: object
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -1,145 +0,0 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.2.4
creationTimestamp: null
name: metricstraits.standard.oam.dev
spec:
group: standard.oam.dev
names:
categories:
- oam
kind: MetricsTrait
listKind: MetricsTraitList
plural: metricstraits
singular: metricstrait
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: MetricsTrait is the Schema for the metricstraits API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: MetricsTraitSpec defines the desired state of MetricsTrait
properties:
scrapeService:
description: An endpoint to be monitored by a ServiceMonitor.
properties:
enabled:
description: The default is true
type: boolean
format:
description: The format of the metrics data, The default and only supported format is "prometheus" for now
type: string
path:
description: HTTP path to scrape for metrics. default is /metrics
type: string
port:
anyOf:
- type: integer
- type: string
description: Number or name of the port to access on the pods targeted by the service. The default is discovered automatically from podTemplate, metricTrait will create a service for the workload
x-kubernetes-int-or-string: true
scheme:
description: Scheme at which metrics should be scraped The default and only supported scheme is "http"
type: string
selector:
additionalProperties:
type: string
description: Route service traffic to pods with label keys and values matching this The default is discovered automatically from podTemplate. If no podTemplate, use the labels specified here, or use the labels of the workload
type: object
type: object
workloadRef:
description: WorkloadReference to the workload whose metrics needs to be exposed
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- scrapeService
type: object
status:
description: MetricsTraitStatus defines the observed state of MetricsTrait
properties:
conditions:
description: Conditions of the resource.
items:
description: A Condition that may apply to a resource.
properties:
lastTransitionTime:
description: LastTransitionTime is the last time this condition transitioned from one status to another.
format: date-time
type: string
message:
description: A Message containing details about this condition's last transition from one status to another, if any.
type: string
reason:
description: A Reason for this condition's last transition from one status to another.
type: string
status:
description: Status of this condition; is it currently True, False, or Unknown?
type: string
type:
description: Type of this condition. At most one of each condition type may apply to a resource at any point in time.
type: string
required:
- lastTransitionTime
- reason
- status
- type
type: object
type: array
port:
anyOf:
- type: integer
- type: string
description: Port is the real port monitoring
x-kubernetes-int-or-string: true
selectorLabels:
additionalProperties:
type: string
description: SelectorLabels is the real labels selected
type: object
serviceMonitorName:
description: ServiceMonitorName managed by this trait
type: string
type: object
required:
- spec
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -0,0 +1,361 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.2.4
creationTimestamp: null
name: rollouttraits.standard.oam.dev
spec:
group: standard.oam.dev
names:
kind: RolloutTrait
listKind: RolloutTraitList
plural: rollouttraits
singular: rollouttrait
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: RolloutTrait is the Schema for the RolloutTrait API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: RolloutTraitSpec defines the desired state of RolloutTrait
properties:
rolloutPlan:
description: RolloutPlan is the details on how to rollout the resources
properties:
canaryMetric:
description: CanaryMetric provides a way for the rollout process to automatically check certain metrics before complete the process
items:
description: CanaryMetric holds the reference to metrics used for canary analysis
properties:
interval:
description: Interval represents the windows size
type: string
metricsRange:
description: Range value accepted for this metric
properties:
max:
anyOf:
- type: integer
- type: string
description: Maximum value
x-kubernetes-int-or-string: true
min:
anyOf:
- type: integer
- type: string
description: Minimum value
x-kubernetes-int-or-string: true
type: object
name:
description: Name of the metric
type: string
templateRef:
description: TemplateRef references a metric template object
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- name
type: object
type: array
lastBatchToRollout:
description: All pods in the batches up to the batchPartition (included) will have the target resource specification while the rest still have the source resource This is designed for the operators to manually rollout Default is the the number of batches which will rollout all the batches
format: int32
type: integer
numBatches:
description: The number of batches, default = 1 mutually exclusive to RolloutBatches
format: int32
type: integer
paused:
description: Paused the rollout, default is false
type: boolean
rolloutBatches:
description: The exact distribution among batches. mutually exclusive to NumBatches. The total number cannot exceed the targetSize or the size of the source resource We will IGNORE the last batch's replica field if it's a percentage since round errors can lead to inaccurate sum We highly recommend to leave the last batch's replica field empty
items:
description: RolloutBatch is used to describe how the each batch rollout should be
properties:
batchRolloutWebhooks:
description: RolloutWebhooks provides a way for the batch rollout to interact with an external process
items:
description: RolloutWebhook holds the reference to external checks used for canary analysis
properties:
metadata:
additionalProperties:
type: string
description: Metadata (key-value pairs) for this webhook
type: object
name:
description: Name of this webhook
type: string
timeout:
description: Request timeout for this webhook
type: string
type:
description: Type of this webhook
type: string
url:
description: URL address of this webhook
type: string
required:
- name
- type
- url
type: object
type: array
canaryMetric:
description: CanaryMetric provides a way for the batch rollout process to automatically check certain metrics before moving to the next batch
items:
description: CanaryMetric holds the reference to metrics used for canary analysis
properties:
interval:
description: Interval represents the windows size
type: string
metricsRange:
description: Range value accepted for this metric
properties:
max:
anyOf:
- type: integer
- type: string
description: Maximum value
x-kubernetes-int-or-string: true
min:
anyOf:
- type: integer
- type: string
description: Minimum value
x-kubernetes-int-or-string: true
type: object
name:
description: Name of the metric
type: string
templateRef:
description: TemplateRef references a metric template object
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- name
type: object
type: array
instanceInterval:
description: The wait time, in seconds, between instances upgrades, default = 0
format: int32
type: integer
maxUnavailable:
anyOf:
- type: integer
- type: string
description: MaxUnavailable is the max allowed number of pods that is unavailable during the upgrade. We will mark the batch as ready as long as there are less or equal number of pods unavailable than this number. default = 0
x-kubernetes-int-or-string: true
podList:
description: The list of Pods to get upgraded it is mutually exclusive with the Replicas field
items:
type: string
type: array
replicas:
anyOf:
- type: integer
- type: string
description: 'Replicas is the number of pods to upgrade in this batch it can be an absolute number (ex: 5) or a percentage of total pods we will ignore the percentage of the last batch to just fill the gap it is mutually exclusive with the PodList field'
x-kubernetes-int-or-string: true
type: object
type: array
rolloutStrategy:
description: RolloutStrategy defines strategies for the rollout plan
type: string
rolloutWebhooks:
description: RolloutWebhooks provide a way for the rollout to interact with an external process
items:
description: RolloutWebhook holds the reference to external checks used for canary analysis
properties:
metadata:
additionalProperties:
type: string
description: Metadata (key-value pairs) for this webhook
type: object
name:
description: Name of this webhook
type: string
timeout:
description: Request timeout for this webhook
type: string
type:
description: Type of this webhook
type: string
url:
description: URL address of this webhook
type: string
required:
- name
- type
- url
type: object
type: array
targetSize:
description: The size of the target resource. The default is the same as the size of the source resource.
format: int32
type: integer
type: object
sourceRef:
description: SourceRef references the list of resources that contains the older version of the software. We assume that it's the first time to deploy when we cannot find any source.
items:
description: A TypedReference refers to an object by Name, Kind, and APIVersion. It is commonly used to reference cluster-scoped objects or objects where the namespace is already known.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
type: array
targetRef:
description: TargetRef references a target resource that contains the newer version of the software. We assumed that new resource already exists. This is the only resource we work on if the resource is a stateful resource (cloneset/statefulset)
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- rolloutPlan
- targetRef
type: object
status:
description: RolloutStatus defines the observed state of a rollout plan
properties:
batchRollingState:
description: BatchRollingState only meaningful when the Status is rolling
type: string
conditions:
description: Conditions of the resource.
items:
description: A Condition that may apply to a resource.
properties:
lastTransitionTime:
description: LastTransitionTime is the last time this condition transitioned from one status to another.
format: date-time
type: string
message:
description: A Message containing details about this condition's last transition from one status to another, if any.
type: string
reason:
description: A Reason for this condition's last transition from one status to another.
type: string
status:
description: Status of this condition; is it currently True, False, or Unknown?
type: string
type:
description: Type of this condition. At most one of each condition type may apply to a resource at any point in time.
type: string
required:
- lastTransitionTime
- reason
- status
- type
type: object
type: array
currentBatch:
description: The current batch the rollout is working on/blocked it starts from 0
format: int32
type: integer
lastAppliedPodTemplateIdentifier:
description: lastAppliedPodTemplateIdentifier is a string that uniquely represent the last pod template each workload type could use different ways to identify that so we cannot compare between resources We update this field only after a successful rollout
type: string
rollingState:
description: RollingState is the Rollout State
type: string
targetGeneration:
description: NewPodTemplateIdentifier is a string that uniquely represent the new pod template each workload type could use different ways to identify that so we cannot compare between resources
type: string
upgradedReadyReplicas:
description: UpgradedReplicas is the number of Pods upgraded by the rollout controller that have a Ready Condition.
format: int32
type: integer
upgradedReplicas:
description: UpgradedReplicas is the number of Pods upgraded by the rollout controller
format: int32
type: integer
required:
- currentBatch
- rollingState
- upgradedReadyReplicas
- upgradedReplicas
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -1,229 +0,0 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.2.4
creationTimestamp: null
name: routes.standard.oam.dev
spec:
group: standard.oam.dev
names:
categories:
- oam
kind: Route
listKind: RouteList
plural: routes
singular: route
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: Route is the Schema for the routes API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: RouteSpec defines the desired state of Route
properties:
host:
description: Host is the host of the route
type: string
provider:
description: Provider indicate which ingress controller implementation the route trait will use, by default it's nginx-ingress
type: string
rules:
description: Rules contain multiple rules of route
items:
description: Rule defines to route rule
properties:
backend:
description: Backend indicate how to connect backend service If it's nil, will auto discovery
properties:
backendService:
description: BackendService specifies the backend K8s service and port, it's optional
properties:
port:
anyOf:
- type: integer
- type: string
description: Port allow you direct specify backend service port.
x-kubernetes-int-or-string: true
serviceName:
description: ServiceName allow you direct specify K8s service for backend service.
type: string
required:
- port
- serviceName
type: object
readTimeout:
description: ReadTimeout used for setting read timeout duration for backend service, the unit is second.
type: integer
sendTimeout:
description: SendTimeout used for setting send timeout duration for backend service, the unit is second.
type: integer
type: object
customHeaders:
additionalProperties:
type: string
description: CustomHeaders pass a custom list of headers to the backend service.
type: object
defaultBackend:
description: DefaultBackend will become the ingress default backend if the backend is not available
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
name:
description: Name will become the suffix of underlying ingress created by this rule, if not, will use index as suffix.
type: string
path:
description: Path is location Path, default for "/"
type: string
rewriteTarget:
description: RewriteTarget will rewrite request from Path to RewriteTarget path.
type: string
type: object
type: array
tls:
description: TLS indicate route trait will create SSL secret using cert-manager with specified issuer If this is nil, route trait will use a selfsigned issuer
properties:
issuerName:
type: string
type:
default: Issuer
description: Type indicate the issuer is ClusterIssuer or Issuer(namespace issuer), by default, it's Issuer
type: string
type: object
workloadRef:
description: WorkloadReference to the workload whose metrics needs to be exposed
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
required:
- host
type: object
status:
description: RouteStatus defines the observed state of Route
properties:
conditions:
description: Conditions of the resource.
items:
description: A Condition that may apply to a resource.
properties:
lastTransitionTime:
description: LastTransitionTime is the last time this condition transitioned from one status to another.
format: date-time
type: string
message:
description: A Message containing details about this condition's last transition from one status to another, if any.
type: string
reason:
description: A Reason for this condition's last transition from one status to another.
type: string
status:
description: Status of this condition; is it currently True, False, or Unknown?
type: string
type:
description: Type of this condition. At most one of each condition type may apply to a resource at any point in time.
type: string
required:
- lastTransitionTime
- reason
- status
- type
type: object
type: array
ingresses:
items:
description: A TypedReference refers to an object by Name, Kind, and APIVersion. It is commonly used to reference cluster-scoped objects or objects where the namespace is already known.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
type: array
service:
description: A TypedReference refers to an object by Name, Kind, and APIVersion. It is commonly used to reference cluster-scoped objects or objects where the namespace is already known.
properties:
apiVersion:
description: APIVersion of the referenced object.
type: string
kind:
description: Kind of the referenced object.
type: string
name:
description: Name of the referenced object.
type: string
uid:
description: UID of the referenced object.
type: string
required:
- apiVersion
- kind
- name
type: object
status:
type: string
type: object
type: object
served: true
storage: true
subresources:
status: {}
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@@ -11,7 +11,9 @@
# 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.
{{- if .Values.installCertManager -}}
{{- if .Values.useWebhook -}}
---
apiVersion: v1
kind: Namespace
metadata:
@@ -1080,4 +1082,6 @@ webhooks:
resources:
- '*/*'
sideEffects: None
---
{{- end -}}
{{- end -}}

View File

@@ -0,0 +1,13 @@
apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
name: containerizedworkloads.core.oam.dev
namespace: {{.Values.systemDefinitionNamespace}}
spec:
definitionRef:
name: containerizedworkloads.core.oam.dev
childResourceKinds:
- apiVersion: apps/v1
kind: Deployment
- apiVersion: v1
kind: Service

View File

@@ -2,7 +2,7 @@ apiVersion: core.oam.dev/v1alpha2
kind: ScopeDefinition
metadata:
name: healthscopes.core.oam.dev
namespace: default
namespace: {{.Values.systemDefinitionNamespace}}
spec:
workloadRefsPath: spec.workloadRefs
allowComponentOverlap: true

View File

@@ -0,0 +1,72 @@
# Code generated by KubeVela templates. DO NOT EDIT.
apiVersion: core.oam.dev/v1alpha2
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/description: "Configures K8s ingress and service to enable web traffic for your service.
Please use route trait in cap center for advanced usage."
name: ingress
namespace: {{.Values.systemDefinitionNamespace}}
spec:
status:
customStatus: |-
if len(context.outputs.ingress.status.loadBalancer.ingress) > 0 {
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host + ", IP: " + context.outputs.ingress.status.loadBalancer.ingress[0].ip
}
if len(context.outputs.ingress.status.loadBalancer.ingress) == 0 {
message: "No loadBalancer found, visiting by using 'vela port-forward " + context.appName + " --route'\n"
}
healthPolicy: |
isHealth: len(context.outputs.service.spec.clusterIP) > 0
appliesToWorkloads:
- webservice
- worker
schematic:
cue:
template: |
parameter: {
domain: string
http: [string]: int
}
// trait template can have multiple outputs in one trait
outputs: service: {
apiVersion: "v1"
kind: "Service"
metadata:
name: context.name
spec: {
selector:
"app.oam.dev/component": context.name
ports: [
for k, v in parameter.http {
port: v
targetPort: v
},
]
}
}
outputs: ingress: {
apiVersion: "networking.k8s.io/v1beta1"
kind: "Ingress"
metadata:
name: context.name
spec: {
rules: [{
host: parameter.domain
http: {
paths: [
for k, v in parameter.http {
path: k
backend: {
serviceName: context.name
servicePort: v
}
},
]
}
}]
}
}

View File

@@ -5,6 +5,7 @@ metadata:
annotations:
definition.oam.dev/description: "Configures replicas for your service."
name: scaler
namespace: {{.Values.systemDefinitionNamespace}}
spec:
appliesToWorkloads:
- webservice
@@ -12,18 +13,19 @@ spec:
definitionRef:
name: manualscalertraits.core.oam.dev
workloadRefPath: spec.workloadRef
extension:
template: |-
output: {
apiVersion: "core.oam.dev/v1alpha2"
kind: "ManualScalerTrait"
spec: {
replicaCount: parameter.replicas
}
}
parameter: {
//+short=r
//+usage=Replicas of the workload
replicas: *1 | int
}
schematic:
cue:
template: |
output: {
apiVersion: "core.oam.dev/v1alpha2"
kind: "ManualScalerTrait"
spec: {
replicaCount: parameter.replicas
}
}
parameter: {
//+short=r
//+usage=Replicas of the workload
replicas: *1 | int
}

View File

@@ -3,45 +3,47 @@ apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
name: task
namespace: {{.Values.systemDefinitionNamespace}}
annotations:
definition.oam.dev/description: "Describes jobs that run code or a script to completion."
spec:
definitionRef:
name: jobs.batch
extension:
template: |
output: {
apiVersion: "batch/v1"
kind: "Job"
spec: {
parallelism: parameter.count
completions: parameter.count
template: spec: {
restartPolicy: parameter.restart
containers: [{
name: context.name
image: parameter.image
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
}]
}
}
}
parameter: {
// +usage=specify number of tasks to run in parallel
// +short=c
count: *1 | int
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Define the job restart policy, the value can only be Never or OnFailure. By default, it's Never.
restart: *"Never" | string
// +usage=Commands to run in the container
cmd?: [...string]
}
schematic:
cue:
template: |
output: {
apiVersion: "batch/v1"
kind: "Job"
spec: {
parallelism: parameter.count
completions: parameter.count
template: spec: {
restartPolicy: parameter.restart
containers: [{
name: context.name
image: parameter.image
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
}]
}
}
}
parameter: {
// +usage=specify number of tasks to run in parallel
// +short=c
count: *1 | int
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Define the job restart policy, the value can only be Never or OnFailure. By default, it's Never.
restart: *"Never" | string
// +usage=Commands to run in the container
cmd?: [...string]
}

View File

@@ -3,90 +3,92 @@ apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
name: webservice
namespace: {{.Values.systemDefinitionNamespace}}
annotations:
definition.oam.dev/description: "Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers.
If workload type is skipped for any service defined in Appfile, it will be defaulted to `webservice` type."
spec:
definitionRef:
name: deployments.apps
extension:
template: |
output: {
apiVersion: "apps/v1"
kind: "Deployment"
spec: {
selector: matchLabels: {
"app.oam.dev/component": context.name
}
template: {
metadata: labels: {
"app.oam.dev/component": context.name
}
spec: {
containers: [{
name: context.name
image: parameter.image
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
if parameter["env"] != _|_ {
env: parameter.env
}
if context["config"] != _|_ {
env: context.config
}
ports: [{
containerPort: parameter.port
}]
if parameter["cpu"] != _|_ {
resources: {
limits:
cpu: parameter.cpu
requests:
cpu: parameter.cpu
}
}
}]
}
}
}
}
parameter: {
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Commands to run in the container
cmd?: [...string]
// +usage=Which port do you want customer traffic sent to
// +short=p
port: *80 | int
// +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=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
cpu?: string
}
schematic:
cue:
template: |
output: {
apiVersion: "apps/v1"
kind: "Deployment"
spec: {
selector: matchLabels: {
"app.oam.dev/component": context.name
}
template: {
metadata: labels: {
"app.oam.dev/component": context.name
}
spec: {
containers: [{
name: context.name
image: parameter.image
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
if parameter["env"] != _|_ {
env: parameter.env
}
if context["config"] != _|_ {
env: context.config
}
ports: [{
containerPort: parameter.port
}]
if parameter["cpu"] != _|_ {
resources: {
limits:
cpu: parameter.cpu
requests:
cpu: parameter.cpu
}
}
}]
}
}
}
}
parameter: {
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Commands to run in the container
cmd?: [...string]
// +usage=Which port do you want customer traffic sent to
// +short=p
port: *80 | int
// +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=Number of CPU units for the service, like `0.5` (0.5 CPU core), `1` (1 CPU core)
cpu?: string
}

View File

@@ -3,49 +3,47 @@ apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
name: worker
namespace: {{.Values.systemDefinitionNamespace}}
annotations:
definition.oam.dev/description: "Describes long-running, scalable, containerized services that running at backend. They do NOT have network endpoint to receive external network traffic."
spec:
definitionRef:
name: deployments.apps
extension:
template: |
output: {
apiVersion: "apps/v1"
kind: "Deployment"
spec: {
selector: matchLabels: {
"app.oam.dev/component": context.name
}
template: {
metadata: labels: {
"app.oam.dev/component": context.name
}
spec: {
containers: [{
name: context.name
image: parameter.image
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
}]
}
}
selector:
matchLabels:
"app.oam.dev/component": context.name
}
}
parameter: {
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Commands to run in the container
cmd?: [...string]
}
schematic:
cue:
template: |
output: {
apiVersion: "apps/v1"
kind: "Deployment"
spec: {
selector: matchLabels: {
"app.oam.dev/component": context.name
}
template: {
metadata: labels: {
"app.oam.dev/component": context.name
}
spec: {
containers: [{
name: context.name
image: parameter.image
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
}]
}
}
}
}
parameter: {
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Commands to run in the container
cmd?: [...string]
}

View File

@@ -113,9 +113,12 @@ spec:
- "--webhook-cert-dir={{ .Values.certificate.mountPath }}"
{{ end }}
- "--health-addr=:{{ .Values.healthCheck.port }}"
- "--apply-once-only={{ .Values.applyOnceOnly }}"
{{ if ne .Values.disableCaps "" }}
- "--disable-caps={{ .Values.disableCaps }}"
{{ end }}
- "--concurrent-reconciles={{ .Values.concurrentReconciles }}"
- "--depend-check-wait={{ .Values.dependCheckWait }}"
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
imagePullPolicy: {{ quote .Values.image.pullPolicy }}
resources:
@@ -145,11 +148,13 @@ spec:
name: tls-cert-vol
readOnly: true
{{ end }}
{{ if .Values.useWebhook }}
volumes:
- name: tls-cert-vol
secret:
defaultMode: 420
secretName: {{ .Values.certificate.secretName | quote }}
{{ end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}

View File

@@ -1,31 +0,0 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: vela-config
# TODO: Currently namespace MUST be vela-system
namespace: vela-system
data:
servicemonitors.monitoring.coreos.com: |
{
"repo": "prometheus-community",
"urL": "https://prometheus-community.github.io/helm-charts",
"name": "kube-prometheus-stack",
"namespace": "monitoring",
"version": "9.4.4"
}
flagger.app: |
{
"repo": "oam-flagger",
"urL": "https://oam.dev/flagger/archives/",
"name": "flagger",
"namespace": "vela-system",
"version": "1.1.0"
}
keda: |
{
"repo": "kedacore",
"urL": "https://kedacore.github.io/charts",
"name": "keda",
"namespace": "keda",
"version": "2.0.0-rc3"
}

View File

@@ -142,6 +142,28 @@ webhooks:
admissionReviewVersions:
- v1beta1
timeoutSeconds: 5
- clientConfig:
caBundle: Cg==
service:
name: {{ template "kubevela.name" . }}-webhook
namespace: {{ .Release.Namespace }}
path: /validating-core-oam-dev-v1alpha2-traitdefinitions
failurePolicy: Fail
name: validating.core.oam.dev.v1alpha2.traitdefinitions
rules:
- apiGroups:
- core.oam.dev
apiVersions:
- v1alpha2
operations:
- CREATE
- UPDATE
resources:
- traitdefinitions
scope: Cluster
admissionReviewVersions:
- v1beta1
timeoutSeconds: 5
- clientConfig:
caBundle: Cg==
service:
@@ -208,6 +230,8 @@ metadata:
spec:
selfSigned: {}
# The following Certificate will generate a secret for vela-core
# This rely on the system has a installed cert-manager in it.
---
apiVersion: cert-manager.io/v1
kind: Certificate

View File

@@ -3,6 +3,9 @@
# Declare variables to be passed into your templates.
replicaCount: 1
installCertManager: false
# Valid applyOnceOnly values: true/false/on/off/force
applyOnceOnly: "off"
useWebhook: true
# By default, don't disable any builtin capabilities
disableCaps: ""
@@ -81,3 +84,11 @@ certificate:
secretName: webhook-server-cert
mountPath: /etc/k8s-webhook-certs
caBundle: replace-me
systemDefinitionNamespace: vela-system
# concurrentReconciles is the concurrent reconcile number of the controller
concurrentReconciles: 4
# dependCheckWait is the time to wait for ApplicationConfiguration's dependent-resource ready
dependCheckWait: 30s

View File

@@ -9,37 +9,37 @@ import (
"os/signal"
"path/filepath"
"strconv"
"strings"
"syscall"
"time"
monitoring "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1"
"github.com/crossplane/crossplane-runtime/pkg/logging"
"github.com/go-logr/logr"
injectorv1alpha1 "github.com/oam-dev/trait-injector/api/v1alpha1"
injectorcontroller "github.com/oam-dev/trait-injector/controllers"
"github.com/oam-dev/trait-injector/pkg/injector"
"github.com/oam-dev/trait-injector/pkg/plugin"
kruise "github.com/openkruise/kruise-api/apps/v1alpha1"
certmanager "github.com/wonderflow/cert-manager-api/pkg/apis/certmanager/v1"
kedav1alpha1 "github.com/wonderflow/keda-api/api/v1alpha1"
"go.uber.org/zap/zapcore"
"gopkg.in/natefinch/lumberjack.v2"
crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
oamcore "github.com/oam-dev/kubevela/apis/core.oam.dev"
velacore "github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
"github.com/oam-dev/kubevela/pkg/appfile/driver"
velacontroller "github.com/oam-dev/kubevela/pkg/controller"
oamcontroller "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
oamv1alpha2 "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1alpha2"
"github.com/oam-dev/kubevela/pkg/controller/dependency"
"github.com/oam-dev/kubevela/pkg/controller/utils"
velawebhook "github.com/oam-dev/kubevela/pkg/webhook"
oamwebhook "github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev/v1alpha2"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/utils/system"
oamwebhook "github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev"
velawebhook "github.com/oam-dev/kubevela/pkg/webhook/standard.oam.dev"
"github.com/oam-dev/kubevela/version"
)
@@ -58,11 +58,10 @@ func init() {
_ = clientgoscheme.AddToScheme(scheme)
_ = crdv1.AddToScheme(scheme)
_ = oamcore.AddToScheme(scheme)
_ = monitoring.AddToScheme(scheme)
_ = velacore.AddToScheme(scheme)
_ = injectorv1alpha1.AddToScheme(scheme)
_ = certmanager.AddToScheme(scheme)
_ = kedav1alpha1.AddToScheme(scheme)
_ = kruise.AddToScheme(scheme)
// +kubebuilder:scaffold:scheme
}
@@ -76,6 +75,9 @@ func main() {
var controllerArgs oamcontroller.Args
var healthAddr string
var disableCaps string
var storageDriver string
var syncPeriod time.Duration
var applyOnceOnly string
flag.BoolVar(&useWebhook, "use-webhook", false, "Enable Admission Webhook")
flag.BoolVar(&useTraitInjector, "use-trait-injector", false, "Enable TraitInjector")
@@ -92,11 +94,19 @@ func main() {
flag.IntVar(&controllerArgs.RevisionLimit, "revision-limit", 50,
"RevisionLimit is the maximum number of revisions that will be maintained. The default value is 50.")
flag.StringVar(&healthAddr, "health-addr", ":9440", "The address the health endpoint binds to.")
flag.BoolVar(&controllerArgs.ApplyOnceOnly, "apply-once-only", false,
"For the purpose of some production environment that workload or trait should not be affected if no spec change")
flag.StringVar(&applyOnceOnly, "apply-once-only", "false",
"For the purpose of some production environment that workload or trait should not be affected if no spec change, available options: on, off, force.")
flag.StringVar(&controllerArgs.CustomRevisionHookURL, "custom-revision-hook-url", "",
"custom-revision-hook-url is a webhook url which will let KubeVela core to call with applicationConfiguration and component info and return a customized component revision")
flag.StringVar(&disableCaps, "disable-caps", "", "To be disabled builtin capability list.")
flag.StringVar(&storageDriver, "storage-driver", driver.LocalDriverName, "Application file save to the storage driver")
flag.DurationVar(&syncPeriod, "informer-re-sync-interval", 2*time.Hour, "controller shared informer lister full re-sync period. The default value is 2 hours")
flag.StringVar(&oam.SystemDefinitonNamespace, "system-definition-namespace", "vela-system", "define the namespace of the system-level definition")
flag.DurationVar(&controllerArgs.LongWait, "long-wait", 1*time.Minute, "long-wait is controller next reconcile interval time like 30s, 2m etc. The default value is 1m,"+
" you can set it to 0 for no reconcile routine after success")
flag.IntVar(&controllerArgs.ConcurrentReconciles, "concurrent-reconciles", 4, "concurrent-reconciles is the concurrent reconcile number of the controller. The default value is 4")
flag.DurationVar(&controllerArgs.DependCheckWait, "depend-check-wait", 30*time.Second, "depend-check-wait is the time to wait for ApplicationConfiguration's dependent-resource ready."+
"The default value is 30s, which means if dependent resources were not prepared, the ApplicationConfiguration would be reconciled after 30s.")
flag.Parse()
// setup logging
@@ -118,16 +128,12 @@ func main() {
setupLog.Info(fmt.Sprintf("KubeVela Version: %s, GIT Revision: %s.", version.VelaVersion, version.GitRevision))
setupLog.Info(fmt.Sprintf("Disable Capabilities: %s.", disableCaps))
setupLog.Info(fmt.Sprintf("core init with definition namespace %s", oam.SystemDefinitonNamespace))
// install dependency charts first
k8sClient, err := client.New(ctrl.GetConfigOrDie(), client.Options{Scheme: scheme})
if err != nil {
setupLog.Error(err, "unable to create a kubernetes client")
os.Exit(1)
}
go dependency.Install(k8sClient)
restConfig := ctrl.GetConfigOrDie()
restConfig.UserAgent = kubevelaName + "/" + version.GitRevision
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
Scheme: scheme,
MetricsBindAddress: metricsAddr,
LeaderElection: enableLeaderElection,
@@ -136,6 +142,7 @@ func main() {
Port: webhookPort,
CertDir: certDir,
HealthProbeBindAddress: healthAddr,
SyncPeriod: &syncPeriod,
})
if err != nil {
setupLog.Error(err, "unable to create a controller manager")
@@ -154,7 +161,7 @@ func main() {
if useWebhook {
setupLog.Info("vela webhook enabled, will serving at :" + strconv.Itoa(webhookPort))
if err = oamwebhook.Add(mgr); err != nil {
if err = oamwebhook.Register(mgr); err != nil {
setupLog.Error(err, "unable to setup oam runtime webhook")
os.Exit(1)
}
@@ -165,6 +172,23 @@ func main() {
}
}
switch strings.ToLower(applyOnceOnly) {
case "", "false", string(oamcontroller.ApplyOnceOnlyOff):
controllerArgs.ApplyMode = oamcontroller.ApplyOnceOnlyOff
setupLog.Info("ApplyOnceOnly is disabled")
case "true", string(oamcontroller.ApplyOnceOnlyOn):
controllerArgs.ApplyMode = oamcontroller.ApplyOnceOnlyOn
setupLog.Info("ApplyOnceOnly is enabled, that means workload or trait only apply once if no spec change even they are changed by others")
case string(oamcontroller.ApplyOnceOnlyForce):
controllerArgs.ApplyMode = oamcontroller.ApplyOnceOnlyForce
setupLog.Info("ApplyOnceOnlyForce is enabled, that means workload or trait only apply once if no spec change even they are changed or deleted by others")
default:
setupLog.Error(fmt.Errorf("invalid apply-once-only value: %s", applyOnceOnly),
"unable to setup the vela core controller",
"valid apply-once-only value:", "on/off/force, by default it's off")
os.Exit(1)
}
if err = oamv1alpha2.Setup(mgr, controllerArgs, logging.NewLogrLogger(setupLog)); err != nil {
setupLog.Error(err, "unable to setup the oam core controller")
os.Exit(1)
@@ -174,6 +198,15 @@ func main() {
setupLog.Error(err, "unable to setup the vela core controller")
os.Exit(1)
}
if driver := os.Getenv(system.StorageDriverEnv); len(driver) == 0 {
// first use system environment,
err := os.Setenv(system.StorageDriverEnv, storageDriver)
if err != nil {
setupLog.Error(err, "unable to setup the vela core controller")
os.Exit(1)
}
}
setupLog.Info("use storage driver", "storageDriver", os.Getenv(system.StorageDriverEnv))
if useTraitInjector {
// register all service injectors
@@ -195,10 +228,7 @@ func main() {
setupLog.Info("starting the vela controller manager")
if controllerArgs.ApplyOnceOnly {
setupLog.Info("applyOnceOnly is enabled that means workload or trait only apply once if no spec change even they are changed by others")
}
if err := mgr.Start(makeSignalHandler(setupLog, k8sClient)); err != nil {
if err := mgr.Start(makeSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}
@@ -262,8 +292,7 @@ func waitWebhookSecretVolume(certDir string, timeout, interval time.Duration) er
}
}
//nolint:unparam
func makeSignalHandler(log logr.Logger, kubecli client.Client) (stopCh <-chan struct{}) {
func makeSignalHandler() (stopCh <-chan struct{}) {
stop := make(chan struct{})
c := make(chan os.Signal, 2)
@@ -271,10 +300,6 @@ func makeSignalHandler(log logr.Logger, kubecli client.Client) (stopCh <-chan st
go func() {
<-c
// Do not uninstall when vela-core terminating.
// When running on K8s, old pod will terminate after new pod running, it will cause charts uninstalled.
// https://github.com/oam-dev/kubevela/issues/499
// dependency.Uninstall(kubecli)
close(stop)
// second signal. Exit directly.

View File

@@ -0,0 +1,21 @@
apiVersion: core.oam.dev/v1alpha2
kind: Application
metadata:
name: application-sample
spec:
components:
- name: myweb
type: worker
settings:
image: "busybox"
cmd:
- sleep
- "1000"
lives: "3"
enemies: "alien"
traits:
- name: ingress
properties:
domain: "www.example.com"
http:
"/": 80

View File

@@ -0,0 +1,124 @@
apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
name: nworker
annotations:
definition.oam.dev/description: "Describes long-running, scalable, containerized services that running at backend. They do NOT have network endpoint to receive external network traffic."
spec:
definitionRef:
name: deployments.apps
status:
healthPolicy: |
isHealth: (context.output.status.readyReplicas > 0) && (context.output.status.readyReplicas == context.output.status.replicas)
customStatus: |-
message: "type: " + context.output.spec.template.spec.containers[0].image + ",\t enemies:" + context.outputs.gameconfig.data.enemies
schematic:
cue:
template: |
output: {
apiVersion: "apps/v1"
kind: "Deployment"
spec: {
selector: matchLabels: {
"app.oam.dev/component": context.name
}
template: {
metadata: labels: {
"app.oam.dev/component": context.name
}
spec: {
containers: [{
name: context.name
image: parameter.image
envFrom: [{
configMapRef: name: context.name + "game-config"
}]
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
}]
}
}
}
}
outputs: gameconfig: {
apiVersion: "v1"
kind: "ConfigMap"
metadata: {
name: context.name + "game-config"
}
data: {
enemies: parameter.enemies
lives: parameter.lives
}
}
parameter: {
// +usage=Which image would you like to use for your service
// +short=i
image: string
// +usage=Commands to run in the container
cmd?: [...string]
lives: string
enemies: string
}
---
apiVersion: core.oam.dev/v1alpha2
kind: TraitDefinition
metadata:
name: ingress
spec:
status:
customStatus: |-
message: "type: "+ context.outputs.service.spec.type +",\t clusterIP:"+ context.outputs.service.spec.clusterIP+",\t ports:"+ "\(context.outputs.service.spec.ports[0].port)"+",\t domain"+context.outputs.ingress.spec.rules[0].host
healthPolicy: |
isHealth: len(context.outputs.service.spec.clusterIP) > 0
schematic:
cue:
template: |
parameter: {
domain: string
http: [string]: int
}
// trait template can have multiple outputs in one trait
outputs: service: {
apiVersion: "v1"
kind: "Service"
spec: {
selector:
app: context.name
ports: [
for k, v in parameter.http {
port: v
targetPort: v
},
]
}
}
outputs: ingress: {
apiVersion: "networking.k8s.io/v1beta1"
kind: "Ingress"
metadata:
name: context.name
spec: {
rules: [{
host: parameter.domain
http: {
paths: [
for k, v in parameter.http {
path: k
backend: {
serviceName: context.name
servicePort: v
}
},
]
}
}]
}
}

View File

@@ -7,37 +7,55 @@ In the root folder of this project, run `make start-dashboard` to start backend
```shell
➜ xxx/src/github.com/oam-dev/kubevela $ make start-dashboard
go run pkg/server/main/startAPIServer.go &
cd dashboard && yarn && yarn start && cd ..
yarn install v1.22.4
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/5] 🔍 Validating package.json...
[2/5] 🔍 Resolving packages...
success Already up-to-date.
$ umi g tmp
✨ Done in 5.89s.
yarn run v1.22.4
$ umi dev
Starting the development server...
I1230 10:37:54.157092 14236 request.go:621] Throttling request took 1.04915427s, request: GET:https://47.242.145.141:6443/apis/split.smi-spec.io/v1alpha2?timeout=32s
cd dashboard && npm install && npm start && cd ..
I0205 11:25:55.742786 5535 request.go:621] Throttling request took 1.002149891s, request: GET:https://47.242.145.141:6443/apis/coordination.k8s.io/v1beta1?timeout=32s
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] POST /api/envs/ --> github.com/oam-dev/kubevela/pkg/server.(*APIServer).CreateEnv-fm (6 handlers)
[GIN-debug] PUT /api/envs/:envName --> github.com/oam-dev/kubevela/pkg/server.(*APIServer).UpdateEnv-fm (6 handlers)
...
[GIN-debug] GET /api/version --> github.com/oam-dev/kubevela/pkg/server.(*APIServer).GetVersion-fm (6 handlers)
[GIN-debug] GET /swagger/*any --> github.com/swaggo/gin-swagger.CustomWrapHandler.func1 (7 handlers)
[GIN-debug] GET /api/envs/:envName --> github.com/oam-dev/kubevela/pkg/server.(*APIServer).GetEnv-fm (6 handlers)
[GIN-debug] GET /api/envs/ --> github.com/oam-dev/kubevela/pkg/server.(*APIServer).ListEnv-fm (6 handlers)
> fsevents@1.2.13 install /Users/zhouzhengxi/Programming/golang/src/github.com/oam-dev/kubevela/dashboard/node_modules/watchpack-chokidar2/node_modules/fsevents
> node install.js
SOLINK_MODULE(target) Release/.node
CXX(target) Release/obj.target/fse/fsevents.o
SOLINK_MODULE(target) Release/fse.node
> ejs@2.7.4 postinstall /Users/zhouzhengxi/Programming/golang/src/github.com/oam-dev/kubevela/dashboard/node_modules/umi-webpack-bundle-analyzer/node_modules/ejs
> node ./postinstall.js
Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/)
> kubevela@0.0.1 postinstall /Users/zhouzhengxi/Programming/golang/src/github.com/oam-dev/kubevela/dashboard
> umi g tmp
added 1234 packages from 743 contributors, removed 49 packages, updated 85 packages and audited 3208 packages in 41.551s
235 packages are looking for funding
run `npm fund` for details
found 19 vulnerabilities (18 low, 1 high)
run `npm audit fix` to fix them, or `npm audit` for details
> kubevela@0.0.1 start /Users/zhouzhengxi/Programming/golang/src/github.com/oam-dev/kubevela/dashboard
> umi dev
Starting the development server...
✔ Webpack
Compiled successfully in 26.86s
Compiled successfully in 34.81s
DONE Compiled successfully in 26865ms 10:38:22 AM
DONE Compiled successfully in 34815ms 11:27:12 AM
App running at:
- Local: http://localhost:8000 (copied to clipboard)
- Network: http://192.168.31.114:8000
- Local: http://localhost:8002 (copied to clipboard)
- Network: http://30.240.99.101:8002
```
## Development
@@ -45,37 +63,11 @@ I1230 10:37:54.157092 14236 request.go:621] Throttling request took 1.04915427
### Install dependencies
```bash
yarn
```
### Build
```bash
yarn build
npm install
```
### Start up
```bash
yarn start
```
### Lint and Test
- Check code style
```bash
yarn lint
```
You can also use script to auto fix some lint error:
```bash
yarn prettier
```
- Test code
```bash
yarn test
npm start
```

View File

@@ -9,6 +9,12 @@
path: `/applications`,
component: './Application',
},
/* Application Create should be moved to /Application */
{
name: 'create_application',
path: '/applications/create',
component: './CreateApplication'
},
{
name: 'capability',
icon: 'AppstoreAddOutlined',

View File

@@ -54,6 +54,7 @@
"@umijs/route-utils": "^1.0.33",
"antd": "^4.9.4",
"classnames": "^2.2.6",
"form-render": "^0.9.0",
"dayjs": "^1.9.7",
"lodash": "^4.17.11",
"moment": "^2.25.3",
@@ -63,6 +64,7 @@
"react-dev-inspector": "^1.1.1",
"react-dom": "^17.0.0",
"react-helmet-async": "^1.0.4",
"react-router-dom": "^5.2.0",
"umi": "^3.2.14",
"umi-request": "^1.0.8",
"use-merge-value": "^1.0.1"
@@ -100,7 +102,8 @@
"pro-download": "1.0.1",
"puppeteer-core": "^5.0.0",
"stylelint": "^13.0.0",
"typescript": "^4.1.2"
"typescript": "^4.1.2",
"webpack-plugin-fr-theme": "^0.2.0"
},
"engines": {
"node": ">=10.0.0"

View File

@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
import * as api from '@/services/traits';
import * as api from '@/services/capability';
interface State {
loading?: boolean;

View File

@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';
import * as api from '@/services/workloads';
import * as api from '@/services/capability';
interface State {
loading?: boolean;

View File

@@ -6,6 +6,8 @@ import { Link, useModel, useRequest } from 'umi';
import { deleteApplication, getApplications } from '@/services/application';
import { PlusOutlined } from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-layout';
// @ts-ignore
import { Link as ReactLink } from 'react-router-dom';
export default () => {
const { currentEnvironment } = useModel('useEnvironmentModel');
@@ -42,7 +44,7 @@ export default () => {
<div style={{ marginBottom: '10px' }}>
<Space>
<Button type="primary" icon={<PlusOutlined />}>
Create
<ReactLink to="/applications/create"> Create</ReactLink>
</Button>
</Space>
</div>

View File

@@ -0,0 +1,174 @@
import React, { useState } from 'react';
import { Input, Dropdown, Menu, Button, Divider, Row, Col } from 'antd';
import { useModel } from '@@/plugin-model/useModel';
import { DownOutlined, UserOutlined } from '@ant-design/icons';
import FormRender from 'form-render/lib/antd';
import { getCapabilityOpenAPISchema } from '@/services/capability';
// prevent Ant design style from being overridden
import 'antd/dist/antd.css';
export default (): React.ReactNode => {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { workloadsLoading, workloadList } = useModel('useWorkloadsModel');
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { traitsLoading, traitsList } = useModel('useTraitsModel');
const workloadMenuList = workloadList?.map((i) => (
<Menu.Item
key={i.name}
icon={<UserOutlined />}
onClick={() => handleMenuClick('workload_type', i.name)}
>
{i.name}
</Menu.Item>
));
const traitMenuList = traitsList?.map((i) => (
<Menu.Item
key={i.name}
icon={<UserOutlined />}
onClick={() => handleMenuClick('trait', i.name)}
>
{i.name}
</Menu.Item>
));
const workloadsMenu = <Menu>{workloadMenuList}</Menu>;
const traitsMenu = <Menu>{traitMenuList}</Menu>;
// Capability parameters form render
const [formData, setData] = useState({});
// schema is OpenAPI Schema JSON data
const [workloadSchema, setWorkloadSchema] = useState({});
const [traitSchema, setTraitSchema] = useState({});
const [valid, setValid] = useState([]);
function handleMenuClick(capabilityType: string, capabilityName: string) {
console.log('click', capabilityName);
getCapabilityOpenAPISchema(capabilityName).then((result) => {
const data = JSON.parse(result.data);
if (capabilityType === 'workload_type') {
setWorkloadSchema(data);
} else if (capabilityType === 'trait') {
setTraitSchema(data);
}
});
}
const onSubmit = () => {
// valid == 0: validation passed
if (valid.length > 0) {
alert(`invalid${valid.toString()}`);
} else {
alert(JSON.stringify(formData, null, 2));
}
};
return (
<div style={{ maxWidth: 600 }}>
<Row>
<Col span="4">Application</Col>
<Col span="20" />
</Row>
<Row>
<Col span="4">Name:</Col>
<Col span="8">
<Input placeholder="Basic usage" />
</Col>
<Col span="12" />
</Row>
<Row>
<Col span="24">
<Divider />
</Col>
</Row>
<Row>
<Col span="4">Services</Col>
<Col span="20" />
</Row>
<Row>
<Col span="4">Name:</Col>
<Col span="8">
<Input placeholder="Basic usage" />
</Col>
<Col span="12" />
</Row>
<Row>
<Col span="4">Type:</Col>
<Col span="20">
<Dropdown overlay={workloadsMenu}>
<a className="ant-dropdown-link">
Select <DownOutlined />
</a>
</Dropdown>
</Col>
</Row>
<Row>
<Col span="4">Settings:</Col>
<Col span="20">
<FormRender
schema={workloadSchema}
formData={formData}
onChange={setData}
onValidate={setValid}
displayType="column"
/>
</Col>
</Row>
<Row>
<Col span="24">
<Divider />
</Col>
</Row>
<Row>
<Col span="4">Traits</Col>
<Col span="20" />
</Row>
<Row>
<Col span="4">Type:</Col>
<Col span="20">
<Dropdown overlay={traitsMenu}>
<a className="ant-dropdown-link" onClick={(e) => e.preventDefault()}>
Select <DownOutlined />
</a>
</Dropdown>
</Col>
</Row>
<Row>
<Col span="4">Properties:</Col>
<Col span="20">
<FormRender
schema={traitSchema}
formData={formData}
onChange={setData}
onValidate={setValid}
displayType="column"
/>
</Col>
</Row>
<Row>
<Col span="8" />
<Col span="8">
<Button onClick={onSubmit} type="primary">
Submit
</Button>
</Col>
<Col span="8" />
</Row>
</div>
);
};

View File

@@ -0,0 +1,21 @@
import { request } from 'umi';
/*
* workload type list: get /api/workloads/
*/
export async function getWorkloads(): Promise<API.VelaResponse<API.Workloads[]>> {
return request('/api/workloads');
}
/*
* trait list: get /api/traits/
*/
export async function getTraits(): Promise<API.VelaResponse<API.Traits[]>> {
return request('/api/traits');
}
export async function getCapabilityOpenAPISchema(
capabilityName: string,
): Promise<API.VelaResponse<string>> {
return request(`/api/definitions/${capabilityName}`, { method: 'get' });
}

View File

@@ -1,10 +0,0 @@
import { request } from 'umi';
const BASE_PATH = '/api/traits';
/*
* trait 列表: get /api/traits/
*/
export async function getTraits(): Promise<API.VelaResponse<API.Traits[]>> {
return request(BASE_PATH);
}

View File

@@ -1,10 +0,0 @@
import { request } from 'umi';
const BASE_PATH = '/api/workloads';
/*
* workload 列表: get /api/workloads/
*/
export async function getWorkloads(): Promise<API.VelaResponse<API.Workloads[]>> {
return request(BASE_PATH);
}

View File

@@ -0,0 +1,24 @@
# KubeVela Controller Parameters Reference
| parameter | type | default | describe |
| :-------------------------: | :----: | :-------------------------------: | :----------------------------------------------------------: |
| use-webhook | bool | false | Enable Admission Webhook |
| use-trait-injector | bool | false | Enable TraitInjector |
| webhook-cert-dir | string | /k8s-webhook-server/serving-certs | Admission webhook cert/key dir. |
| metrics-addr | string | :8080 | The address the metric endpoint binds to. |
| enable-leader-election | bool | false | Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager. |
| leader-election-namespace | string | "" | Determines the namespace in which the leader election configmap will be created. |
| log-file-path | string | "" | The file to write logs to. |
| log-retain-date | int | 7 | The number of days of logs history to retain. |
| log-compress | bool | true | Enable compression on the rotated logs. |
| revision-limit | int | 50 | revision-limit is the maximum number of revisions that will be maintained. The default value is 50. |
| health-addr | string | :9440 | The address the health endpoint binds to. |
| apply-once-only | string | false | For the purpose of some production environment that workload or trait should not be affected if no spec change, available options: on, off, force. |
| custom-revision-hook-url | string | "" | custom-revision-hook-url is a webhook url which will let KubeVela core to call with applicationConfiguration and component info and return a customized component revision |
| disable-caps | string | "" | To be disabled builtin capability list. |
| storage-driver | string | Local | Application file save to the storage driver |
| informer-re-sync-interval | time | 2h | controller shared informer lister full re-sync period |
| system-definition-namespace | string | vela-system | define the namespace of the system-level definition |
| long-wait | time | 1m | long-wait is controller next reconcile interval time like 30s, 2m etc. The default value is 1m, you can set it to 0 for no reconcile routine after success |
| concurrent-reconciles | int | 4 | concurrent-reconciles is the concurrent reconcile number of the controller. |
| depend-check-wait | time | 30s | depend-check-wait is the time to wait for ApplicationConfiguration's dependent-resource ready. |

View File

@@ -2,20 +2,24 @@
## Summary
In KubeVela, APIServer provides the RESTful API for external systems (e.g. UI) to manage Vela abstractions like Applications, Definitions; Catalog stores templates to install common-off-the-shell (COTS) applications on Kubernetes.
In KubeVela, APIServer provides the RESTful API for external systems (e.g. UI) to manage Vela abstractions like Applications, Definitions; Catalog stores templates to install common-off-the-shell (COTS) capabilities on Kubernetes.
This doc provides a top-down architecture design for Vela APIServer and Catalog. It clarifies the API interfaces for platform builders to build integration solutions, and describes the architecture design in details for incoming roadmap. Some of the interfaces might have not been implemented yet, but we will follow this design in the future project roadmap.
This doc provides a top-down architecture design for Vela APIServer and Catalog. It clarifies the API interfaces for platform builders to build integration solutions and describes the architecture design in details for the incoming roadmap. Some of the interfaces might have not been implemented yet, but we will follow this design in the future project roadmap.
## Motivation
This design is based on and tries to resolve the following use cases:
1. UI component wants to discover APIs to integrate with Vela APIServer.
1. Users want to manage multiple clusters, catalogs, configuration environments in a single place.
1. Users want to manage multiple clusters, catalogues, configuration environments in a single place.
1. The management data can be stored in a cloud database like MySQL instead of k8s control plane.
1. Because there aren't control logic for those data. This is unlike other Vela resources stored as CR in K8s control plane.
1. It is more expensive to host a k8s control plane than MySQL database on cloud.
1. Users want to manage OTS applications via a well-defined, standard Catalog API interface and Package format.
1. Users want to manage third-party capabilities via a well-defined, standard Catalog API interface and Package format.
1. Here is the workflow of creating an application:
- The user chooses an environment
- The user chooses one or more clusters in the environment
- The user configures the service deployment configuration such as replica count, instance labels, container image, domain name, port number, etc.
## Proposal
@@ -25,15 +29,15 @@ The overall architecture diagram:
![alt](../../docs/resources/apiserver-arch.jpg)
Here is the workflow:
Here's some explanation of the diagram:
- UI requests APIServer for data to render the dashboard.
- Vela APIServer aggregates data from different kinds of sources.
- Vela APIServer can sync with multiple k8s clusters.
- Vela APIServer can sync with multiple catalog servers.
- For those data not in k8s or catalog servers, Vela APIServer stores them in MySQL database.
- For those data not in k8s or catalog servers, Vela APIServer syncs them in MySQL database.
Here is what a full platform deployment would look like:
The above architecture implies that the Vela APIServer could be used to multiple k8s clusters and catalogs. Below is what a deployment of Vela platform would look like:
![alt](../../docs/resources/api-workflow.png)
@@ -64,16 +68,14 @@ Environment is a collection of configurations of the application and dependent r
```json
{
"id": "env-1",
// The clusters bound to this environment
"clusters": [
{
"id": "cluster-1"
}
],
"applications": [
{
"id": "app-1"
}
],
"config": {
"foo": "bar"
}
@@ -82,7 +84,7 @@ Environment is a collection of configurations of the application and dependent r
#### Application API
Application is a global unit to manage cross-cluster, cross-namespace application deployment. An application can only belong to one environment.
Application is a global unit to manage cross-cluster, cross-namespace application deployment.
- `/applications`
- Description: List all applications
@@ -91,16 +93,34 @@ Application is a global unit to manage cross-cluster, cross-namespace applicatio
```json
{
"id": "app-1",
"clusters": [
"configuration": {
"services": {
"testsvc": {
"type": "webservice",
"image": "crccheck/hello-world"
}
}
},
// An application could be deployed to multiple environments
"environments": [
{
"id": "cluster-1",
"deployments": [
"id": "env-1",
// In each env it could deploy to multiple clusters
"clusters": [
{
"id": "deploy-1"
"id": "cluster-1",
"deployments": [
{
"id": "deploy-1",
"namespace": "ns-1"
}
]
}
]
}
],
]
}
```
@@ -113,20 +133,18 @@ Application is a global unit to manage cross-cluster, cross-namespace applicatio
```json
{
"id": "cluster-1",
"applications": [
{
"id": "app-1",
"deployments": [
{
"id": "deploy-1"
}
]
}
],
// The definitions indicate the capabilties enabled in this cluster
"definitions": [
{
"id": "def-1"
}
],
"deployments": [
{
"id": "deploy-1"
}
]
}
```
@@ -139,12 +157,8 @@ Application is a global unit to manage cross-cluster, cross-namespace applicatio
{
"id": "deploy-1",
"namespace": "ns-1",
"services": {
"testsvc": {
"type": "webservice",
"image": "crccheck/hello-world"
}
}
"resources": {},
"status": {},
}
```
@@ -168,19 +182,19 @@ Application is a global unit to manage cross-cluster, cross-namespace applicatio
- `/catalogs`
- Description: List all catalogs.
- `/catalogs/<catalog>`
- Description: CRUD operations of a catalog.
```json
{
"namespace": "ns-1",
"name": "pkg-1",
"name": "catalog-1",
"address": "example.com:8080",
"protocols": {
"git": {
"root": "catalog"
"root_dir": "catalog/"
}
}
}
```
- Description: CRUD operations of a catalog.
- `/catalogs/<catalog>/sync`
- Description: Sync this catalog.
- `/catalogs/<catalog>/packages`
@@ -194,33 +208,32 @@ Application is a global unit to manage cross-cluster, cross-namespace applicatio
### 3. Catalog Design
This section will provide the design of the catalog repo file structure and its interaction with APIServer and users.
This section will describe the design of the catalog structure, how it interacts with APIServer, and the workflow users install packages.
#### Catalog repo structure
#### Catalog structure
All packages are put within `/catalog/` dir (This is configurable). Under `/catalog/` dir the package files obey the following structure:
All packages are put under `/catalog/` dir (this is configurable). The directory structure follows a predefined format:
```bash
/catalog/
/catalog/ # a catalog consists of multiple packages
|-- <package>
|-- v1.0
|-- v1.0 # a package consists of multiple versions
|-- metadata.yaml
|-- definitions/
|-- xxx-workload.yaml
|-- xxx-trait.yaml
|-- parameters.yaml
|-- conditions/
|-- check-crd.yaml
|-- hooks/
|-- pre-install.yaml
|-- chart/
|-- modules.yaml
|-- v2.0
|-- <package>
```
A catalog contains multiple packages, and a package contains multiple versions. Below we will explain the format of each package version:
The structure of one package version contains:
- `metadata.yaml` defines the metadata of the package.
- `metadata.yaml`: the metadata of the package.
```yaml
name: "foo"
@@ -233,33 +246,11 @@ A catalog contains multiple packages, and a package contains multiple versions.
url: "https://..."
label:
category: foo
# use existing Helm Chart as the manifest source for this package
chart:
# choose either local path or remote repo
path: ./chart/
remote:
repo: https://charts.bitnami.com/bitnami
name: redis
```
Note that we choose to integrate with existing community solutions instead of inventing another packaging solution (e.g. Helm, Terraform). In this way we can adopt the reservoir of community resources and also be extensible to more packaing formats.
- `definitions`: definition files that describe the capabilities from this package to enable on a cluster. Note that these definitions will compared against a cluster on APIServer side to see if a cluster can install or upgrade this package.
- Each package could expose multiple workload and trait definitions under `definitions/`. These definitions will be parsed on APIServer side to check if a cluster needs install or upgrade this package by comparing definitions.
- The parameters of this package are defined in `parameters.yaml` . It will be used as the values to render the manifest source (e.g. Helm Chart).
```yaml
parameters:
- name: foo
type: string
description: |
More details about the parameter
default: "bar"
- name: bar
type: integer
```
- `conditions/` contains the conditional checks before deploy. For example, check if a CRD with specific version exist, if not then the deployment should fail.
- `conditions/`: defining conditional checks before deploying this package. For example, check if a CRD with specific version exist, if not then the deployment should fail.
```yaml
# check-crd.yaml
@@ -273,7 +264,7 @@ A catalog contains multiple packages, and a package contains multiple versions.
value: "v1"
```
- `hooks/` contains manifests of lifecycle hooks which are the k8s jobs. It consists of pre-install, post-install, pre-uninstall, post-uninstall.
- `hooks/`:lifecycle hooks on deploying this package. These are the k8s jobs, and consists of pre-install, post-install, pre-uninstall, post-uninstall.
```yaml
# pre-install.yaml
@@ -290,12 +281,27 @@ A catalog contains multiple packages, and a package contains multiple versions.
command: ["/bin/pre-install"]
```
- `modules.yaml`: defining the modules that contain the actual resources, e.g. Helm Charts or Terraform modules. Note that we choose to integrate with existing community solutions instead of inventing our own format. In this way we can adopt the reservoir of community efforts and make the design extensible to more in-house formats as we have observed.
```yaml
modules:
- chart:
path: ./charts/ingress-nginx/ # local path in this package
remote:
repo: https://kubernetes.github.io/ingress-nginx
name: ingress-nginx
- terraform:
path: ./tf_modules/rds/ # local path in this package
remote:
source: terraform-aws-modules/rds/aws
version: "~> 2.0"
```
#### Register a catalog in APIServer
Please refer to `/catalogs/<catalog>` API endpoint above.
Under the hood, APIServer will scan the catalog repo based on the predefined structure to parse each packages and versions.
Under the hood, APIServer will scan the catalog repo based on the predefined structure to parse each packag and versions.
#### Sync a catalog in APIServer
@@ -309,18 +315,24 @@ Vela APIServer aggregates package information from multiple catalog servers. To
![alt](../../docs/resources/catalog-workflow.jpg)
In our future roadmap, we will build a catalog controller for each k8s cluster. Then we will add API endpoint to install the package in APIServer which basically creates a CR to trigger the controller to reconcile package installation into the cluster. We choose this instead of APIServer installing the package because in this way we can bypass the APIServer in the package data transfer path and avoid APIServer becoming single point of failure.
In our future roadmap, we will build a catalog controller for each k8s cluster. Then we will add API endpoint to install the package in APIServer which basically creates a CR to trigger the controller to reconcile package installation into the cluster. We choose this instead of APIServer installing the package because in this way we can bypass the APIServer in the package data transfer path and avoid APIServer becoming a single point of failure.
## Examples
## Considerations
### Package parameters
We can parse the schema of parameters from Helm Chart or Terraform. For example, Helm supports [value schema file](https://www.arthurkoziel.com/validate-helm-chart-values-with-json-schemas/) for input validation and there is an [automation tool](https://github.com/karuppiah7890/helm-schema-gen) to generate the schema.
### Package dependency
Instead of having multiple definitions in one package, we could define that one package correlates to one definition only. But some users will need a bundle of definitions instead of one. For example, a full-observability trait might include a prometheus package, a grafana package, a loki package, and a jaeger package. This is what we call "package bundling".
To provide a bundle of definitions, we could define package dependency. So a parent package could depend on multiple atomic packages to provide a full-fledged capability.
Package dependency solution will simplify the structure and provide more atomic packages. But this is not a simple problem and beyond the current scope. We will add this on future roadmap.
Package dependency solution will simplify the structure and provide more atomic packages. But this is not a simple problem and beyond the current scope. We will add this on the future roadmap.
### Multi-tenancy
For initial version we plan to implement APIServer without multi-tenancy. But as an applicatio platform we expect multi-tenancy is a necessary part of Vela. We will keep API compatibility and might add some sort of auth token (e.g. JWT) as a query parameter in the future.
For initial version we plan to implement APIServer without multi-tenancy. But as an application platform we expect multi-tenancy is a necessary part of Vela. We will keep API compatibility and might add some sort of auth token (e.g. JWT) as a query parameter in the future.

View File

@@ -127,3 +127,33 @@ Since discrepancy is found, vela-core controller will apply(update) the Deployme
Thus, the changes we made to the Deployment before will also be eliminated.
The same mechanism also works for Trait as well as Workload.
### Apply Once Only Force
Based on the same mechanism as `apply-once-only`, `apply-once-only-force` has a more strict method for apply only once.
It allows to skip re-creating a workload or trait that has already been DELETED from the cluster if its spec is not changed.
Besides the condition in `apply-once-only`, `apply-once-only-force` has one more condition:
- if the component revision not changed, the workload will not be applied.
## Usage
Three available options are provided to a vela-core runtime setup flag named `apply-one-only`, referring to three modes:
- off - `apply-once-only` is disabeld, this is the default option
- on - `apply-once-only` is enabled
- force - `apply-once-only-force` is enabled
You can set it through `helm` chart value `applyOnceOnly` which is "off" by default if omitted, for example
```shell
helm install -n vela-system kubevela ./charts/vela-core --set applyOnceOnly=on
```
or
```
helm install -n vela-system kubevela ./charts/vela-core --set applyOnceOnly=force
```

View File

@@ -0,0 +1,180 @@
# Apply workload/trait through 3-way-merge-patch
- Owner: Yue Wang(@captainroy-hy), Jianbo Sun(@wonderflow)
- Date: 01/21/2021
- Status: [Implemented](https://github.com/oam-dev/kubevela/pull/857)
## Intro
When an ApplicationConfiguration is deployed,
vela-core will create(apply) corresponding workload/trait instances and keep them stay align with the `spec` defined in ApplicationConfiguration through periodical reconciliation in AppConfig controller.
In each round of reconciliation, if the configurations rendered from AppConfig are changed comparing to last round reconciliation, it's required to apply all changes to the workloads or traits.
Additionally, it also allows others (anything except AppConfig controller, e.g., trait controllers) to modify workload/trait instances.
## Goals
Apply should handle three kinds of modification including
- add a field
- change a field
- remove a field by omitting it
Meanwhile, Apply should have no impact on changes made by others, namely, not eliminate or override those changes UNLESS the change is made upon fields that are rendered from AppConfig originally.
## Implementation
We employed the same mechanism as `kubectl apply`, that is, computing a 3-way diff based on target object's current state, modified state, and last-appied state.
Specifically, a new annotaion, `app.oam.dev/last-applied-configuration`, is introduced to record workload/trait's last-applied state.
Once there's a conflict on field, both changed by AppConfig and others, AppConfig's value will always override others' assignment.
## Impact on existing system
Before this implementation, vela-core use `JSON-Merge` patch to apply workloads and `update` to apply traits.
That brought several defects shown in below samples.
This section introduced a comparison between how old mechanism and new applies workload/trait, also shows how new Apply overcomed the defects.
### Apply Workloads
The reason why abandon json-merge patch is that, it cannot remove a field through unsetting value in the patched manifest.
#### Before
For example, apply below deployment as a workload. json-merge patch cannot remove `minReadySeconds` field through applying a modifiied manifest with `minReadySeconds` omitted .
```yaml
# original workload manifest
apiVersion: apps/v1
kind: Deployment
...
spec:
minReadySeconds: 60
replicas: 3
template:
spec:
containers:
- name: nginx
image: nginx:1.14.2
---
# modified workload manifest
apiVersion: apps/v1
kind: Deployment
...
spec:
# minReadySeconds: 60 <=== unset to remove field
replicas: 3
template:
spec:
containers:
- name: nginx
image: nginx:1.14.2
---
# result
apiVersion: apps/v1
kind: Deployment
...
spec:
minReadySeconds: 60 # <=== not removed
replicas: 3
template:
spec:
containers:
- name: nginx
image: nginx:1.14.2
```
#### After
By computing a 3-way diff, we can get a patch aware of the field set in last-applied manifest is omitted in the new modified manifest, namely, users wanna remove this field.
And an annotation, `app.oam.dev/last-applied-configuration`, is used to record last-applied-state of the resource for further use in computing 3-way diff next time.
```yaml
# result
apiVersion: apps/v1
kind: Deployment
metadata:
annotations: # v=== record last-applied-state
app.oam.dev/last-applied-configuration: |
{"apiVersion":"apps/v1","kind":"Deployment","metadata":{"name":"nginx-deployment","labels":{"app":"nginx"}},"spec":{"replicas":3,"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"name":"nginx","image":"nginx:1.14.2"}]}}}}
...
spec:
# minReadySeconds: 60 <=== removed successfully
replicas: 3
template:
spec:
containers:
- name: nginx
image: nginx:1.14.2
```
---
### Apply Traits
The reasons why abandon `update`
- update always eliminates all fields set by others (e.g., trait controllers)
- if trait contains immutable field (e.g., k8s Service), update fails
#### Before
For example, apply below Service as a trait.
```yaml
# original trait manifest
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: myweb
ports:
- protocol: TCP
port: 80
---
# after applying
apiVersion: v1
kind: Service
...
spec:
clusterIP: 172.21.7.149 # <=== immutable field
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: myweb
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
---
# update with original manifest fails
# reconciling also fails for cannot applying trait
```
Additonally, if a trait has no immutable field, update will eliminate all fields set by others.
```yaml
# original trait manifest
kind: Bar
spec:
f1: v1
# someone add a new field to it
kind: Bar
spec:
f1: v1
f2: v2 # <=== newly set field
# after reconciling AppConfig
kind: Bar
spec:
f1: v1
# f2: v2 <=== removed
```
But as described in [Goals](#goals) section, we expect to keep these changes.
#### After
Applying traits works in the same way as workloads. We use annotation, `app.oam.dev/last-applied-configuration`, to record last-applied manifest.
- Because 3-way diff will ignore the fields not touched in last-applied-state, the immutable fields will not be involved into patch data.
- Because 3-way diff also will ignore the fields set by others (others are not supposed to modify the field rendered from AppConfig), the changes made by others will be retained.

View File

@@ -100,13 +100,7 @@ $ kubectl create ns vela-system
$ kubectl apply -f charts/vela-core/templates/cert-manager.yaml
```
5. Install Vela Dependency ConfigMap
```shell script
$ kubectl apply -f charts/vela-core/templates/velaConfig.yaml
```
6. Delete your old oam-runtime deployment
5. Delete your old oam-runtime deployment
Find the running deployment.
@@ -122,13 +116,13 @@ Delete the deployment found.
$ kubectl -n oam-system delete deployment oam-kubernetes-runtime-oam
```
7. Install Certificate and Webhook for the new controller
6. Install Certificate and Webhook for the new controller
```shell script
$ helm template --release-name kubevela -n vela-system -s templates/webhook.yaml charts/vela-core/ | kubectl apply -f -
```
8. Install the new controller
7. Install the new controller
```shell script
$ helm template --release-name kubevela -n vela-system -s templates/kubevela-controller.yaml charts/vela-core/ | kubectl apply -f -

View File

@@ -0,0 +1,310 @@
# OAM Rollout Controller Design
- Owner: Ryan Zhang (@ryangzhang-oss)
- Date: 01/14/2021
- Status: Draft
## Table of Contents
- [Introduction](#introduction)
- [Two flavors of Rollout](#two-flavors-of-rollout)
- [Goals](#goals)
- [Proposal](#proposal)
- [Registration via Definition/Capability](#registration-via-definitioncapability)
- [Templating](#templating)
- [CLI/UI interoperability](#cliui-interoperability)
- [vela up](#vela-up)
- [Examples](#examples)
## Introduction
`Rollout` or `Upgrade` is one of the most essential "day 2" operation on any application
. KubeVela, as an application centric platform, definitely needs to provide a customized solution
to alleviate the burden on the application operators. There are several popular rollout solutions
, i.e. [flagger](https://flagger.app/), in the open source community. However, none of them
work directly with our OAM framework. Therefore, we propose to create an OAM native rollout
framework that can address all the application rollout/upgrade needs in Kubevela.
### Two flavors of Rollout
After hearing from the OAM community, it is clear to us that there are two flavors of rollout
that we need to support.
- One way is through an OAM trait. This flavor works for existing OAM applications that don't
have many specialized requirements such as interaction with other traits. For
example, most rollout operations don't work well with scaling operations. Thus, the
application operator needs to remove any scalar traits from the component before applying the
rollout trait. Another example is rollout operations usually also involve traffic spliting
of sorts. Thus, the application operators might also need to manually adjust the related
traffic trait before and after applying the rollout trait.
- The other ways is through a new applicationDeployment CR which directly reference different
versions of applications instead of workloads. This opens up the possibility for the controller
to solve conflicts between traits automatically. This resource, however, not a trait and requires
the application to be immutable.
### Design Principles and Goals
We design our controllers with the following principles in mind
- First, we want all flavors of rollout controllers share the same core rollout
related logic. The trait and application related logic can be easily encapsulated into its own
package.
- Second, the core rollout related logic is easily extensible to support different type of
workloads, i.e. Deployment, Cloneset, Statefulset, Daemonset or even customized workloads.
- Thirdly, the core rollout related logic has a well documented state machine that
does state transition explicitly.
- Finally, the controllers can support all the rollout/upgrade needs of an application running
in a production environment.
### Proposal Layout
Here is the rest of the proposal
- First, we will present the exact rollout CRD spec.
- Second, we will give a high level design on how do we plan to implement the controller.
- Third, we will present the state machine and their transition events.
- Finally, we will list common rollout scenarios and their corresponding user experience and
implementation details.
## Rollout API Design
Let's start with the rollout trait spec definition. The applicationDeployment spec is very similar.
```go
// RolloutTraitSpec defines the desired state of RolloutTrait
type RolloutTraitSpec struct {
// TargetRef references a target resource that contains the newer version
// of the software. We assumed that new resource already exists.
// This is the only resource we work on if the resource is a stateful resource (cloneset/statefulset)
TargetRef runtimev1alpha1.TypedReference `json:"targetRef"`
// SourceRef references the list of resources that contains the older version
// of the software. We assume that it's the first time to deploy when we cannot find any source.
// +optional
SourceRef []runtimev1alpha1.TypedReference `json:"sourceRef,omitempty"`
// RolloutPlan is the details on how to rollout the resources
RolloutPlan RolloutPlan `json:"rolloutPlan"`
}
```
The target and source here are the same as other OAM traits that refers to a workload instance
with its GVK and name.
We can see that the core part of the rollout logic is encapsulated by the `RolloutPlan` object. This
allows us to write multiple controllers that share the same logic without duplicating the code
. Here is the definition of the `RolloutPlan` structure.
```go
// RolloutPlan fines the details of the rollout plan
type RolloutPlan struct {
// RolloutStrategy defines strategies for the rollout plan
// +optional
RolloutStrategy RolloutStrategyType `json:"rolloutStrategy,omitempty"`
// The size of the target resource. The default is the same
// as the size of the source resource.
// +optional
TargetSize *int32 `json:"targetSize,omitempty"`
// The number of batches, default = 1
// mutually exclusive to RolloutBatches
// +optional
NumBatches *int32 `json:"numBatches,omitempty"`
// The exact distribution among batches.
// mutually exclusive to NumBatches
// +optional
RolloutBatches []RolloutBatch `json:"rolloutBatches,omitempty"`
// All pods in the batches up to the batchPartition (included) will have
// the target resource specification while the rest still have the source resource
// This is designed for the operators to manually rollout
// Default is the the number of batches which will rollout all the batches
// +optional
BatchPartition *int32 `json:"lastBatchToRollout,omitempty"`
// RevertOnDelete revert the rollout when the rollout CR is deleted, default is false
//+optional
RevertOnDelete bool `json:"revertOnDelete,omitempty"`
// Paused the rollout, default is false
//+optional
Paused bool `json:"paused,omitempty"`
// RolloutWebhooks provides a way for the rollout to interact with an external process
// +optional
RolloutWebhooks []RolloutWebhook `json:"rolloutWebhooks,omitempty"`
// CanaryMetric provides a way for the rollout process to automatically check certain metrics
// before complete the process
// +optional
CanaryMetric []CanaryMetric `json:"canaryMetric,omitempty"`
}
```
## User Experience Workflow
OAM rollout experience is different from flagger in some key areas and here are the
implications on its impact on the user experience.
- We assume that the resources it refers to are **immutable**. In contrast, flagger watches over a
target resource and reacts whenever the target's specification changes.
- The trait version of the controller refers to componentRevision.
- The application version of the controller refers to immutable application.
- The rollout logic **works only once** and stops after it reaches a terminal state. One can
still change the rollout plan in the middle of the rollout as long as it does not change the
pods that are already updated.
- The applicationDeployment controller only rollout one component in the applications for now.
- Users in general should rely on the rollout CR to do the actual rollout which means they
shall set the `replicas` or `partition` field of the new resources to the starting value
indicated in the [detailed rollout plan design](#rollout-plan-work-with-different-type-of-workloads).
## Notable implementation level design decisions
Here are some high level implementation design decisions that will impact the user experience of
rolling out.
### Rollout workflows
As we mentioned in the introduction section, we will implement two rollout controllers that work
on different levels. At the end, they both emit an in-memory rollout plan object which includes
references to the target and source kubernetes resources that the rollout planner will execute
upon. For example, the applicationDeployment controller will get the component from the
application and extract the real workload from it before passing it to the rollout plan object.
With that said, two controllers operate differently to extract the real workload. Here are the
high level descriptions of how each works.
#### ApplicationDeployment workflow
When an appDeployment is used to do application level rollout, **the target application
is not reconciled by the application controller yet**. This is to make sure the
appDeployment controller has the full control of the new application from the beginning.
We will use a pre-defined annotation "app.oam.dev/rollout" that equals to "true" to facilitate
that. We expect any system, such as the [kubevela apiserver](APIServer-Catalog.md), that
utilizes an appDeployment object to follow this rule.
- Upon creation, the appDeployment controller marks itself as the owner of the application. The
application controller will have built-in logic to ignore any applications that has the
"app.oam.dev/rollout-template" annotation set to true.
- The appDeployment controller can change the target application fields. For example,
- It might remove all the conflict traits, such as HPA during upgrade.
- It might modify the label selectors fields in the services to make sure there are ways to
differentiate traffic routing to the old and new application resources.
- The appDeployment controller will return the control of the new application back to the
application controller after it makes the initial adjustment of the application by removing the
annotation.
- We will use a webhook to ensure that the "rollout" annotation cannot be added back once removed.
- Upon a successful rollout, the appDeployment controller leaves no pods running for the old
application.
- Upon a failed rollout, the condition is not determined, it could result in an unstable state
since both the old and new applications have been modified.
- Thus, we introduced a `revertOnDelete` field so that a user can delete the appDeployment and
expect the old application to be intact, and the new application takes no effect.
#### Rollout trait workflow
The rollout traits controller only works with componentRevision.
- The component controller emits the new component revision when a new component is created or
updated.
- The application configuration controller emits the new component and assign the
componentRevision as the source and target of rollout trait.
- We assume that there is no other scalar related traits deployed at the same time. We will use
`conflict-with` fields in the traitDefinition and webhooks to enforce that.
- Upon a successful rollout, the rollout trait will keep the old component revision with no
pod left.
- Upon a failed rollout,the rollout trait will just stop and leaves the resource mixed. This
state mostly should still work since the other traits are not touched.
### Rollout plan work with different type of workloads
The rollout plan part of the rollout logic is shared between all rollout controller. It comes
with references to the target and source workload. The controller is responsible for fetching
the different revisions of the resources. Deployment and Cloneset represents the two major types
of resources in that Cloneset can contain both the new and old revisions at a stable state while
deployment only contains one version when it's stable.
#### Rollout plan works with deployment
It's pretty straightforward for the outer controller to create the in-memory target and source
deployment object since they are just a copy of the kubernetes resources.
- The deployment workload should set the **`Paused` field to be true** by the user in the
appDeployment case.
- Another options is for the user to leave the `replicas` field as 0 if the rollout does not have
access to that field.
- If the rollout is successful, the source deployment `replicas` field will be zero and the
target deployment will be the same as the original source.
- If the rollout failed, we will leave the state as it is.
- If the rollout failed and `revertOnDelete` is `true` and the rollout CR is deleted, then the
source deployment `replicas` field will be turned back to before rollout and the target deployment's `replicas` field will
be zero.
#### Rollout plan works with cloneset
The outer controller creates the in-memory target and source cloneset object with different image
ids. The source is only used when we do need to do rollback.
- The user should set the Cloneset workload's **`Paused` field to be true** by the user in the
appDeployment case.
- Another options is for the user to leave the `partition` field in a value that effectively stop
upgrade if the rollout does not have access to that field.
- The rollout plan mostly just adjusts the `partition` field in the Cloneset and leaves the rest
of the rollout logic to the Cloneset controller.
- If the rollout is successful, the `partition` field will be zero
- If the rollout failed, we will leave the `partition` field as the last time we touch it.
- If the rollout failed and `revertOnDelete` is `true` and the rollout CR is deleted, we will
perform a revert on the Cloneset. Note that only the latest Cloneset controller allows rollback
when one increases the `partition` field.
### Operational features
- We will use the same service mesh model as flagger in the sense that user needs to provide the
service mesh provider type and give us the reference to an ingress object.
- We plan to directly import the various flagger mesh implementation.
- We plan to import the implementation of notifiers from flagger too
- We can consider adding an alert rule in the rollout Plan api in the future
### We use webhook to validate whether the change to the rollout CRD is valid.
We will go with strict restrictions on the CRD update in that nothing can be updated other than
the following fields:
- the BatchPartition field can only increase unless the target ref has changed
- the RolloutBatches field can only change the part after the BatchPartition field
- the CanaryMetric/Paused/RevertOnDelete can be modified freely.
- the rollout controller will simply replace the existing rollout CR value in the in-memory map
which will lead to its in-memory execution to stop. The new CR will kick off a new execution
loop which will resume the rollout operation based on the rollout and its resources status which
follows the pre-determined state machine transition.
### The controller have extension points setup for the following plug-ins:
- workloads. Each workload handler needs to implement the following operations:
- scale the resources
- determine the health of the workload
- report how many replicas are upgraded/ready/available
- (future) metrics provider.
- (future) service mesh provider. Each mesh provider needs to implement the following operations:
- direct certain percent of the traffic to the source/target workload
- fetch the current traffic split
## State Transition
Here are the various top-level states of the rollout
```go
// Verifying verifies that the rollout setting is valid and the controller can locate both the
// target and the source
Verifying
// Initializing rollout is initializing all the new resources
Initializing
// Rolling rolling out
Rolling
// Finalising finalize the rolling, possibly clean up the old resources, adjust traffic
Finalising
// Succeed rollout successfully completed to match the desired target state
Succeed
// Failed rollout is failed, the target replica is not reached
// we can not move forward anymore
// we will let the client to decide when or whether to revert
Failed
)
```
These are the sub-states of the rollout when its in the rolling state.
```go
// BatchRolling still rolling the batch, the batch rolling is not completed yet
BatchRolling
// BatchStopped rollout is stopped, the batch rolling is not completed
BatchStopped
// BatchReady the pods in the batch are ready. Wait for auto or manual verification.
BatchReady
// BatchVerifying verifying if the application is ready to roll. This happens when it's either manual or
// automatic with analysis
BatchVerifying
// BatchAvailable one batch is ready, we could move to the batch
BatchAvailable
)
```
## Future work
The applicationDeployment should also work on traits. For example, if someone plans to update the
HPA traits formula, there should be a way for them to rolling out the HPA change step by step too.

View File

@@ -29,6 +29,9 @@ type RouteSpec struct {
// Provider indicate which ingress controller implementation the route trait will use, by default it's nginx-ingress
Provider string `json:"provider,omitempty"`
// IngressClass indicate which ingress class the route trait will use, by default it's nginx
IngressClass string `json:"ingressClass,omitempty"`
}
// Rule defines to route rule
@@ -92,7 +95,8 @@ Besides `workloadRef`, one Route will have only one `host` and many rules. `host
It's required and will be used to generate mTLS secrets.
Route Trait designed to be compatible with different ingress controller implementations, the `provider` field will allow
you to give a specified ingress controller type. Currently, only nginx-ingress is supported.
you to give a specified ingress controller type. The `ingressClass` field will allow you to set the ingressClass.
Currently, only nginx-ingress is supported.
The `tls` field allow you to specify a TLS for this route with an IssuerName, the IssuerName pointing to an [Issuer Object](https://cert-manager.io/docs/concepts/issuer/)
created by cert-manager. Cert-manager and ingress controller will handle certificate creation and binding.
@@ -148,4 +152,3 @@ route trait will check `WorkloadDefinition` for podSpec field, with the `podSpec
- 2.2 Use ChildResource: If No `PodSpecable` mechanism found in workload, we will continue discovery child resources of workload. If there
is a valid `PodTemplate` structure in child resource, we will regard it as discovery target, use the same strategy like
`workload.oam.dev/podspecable: true` but no `podSpecPath`.

View File

@@ -4,24 +4,25 @@
- [Concepts and Glossaries](/en/concepts.md)
- Platform Team Guide
- [Register Workload Type](/en/platform-engineers/workload-type.md)
- [Register Trait](/en/platform-engineers/trait.md)
- [Register Cloud Services](/en/platform-engineers/cloud-services.md)
- [What is KubeVela?](/en/platform-engineers/overview.md)
- Register Capability Modules
- [Workload Type](/en/platform-engineers/workload-type.md)
- [Trait](/en/platform-engineers/trait.md)
- [Cloud Services](/en/platform-engineers/cloud-services.md)
- End User Guide
- Appfile
- [Learning Appfile](/en/developers/learn-appfile.md)
- Operating
- [Setting Routes](/en/developers/set-route.md)
- [Setting Auto-scaling Policy](/en/developers/set-autoscale.md)
- [Setting Rollout Strategy](/en/developers/set-rollout.md)
- [Setting Monitoring Policy](/en/developers/set-metrics.md)
- Debugging
- [Port Forwarding](/en/developers/port-forward.md)
- [Check Application Logs](/en/developers/check-logs.md)
- [Execute Commands in Container](/en/developers/exec-cmd.md)
- Extending
- [Managing Capabilities](/en/developers/cap-center.md)
- [Setting Routes](/en/developers/extensions/set-route.md)
- [Setting Auto-scaling Policy](/en/developers/extensions/set-autoscale.md)
- [Setting Rollout Strategy](/en/developers/extensions/set-rollout.md)
- [Setting Monitoring Policy](/en/developers/extensions/set-metrics.md)
- Configuring
- [Setting Up Deployment Environment](/en/developers/config-enviroments.md)
- [Configuring data/env in Application](/en/developers/config-app.md)
@@ -32,7 +33,7 @@
- References
- [Appfile](/en/developers/references/devex/appfile.md)
- Capabilities
- [Capabilities](/en/developers/references/README.md)
- Workload Types
- [Webservice](/en/developers/references/workload-types/webservice.md)
- [Task](/en/developers/references/workload-types/task.md)

110
docs/en/application.md Normal file
View File

@@ -0,0 +1,110 @@
# Designing Application
Application encapsulation and abstraction is achieved by the `Application` custom resource.
## Example
The sample application below claimed a `backend` component with *Worker* workload type, and a `frontend` component with *Web Service* workload type.
Moreover, the `frontend` component claimed `sidecar` and `autoscaler` traits which means the workload will be automatically injected with a `fluentd` sidecar and scale from 1-100 replicas triggered by CPU usage.
> For detailed definition about `Application` *workload type* and *traits*, please read the [core concepts](/en/concepts.md#application) documentation.
```yaml
apiVersion: core.oam.dev/v1alpha2
kind: Application
metadata:
name: website
spec:
components:
- name: backend
type: worker
settings:
image: busybox
cmd:
- sleep
- '1000'
- name: frontend
type: webservice
settings:
image: nginx
traits:
- name: autoscaler
properties:
min: 1
max: 10
cpuPercent: 60
- name: sidecar
properties:
name: "sidecar-test"
image: "fluentd"
```
The `type: worker` means the specification of this workload (claimed in following `settings` section) will be enforced by a `WorkloadDefinition` object named `worker` as below:
```yaml
apiVersion: core.oam.dev/v1alpha2
kind: WorkloadDefinition
metadata:
name: worker
annotations:
definition.oam.dev/description: "Describes long-running, scalable, containerized services that running at backend. They do NOT have network endpoint to receive external network traffic."
spec:
schematic:
cue:
template: |
output: {
apiVersion: "apps/v1"
kind: "Deployment"
spec: {
selector: matchLabels: {
"app.oam.dev/component": context.name
}
template: {
metadata: labels: {
"app.oam.dev/component": context.name
}
spec: {
containers: [{
name: context.name
image: parameter.image
if parameter["cmd"] != _|_ {
command: parameter.cmd
}
}]
}
}
}
}
parameter: {
image: string
cmd?: [...string]
}
```
Hence, the `settings` section of `backend` only supports two parameters: `image` and `cmd`, this is enforced by the `parameter` list of the `.spec.template` field of the definition.
The similar extensible abstraction mechanism also applies to traits. For example, `name: autoscaler` in `frontend` means its trait specification (i.e. `properties` section) will be enforced by a `TraitDefinition` object named `autoscaler` as below:
> TBD: a autoscaler TraitDefinition (HPA)
All the definition objects are expected to be defined and installed by platform team. The end users will only focus on `Application` resource (either render it by tools or author it manually).
## Conventions and "Standard Contract"
After the `Application` resource is applied to Kubernetes cluster, the KubeVela runtime will generate and manage the underlying resources instances following below "standard contract" and conventions.
| Label | Description |
| :--: | :---------: |
|`workload.oam.dev/type=<workload definition name>` | The name of its corresponding `WorkloadDefinition` |
|`trait.oam.dev/type=<trait definition name>` | The name of its corresponding `TraitDefinition` |
|`app.oam.dev/name=<app name>` | The name of the application it belongs to |
|`app.oam.dev/component=<component name>` | The name of the component it belongs to |
|`trait.oam.dev/resource=<name of trait resource instance>` | The name of trait resource instance |
> TBD: the revision names and labels for resource instances are currently work in progress.
> TBD: a demo for kubectl apply above Application CR and show full detailed underlying resources.

View File

@@ -15,7 +15,6 @@ vela [flags]
### SEE ALSO
* [vela autoscale](vela_autoscale.md) - Attach autoscale trait to an app
* [vela cap](vela_cap.md) - Manage capability centers and installing/uninstalling capabilities
* [vela completion](vela_completion.md) - Output shell completion code for the specified shell (bash or zsh)
* [vela config](vela_config.md) - Manage configurations
@@ -27,14 +26,9 @@ vela [flags]
* [vela install](vela_install.md) - Install Vela Core with built-in capabilities
* [vela logs](vela_logs.md) - Tail logs for application
* [vela ls](vela_ls.md) - List services
* [vela metrics](vela_metrics.md) - Attach metrics trait to an app
* [vela port-forward](vela_port-forward.md) - Forward local ports to services in an application
* [vela rollout](vela_rollout.md) - Attach rollout trait to an app
* [vela route](vela_route.md) - Attach route trait to an app
* [vela scaler](vela_scaler.md) - Attach scaler trait to an app
* [vela show](vela_show.md) - Show details of an application
* [vela show](vela_show.md) - Show the reference doc for a workload type or trait
* [vela status](vela_status.md) - Show status of an application
* [vela svc](vela_svc.md) - Manage services
* [vela system](vela_system.md) - System management utilities
* [vela template](vela_template.md) - Manage templates
* [vela traits](vela_traits.md) - List traits
@@ -42,4 +36,4 @@ vela [flags]
* [vela version](vela_version.md) - Prints out build version information
* [vela workloads](vela_workloads.md) - List workloads
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -1,41 +0,0 @@
## vela autoscale
Attach autoscale trait to an app
### Synopsis
Attach autoscale trait to an app
```
vela autoscale <appname> [args]
```
### Examples
```
vela autoscale frontend
```
### Options
```
--cpu-percent int Specify the value for CPU utilization, like 80, which means 80%
--detach detach trait from service
-h, --help help for autoscale
--max int Maximal replicas of the workload
--min int Minimal replicas of the workload
-s, --staging only save changes locally without real update application
--svc string specify one service belonging to the application
```
### Options inherited from parent commands
```
-e, --env string specify environment name for application
```
### SEE ALSO
* [vela](vela.md) -
###### Auto generated by spf13/cobra on 9-Dec-2020

View File

@@ -26,4 +26,4 @@ Manage capability centers and installing/uninstalling capabilities
* [vela cap ls](vela_cap_ls.md) - List capabilities from cap-center
* [vela cap uninstall](vela_cap_uninstall.md) - Uninstall capability from cluster
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -26,4 +26,4 @@ Manage Capability Center with config, sync, list
* [vela cap center remove](vela_cap_center_remove.md) - Remove specified capability center
* [vela cap center sync](vela_cap_center_sync.md) - Sync capabilities from remote center, default to sync all centers
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -33,4 +33,4 @@ vela cap center config mycenter https://github.com/oam-dev/catalog/cap-center
* [vela cap center](vela_cap_center.md) - Manage Capability Center
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela cap center ls
* [vela cap center](vela_cap_center.md) - Manage Capability Center
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela cap center remove mycenter
* [vela cap center](vela_cap_center.md) - Manage Capability Center
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela cap center sync mycenter
* [vela cap center](vela_cap_center.md) - Manage Capability Center
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -33,4 +33,4 @@ vela cap install mycenter/route
* [vela cap](vela_cap.md) - Manage capability centers and installing/uninstalling capabilities
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela cap ls
* [vela cap](vela_cap.md) - Manage capability centers and installing/uninstalling capabilities
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -33,4 +33,4 @@ vela cap uninstall route
* [vela cap](vela_cap.md) - Manage capability centers and installing/uninstalling capabilities
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -27,4 +27,4 @@ of vela commands.
* [vela completion bash](vela_completion_bash.md) - generate autocompletions script for bash
* [vela completion zsh](vela_completion_zsh.md) - generate autocompletions script for zsh
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -36,4 +36,4 @@ vela completion bash
* [vela completion](vela_completion.md) - Output shell completion code for the specified shell (bash or zsh)
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -33,4 +33,4 @@ vela completion zsh
* [vela completion](vela_completion.md) - Output shell completion code for the specified shell (bash or zsh)
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -26,4 +26,4 @@ Manage configurations
* [vela config ls](vela_config_ls.md) - List configs
* [vela config set](vela_config_set.md) - Set data for a config
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela config del <config-name>
* [vela config](vela_config.md) - Manage configurations
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela config get <config-name>
* [vela config](vela_config.md) - Manage configurations
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela config ls
* [vela config](vela_config.md) - Manage configurations
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela config set <config-name> KEY=VALUE K2=V2
* [vela config](vela_config.md) - Manage configurations
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -33,4 +33,4 @@ vela delete frontend
* [vela](vela.md) -
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -26,4 +26,4 @@ Manage environments
* [vela env ls](vela_env_ls.md) - List environments
* [vela env set](vela_env_set.md) - Set an environment
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela env delete test
* [vela env](vela_env.md) - Manage environments
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -36,4 +36,4 @@ vela env init test --namespace test --email my@email.com
* [vela env](vela_env.md) - Manage environments
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela env ls [env-name]
* [vela env](vela_env.md) - Manage environments
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -32,4 +32,4 @@ vela env set test
* [vela env](vela_env.md) - Manage environments
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -16,6 +16,7 @@ vela exec [flags] APP_NAME -- COMMAND [args...]
-h, --help help for exec
--pod-running-timeout duration The length of time (like 5s, 2m, or 3h, higher than zero) to wait until at least one pod is running (default 1m0s)
-i, --stdin Pass stdin to the container (default true)
-s, --svc string service name
-t, --tty Stdin is a TTY (default true)
```
@@ -29,4 +30,4 @@ vela exec [flags] APP_NAME -- COMMAND [args...]
* [vela](vela.md) -
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -27,4 +27,4 @@ vela export
* [vela](vela.md) -
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -33,4 +33,4 @@ vela init
* [vela](vela.md) -
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -17,6 +17,7 @@ vela install [flags]
--image-pull-policy string vela core image pull policy, this will align to chart value image.pullPolicy
--image-repo string vela core image repo, this will align to chart value image.repo
--image-tag string vela core image repo, this will align to chart value image.tag
-s, --set strings arguments for installing vela-core chart
-p, --vela-chart-path string path to vela core chart to override default chart
-w, --wait string wait until vela-core is ready to serve, default will not wait (default "0s")
```
@@ -31,4 +32,4 @@ vela install [flags]
* [vela](vela.md) -
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -27,4 +27,4 @@ vela logs [flags]
* [vela](vela.md) -
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

View File

@@ -33,4 +33,4 @@ vela ls
* [vela](vela.md) -
###### Auto generated by spf13/cobra on 9-Dec-2020
###### Auto generated by spf13/cobra on 28-Jan-2021

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