Compare commits

...

28 Commits

Author SHA1 Message Date
github-actions[bot]
a3ee8eb01d [Backport release-1.5] Fix: remove the cloudshell dockerfile (#4549)
* Fix: remove the cloudshell dockerfile

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

* Fix: change the configmap name

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

* Fix: change the way to get the namespace

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-08-03 16:20:34 +08:00
github-actions[bot]
84b4d0f685 [Backport release-1.5] Feat: report the manifest name when addon enabling failed (#4547)
* Feat: Report the manifest name when Addon enabling failed

Signed-off-by: ghostloda <78798447@qq.com>
(cherry picked from commit d143c341af)

* Apply suggestions from code review

Co-authored-by: Jianbo Sun <wonderflow@icloud.com>
Signed-off-by: ghostloda <78798447@qq.com>
(cherry picked from commit a5ba4658a9)

* Apply suggestions from code review

Co-authored-by: Charlie Chiang <charlie_c_0129@outlook.com>
Signed-off-by: ghostloda <78798447@qq.com>
(cherry picked from commit 67f34ac4a6)

Co-authored-by: ghostloda <78798447@qq.com>
2022-08-03 13:52:25 +08:00
github-actions[bot]
4e370b940c Fix: sidecar trait (#4543)
Signed-off-by: qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit 3eaf2dd02a)

Co-authored-by: qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-08-02 23:10:12 +08:00
github-actions[bot]
110156aff0 Fix: upgrade the cloudshell image (#4540)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 922b9b10ef)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-08-02 22:21:57 +08:00
github-actions[bot]
62df98818e [Backport release-1.5] Feat: Check def binding to a component (#4539)
* finish logic

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

* finish tests

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

small fix

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

fix ci

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

* fix comments

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

fix ci

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

* fix test

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

* fix tests

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-08-02 21:37:53 +08:00
github-actions[bot]
992e636211 Feat: support change resource gc policy from onAppUpdate to Never (#4537)
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
(cherry picked from commit 55c9f6049f)

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-08-02 20:21:42 +08:00
github-actions[bot]
3a7a8ac59f Fix: publish chart version (#4536)
Signed-off-by: qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
(cherry picked from commit 53ebebba78)

Co-authored-by: qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-08-02 20:20:56 +08:00
github-actions[bot]
75fd38f1de [Backport release-1.5] Chore: update chart-publishing, only push index and new charts (#4534)
* Chore: update chart-publishing, only push index and new charts

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

* fix

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

Co-authored-by: qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-08-02 19:29:40 +08:00
github-actions[bot]
8abd78e5f1 [Backport release-1.5] Fix: storage patch env (#4533)
* Fix: empty health policy do not check object existence

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

* Fix: fix health check error

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

* Fix: app use storage and env trait

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

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-08-02 19:19:23 +08:00
github-actions[bot]
2d82e74c5b [Backport release-1.5] Feat: add the daemonset resource rule for building the tree (#4532)
* Feat: add the daemonset resource policy for building the tree

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

* Fix: the import package

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

* Fix: the unit test case

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

* Fix: change some function and variable names

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-08-02 19:15:53 +08:00
github-actions[bot]
66dfcec0ad [Backport release-1.5] Feat: add http status and code from http cmd run (#4528)
* Feat: add http status and code from http cmd run

Signed-off-by: suxiang <704427617@qq.com>
(cherry picked from commit 0b96b2e60a)

* Feat: fix unit test error

Signed-off-by: suxiang <704427617@qq.com>
(cherry picked from commit 25f2291503)

* Feat: status is not necessary

Signed-off-by: suxiang <704427617@qq.com>
(cherry picked from commit ef3b8ac82b)

* Feat: make reviewable

Signed-off-by: suxiang <704427617@qq.com>
(cherry picked from commit 684f5e9ae2)

* Feat: add unit test

Signed-off-by: suxiang <704427617@qq.com>
(cherry picked from commit 6c39f602ea)

* Feat: make reviewable

Signed-off-by: suxiang <704427617@qq.com>
(cherry picked from commit 20ae7f2e15)

Co-authored-by: suxiang <704427617@qq.com>
2022-08-02 16:18:47 +08:00
github-actions[bot]
37dd176dd3 [Backport release-1.5] Fix: fix e2e flaky tests (#4524)
* try to show

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

test

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

fix e2e tests

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

add mock server back

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

fix flaky tests

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

fix tests

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

fix e2e-test

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

only for tests

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

fix

(cherry picked from commit ba5cc24d54)

* only for tests

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-08-02 15:18:34 +08:00
Zhiyu Wang
da9bd8ca63 Fix: missing return when token is null (#4520)
Signed-off-by: Zhiyu Wang <cloudsky.newbis@gmail.com>
(cherry picked from commit d810d9d042)
2022-08-02 11:02:02 +08:00
github-actions[bot]
bc1d24e034 [Backport release-1.5] Fix: empty health policy do not check object existence (#4522)
* Fix: empty health policy do not check object existence

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

* Fix: fix health check error

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

* Fix: add test

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

Co-authored-by: Somefive <yd219913@alibaba-inc.com>
2022-08-02 11:00:57 +08:00
github-actions[bot]
bcce87c073 Fix: can not find the resource when the resource namespace is diffrent with application (#4518)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 56b440677d)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-08-01 22:43:28 +08:00
github-actions[bot]
3a9e5ccd5d [Backport release-1.5] Feat: refactor CLI commands related to resources (#4514)
* Feat: refactor CLI commands related to resources

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

* Fix: remove the old test case.

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

* Fix: e2e test

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

* Fix: optimize test cases

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

* Feat: rename 'vela pods' to 'vela status --pod'

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

* Feat: optimize the e2e test case

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

* Fix: sort the objects

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

* Fix: optimize the e2e test case

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

* Fix: list the pod by the labels

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

* Fix: order the tree resource

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

* Fix: set multicluster config

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-08-01 19:46:20 +08:00
github-actions[bot]
1b21db979f Fix: there is no color in the diff report (#4513)
Signed-off-by: barnettZQG <barnett.zqg@gmail.com>
(cherry picked from commit 7ab3d58d8a)

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-08-01 18:27:56 +08:00
github-actions[bot]
618596b98e [Backport release-1.5] Feat: support set labels for env (#4506)
* Feat: support set labels for env

Signed-off-by: codinghuang <codinghuang@qq.com>
(cherry picked from commit 25558c1f18)

* Refactor: Remove util.ParseLabelString

use k8s.io/apimachinery/pkg/labels

Signed-off-by: codinghuang <codinghuang@qq.com>
(cherry picked from commit abf756fb14)

Co-authored-by: codinghuang <codinghuang@qq.com>
2022-07-29 19:18:32 +08:00
github-actions[bot]
db21d74a52 [Backport release-1.5] Fix: failed to assign the default role for the users who log in from dex (#4504)
* Fix: failed to assign the default role for the users who log in from dex

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

* Fix: cluster e2e test case

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

* Fix: the ensure namespace error is ignored

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-07-29 17:19:21 +08:00
github-actions[bot]
fafa18e8db [Backport release-1.5] Fix: check definition of addon whether is conflict (#4502)
* fix checksemver

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

override defs

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

add tests

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

* add test and fix some special cases

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

fix checkdiff

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

fix flags

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

* fix comments

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

* small fix

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

Co-authored-by: 楚岳 <wangyike.wyk@alibaba-inc.com>
2022-07-29 16:47:43 +08:00
github-actions[bot]
acf923dd10 [Backport release-1.5] Fix: CloudShell read-only authorization is not automatically revoked (#4503)
* Fix: CloudShell read-only authorization is not automatically revoked

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

* Fix: code style

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

* Fix: rename the prefix

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

Co-authored-by: barnettZQG <barnett.zqg@gmail.com>
2022-07-29 16:47:17 +08:00
github-actions[bot]
8fc94f057f [Backport release-1.5] Feat: System Info & Diagnose (#4499)
* Feat: System Info & Diagnose

Signed-off-by: foursevenlove <foursevenlove@gmail.com>
(cherry picked from commit 96e303f2e6)

* Fix:1.misspelling 2.license

Signed-off-by: foursevenlove <foursevenlove@gmail.com>
(cherry picked from commit 3f9d8dfa8f)

* Fix: pattern of imported package

Signed-off-by: foursevenlove <foursevenlove@gmail.com>
(cherry picked from commit 6584564a89)

* Fix: pattern of imported package

Signed-off-by: foursevenlove <foursevenlove@gmail.com>
(cherry picked from commit b500f41cc6)

* Fix:1.return error instead of panic 2.get deployment by label instead of by namespace 3.when getting a single deployment, the result is displayed in multi rows. Feat: 1.the system info command displays the cpu and memory metrics 2.the system info command displays the numbers of ready pods and desired pods.

(cherry picked from commit 548a3accef)

* Feat: 1.the system info command displays the environment variables

(cherry picked from commit 9ba993d71a)

* Fix: Making syntax simple

(cherry picked from commit 558812d64d)

Co-authored-by: foursevenlove <foursevenlove@gmail.com>
2022-07-29 14:28:01 +08:00
github-actions[bot]
6a6dfba79b [Backport release-1.5] Chore: organize appliesToWorkloads field of trait defs, add doc example (#4497)
* Chore: organize appliesToWorkloads field of trait defs, add doc example

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

* fix gen

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

* add deprecate label

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

* fix

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

* fix script to read all definition in directory

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

* add comment

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

* go.mod

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

* update some usage, better trait doc gen

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

* minor fix

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

* minor fix

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

* postpone markdown escape pipe char

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

Co-authored-by: qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2022-07-29 11:23:35 +08:00
github-actions[bot]
3b7a997b3e Fix: repeat query configuration type (#4494)
Signed-off-by: ghostloda <78798447@qq.com>
(cherry picked from commit 5c048b3ee3)

Co-authored-by: ghostloda <78798447@qq.com>
2022-07-28 14:27:36 +08:00
github-actions[bot]
e13a259bca Feat: delete multi apps from vela delete cli command (#4486)
Signed-off-by: suxiang <704427617@qq.com>
(cherry picked from commit 957da65449)

Co-authored-by: suxiang <704427617@qq.com>
2022-07-27 18:59:10 +08:00
Somefive
58af7103e7 Fix: address vela-core crash due to empty policy properties (#4473) (#4479)
* Fix: fix topology core crash

Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>

* Test: add tests

Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>

* Fix: same problem in other places

Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>

* Style: remove empty line

Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>

* Feat: raise error when empty topology is used

Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>

* Feat: raise error when empty override policy is used

Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>

Co-authored-by: Charlie Chiang <charlie_c_0129@outlook.com>
2022-07-27 13:15:39 +08:00
github-actions[bot]
b329923f81 Fix: fix logs to record the right publish version (#4477)
Signed-off-by: yangsoon <songyang.song@alibaba-inc.com>
(cherry picked from commit 4846104c8f)

Co-authored-by: yangsoon <songyang.song@alibaba-inc.com>
2022-07-27 01:12:40 +08:00
github-actions[bot]
6f8cc0f5b4 [Backport release-1.5] Feat: show warnings about internal addon rendering logic (#4478)
* Feat: show warnings about addon rendering logic

Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>
(cherry picked from commit d466897e5a)

* Feat: update vela init to not show warnings

Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>
(cherry picked from commit b438114311)

* Refactor: use setter

Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>
(cherry picked from commit a3b501d29e)

* fix check-diff

Signed-off-by: Charlie Chiang <charlie_c_0129@outlook.com>
(cherry picked from commit 3c0e72e1ad)

Co-authored-by: Charlie Chiang <charlie_c_0129@outlook.com>
2022-07-26 23:37:56 +08:00
205 changed files with 4015 additions and 1459 deletions

View File

@@ -21,7 +21,11 @@ jobs:
MINIMAL_HELM_CHART: charts/vela-minimal
LEGACY_HELM_CHART: legacy/charts/vela-core-legacy
VELA_ROLLOUT_HELM_CHART: runtime/rollout/charts
LOCAL_OSS_DIRECTORY: .oss/
LOCAL_OSS_DIRECTORY: .oss
HELM_CHART_NAME: vela-core
MINIMAL_HELM_CHART_NAME: vela-minimal
LEGACY_HELM_CHART_NAME: vela-core-legacy
VELA_ROLLOUT_HELM_CHART_NAME: vela-rollout
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@master
@@ -86,4 +90,11 @@ jobs:
helm package $VELA_ROLLOUT_HELM_CHART --destination $LOCAL_OSS_DIRECTORY
helm repo index --url https://$BUCKET.$ENDPOINT/core $LOCAL_OSS_DIRECTORY
- name: sync local to cloud
run: ./ossutil --config-file .ossutilconfig sync $LOCAL_OSS_DIRECTORY oss://$BUCKET/core -f
run: |
image_tag=${{ steps.get_version.outputs.VERSION }}
chart_semver=${image_tag#"v"}
./ossutil --config-file .ossutilconfig cp -f $LOCAL_OSS_DIRECTORY/index.yaml oss://$BUCKET/core/index.yaml
./ossutil --config-file .ossutilconfig cp -f $LOCAL_OSS_DIRECTORY/$HELM_CHART_NAME-${chart_semver}.tgz oss://$BUCKET/core/$HELM_CHART_NAME-${chart_semver}.tgz
./ossutil --config-file .ossutilconfig cp -f $LOCAL_OSS_DIRECTORY/$MINIMAL_HELM_CHART_NAME-${chart_semver}.tgz oss://$BUCKET/core/$MINIMAL_HELM_CHART_NAME-${chart_semver}.tgz
./ossutil --config-file .ossutilconfig cp -f $LOCAL_OSS_DIRECTORY/$LEGACY_HELM_CHART_NAME-${chart_semver}.tgz oss://$BUCKET/core/$LEGACY_HELM_CHART_NAME-${chart_semver}.tgz
./ossutil --config-file .ossutilconfig cp -f $LOCAL_OSS_DIRECTORY/$VELA_ROLLOUT_HELM_CHART_NAME-${chart_semver}.tgz oss://$BUCKET/core/$VELA_ROLLOUT_HELM_CHART_NAME-${chart_semver}.tgz

View File

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

View File

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

View File

@@ -62,12 +62,12 @@ type GarbageCollectPolicyRule struct {
// if one resource is specified with conflict strategies, strategy as component go first.
// 2) for ApplyOncePolicyRule only CompNames and ResourceTypes are used
type ResourcePolicyRuleSelector struct {
CompNames []string `json:"componentNames"`
CompTypes []string `json:"componentTypes"`
OAMResourceTypes []string `json:"oamTypes"`
TraitTypes []string `json:"traitTypes"`
ResourceTypes []string `json:"resourceTypes"`
ResourceNames []string `json:"resourceNames"`
CompNames []string `json:"componentNames,omitempty"`
CompTypes []string `json:"componentTypes,omitempty"`
OAMResourceTypes []string `json:"oamTypes,omitempty"`
TraitTypes []string `json:"traitTypes,omitempty"`
ResourceTypes []string `json:"resourceTypes,omitempty"`
ResourceNames []string `json:"resourceNames,omitempty"`
}
// Match check if current rule selector match the target resource

View File

@@ -120,7 +120,7 @@ type TraitDefinitionSpec struct {
PodDisruptive bool `json:"podDisruptive,omitempty"`
// AppliesToWorkloads specifies the list of workload kinds this trait
// applies to. Workload kinds are specified in kind.group/version format,
// applies to. Workload kinds are specified in resource.group/version format,
// e.g. server.core.oam.dev/v1alpha2. Traits that omit this field apply to
// all workload kinds.
// +optional

View File

@@ -82,6 +82,8 @@ type ManagedResource struct {
Data *runtime.RawExtension `json:"raw,omitempty"`
// Deleted marks the resource to be deleted
Deleted bool `json:"deleted,omitempty"`
// SkipGC marks the resource to skip gc
SkipGC bool `json:"skipGC,omitempty"`
}
// Equal check if two managed resource equals
@@ -215,8 +217,9 @@ func (in *ResourceTracker) ContainsManagedResource(rsc client.Object) bool {
}
// AddManagedResource add object to managed resources, if exists, update
func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool, creator common.ResourceCreatorRole) (updated bool) {
func (in *ResourceTracker) AddManagedResource(rsc client.Object, metaOnly bool, skipGC bool, creator common.ResourceCreatorRole) (updated bool) {
mr := newManagedResourceFromResource(rsc)
mr.SkipGC = skipGC
if !metaOnly {
mr.Data = &runtime.RawExtension{Object: rsc}
}

View File

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

View File

@@ -106,6 +106,7 @@ type Config map[string]string
type EnvMeta struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Labels string `json:"labels"`
Current string `json:"current"`
}

View File

@@ -3650,7 +3650,7 @@ spec:
appliesToWorkloads:
description: AppliesToWorkloads specifies the list of workload
kinds this trait applies to. Workload kinds are specified
in kind.group/version format, e.g. server.core.oam.dev/v1alpha2.
in resource.group/version format, e.g. server.core.oam.dev/v1alpha2.
Traits that omit this field apply to all workload kinds.
items:
type: string

View File

@@ -708,7 +708,7 @@ spec:
appliesToWorkloads:
description: AppliesToWorkloads specifies the list of workload
kinds this trait applies to. Workload kinds are specified
in kind.group/version format, e.g. server.core.oam.dev/v1alpha2.
in resource.group/version format, e.g. server.core.oam.dev/v1alpha2.
Traits that omit this field apply to all workload kinds.
items:
type: string

View File

@@ -105,6 +105,9 @@ spec:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
skipGC:
description: SkipGC marks the resource to skip gc
type: boolean
trait:
type: string
uid:

View File

@@ -356,7 +356,7 @@ spec:
properties:
appliesToWorkloads:
description: AppliesToWorkloads specifies the list of workload kinds
this trait applies to. Workload kinds are specified in kind.group/version
this trait applies to. Workload kinds are specified in resource.group/version
format, e.g. server.core.oam.dev/v1alpha2. Traits that omit this
field apply to all workload kinds.
items:

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -4,7 +4,7 @@ apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/description: Add annotations on K8s pod for your workload which follows the pod spec in path 'spec.template'.
definition.oam.dev/description: Add annotations on your workload. if it generates pod, add same annotations for generated pods.
labels:
custom.definition.oam.dev/ui-hidden: "true"
name: annotations

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
schematic:
cue:
template: |

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -12,6 +12,7 @@ metadata:
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
schematic:
cue:
template: |

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
schematic:
cue:
template: |

View File

@@ -10,6 +10,9 @@ metadata:
name: expose
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
podDisruptive: false
schematic:
cue:

View File

@@ -9,7 +9,8 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
podDisruptive: false
schematic:
cue:
@@ -85,7 +86,7 @@ spec:
// +usage=Set ingress class in '.spec.ingressClassName' instead of 'kubernetes.io/ingress.class' annotation.
classInSpec: *false | bool
// +usage=Specify the secret name you want to quote.
// +usage=Specify the secret name you want to quote to use tls.
secretName?: string
// +usage=Specify the host of the ingress gateway, which is used to generate the endpoints when the host is empty.

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: false
schematic:
cue:

View File

@@ -12,6 +12,9 @@ metadata:
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -4,7 +4,7 @@ apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/description: Add labels on K8s pod for your workload which follows the pod spec in path 'spec.template'.
definition.oam.dev/description: Add labels on your workload. if it generates pod, add same label for generated pods.
labels:
custom.definition.oam.dev/ui-hidden: "true"
name: labels

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -6,11 +6,13 @@ metadata:
annotations:
definition.oam.dev/description: Enable public web traffic for the component without creating a Service.
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/ui-hidden: "true"
name: pure-ingress
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads: []
appliesToWorkloads:
- '*'
conflictsWith: []
podDisruptive: false
schematic:

View File

@@ -6,6 +6,7 @@ metadata:
annotations:
definition.oam.dev/description: Add a datasource to Grafana
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/ui-hidden: "true"
name: register-grafana-datasource
namespace: {{ include "systemDefinitionNamespace" . }}

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -9,7 +9,8 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
podDisruptive: false
schematic:
cue:

View File

@@ -9,7 +9,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: false
schematic:
cue:

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
schematic:
cue:
template: |

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -10,6 +10,9 @@ metadata:
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -0,0 +1,77 @@
{{- if not (lookup "v1" "ConfigMap" (include "systemDefinitionNamespace" .) "component-pod-view") }}
apiVersion: v1
data:
template: |
import (
"vela/ql"
)
parameter: {
appName: string
appNs: string
name?: string
cluster?: string
clusterNs?: string
}
result: ql.#CollectPods & {
app: {
name: parameter.appName
namespace: parameter.appNs
filter: {
if parameter.cluster != _|_ {
cluster: parameter.cluster
}
if parameter.clusterNs != _|_ {
clusterNamespace: parameter.clusterNs
}
if parameter.name != _|_ {
components: [parameter.name]
}
}
}
}
if result.err == _|_ {
status: {
podList: [ for pod in result.list if pod.object != _|_ {
cluster: pod.cluster
workload: pod.workload
component: pod.component
metadata: {
name: pod.object.metadata.name
namespace: pod.object.metadata.namespace
creationTime: pod.object.metadata.creationTimestamp
labels: pod.object.metadata.labels
version: {
if pod.publishVersion != _|_ {
publishVersion: pod.publishVersion
}
if pod.deployVersion != _|_ {
deployVersion: pod.deployVersion
}
}
}
status: {
phase: pod.object.status.phase
// refer to https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
if phase != "Pending" && phase != "Unknown" {
podIP: pod.object.status.podIP
hostIP: pod.object.status.hostIP
nodeName: pod.object.spec.nodeName
}
}
}]
}
}
if result.err != _|_ {
status: {
error: result.err
}
}
kind: ConfigMap
metadata:
name: component-pod-view
namespace: {{ include "systemDefinitionNamespace" . }}
{{- end }}

View File

@@ -0,0 +1,50 @@
{{- if not (lookup "v1" "ConfigMap" (include "systemDefinitionNamespace" .) "component-service-view") }}
apiVersion: v1
data:
template: |
import (
"vela/ql"
)
parameter: {
appName: string
appNs: string
name?: string
cluster?: string
clusterNs?: string
}
result: ql.#CollectServices & {
app: {
name: parameter.appName
namespace: parameter.appNs
filter: {
if parameter.cluster != _|_ {
cluster: parameter.cluster
}
if parameter.clusterNs != _|_ {
clusterNamespace: parameter.clusterNs
}
if parameter.name != _|_ {
components: [parameter.name]
}
}
}
}
if result.err == _|_ {
status: {
services: result.list
}
}
if result.err != _|_ {
status: {
error: result.err
}
}
kind: ConfigMap
metadata:
name: component-service-view
namespace: {{ include "systemDefinitionNamespace" . }}
{{- end}}

View File

@@ -3650,7 +3650,7 @@ spec:
appliesToWorkloads:
description: AppliesToWorkloads specifies the list of workload
kinds this trait applies to. Workload kinds are specified
in kind.group/version format, e.g. server.core.oam.dev/v1alpha2.
in resource.group/version format, e.g. server.core.oam.dev/v1alpha2.
Traits that omit this field apply to all workload kinds.
items:
type: string

View File

@@ -708,7 +708,7 @@ spec:
appliesToWorkloads:
description: AppliesToWorkloads specifies the list of workload
kinds this trait applies to. Workload kinds are specified
in kind.group/version format, e.g. server.core.oam.dev/v1alpha2.
in resource.group/version format, e.g. server.core.oam.dev/v1alpha2.
Traits that omit this field apply to all workload kinds.
items:
type: string

View File

@@ -105,6 +105,9 @@ spec:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
skipGC:
description: SkipGC marks the resource to skip gc
type: boolean
trait:
type: string
uid:

View File

@@ -356,7 +356,7 @@ spec:
properties:
appliesToWorkloads:
description: AppliesToWorkloads specifies the list of workload kinds
this trait applies to. Workload kinds are specified in kind.group/version
this trait applies to. Workload kinds are specified in resource.group/version
format, e.g. server.core.oam.dev/v1alpha2. Traits that omit this
field apply to all workload kinds.
items:

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -4,7 +4,7 @@ apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/description: Add annotations on K8s pod for your workload which follows the pod spec in path 'spec.template'.
definition.oam.dev/description: Add annotations on your workload. if it generates pod, add same annotations for generated pods.
labels:
custom.definition.oam.dev/ui-hidden: "true"
name: annotations

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
schematic:
cue:
template: |

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -12,6 +12,7 @@ metadata:
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
schematic:
cue:
template: |

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
schematic:
cue:
template: |

View File

@@ -10,6 +10,9 @@ metadata:
name: expose
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
podDisruptive: false
schematic:
cue:

View File

@@ -9,7 +9,8 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
podDisruptive: false
schematic:
cue:
@@ -85,7 +86,7 @@ spec:
// +usage=Set ingress class in '.spec.ingressClassName' instead of 'kubernetes.io/ingress.class' annotation.
classInSpec: *false | bool
// +usage=Specify the secret name you want to quote.
// +usage=Specify the secret name you want to quote to use tls.
secretName?: string
// +usage=Specify the host of the ingress gateway, which is used to generate the endpoints when the host is empty.

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: false
schematic:
cue:

View File

@@ -12,6 +12,9 @@ metadata:
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -4,7 +4,7 @@ apiVersion: core.oam.dev/v1beta1
kind: TraitDefinition
metadata:
annotations:
definition.oam.dev/description: Add labels on K8s pod for your workload which follows the pod spec in path 'spec.template'.
definition.oam.dev/description: Add labels on your workload. if it generates pod, add same label for generated pods.
labels:
custom.definition.oam.dev/ui-hidden: "true"
name: labels

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -6,11 +6,13 @@ metadata:
annotations:
definition.oam.dev/description: Enable public web traffic for the component without creating a Service.
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/ui-hidden: "true"
name: pure-ingress
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads: []
appliesToWorkloads:
- '*'
conflictsWith: []
podDisruptive: false
schematic:

View File

@@ -6,6 +6,7 @@ metadata:
annotations:
definition.oam.dev/description: Add a datasource to Grafana
labels:
custom.definition.oam.dev/deprecated: "true"
custom.definition.oam.dev/ui-hidden: "true"
name: register-grafana-datasource
namespace: {{ include "systemDefinitionNamespace" . }}

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -9,7 +9,8 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
podDisruptive: false
schematic:
cue:

View File

@@ -9,7 +9,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: false
schematic:
cue:

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
schematic:
cue:
template: |

View File

@@ -11,7 +11,10 @@ metadata:
namespace: {{ include "systemDefinitionNamespace" . }}
spec:
appliesToWorkloads:
- '*'
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -10,6 +10,9 @@ metadata:
spec:
appliesToWorkloads:
- deployments.apps
- statefulsets.apps
- daemonsets.apps
- jobs.batch
podDisruptive: true
schematic:
cue:

View File

@@ -26,6 +26,7 @@ import (
"time"
restfulspec "github.com/emicklei/go-restful-openapi/v2"
"github.com/fatih/color"
"github.com/go-openapi/spec"
"github.com/google/uuid"
flag "github.com/spf13/pflag"
@@ -82,6 +83,10 @@ func main() {
return
}
// The server is not terminal, there is no color default.
// Force set to false, this is useful for the dry-run API.
color.NoColor = false
errChan := make(chan error)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

View File

@@ -0,0 +1,50 @@
"kustomize-json-patch-mock-adddon": {
attributes: {
podDisruptive: false
}
description: "A list of JSON6902 patch to selected target"
labels: {
"ui-hidden": "true"
}
type: "trait"
}
template: {
patch: {
spec: {
patches: parameter.patchesJson
}
}
parameter: {
// +usage=A list of JSON6902 patch.
patchesJson: [...#jsonPatchItem]
}
// +usage=Contains a JSON6902 patch
#jsonPatchItem: {
target: #selector
patch: [...{
// +usage=operation to perform
op: string | "add" | "remove" | "replace" | "move" | "copy" | "test"
// +usage=operate path e.g. /foo/bar
path: string
// +usage=specify source path when op is copy/move
from?: string
// +usage=specify opraation value when op is test/add/replace
value?: string
}]
}
// +usage=Selector specifies a set of resources
#selector: {
group?: string
version?: string
kind?: string
namespace?: string
name?: string
annotationSelector?: string
labelSelector?: string
}
}

View File

@@ -0,0 +1 @@
Test addon readme.md file

View File

@@ -76,6 +76,8 @@ func ApplyMockServerConfig() error {
} else {
cm.ResourceVersion = originCm.ResourceVersion
if err = k8sClient.Update(ctx, &cm); err != nil {
fmt.Println("print errr------")
fmt.Println(err)
return err
}
}

View File

@@ -42,10 +42,10 @@ var (
applicationName = "app-basic"
traitAlias = "scaler"
appNameForInit = "initmyapp"
jsonAppFile = `{"name":"nginx-vela","services":{"nginx":{"type":"webservice","image":"nginx:1.9.4","port":80}}}`
testDeleteJsonAppFile = `{"name":"test-vela-delete","services":{"nginx-test":{"type":"webservice","image":"nginx:1.9.4","port":80}}}`
appbasicJsonAppFile = `{"name":"app-basic","services":{"app-basic":{"type":"webservice","image":"nginx:1.9.4","port":80}}}`
appbasicAddTraitJsonAppFile = `{"name":"app-basic","services":{"app-basic":{"type":"webservice","image":"nginx:1.9.4","port":80,"scaler":{"replicas":2}}}}`
jsonAppFile = `{"name":"nginx-vela","services":{"nginx":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}]}}}`
testDeleteJsonAppFile = `{"name":"test-vela-delete","services":{"nginx-test":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}]}}}`
appbasicJsonAppFile = `{"name":"app-basic","services":{"app-basic":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}]}}}`
appbasicAddTraitJsonAppFile = `{"name":"app-basic","services":{"app-basic":{"type":"webservice","image":"nginx:1.9.4","ports":[{port: 80, expose: true}],"scaler":{"replicas":2}}}}`
velaQL = "test-component-pod-view{appNs=default,appName=nginx-vela,name=nginx}"
)
@@ -303,7 +303,7 @@ var VelaQLPodListContext = func(context string, velaQL string) bool {
gomega.Expect(v.Workload.ApiVersion).To(gomega.ContainSubstring("apps/v1"))
}
if v.Workload.Kind != "" {
gomega.Expect(v.Workload.Kind).To(gomega.ContainSubstring("Deployment"))
gomega.Expect(v.Workload.Kind).To(gomega.ContainSubstring("ReplicaSet"))
}
}
})

View File

@@ -7,7 +7,6 @@ data:
template: |
import (
"vela/ql"
"vela/op"
)
parameter: {
@@ -18,7 +17,7 @@ data:
clusterNs?: string
}
application: ql.#ListResourcesInApp & {
result: ql.#CollectPods & {
app: {
name: parameter.appName
namespace: parameter.appNs
@@ -36,63 +35,41 @@ data:
}
}
if application.err != _|_ {
status: error: application.err
}
if application.err == _|_ {
resources: application.list
podsMap: op.#Steps & {
for i, resource in resources {
"\(i)": ql.#CollectPods & {
value: resource.object
cluster: resource.cluster
}
}
}
podsWithCluster: [ for i, pods in podsMap for podObj in pods.list {
cluster: pods.cluster
obj: podObj
}]
podStatus: op.#Steps & {
for i, pod in podsWithCluster {
"\(i)": op.#Steps & {
name: pod.obj.metadata.name
containers: {for container in pod.obj.status.containerStatuses {
"\(container.name)": {
image: container.image
state: container.state
}
}}
events: ql.#SearchEvents & {
value: pod.obj
cluster: pod.cluster
}
metrics: ql.#Read & {
cluster: pod.cluster
value: {
apiVersion: "metrics.k8s.io/v1beta1"
kind: "PodMetrics"
metadata: {
name: pod.obj.metadata.name
namespace: pod.obj.metadata.namespace
}
}
}
}
}
}
if result.err == _|_ {
status: {
podList: [ for podInfo in podStatus {
name: podInfo.name
containers: [ for containerName, container in podInfo.containers {
containerName
}]
events: podInfo.events.list
podList: [ for pod in result.list if pod.object != _|_ {
cluster: pod.cluster
workload: pod.workload
component: pod.component
metadata: {
name: pod.object.metadata.name
namespace: pod.object.metadata.namespace
creationTime: pod.object.metadata.creationTimestamp
labels: pod.object.metadata.labels
version: {
if pod.publishVersion != _|_ {
publishVersion: pod.publishVersion
}
if pod.deployVersion != _|_ {
deployVersion: pod.deployVersion
}
}
}
status: {
phase: pod.object.status.phase
// refer to https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
if phase != "Pending" && phase != "Unknown" {
podIP: pod.object.status.podIP
hostIP: pod.object.status.hostIP
nodeName: pod.object.spec.nodeName
}
}
}]
}
}
if result.err != _|_ {
status: {
error: result.err
}
}

3
go.mod
View File

@@ -124,6 +124,8 @@ require (
sigs.k8s.io/gateway-api v0.4.3
)
require github.com/rogpeppe/go-internal v1.8.0
require (
cloud.google.com/go/compute v1.7.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
@@ -256,7 +258,6 @@ require (
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.28.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/rogpeppe/go-internal v1.8.0 // indirect
github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc // indirect
github.com/russross/blackfriday v1.6.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect

View File

@@ -86,7 +86,9 @@ func TraitDef(ctx context.Context, c common.Args, path, location *string, defdir
},
CustomDocHeader: CustomTraitHeaderEN,
}
ref.Remote = &docgen.FromCluster{Namespace: types.DefaultKubeVelaNS}
ref.Local = &docgen.FromLocal{
Path: TraitDefDir,
}
if *path != "" {
ref.I18N = &docgen.En
@@ -99,22 +101,24 @@ func TraitDef(ctx context.Context, c common.Args, path, location *string, defdir
os.Exit(1)
}
fmt.Printf("trait reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), *path)
}
if *location == "" || *location == "en" {
ref.I18N = &docgen.En
if err := ref.GenerateReferenceDocs(ctx, c, TraitDefRefPath); err != nil {
fmt.Println(err)
os.Exit(1)
} else {
// Generate to default path depends on language
if *location == "" || *location == "en" {
ref.I18N = &docgen.En
if err := ref.GenerateReferenceDocs(ctx, c, TraitDefRefPath); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("trait reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), TraitDefRefPath)
}
fmt.Printf("trait reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), TraitDefRefPath)
}
if *location == "" || *location == "zh" {
ref.I18N = &docgen.Zh
ref.CustomDocHeader = CustomTraitHeaderZH
if err := ref.GenerateReferenceDocs(ctx, c, TraitDefRefPathZh); err != nil {
fmt.Println(err)
os.Exit(1)
if *location == "" || *location == "zh" {
ref.I18N = &docgen.Zh
ref.CustomDocHeader = CustomTraitHeaderZH
if err := ref.GenerateReferenceDocs(ctx, c, TraitDefRefPathZh); err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Printf("trait reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), TraitDefRefPathZh)
}
fmt.Printf("trait reference docs (%s) successfully generated in %s \n", ref.I18N.Language(), TraitDefRefPathZh)
}
}

View File

@@ -3650,7 +3650,7 @@ spec:
appliesToWorkloads:
description: AppliesToWorkloads specifies the list of workload
kinds this trait applies to. Workload kinds are specified
in kind.group/version format, e.g. server.core.oam.dev/v1alpha2.
in resource.group/version format, e.g. server.core.oam.dev/v1alpha2.
Traits that omit this field apply to all workload kinds.
items:
type: string

View File

@@ -708,7 +708,7 @@ spec:
appliesToWorkloads:
description: AppliesToWorkloads specifies the list of workload
kinds this trait applies to. Workload kinds are specified
in kind.group/version format, e.g. server.core.oam.dev/v1alpha2.
in resource.group/version format, e.g. server.core.oam.dev/v1alpha2.
Traits that omit this field apply to all workload kinds.
items:
type: string

View File

@@ -105,6 +105,9 @@ spec:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
skipGC:
description: SkipGC marks the resource to skip gc
type: boolean
trait:
type: string
uid:

View File

@@ -356,7 +356,7 @@ spec:
properties:
appliesToWorkloads:
description: AppliesToWorkloads specifies the list of workload kinds
this trait applies to. Workload kinds are specified in kind.group/version
this trait applies to. Workload kinds are specified in resource.group/version
format, e.g. server.core.oam.dev/v1alpha2. Traits that omit this
field apply to all workload kinds.
items:

View File

@@ -8,7 +8,8 @@ e2e-setup-core-post-hook:
helm upgrade --install --namespace vela-system --wait oam-rollout --set image.repository=vela-runtime-rollout-test --set image.tag=$(GIT_COMMIT) ./runtime/rollout/charts
go run ./e2e/addon/mock &
sleep 15
bin/vela addon enable rollout
bin/vela addon enable ./e2e/addon/mock/testdata/fluxcd
bin/vela addon enable ./e2e/addon/mock/testdata/rollout
.PHONY: e2e-setup-core-wo-auth
e2e-setup-core-wo-auth:
@@ -37,10 +38,10 @@ e2e-setup:
go run ./e2e/addon/mock &
sleep 15
bin/vela addon enable fluxcd
bin/vela addon enable terraform
bin/vela addon enable terraform-alibaba ALICLOUD_ACCESS_KEY=xxx ALICLOUD_SECRET_KEY=yyy ALICLOUD_REGION=cn-beijing
bin/vela addon enable rollout
bin/vela addon enable ./e2e/addon/mock/testdata/fluxcd
bin/vela addon enable ./e2e/addon/mock/testdata/terraform
bin/vela addon enable ./e2e/addon/mock/testdata/terraform-alibaba ALICLOUD_ACCESS_KEY=xxx ALICLOUD_SECRET_KEY=yyy ALICLOUD_REGION=cn-beijing
bin/vela addon enable ./e2e/addon/mock/testdata/rollout
ginkgo version
ginkgo -v -r e2e/setup

View File

@@ -79,6 +79,9 @@ const (
// ReadmeFileName is the addon readme file name
ReadmeFileName string = "README.md"
// LegacyReadmeFileName is the addon readme lower case file name
LegacyReadmeFileName string = "readme.md"
// MetadataFileName is the addon meatadata.yaml file name
MetadataFileName string = "metadata.yaml"
@@ -205,7 +208,7 @@ type Pattern struct {
var Patterns = []Pattern{
{Value: ReadmeFileName}, {Value: MetadataFileName}, {Value: TemplateFileName},
{Value: ParameterFileName}, {IsDir: true, Value: ResourcesDirName}, {IsDir: true, Value: DefinitionsDirName},
{IsDir: true, Value: DefSchemaName}, {IsDir: true, Value: ViewDirName}, {Value: AppTemplateCueFileName}, {Value: GlobalParameterFileName}}
{IsDir: true, Value: DefSchemaName}, {IsDir: true, Value: ViewDirName}, {Value: AppTemplateCueFileName}, {Value: GlobalParameterFileName}, {Value: LegacyReadmeFileName}}
// GetPatternFromItem will check if the file path has a valid pattern, return empty string if it's invalid.
// AsyncReader is needed to calculate relative path
@@ -285,6 +288,7 @@ func GetUIDataFromReader(r AsyncReader, meta *SourceMeta, opt ListOptions) (*UID
read func(a *UIData, reader AsyncReader, readPath string) error
}{
ReadmeFileName: {!opt.GetDetail, readReadme},
LegacyReadmeFileName: {!opt.GetDetail, readReadme},
MetadataFileName: {false, readMetadata},
DefinitionsDirName: {!opt.GetDefinition, readDefFile},
ParameterFileName: {!opt.GetParameter, readParamFile},
@@ -481,6 +485,10 @@ func readMetadata(a *UIData, reader AsyncReader, readPath string) error {
}
func readReadme(a *UIData, reader AsyncReader, readPath string) error {
// the detail will contain readme.md or README.md, if the content already is filled, don't read another.
if len(a.Detail) != 0 {
return nil
}
content, err := reader.ReadFile(readPath)
if err != nil {
return err
@@ -675,7 +683,7 @@ func RenderDefinitions(addon *InstallPackage, config *rest.Config) ([]*unstructu
for _, def := range addon.Definitions {
obj, err := renderObject(def)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "render definition file %s", def.Name)
}
// we should ignore the namespace defined in definition yaml, override the filed by DefaultKubeVelaNS
obj.SetNamespace(types.DefaultKubeVelaNS)
@@ -704,7 +712,7 @@ func RenderDefinitionSchema(addon *InstallPackage) ([]*unstructured.Unstructured
for _, teml := range addon.DefSchemas {
u, err := renderSchemaConfigmap(teml)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "render uiSchema file %s", teml.Name)
}
schemaConfigmaps = append(schemaConfigmaps, u)
}
@@ -717,14 +725,14 @@ func RenderViews(addon *InstallPackage) ([]*unstructured.Unstructured, error) {
for _, view := range addon.YAMLViews {
obj, err := renderObject(view)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "render velaQL view file %s", view.Name)
}
views = append(views, obj)
}
for _, view := range addon.CUEViews {
obj, err := renderCUEView(view)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "render velaQL view file %s", view.Name)
}
views = append(views, obj)
}
@@ -788,7 +796,7 @@ func renderK8sObjectsComponent(elems []ElementFile, addonName string) (*common2.
for _, elem := range elems {
obj, err := renderObject(elem)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "render resource file %s", elem.Name)
}
objects = append(objects, obj)
}
@@ -889,6 +897,7 @@ type Installer struct {
cache *Cache
dc *discovery.DiscoveryClient
skipVersionValidate bool
overrideDefs bool
}
// NewAddonInstaller will create an installer for addon
@@ -1069,6 +1078,16 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
return errors.Wrap(err, "render addon definitions fail")
}
if !h.overrideDefs {
existDefs, err := checkConflictDefs(h.ctx, h.cli, defs, app.Name)
if err != nil {
return err
}
if len(existDefs) != 0 {
return produceDefConflictError(existDefs)
}
}
schemas, err := RenderDefinitionSchema(addon)
if err != nil {
return errors.Wrap(err, "render addon definitions' schema fail")
@@ -1088,6 +1107,10 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
}
for _, def := range defs {
if !checkBondComponentExist(*def, *app) {
continue
}
// if binding component exist, apply the definition
addOwner(def, app)
err = h.apply.Apply(h.ctx, def, apply.DisableUpdateAnnotation())
if err != nil {
@@ -1112,6 +1135,9 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
}
for _, o := range auxiliaryOutputs {
if !checkBondComponentExist(*o, *app) {
continue
}
addOwner(o, app)
err = h.apply.Apply(h.ctx, o, apply.DisableUpdateAnnotation())
if err != nil {
@@ -1286,26 +1312,30 @@ func checkSemVer(actual string, require string) (bool, error) {
if len(require) == 0 {
return true, nil
}
smeVer := strings.TrimPrefix(actual, "v")
semVer := strings.TrimPrefix(actual, "v")
l := strings.ReplaceAll(require, "v", " ")
constraint, err := semver.NewConstraint(l)
if err != nil {
log.Logger.Errorf("fail to new constraint: %s", err.Error())
return false, err
}
v, err := semver.NewVersion(smeVer)
v, err := semver.NewVersion(semVer)
if err != nil {
log.Logger.Errorf("fail to new version %s: %s", smeVer, err.Error())
log.Logger.Errorf("fail to new version %s: %s", semVer, err.Error())
return false, err
}
if constraint.Check(v) {
return true, nil
}
if strings.Contains(actual, "-") && !strings.Contains(require, "-") {
smeVer := strings.TrimPrefix(actual[:strings.Index(actual, "-")], "v")
v, err := semver.NewVersion(smeVer)
semVer := strings.TrimPrefix(actual[:strings.Index(actual, "-")], "v")
if strings.Contains(require, ">=") && require[strings.Index(require, "=")+1:] == semVer {
// for case: `actual` is 1.5.0-beta.1 require is >=`1.5.0`
return false, nil
}
v, err := semver.NewVersion(semVer)
if err != nil {
log.Logger.Errorf("fail to new version %s: %s", smeVer, err.Error())
log.Logger.Errorf("fail to new version %s: %s", semVer, err.Error())
return false, err
}
if constraint.Check(v) {

View File

@@ -26,6 +26,7 @@ import (
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
types2 "k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -396,6 +397,60 @@ var _ = Describe("test enable addon which applies the views independently", func
})
})
var _ = Describe("test override defs of addon", func() {
It("test compDef exist", func() {
ctx := context.Background()
comp := v1beta1.ComponentDefinition{TypeMeta: metav1.TypeMeta{APIVersion: v1beta1.SchemeGroupVersion.String(), Kind: v1beta1.ComponentDefinitionKind}}
Expect(yaml.Unmarshal([]byte(helmCompDefYaml), &comp)).Should(BeNil())
Expect(k8sClient.Create(ctx, &comp)).Should(BeNil())
comp2 := v1beta1.ComponentDefinition{TypeMeta: metav1.TypeMeta{APIVersion: v1beta1.SchemeGroupVersion.String(), Kind: v1beta1.ComponentDefinitionKind}}
Expect(yaml.Unmarshal([]byte(kustomizeCompDefYaml), &comp2)).Should(BeNil())
Expect(k8sClient.Create(ctx, &comp2)).Should(BeNil())
app := v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Name: "addon-fluxcd"}}
comp3 := v1beta1.ComponentDefinition{TypeMeta: metav1.TypeMeta{APIVersion: v1beta1.SchemeGroupVersion.String(), Kind: v1beta1.ComponentDefinitionKind}}
Expect(yaml.Unmarshal([]byte(kustomizeCompDefYaml1), &comp3)).Should(BeNil())
Expect(k8sClient.Create(ctx, &comp3)).Should(BeNil())
compUnstructured, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&comp)
Expect(err).Should(BeNil())
u := unstructured.Unstructured{Object: compUnstructured}
u.SetAPIVersion(v1beta1.SchemeGroupVersion.String())
u.SetKind(v1beta1.ComponentDefinitionKind)
c, err := checkConflictDefs(ctx, k8sClient, []*unstructured.Unstructured{&u}, app.GetName())
Expect(err).Should(BeNil())
Expect(len(c)).Should(BeEquivalentTo(1))
u.SetName("rollout")
c, err = checkConflictDefs(ctx, k8sClient, []*unstructured.Unstructured{&u}, app.GetName())
Expect(err).Should(BeNil())
Expect(len(c)).Should(BeEquivalentTo(0))
u.SetKind("NotExistKind")
_, err = checkConflictDefs(ctx, k8sClient, []*unstructured.Unstructured{&u}, app.GetName())
Expect(err).ShouldNot(BeNil())
compUnstructured2, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&comp2)
Expect(err).Should(BeNil())
u2 := &unstructured.Unstructured{Object: compUnstructured2}
u2.SetAPIVersion(v1beta1.SchemeGroupVersion.String())
u2.SetKind(v1beta1.ComponentDefinitionKind)
c, err = checkConflictDefs(ctx, k8sClient, []*unstructured.Unstructured{u2}, app.GetName())
Expect(err).Should(BeNil())
Expect(len(c)).Should(BeEquivalentTo(1))
compUnstructured3, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&comp3)
Expect(err).Should(BeNil())
u3 := &unstructured.Unstructured{Object: compUnstructured3}
u3.SetAPIVersion(v1beta1.SchemeGroupVersion.String())
u3.SetKind(v1beta1.ComponentDefinitionKind)
c, err = checkConflictDefs(ctx, k8sClient, []*unstructured.Unstructured{u3}, app.GetName())
Expect(err).Should(BeNil())
Expect(len(c)).Should(BeEquivalentTo(0))
})
})
const (
appYaml = `apiVersion: core.oam.dev/v1beta1
kind: Application
@@ -491,5 +546,49 @@ spec:
properties:
image: crccheck/hello-world
port: 8000
`
helmCompDefYaml = `
apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
name: helm
namespace: vela-system
ownerReferences:
- apiVersion: core.oam.dev/v1beta1
blockOwnerDeletion: true
controller: true
kind: Application
name: addon-fluxcd-helm
uid: 73c47933-002e-4182-a673-6da6a9dcf080
spec:
schematic:
cue:
`
kustomizeCompDefYaml = `
apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
name: kustomize
namespace: vela-system
spec:
schematic:
cue:
`
kustomizeCompDefYaml1 = `
apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
name: kustomize-another
namespace: vela-system
ownerReferences:
- apiVersion: core.oam.dev/v1beta1
blockOwnerDeletion: true
controller: true
kind: Application
name: addon-fluxcd
uid: 73c47933-002e-4182-a673-6da6a9dcf080
spec:
schematic:
cue:
`
)

View File

@@ -945,6 +945,16 @@ func TestCheckSemVer(t *testing.T) {
require: ">=v1.2.4-beta.3",
res: false,
},
{
actual: "1.5.0-beta.2",
require: ">=1.5.0",
res: false,
},
{
actual: "1.5.0-alpha.2",
require: ">=1.5.0",
res: false,
},
}
for _, testCase := range testCases {
result, err := checkSemVer(testCase.actual, testCase.require)
@@ -1306,3 +1316,15 @@ func TestMergeAddonInstallArgs(t *testing.T) {
}
}
func TestGenerateConflictError(t *testing.T) {
confictAddon := map[string]string{
"helm": "definition: helm already exist and not belong to any addon \n",
"kustomize": "definition: kustomize in this addon already exist in fluxcd \n",
}
err := produceDefConflictError(confictAddon)
assert.Error(t, err)
strings.Contains(err.Error(), "in this addon already exist in fluxcd")
assert.NoError(t, produceDefConflictError(map[string]string{}))
}

View File

@@ -180,9 +180,7 @@ func (cmd *InitCmd) createRequiredFiles() {
Description: "An addon for KubeVela.",
Tags: []string{"my-tag"},
Dependencies: []*Dependency{},
DeployTo: &DeployTo{
RuntimeCluster: false,
},
DeployTo: nil,
}
}
@@ -507,10 +505,6 @@ parameter: {
output: {
apiVersion: "core.oam.dev/v1beta1"
kind: "Application"
metadata: {
name: "my-addon-name"
namespace: "vela-system"
}
spec: {
components: []
policies: []

View File

@@ -28,6 +28,7 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
common2 "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
@@ -189,9 +190,17 @@ func generateAppFramework(addon *InstallPackage, parameters map[string]interface
}
}
app.Name = addonutil.Addon2AppName(addon.Name)
// force override the namespace defined vela with DefaultVelaNS,this value can be modified by Env
if app.Name != "" && app.Name != addonutil.Addon2AppName(addon.Name) {
klog.Warningf("Application name %s will be overwritten with %s. Consider removing metadata.name in template.", app.Name, addonutil.Addon2AppName(addon.Name))
}
app.SetName(addonutil.Addon2AppName(addon.Name))
if app.Namespace != "" && app.Namespace != types.DefaultKubeVelaNS {
klog.Warningf("Namespace %s will be overwritten with %s. Consider removing metadata.namespace in template.", app.Namespace, types.DefaultKubeVelaNS)
}
// force override the namespace defined vela with DefaultVelaNS. This value can be modified by env
app.SetNamespace(types.DefaultKubeVelaNS)
if app.Labels == nil {
app.Labels = make(map[string]string)
}
@@ -319,7 +328,7 @@ func renderResources(addon *InstallPackage, args map[string]interface{}) ([]comm
if len(addon.YAMLTemplates) != 0 {
comp, err := renderK8sObjectsComponent(addon.YAMLTemplates, addon.Name)
if err != nil {
return nil, err
return nil, errors.Wrapf(err, "render components from yaml template")
}
resources = append(resources, *comp)
}
@@ -345,6 +354,7 @@ func checkNeedAttachTopologyPolicy(app *v1beta1.Application, addon *InstallPacka
}
for _, policy := range app.Spec.Policies {
if policy.Type == v1alpha1.TopologyPolicyType {
klog.Warningf("deployTo in metadata will NOT have any effect. It conflicts with %s policy named %s. Consider removing deployTo field in addon metadata.", v1alpha1.TopologyPolicyType, policy.Name)
return false
}
}

View File

@@ -27,6 +27,8 @@ import (
errors "github.com/pkg/errors"
"helm.sh/helm/v3/pkg/chart"
"helm.sh/helm/v3/pkg/chartutil"
errors2 "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
rest "k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -36,6 +38,7 @@ import (
"github.com/oam-dev/kubevela/pkg/definition"
"github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/utils/addon"
"github.com/oam-dev/kubevela/pkg/utils/common"
)
@@ -43,13 +46,22 @@ const (
compDefAnnotation = "addon.oam.dev/componentDefinitions"
traitDefAnnotation = "addon.oam.dev/traitDefinitions"
workflowStepDefAnnotation = "addon.oam.dev/workflowStepDefinitions"
policyDefAnnotation = "addon.oam.dev/policyDefinitions"
defKeytemplate = "addon-%s-%s"
compMapKey = "comp"
traitMapKey = "trait"
wfStepMapKey = "wfStep"
policyMapKey = "policy"
)
// parse addon's created x-defs in addon-app's annotation, this will be used to check whether app still using it while disabling.
func passDefInAppAnnotation(defs []*unstructured.Unstructured, app *v1beta1.Application) error {
var comps, traits, workflowSteps []string
var comps, traits, workflowSteps, policies []string
for _, def := range defs {
if !checkBondComponentExist(*def, *app) {
// if the definition binding a component, and the component not exist, skip recording.
continue
}
switch def.GetObjectKind().GroupVersionKind().Kind {
case v1beta1.ComponentDefinitionKind:
comps = append(comps, def.GetName())
@@ -57,6 +69,8 @@ func passDefInAppAnnotation(defs []*unstructured.Unstructured, app *v1beta1.Appl
traits = append(traits, def.GetName())
case v1beta1.WorkflowStepDefinitionKind:
workflowSteps = append(workflowSteps, def.GetName())
case v1beta1.PolicyDefinitionKind:
policies = append(policies, def.GetName())
default:
return fmt.Errorf("cannot handle definition types %s, name %s", def.GetObjectKind().GroupVersionKind().Kind, def.GetName())
}
@@ -70,6 +84,9 @@ func passDefInAppAnnotation(defs []*unstructured.Unstructured, app *v1beta1.Appl
if len(workflowSteps) != 0 {
app.SetAnnotations(util.MergeMapOverrideWithDst(app.GetAnnotations(), map[string]string{workflowStepDefAnnotation: strings.Join(workflowSteps, ",")}))
}
if len(policies) != 0 {
app.SetAnnotations(util.MergeMapOverrideWithDst(app.GetAnnotations(), map[string]string{policyDefAnnotation: strings.Join(policies, ",")}))
}
return nil
}
@@ -87,7 +104,7 @@ func checkAddonHasBeenUsed(ctx context.Context, k8sClient client.Client, name st
createdDefs := make(map[string]bool)
for key, defNames := range addonApp.GetAnnotations() {
switch key {
case compDefAnnotation, traitDefAnnotation, workflowStepDefAnnotation:
case compDefAnnotation, traitDefAnnotation, workflowStepDefAnnotation, policyDefAnnotation:
merge2DefMap(key, defNames, createdDefs)
}
}
@@ -102,25 +119,34 @@ func checkAddonHasBeenUsed(ctx context.Context, k8sClient client.Client, name st
CHECKNEXT:
for _, app := range apps.Items {
for _, component := range app.Spec.Components {
if createdDefs[fmt.Sprintf(defKeytemplate, "comp", component.Type)] {
if createdDefs[fmt.Sprintf(defKeytemplate, compMapKey, component.Type)] {
res = append(res, app)
// this app has used this addon, there is no need check other components
continue CHECKNEXT
}
for _, trait := range component.Traits {
if createdDefs[fmt.Sprintf(defKeytemplate, "trait", trait.Type)] {
if createdDefs[fmt.Sprintf(defKeytemplate, traitMapKey, trait.Type)] {
res = append(res, app)
continue CHECKNEXT
}
}
}
if app.Spec.Workflow == nil || len(app.Spec.Workflow.Steps) == 0 {
return res, nil
if app.Spec.Workflow != nil && len(app.Spec.Workflow.Steps) != 0 {
for _, s := range app.Spec.Workflow.Steps {
if createdDefs[fmt.Sprintf(defKeytemplate, wfStepMapKey, s.Type)] {
res = append(res, app)
continue CHECKNEXT
}
}
}
for _, s := range app.Spec.Workflow.Steps {
if createdDefs[fmt.Sprintf(defKeytemplate, "wfStep", s.Type)] {
res = append(res, app)
continue CHECKNEXT
if app.Spec.Policies != nil && len(app.Spec.Policies) != 0 {
for _, p := range app.Spec.Policies {
if createdDefs[fmt.Sprintf(defKeytemplate, policyMapKey, p.Type)] {
res = append(res, app)
continue CHECKNEXT
}
}
}
}
@@ -134,11 +160,13 @@ func merge2DefMap(defType string, defNames string, defMap map[string]bool) {
for _, defName := range list {
switch defType {
case compDefAnnotation:
defMap[fmt.Sprintf(template, "comp", defName)] = true
defMap[fmt.Sprintf(template, compMapKey, defName)] = true
case traitDefAnnotation:
defMap[fmt.Sprintf(template, "trait", defName)] = true
defMap[fmt.Sprintf(template, traitMapKey, defName)] = true
case workflowStepDefAnnotation:
defMap[fmt.Sprintf(template, "wfStep", defName)] = true
defMap[fmt.Sprintf(template, wfStepMapKey, defName)] = true
case policyDefAnnotation:
defMap[fmt.Sprintf(template, policyMapKey, defName)] = true
}
}
}
@@ -210,6 +238,8 @@ func findLegacyAddonDefs(ctx context.Context, k8sClient client.Client, addonName
defs[fmt.Sprintf(defKeytemplate, "trait", defObject.GetName())] = true
case v1beta1.WorkflowStepDefinitionKind:
defs[fmt.Sprintf(defKeytemplate, "wfStep", defObject.GetName())] = true
case v1beta1.PolicyDefinitionKind:
}
}
return nil
@@ -242,6 +272,11 @@ func SkipValidateVersion(installer *Installer) {
installer.skipVersionValidate = true
}
// OverrideDefinitions menas override definitions within this addon if some of them already exist
func OverrideDefinitions(installer *Installer) {
installer.overrideDefs = true
}
// IsAddonDir validates an addon directory.
// It checks required files like metadata.yaml and template.yaml
func IsAddonDir(dirName string) (bool, error) {
@@ -409,3 +444,54 @@ func generateAnnotation(meta *Meta) map[string]string {
func isErrorCueRenderPathNotFound(err error, path string) bool {
return err.Error() == fmt.Sprintf("var(path=%s) not exist", path)
}
func checkConflictDefs(ctx context.Context, k8sClient client.Client, defs []*unstructured.Unstructured, appName string) (map[string]string, error) {
res := map[string]string{}
for _, def := range defs {
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(def), def)
if err == nil {
owner := metav1.GetControllerOf(def)
if owner == nil || owner.Kind != v1beta1.ApplicationKind {
res[def.GetName()] = fmt.Sprintf("definition: %s already exist and not belong to any addon \n", def.GetName())
continue
}
if owner.Name != appName {
// if addon not belong to an addon or addon name is another one, we should put them in result
res[def.GetName()] = fmt.Sprintf("definition: %s in this addon already exist in %s \n", def.GetName(), addon.AppName2Addon(appName))
}
}
if err != nil && !errors2.IsNotFound(err) {
return nil, errors.Wrapf(err, "check definition %s", def.GetName())
}
}
return res, nil
}
func produceDefConflictError(conflictDefs map[string]string) error {
if len(conflictDefs) == 0 {
return nil
}
var errorInfo string
for _, s := range conflictDefs {
errorInfo += s
}
errorInfo += "if you want override them, please use argument '--override-definitions' to enable \n"
return errors.New(errorInfo)
}
// checkBondComponentExistt will check the ready-to-apply object(def or auxiliary outputs) whether bind to a component
// if the target component not exist, return false.
func checkBondComponentExist(u unstructured.Unstructured, app v1beta1.Application) bool {
comp, existKey := u.GetAnnotations()[oam.AnnotationIgnoreWithoutCompKey]
if !existKey {
// if an object(def or auxiliary outputs ) binding no components return true
return true
}
for _, component := range app.Spec.Components {
if component.Name == comp {
// the bond component exists, return ture
return true
}
}
return false
}

View File

@@ -33,6 +33,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"sigs.k8s.io/yaml"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
velatypes "github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/oam"
@@ -108,9 +109,13 @@ var _ = Describe("Test definition check", func() {
Expect(yaml.Unmarshal([]byte(testApp3Yaml), &app3)).Should(BeNil())
Expect(k8sClient.Create(ctx, &app3)).Should(BeNil())
app4 := v1beta1.Application{}
Expect(yaml.Unmarshal([]byte(testApp4Yaml), &app4)).Should(BeNil())
Expect(k8sClient.Create(ctx, &app4)).Should(BeNil())
usedApps, err := checkAddonHasBeenUsed(ctx, k8sClient, "my-addon", addonApp, cfg)
Expect(err).Should(BeNil())
Expect(len(usedApps)).Should(BeEquivalentTo(3))
Expect(len(usedApps)).Should(BeEquivalentTo(4))
})
It("check fetch lagacy addon definitions", func() {
@@ -283,6 +288,36 @@ func TestMakeChart(t *testing.T) {
assert.Equal(t, isChartDir, true)
}
func TestCheckObjectBindingComponent(t *testing.T) {
existingBindingDef := unstructured.Unstructured{}
existingBindingDef.SetAnnotations(map[string]string{oam.AnnotationIgnoreWithoutCompKey: "kustomize"})
emptyAnnoDef := unstructured.Unstructured{}
emptyAnnoDef.SetAnnotations(map[string]string{"test": "onlyForTest"})
testCases := map[string]struct {
object unstructured.Unstructured
app v1beta1.Application
res bool
}{
"bindingExist": {object: existingBindingDef,
app: v1beta1.Application{Spec: v1beta1.ApplicationSpec{Components: []common.ApplicationComponent{{Name: "kustomize"}}}},
res: true},
"NotExisting": {object: existingBindingDef,
app: v1beta1.Application{Spec: v1beta1.ApplicationSpec{Components: []common.ApplicationComponent{{Name: "helm"}}}},
res: false},
"NoBidingAnnotation": {object: emptyAnnoDef,
app: v1beta1.Application{Spec: v1beta1.ApplicationSpec{Components: []common.ApplicationComponent{{Name: "kustomize"}}}},
res: true},
"EmptyApp": {object: existingBindingDef,
app: v1beta1.Application{Spec: v1beta1.ApplicationSpec{Components: []common.ApplicationComponent{}}},
res: false},
}
for _, s := range testCases {
result := checkBondComponentExist(s.object, s.app)
assert.Equal(t, result, s.res)
}
}
const (
compDefYaml = `
apiVersion: core.oam.dev/v1beta1
@@ -319,6 +354,7 @@ metadata:
addon.oam.dev/componentDefinitions: "my-comp"
addon.oam.dev/traitDefinitions: "my-trait"
addon.oam.dev/workflowStepDefinitions: "my-wfstep"
addon.oam.dev/policyDefinitions: "my-policy"
name: addon-myaddon
namespace: vela-system
spec:
@@ -367,6 +403,22 @@ spec:
- type: my-wfstep
name: deploy
`
testApp4Yaml = `
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app-4
namespace: test-ns
spec:
components:
- name: podinfo
type: webservice
policies:
- type: my-policy
name: topology
`
registryCmYaml = `
apiVersion: v1
data:

View File

@@ -86,6 +86,7 @@ func (i *versionedRegistry) GetAddonUIData(ctx context.Context, addonName, versi
Detail: wholePackage.Detail,
Definitions: wholePackage.Definitions,
AvailableVersions: wholePackage.AvailableVersions,
CUEDefinitions: wholePackage.CUEDefinitions,
}, nil
}

View File

@@ -32,11 +32,12 @@ const (
// SystemInfo systemInfo model
type SystemInfo struct {
BaseModel
InstallID string `json:"installID"`
EnableCollection bool `json:"enableCollection"`
StatisticInfo StatisticInfo `json:"statisticInfo,omitempty"`
LoginType string `json:"loginType"`
DexUserDefaultProjects []ProjectRef `json:"projects"`
InstallID string `json:"installID"`
EnableCollection bool `json:"enableCollection"`
StatisticInfo StatisticInfo `json:"statisticInfo,omitempty"`
LoginType string `json:"loginType"`
DexUserDefaultProjects []ProjectRef `json:"projects"`
DexUserDefaultPlatformRoles []string `json:"dexUserDefaultPlatformRoles"`
}
// ProjectRef set the project name and roles

View File

@@ -26,6 +26,7 @@ import (
"sync"
"time"
errors3 "github.com/pkg/errors"
v1 "k8s.io/api/core/v1"
errors2 "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -44,6 +45,7 @@ import (
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
"github.com/oam-dev/kubevela/pkg/apiserver/utils/log"
"github.com/oam-dev/kubevela/pkg/definition"
"github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam"
addonutil "github.com/oam-dev/kubevela/pkg/utils/addon"
@@ -68,7 +70,7 @@ type AddonService interface {
}
// AddonImpl2AddonRes convert pkgaddon.UIData to the type apiserver need
func AddonImpl2AddonRes(impl *pkgaddon.UIData) (*apis.DetailAddonResponse, error) {
func AddonImpl2AddonRes(impl *pkgaddon.UIData, config *rest.Config) (*apis.DetailAddonResponse, error) {
var defs []*apis.AddonDefinition
for _, def := range impl.Definitions {
obj := &unstructured.Unstructured{}
@@ -83,6 +85,20 @@ func AddonImpl2AddonRes(impl *pkgaddon.UIData) (*apis.DetailAddonResponse, error
Description: obj.GetAnnotations()["definition.oam.dev/description"],
})
}
for _, cueDef := range impl.CUEDefinitions {
def := definition.Definition{Unstructured: unstructured.Unstructured{}}
err := def.FromCUEString(cueDef.Data, config)
if err != nil {
return nil, errors3.Wrapf(err, "fail to render definition: %s in cue's format", cueDef.Name)
}
defs = append(defs, &apis.AddonDefinition{
Name: def.GetName(),
DefType: def.GetKind(),
Description: def.GetAnnotations()["definition.oam.dev/description"],
})
}
if impl.Meta.DeployTo != nil && impl.Meta.DeployTo.LegacyRuntimeCluster != impl.Meta.DeployTo.RuntimeCluster {
impl.Meta.DeployTo.LegacyRuntimeCluster = impl.Meta.DeployTo.LegacyRuntimeCluster || impl.Meta.DeployTo.RuntimeCluster
impl.Meta.DeployTo.RuntimeCluster = impl.Meta.DeployTo.LegacyRuntimeCluster || impl.Meta.DeployTo.RuntimeCluster
@@ -175,7 +191,7 @@ func (u *addonServiceImpl) GetAddon(ctx context.Context, name string, registry s
addon.UISchema = renderAddonCustomUISchema(ctx, u.kubeClient, name, renderDefaultUISchema(addon.APISchema))
a, err := AddonImpl2AddonRes(addon)
a, err := AddonImpl2AddonRes(addon, u.config)
if err != nil {
return nil, err
}
@@ -284,7 +300,7 @@ func (u *addonServiceImpl) ListAddons(ctx context.Context, registry, query strin
var addonResources []*apis.DetailAddonResponse
for _, a := range addons {
addonRes, err := AddonImpl2AddonRes(a)
addonRes, err := AddonImpl2AddonRes(a, u.config)
if err != nil {
log.Logger.Errorf("err while converting AddonImpl to DetailAddonResponse: %v", err)
continue

View File

@@ -484,6 +484,10 @@ func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) {
}
userBase = convertUserBase(u)
} else {
systemInfo, err := d.systemInfoService.GetSystemInfo(ctx)
if err != nil {
log.Logger.Errorf("failed to get the system info %s", err.Error())
}
user := &model.User{
Email: claims.Email,
Name: strings.ToLower(claims.Sub),
@@ -491,18 +495,17 @@ func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) {
Alias: claims.Name,
LastLoginTime: time.Now(),
}
if systemInfo != nil {
user.UserRoles = systemInfo.DexUserDefaultPlatformRoles
}
if err := d.Store.Add(ctx, user); err != nil {
log.Logger.Errorf("failed to save the user from the dex: %s", err.Error())
return nil, err
}
systemInfo, err := d.systemInfoService.GetSystemInfo(ctx)
if err != nil {
log.Logger.Errorf("failed to get the system info %s", err.Error())
}
if systemInfo != nil {
for _, project := range systemInfo.DexUserDefaultProjects {
_, err := d.projectService.AddProjectUser(ctx, project.Name, apisv1.AddProjectUserRequest{
UserName: claims.Sub,
UserName: strings.ToLower(claims.Sub),
UserRoles: project.Roles,
})
if err != nil {

View File

@@ -23,6 +23,7 @@ import (
"io/ioutil"
"reflect"
"strconv"
"strings"
"time"
. "github.com/agiledragon/gomonkey/v2"
@@ -65,7 +66,7 @@ var _ = Describe("Test authentication service functions", func() {
})
It("Test Dex login", func() {
testIDToken := &oidc.IDToken{}
sub := "248289761001"
sub := "248289761001Abv"
patch := ApplyMethod(reflect.TypeOf(testIDToken), "Claims", func(_ *oidc.IDToken, v interface{}) error {
return json.Unmarshal([]byte(fmt.Sprintf(`{"email":"test@test.com", "name":"show name", "sub": "%s"}`, sub)), v)
})
@@ -78,13 +79,14 @@ var _ = Describe("Test authentication service functions", func() {
err = projectService.Init(context.TODO())
Expect(err).Should(BeNil())
_, err = sysService.UpdateSystemInfo(context.TODO(), apisv1.SystemInfoRequest{
LoginType: "local",
DexUserDefaultProjects: []model.ProjectRef{{
Name: "default",
Roles: []string{"app-developer"},
}},
})
info, err := sysService.Get(context.TODO())
Expect(err).Should(BeNil())
info.DexUserDefaultProjects = []model.ProjectRef{{
Name: "default",
Roles: []string{"app-developer"},
}}
info.DexUserDefaultPlatformRoles = []string{"admin"}
err = ds.Put(context.TODO(), info)
Expect(err).Should(BeNil())
dexHandler := dexHandlerImpl{
@@ -96,9 +98,14 @@ var _ = Describe("Test authentication service functions", func() {
resp, err := dexHandler.login(context.Background())
Expect(err).Should(BeNil())
Expect(resp.Email).Should(Equal("test@test.com"))
Expect(resp.Name).Should(Equal(sub))
Expect(resp.Name).Should(Equal(strings.ToLower(sub)))
Expect(resp.Alias).Should(Equal("show name"))
newUser, err := userService.GetUser(context.TODO(), resp.Name)
Expect(err).Should(BeNil())
Expect(newUser.DexSub).Should(Equal(sub))
Expect(newUser.UserRoles).Should(Equal([]string{"admin"}))
projects, err := projectService.ListUserProjects(context.TODO(), sub)
Expect(err).Should(BeNil())
Expect(len(projects)).Should(Equal(1))

View File

@@ -75,6 +75,7 @@ const (
type CloudShellService interface {
Prepare(ctx context.Context) (*apisv1.CloudShellPrepareResponse, error)
GetCloudShellEndpoint(ctx context.Context) (string, error)
Destroy(ctx context.Context) error
}
// GenerateKubeConfig generate the kubeconfig for the cloudshell
@@ -157,6 +158,32 @@ func (c *cloudShellServiceImpl) Prepare(ctx context.Context) (*apisv1.CloudShell
return res, nil
}
// Destroy destroy the cloud shell environment
func (c *cloudShellServiceImpl) Destroy(ctx context.Context) error {
var userName string
if user := ctx.Value(&apisv1.CtxKeyUser); user != nil {
if u, ok := user.(string); ok {
userName = u
}
}
if userName == "" {
return bcode.ErrUnauthorized
}
ctx, cancel := context.WithTimeout(ctx, time.Second*20)
defer cancel()
var cloudShell v1alpha1.CloudShell
if err := c.KubeClient.Get(ctx, types.NamespacedName{Namespace: kubevelatypes.DefaultKubeVelaNS, Name: makeUserCloudShellName(userName)}, &cloudShell); err != nil {
if apierrors.IsNotFound(err) {
return nil
}
if meta.IsNoMatchError(err) {
return bcode.ErrCloudShellAddonNotEnabled
}
return err
}
return c.KubeClient.Delete(ctx, &cloudShell)
}
func (c *cloudShellServiceImpl) GetCloudShellEndpoint(ctx context.Context) (string, error) {
var userName string
if user := ctx.Value(&apisv1.CtxKeyUser); user != nil {
@@ -182,7 +209,7 @@ func (c *cloudShellServiceImpl) GetCloudShellEndpoint(ctx context.Context) (stri
return cloudShell.Status.AccessURL, nil
}
// prepareKubeConfig prepare the user's kubeconfig
// prepareKubeConfig prepare the user's kube config
func (c *cloudShellServiceImpl) prepareKubeConfig(ctx context.Context) error {
var userName string
if user := ctx.Value(&apisv1.CtxKeyUser); user != nil {
@@ -212,10 +239,13 @@ func (c *cloudShellServiceImpl) prepareKubeConfig(ctx context.Context) error {
readOnly = checkReadOnly(p.Name, permissions)
}
if readOnly {
// TODO:(@barnettZQG) there needs a method to revoke the privileges
if err := c.managePrivilegesForUser(ctx, p.Name, true, userName, false); err != nil {
groupName, err := c.managePrivilegesForProjectRead(ctx, p.Name, true)
if err != nil {
log.Logger.Errorf("failed to privileges the user %s", err.Error())
}
if groupName != "" {
groups = append(groups, groupName)
}
} else {
groups = append(groups, utils.KubeVelaProjectGroupPrefix+p.Name)
}
@@ -345,8 +375,8 @@ func checkReadOnly(projectName string, permissions []*model.Permission) bool {
return !ra.Match(permissions)
}
// managePrivilegesForUser grant or revoke privileges for a user
func (c *cloudShellServiceImpl) managePrivilegesForUser(ctx context.Context, projectName string, readOnly bool, userName string, revoke bool) error {
// managePrivilegesForProjectRead grant the read privileges for a project
func (c *cloudShellServiceImpl) managePrivilegesForProjectRead(ctx context.Context, projectName string, readOnly bool) (string, error) {
targets, err := c.TargetService.ListTargets(ctx, 0, 0, projectName)
if err != nil {
log.Logger.Infof("failed to list the targets by the project name %s :%s", projectName, err.Error())
@@ -362,16 +392,12 @@ func (c *cloudShellServiceImpl) managePrivilegesForUser(ctx context.Context, pro
for _, e := range envs.Envs {
authPDs = append(authPDs, &auth.ApplicationPrivilege{Cluster: kubevelatypes.ClusterLocalName, Namespace: e.Namespace, ReadOnly: readOnly})
}
identity := &auth.Identity{User: userName}
groupName := utils.KubeVelaProjectReadGroupPrefix + projectName
identity := &auth.Identity{Groups: []string{groupName}}
writer := &bytes.Buffer{}
f, msg := auth.GrantPrivileges, "GrantPrivileges"
if revoke {
f, msg = auth.RevokePrivileges, "RevokePrivileges"
if err := auth.GrantPrivileges(ctx, c.KubeClient, authPDs, identity, writer, auth.WithReplace); err != nil {
return "", err
}
if err := f(ctx, c.KubeClient, authPDs, identity, writer); err != nil {
return err
}
log.Logger.Debugf("%s: %s", msg, writer.String())
return nil
log.Logger.Debugf("GrantPrivileges: %s", writer.String())
return groupName, nil
}

View File

@@ -154,10 +154,13 @@ var _ = Describe("Test cloudshell service function", func() {
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "kubevela:reader:application:binding", Namespace: "default"}, &rb)
Expect(err).Should(BeNil())
Expect(len(rb.Subjects)).Should(Equal(1))
Expect(rb.Subjects[0].Name).Should(Equal("test-viewer"))
Expect(rb.Subjects[0].Kind).Should(Equal("User"))
Expect(rb.Subjects[0].Name).Should(Equal(utils.KubeVelaProjectReadGroupPrefix + "default"))
Expect(rb.Subjects[0].Kind).Should(Equal("Group"))
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "kubevela:reader:binding", Namespace: "default"}, &rb)
Expect(err).Should(BeNil())
Expect(len(rb.Subjects)).Should(Equal(1))
Expect(rb.Subjects[0].Name).Should(Equal(utils.KubeVelaProjectReadGroupPrefix + "default"))
Expect(rb.Subjects[0].Kind).Should(Equal("Group"))
By("test the administrator users")
@@ -178,7 +181,7 @@ var _ = Describe("Test cloudshell service function", func() {
})
It("test prepare", func() {
By("With not CRD")
By("Test with not CRD")
_, err = userService.CreateUser(context.TODO(), apisv1.CreateUserRequest{Name: "test", Password: "test"})
Expect(err).Should(BeNil())
ctx := context.WithValue(context.TODO(), &apisv1.CtxKeyUser, "test")
@@ -186,6 +189,7 @@ var _ = Describe("Test cloudshell service function", func() {
Expect(err).ShouldNot(BeNil())
Expect(err.Error()).Should(Equal(bcode.ErrCloudShellAddonNotEnabled.Error()))
By("Test with CRD")
cloudshellCRDBytes, err := ioutil.ReadFile("./testdata/cloudshell-crd.yaml")
Expect(err).Should(BeNil())
@@ -210,8 +214,12 @@ var _ = Describe("Test cloudshell service function", func() {
Expect(err).Should(BeNil())
Expect(re.Status).Should(Equal(StatusCompleted))
By("Test get the cloud shell endpoint")
endpoint, err := cloudShellService.GetCloudShellEndpoint(ctx)
Expect(err).Should(BeNil())
Expect(endpoint).Should(Equal("10.10.1.1:8765"))
By("Test destroy cloud shell")
Expect(cloudShellService.Destroy(ctx)).Should(BeNil())
})
})

View File

@@ -89,8 +89,13 @@ func (u *configServiceImpl) ListConfigTypes(ctx context.Context, query string) (
}); err != nil {
return nil, err
}
items = append(items, defsLegacy.Items...)
// filter repeated config,due to new labels that exist at the same time
for _, legacy := range defsLegacy.Items {
if legacy.Labels[configCatalog] == types.VelaCoreConfig {
continue
}
items = append(items, legacy)
}
var tfDefs []v1beta1.ComponentDefinition
var configTypes []*apis.ConfigType

View File

@@ -484,7 +484,7 @@ func (p *rbacServiceImpl) GetUserPermissions(ctx context.Context, user *model.Us
perms = append(perms, &model.Permission{
Name: "cloudshell",
Resources: []string{"cloudshell"},
Actions: []string{"create"},
Actions: []string{"*"},
Effect: "Allow",
})
return perms, nil

View File

@@ -113,8 +113,9 @@ func (u systemInfoServiceImpl) UpdateSystemInfo(ctx context.Context, sysInfo v1.
CreateTime: info.CreateTime,
UpdateTime: time.Now(),
},
StatisticInfo: info.StatisticInfo,
DexUserDefaultProjects: sysInfo.DexUserDefaultProjects,
StatisticInfo: info.StatisticInfo,
DexUserDefaultProjects: sysInfo.DexUserDefaultProjects,
DexUserDefaultPlatformRoles: info.DexUserDefaultPlatformRoles,
}
if sysInfo.LoginType == model.LoginTypeDex {
@@ -167,10 +168,11 @@ func (u systemInfoServiceImpl) Init(ctx context.Context) error {
func convertInfoToBase(info *model.SystemInfo) v1.SystemInfo {
return v1.SystemInfo{
PlatformID: info.InstallID,
EnableCollection: info.EnableCollection,
LoginType: info.LoginType,
InstallTime: info.CreateTime,
DexUserDefaultProjects: info.DexUserDefaultProjects,
PlatformID: info.InstallID,
EnableCollection: info.EnableCollection,
LoginType: info.LoginType,
InstallTime: info.CreateTime,
DexUserDefaultProjects: info.DexUserDefaultProjects,
DexUserDefaultPlatformRoles: info.DexUserDefaultPlatformRoles,
}
}

View File

@@ -104,6 +104,7 @@ func authCheckFilter(req *restful.Request, res *restful.Response, chain *restful
}
if tokenValue == "" {
bcode.ReturnError(req, res, bcode.ErrNotAuthorized)
return
}
}

View File

@@ -61,6 +61,14 @@ func (c *CloudShellAPIInterface) GetWebServiceRoute() *restful.WebService {
Returns(400, "Bad Request", bcode.Bcode{}).
Writes(apis.CloudShellPrepareResponse{}).Do(returns200, returns500))
ws.Route(ws.DELETE("/").To(c.destroyCloudShell).
Doc("destroy the user's cloud shell environment").
Metadata(restfulspec.KeyOpenAPITags, tags).
Filter(c.RbacService.CheckPerm("cloudshell", "delete")).
Returns(200, "OK", apis.EmptyResponse{}).
Returns(400, "Bad Request", bcode.Bcode{}).
Writes(apis.EmptyResponse{}).Do(returns200, returns500))
ws.Filter(authCheckFilter)
return ws
}
@@ -82,6 +90,19 @@ func (c *CloudShellAPIInterface) prepareCloudShell(req *restful.Request, res *re
}
}
func (c *CloudShellAPIInterface) destroyCloudShell(req *restful.Request, res *restful.Response) {
err := c.CloudShellService.Destroy(req.Request.Context())
// Write back response data
if err != nil {
bcode.ReturnError(req, res, err)
return
}
if err := res.WriteEntity(apis.EmptyResponse{}); err != nil {
bcode.ReturnError(req, res, err)
return
}
}
// CloudShellView provide the view handler
type CloudShellView struct {
RbacService service.RBACService `inject:""`

View File

@@ -1194,11 +1194,12 @@ type SystemInfoResponse struct {
// SystemInfo system info
type SystemInfo struct {
PlatformID string `json:"platformID"`
EnableCollection bool `json:"enableCollection"`
LoginType string `json:"loginType" validate:"oneof=dex local"`
InstallTime time.Time `json:"installTime,omitempty"`
DexUserDefaultProjects []model.ProjectRef `json:"dexUserDefaultProjects,omitempty"`
PlatformID string `json:"platformID"`
EnableCollection bool `json:"enableCollection"`
LoginType string `json:"loginType" validate:"oneof=dex local"`
InstallTime time.Time `json:"installTime,omitempty"`
DexUserDefaultProjects []model.ProjectRef `json:"dexUserDefaultProjects,omitempty"`
DexUserDefaultPlatformRoles []string `json:"dexUserDefaultPlatformRoles,omitempty"`
}
// StatisticInfo generated by cronJob running in backend

View File

@@ -32,6 +32,9 @@ import (
// KubeVelaProjectGroupPrefix the prefix kubevela project
const KubeVelaProjectGroupPrefix = "kubevela:project:"
// KubeVelaProjectReadGroupPrefix the prefix kubevela project group that only has the read permissions
const KubeVelaProjectReadGroupPrefix = "kubevela:project-ro:"
// KubeVelaAdminGroupPrefix the prefix kubevela admin
const KubeVelaAdminGroupPrefix = "kubevela:admin:"

View File

@@ -109,7 +109,7 @@ func (wl *Workload) EvalStatus(ctx process.Context, cli client.Client, accessor
// EvalHealth eval workload health check
func (wl *Workload) EvalHealth(ctx process.Context, client client.Client, accessor util.NamespaceAccessor) (bool, error) {
// if health of template is not set or standard workload is managed by trait always return true
if wl.FullTemplate.Health == "" || wl.SkipApplyWorkload {
if wl.SkipApplyWorkload {
return true, nil
}
return wl.engine.HealthCheck(ctx, client, accessor, wl.FullTemplate.Health)
@@ -152,9 +152,6 @@ func (trait *Trait) EvalStatus(ctx process.Context, cli client.Client, accessor
// EvalHealth eval trait health check
func (trait *Trait) EvalHealth(ctx process.Context, client client.Client, accessor util.NamespaceAccessor) (bool, error) {
if trait.FullTemplate.Health == "" {
return true, nil
}
return trait.engine.HealthCheck(ctx, client, accessor, trait.HealthCheckPolicy)
}

View File

@@ -403,8 +403,21 @@ func removeSubjects(src []rbacv1.Subject, toRemove []rbacv1.Subject) []rbacv1.Su
return subs
}
type opts struct {
replace bool
}
// WithReplace means to replace all subjects, this is only useful in Grant Privileges
func WithReplace(o *opts) {
o.replace = true
}
// GrantPrivileges grant privileges to identity
func GrantPrivileges(ctx context.Context, cli client.Client, privileges []PrivilegeDescription, identity *Identity, writer io.Writer) error {
func GrantPrivileges(ctx context.Context, cli client.Client, privileges []PrivilegeDescription, identity *Identity, writer io.Writer, optionFuncs ...func(*opts)) error {
var options = &opts{}
for _, fc := range optionFuncs {
fc(options)
}
subs := identity.Subjects()
if len(subs) == 0 {
return fmt.Errorf("failed to find RBAC subjects in identity")
@@ -434,12 +447,20 @@ func GrantPrivileges(ctx context.Context, cli client.Client, privileges []Privil
case *rbacv1.RoleBinding:
obj := &rbacv1.RoleBinding{}
if err := cli.Get(_ctx, client.ObjectKeyFromObject(bindingObj), obj); err == nil {
bindingObj.Subjects = mergeSubjects(bindingObj.Subjects, obj.Subjects)
if options.replace {
bindingObj.Subjects = obj.Subjects
} else {
bindingObj.Subjects = mergeSubjects(bindingObj.Subjects, obj.Subjects)
}
}
case *rbacv1.ClusterRoleBinding:
obj := &rbacv1.ClusterRoleBinding{}
if err := cli.Get(_ctx, client.ObjectKeyFromObject(bindingObj), obj); err == nil {
bindingObj.Subjects = mergeSubjects(bindingObj.Subjects, obj.Subjects)
if options.replace {
bindingObj.Subjects = obj.Subjects
} else {
bindingObj.Subjects = mergeSubjects(bindingObj.Subjects, obj.Subjects)
}
}
}
res, err := utils.CreateOrUpdate(_ctx, cli, binding)
@@ -454,7 +475,11 @@ func GrantPrivileges(ctx context.Context, cli client.Client, privileges []Privil
// RevokePrivileges revoke privileges (notice that the revoking process only deletes bond subject in the
// RoleBinding/ClusterRoleBinding, it does not ensure the identity's other related privileges are removed to
// prevent identity from accessing)
func RevokePrivileges(ctx context.Context, cli client.Client, privileges []PrivilegeDescription, identity *Identity, writer io.Writer) error {
func RevokePrivileges(ctx context.Context, cli client.Client, privileges []PrivilegeDescription, identity *Identity, writer io.Writer, optionFuncs ...func(*opts)) error {
var options = &opts{}
for _, fc := range optionFuncs {
fc(options)
}
subs := identity.Subjects()
if len(subs) == 0 {
return fmt.Errorf("failed to find RBAC subjects in identity")

View File

@@ -128,9 +128,10 @@ func (c *HTTPCmd) Run(meta *registry.Meta) (res interface{}, err error) {
b, err := io.ReadAll(resp.Body)
// parse response body and headers
return map[string]interface{}{
"body": string(b),
"header": resp.Header,
"trailer": resp.Trailer,
"body": string(b),
"header": resp.Header,
"trailer": resp.Trailer,
"statusCode": resp.StatusCode,
}, err
}

View File

@@ -136,7 +136,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
if annotations := app.GetAnnotations(); annotations == nil || annotations[oam.AnnotationKubeVelaVersion] == "" {
metav1.SetMetaDataAnnotation(&app.ObjectMeta, oam.AnnotationKubeVelaVersion, version.VelaVersion)
}
logCtx.AddTag("publish_version", app.GetAnnotations()[oam.AnnotationKubeVelaVersion])
logCtx.AddTag("publish_version", app.GetAnnotations()[oam.AnnotationPublishVersion])
appParser := appfile.NewApplicationParser(r.Client, r.dm, r.pd)
handler, err := NewAppHandler(logCtx, r, app, appParser)

View File

@@ -186,7 +186,7 @@ func (wd *workloadDef) getTemplateContext(ctx process.Context, cli client.Reader
return nil, err
}
// AuxiliaryWorkload will have a unique label("trait.oam.dev/resource"="name of outputs") in per component/app level
object, err := getResourceFromObj(ctx.GetCtx(), traitRef, cli, accessor.For(componentWorkload), util.MergeMapOverrideWithDst(map[string]string{
object, err := getResourceFromObj(ctx.GetCtx(), traitRef, cli, accessor.For(traitRef), util.MergeMapOverrideWithDst(map[string]string{
oam.TraitTypeLabel: AuxiliaryWorkload,
}, commonLabels), assist.Name)
if err != nil {
@@ -202,9 +202,6 @@ func (wd *workloadDef) getTemplateContext(ctx process.Context, cli client.Reader
// HealthCheck address health check for workload
func (wd *workloadDef) HealthCheck(ctx process.Context, cli client.Client, accessor util.NamespaceAccessor, healthPolicyTemplate string) (bool, error) {
if healthPolicyTemplate == "" {
return true, nil
}
templateContext, err := wd.getTemplateContext(ctx, cli, accessor)
if err != nil {
return false, errors.WithMessage(err, "get template context")
@@ -213,6 +210,9 @@ func (wd *workloadDef) HealthCheck(ctx process.Context, cli client.Client, acces
}
func checkHealth(templateContext map[string]interface{}, healthPolicyTemplate string) (bool, error) {
if healthPolicyTemplate == "" {
return true, nil
}
bt, err := json.Marshal(templateContext)
if err != nil {
return false, errors.WithMessage(err, "json marshal template context")
@@ -233,9 +233,6 @@ func checkHealth(templateContext map[string]interface{}, healthPolicyTemplate st
// Status get workload status by customStatusTemplate
func (wd *workloadDef) Status(ctx process.Context, cli client.Client, accessor util.NamespaceAccessor, customStatusTemplate string, parameter interface{}) (string, error) {
if customStatusTemplate == "" {
return "", nil
}
templateContext, err := wd.getTemplateContext(ctx, cli, accessor)
if err != nil {
return "", errors.WithMessage(err, "get template context")
@@ -244,6 +241,9 @@ func (wd *workloadDef) Status(ctx process.Context, cli client.Client, accessor u
}
func getStatusMessage(pd *packages.PackageDiscover, templateContext map[string]interface{}, customStatusTemplate string, parameter interface{}) (string, error) {
if customStatusTemplate == "" {
return "", nil
}
bi := build.NewContext().NewInstance("", nil)
var ctxBuff string
var paramBuff = "parameter: {}\n"
@@ -455,9 +455,6 @@ func (td *traitDef) getTemplateContext(ctx process.Context, cli client.Reader, a
// Status get trait status by customStatusTemplate
func (td *traitDef) Status(ctx process.Context, cli client.Client, accessor util.NamespaceAccessor, customStatusTemplate string, parameter interface{}) (string, error) {
if customStatusTemplate == "" {
return "", nil
}
templateContext, err := td.getTemplateContext(ctx, cli, accessor)
if err != nil {
return "", errors.WithMessage(err, "get template context")
@@ -467,9 +464,6 @@ func (td *traitDef) Status(ctx process.Context, cli client.Client, accessor util
// HealthCheck address health check for trait
func (td *traitDef) HealthCheck(ctx process.Context, cli client.Client, accessor util.NamespaceAccessor, healthPolicyTemplate string) (bool, error) {
if healthPolicyTemplate == "" {
return true, nil
}
templateContext, err := td.getTemplateContext(ctx, cli, accessor)
if err != nil {
return false, errors.WithMessage(err, "get template context")

View File

@@ -115,6 +115,9 @@ func listMergeProcess(field *ast.Field, key string, baseList, patchList *ast.Lis
kmaps[fmt.Sprintf(key, blit.Value)] = patchList.Elts[i]
}
if !foundPatch {
if len(patchList.Elts) == 0 {
continue
}
return
}

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