Compare commits

...

27 Commits
v1.9.0 ... main

Author SHA1 Message Date
am6737 9c8cc5d816
fix: Prevent crashes when accessing cluster details (#911)
- Added optional chaining to safely access cluster details in `AddClusterDialog`.

This fix addresses the issue where the page crashes when trying to load details for an inaccessible cluster.

Signed-off-by: am6737 <1359816810@qq.com>
2025-03-13 09:43:00 +05:30
am6737 0d00d92f55
fix: Set default values for traits in VelaUX (#913)
Added `setDefaultProperties` to ensure default values are correctly set for traits like "cpuscaler", "hpa", "resource", and "k8s-update-strategy".

Signed-off-by: am6737 <1359816810@qq.com>
2025-03-13 09:40:29 +05:30
PushparajShetty 021024e4af
Fix: Modified error message for invalid pwd and username (#918)
* Modified error message for invalid pwd and username

Signed-off-by: viskumar <viskumar@guidewire.com>

* changed the actions/cache version to v4

Signed-off-by: Vibhor Chinda <vibhorchinda@gmail.com>

* Fix: permission for PR labeling

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

---------

Signed-off-by: viskumar <viskumar@guidewire.com>
Signed-off-by: Vibhor Chinda <vibhorchinda@gmail.com>
Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>
Co-authored-by: viskumar <viskumar@guidewire.com>
Co-authored-by: Anoop Gopalakrishnan <anoop2811@aol.in>
2025-03-13 09:26:50 +05:30
am6737 d9b7ae102f
feat: improve Helm charts values.yaml popup (#909)
- Added custom width (60vw) to Helm values.yaml dialog for better visibility.
- Enabled close modes: 'close' and 'mask' to improve user experience.

Closes #851

Signed-off-by: am6737 <1359816810@qq.com>
2024-10-10 13:36:59 +08:00
am6737 8e11f93ed7
Fix(addons): Align Button with Title in AddonDetailDialog (#915)
Signed-off-by: am6737 <1359816810@qq.com>
2024-10-09 18:24:09 +08:00
Anoop Gopalakrishnan 5704854899
Chore: Bump versions (#905)
* Chore: Bump versions

- Golang
- Kubernetes version in kubebuilder
- Ubuntu version

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore: Bump golang version

- Bump the github action versions

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore: Bump golang and github actions versions

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore: Bump golang and github action versions

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore(debug): Downgrade kubebuilder k8s version

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore(debug): Use makefile for kubebuilder install

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore(debug): Set kubernetes version in kubebuilder

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore: Bump all actions versions

- And golang versions

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore(debug): Bump versions

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Fix: Bump versions

- Updated golang version in go.mod
- Updated staticcheck version

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore: Bump versions

- Update the golangci-lint version

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore: Bump versions

- Fix lint/staticcheck issues

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore: Bump versions

- Fix lint issues

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

* Chore: Bump versions

- Fix lint issues

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>

---------

Signed-off-by: Anoop Gopalakrishnan <anoop2811@aol.in>
2024-07-11 16:01:28 +05:30
Oana Schipor 73334e7516
Fix: Username length in projects users to match users (#904)
* truncating username in vela_project_user to match vela_user username

Signed-off-by: Oana Schipor <oana.schipor@vortexa.com>

* update fn

Signed-off-by: Oana Schipor <oana.schipor@vortexa.com>

* Remove old k8s version

Signed-off-by: Oana Schipor <oana.schipor@vortexa.com>

---------

Signed-off-by: Oana Schipor <oana.schipor@vortexa.com>
2024-07-04 20:46:27 +05:30
Bob 127f5325e9
fix: fix swgger.json (#891)
* Update swagger.json by `make update-swagger`.
* Returns a predefined structure instead of a map object to avoid Swagger being unable to generate code correctly
* Delete duplicate runtimes_cluster parameter definition to avoid the code constructed by swagger being unusable
* Add swagger 3.0.json to facilitate developers debugging APIs on the swagger UI.

Signed-off-by: 上郡 <shangjun.csb@alibaba-inc.com>
Co-authored-by: 上郡 <shangjun.csb@alibaba-inc.com>
2023-12-05 13:03:22 +08:00
Bob d5ea29f5ab
fix: fix some typo errors (#890)
Signed-off-by: 上郡 <shangjun.csb@alibaba-inc.com>
Co-authored-by: 上郡 <shangjun.csb@alibaba-inc.com>
2023-12-05 12:52:21 +08:00
dependabot[bot] 2ab672c09a
Chore(deps): Bump get-func-name from 2.0.0 to 2.0.2 (#880)
Bumps [get-func-name](https://github.com/chaijs/get-func-name) from 2.0.0 to 2.0.2.
- [Release notes](https://github.com/chaijs/get-func-name/releases)
- [Commits](https://github.com/chaijs/get-func-name/commits/v2.0.2)

---
updated-dependencies:
- dependency-name: get-func-name
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-30 19:49:50 -05:00
Neeraj Gartia 4579408f62
Fix: Enables translate error property of `gorm` (#877) 2023-09-15 13:58:26 +08:00
qiaozp d14a2b6538
Chore: unify sql data driver implementation (#873) 2023-09-07 11:44:59 +08:00
qiaozp 7937d098d5
Feat: support exit-on-lost-leader flag (#868) 2023-08-08 13:45:35 +08:00
qiaozp 8438aa72e9
Fix: fail to get global helm config secret (#867)
* Fix: fail to get global config when config not exist in project scope

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Add unit test

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* add test clean up

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix: infinite forloop

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* restore 404

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

---------

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-08-02 20:19:11 +08:00
Namo 27b45c265c
Feat: Add support for OpenGauss database types (#865)
Signed-off-by: ligjn <lgj112113@163.com>

change opengauss to postgres

Co-authored-by: ligjn <lgj112113@163.com>
2023-08-01 21:26:26 +08:00
zuoningz d0b2a3b995
Fix: incorrect API response mark (#864)
Co-authored-by: Z Zhang <zuoning@AndrewZs-MacBook-Air.local>
2023-07-27 17:42:23 +08:00
qiaozp 3978079cfd
Fix: additionalPropertis in openapi schema converted to uischema wrongly (#861)
Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-07-22 19:36:26 +08:00
qiaozp 76a39a7b99
Fix: CodeQL job fails (#860)
* Fix: CodeQL job fails

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix: code lint

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix: code lint

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix: code lint

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

---------

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-07-21 10:41:58 +08:00
dependabot[bot] 470699b3fb
Chore(deps): Bump semver from 5.7.1 to 5.7.2 (#853)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-20 16:59:46 +08:00
dependabot[bot] 2570713556
Chore(deps): Bump word-wrap from 1.2.3 to 1.2.4 (#858)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-20 15:27:38 +08:00
zuoningz 0e56cec6b5
Fix: applied default cluster to created target (#857)
Co-authored-by: Z Zhang <zuoning@AndrewZs-MacBook-Air.local>
2023-07-18 16:04:43 +08:00
mujinhuakai 8a81aa1e1d
Fix: customized uiSchema can't show properly (#854)
Co-authored-by: liyanfang <liyanfang@cmss.chinamobile.com>
2023-07-14 14:36:18 +08:00
qiaozp 28dea8a27e
Fix: cloudshell scheme not found (#856)
Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-07-14 09:56:36 +08:00
Neeraj Gartia 118a9fee6c
Feat: adds support of mongodb urls with prefix `mongodb+srv://` (#849) 2023-06-28 14:32:18 +08:00
Neeraj Gartia 580372f9d0
Feat: add MySQL data store driver implementation (#841) 2023-06-26 21:25:20 +08:00
qiaozp ff8382cba0
Feat: upgrade kubevela and pkg (#848)
* Feat: upgrade kubevela and pkg

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* reviewable

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix nil pointer

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Migrate cloudprovider

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Upgrade ginkgo to v2

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* fix: add cloudshell to scheme

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix: ginkgo by clause

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* Fix: addon dependency test

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

* rollback pending test

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>

---------

Signed-off-by: Qiaozp <qiaozhongpei.qzp@alibaba-inc.com>
2023-06-26 08:40:38 +08:00
qiaozp 7a81518059
Chore: remove acr image (#844) 2023-06-21 09:57:11 +08:00
182 changed files with 23963 additions and 1946 deletions

View File

@ -1 +1 @@
node_modules **/node_modules/

View File

@ -15,7 +15,7 @@ on:
env: env:
# Common versions # Common versions
GO_VERSION: '1.19' GO_VERSION: '1.22.0'
permissions: permissions:
contents: read contents: read
@ -23,13 +23,13 @@ permissions:
jobs: jobs:
detect-noop: detect-noop:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
outputs: outputs:
noop: ${{ steps.noop.outputs.should_skip }} noop: ${{ steps.noop.outputs.should_skip }}
steps: steps:
- name: Detect No-op Changes - name: Detect No-op Changes
id: noop id: noop
uses: fkirc/skip-duplicate-actions@12aca0a884f6137d619d6a8a09fcc3406ced5281 uses: fkirc/skip-duplicate-actions@f75f66ce1886f00957d99748a42c724f4330bdcf
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]' paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]'
@ -37,23 +37,23 @@ jobs:
continue-on-error: true continue-on-error: true
arm64-build-test: arm64-build-test:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
needs: detect-noop needs: detect-noop
if: needs.detect-noop.outputs.noop != 'true' if: needs.detect-noop.outputs.noop != 'true'
steps: steps:
- name: Check out code into the Go module directory - name: Check out code into the Go module directory
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6
with: with:
submodules: true submodules: true
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v2 uses: docker/setup-qemu-action@5927c834f5b4fdf503fca6f4c7eccda82949e1ee
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@4fd812986e6c8c2a69e18311145f9371337f27d4
- name: Build linux/arm64 image - name: Build linux/arm64 image
id: docker_build_2 id: docker_build_2
uses: docker/build-push-action@v2 uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c
with: with:
context: ./ context: ./
build-args: | build-args: |

View File

@ -7,16 +7,16 @@ on:
jobs: jobs:
# align with crossplane's choice https://github.com/crossplane/crossplane/blob/master/.github/workflows/backport.yml # align with crossplane's choice https://github.com/crossplane/crossplane/blob/master/.github/workflows/backport.yml
open-pr: open-pr:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
if: github.event.pull_request.merged if: github.event.pull_request.merged
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v2 uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Open Backport PR - name: Open Backport PR
uses: zeebe-io/backport-action@v0.0.6 uses: zeebe-io/backport-action@v0.0.9
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
github_workspace: ${{ github.workspace }} github_workspace: ${{ github.workspace }}

View File

@ -24,18 +24,18 @@ jobs:
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v3 uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v3
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
queries: +security-and-quality queries: +security-and-quality
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v3
with: with:
category: "/language:${{ matrix.language }}" category: "/language:${{ matrix.language }}"

View File

@ -11,9 +11,11 @@ on:
jobs: jobs:
check: check:
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions:
pull-requests: write
steps: steps:
- uses: thehanimo/pr-title-checker@v1.3.1 - uses: thehanimo/pr-title-checker@v1.4.2
with: with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
pass_on_octokit_error: true pass_on_octokit_error: true
configuration_path: ".github/pr-title-checker-config.json" configuration_path: '.github/pr-title-checker-config.json'

View File

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6
- name: Build Vela Core image from Dockerfile - name: Build Vela Core image from Dockerfile
run: | run: |
@ -23,7 +23,7 @@ jobs:
output: 'trivy-results.sarif' output: 'trivy-results.sarif'
- name: Upload Trivy scan results to GitHub Security tab - name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v1 uses: github/codeql-action/upload-sarif@v3
if: always() if: always()
with: with:
sarif_file: 'trivy-results.sarif' sarif_file: 'trivy-results.sarif'

View File

@ -10,18 +10,18 @@ permissions:
jobs: jobs:
bot: bot:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- name: Checkout Actions - name: Checkout Actions
uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6
with: with:
repository: "oam-dev/kubevela-github-actions" repository: "oam-dev/kubevela-github-actions"
path: ./actions path: ./actions
ref: v0.4.2 ref: v0.4.2
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b
with: with:
node-version: '14' node-version: '16'
cache: 'npm' cache: 'npm'
cache-dependency-path: ./actions/package-lock.json cache-dependency-path: ./actions/package-lock.json
- name: Install Dependencies - name: Install Dependencies
@ -51,7 +51,7 @@ jobs:
allow-edits: "false" allow-edits: "false"
permission-level: read permission-level: read
- name: Handle Command - name: Handle Command
uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
env: env:
VERSION: ${{ steps.command.outputs.command-arguments }} VERSION: ${{ steps.command.outputs.command-arguments }}
with: with:
@ -72,11 +72,11 @@ jobs:
}) })
console.log("Added '" + label + "' label.") console.log("Added '" + label + "' label.")
- name: Checkout - name: Checkout
uses: actions/checkout@24cb9080177205b6e8c946b17badbe402adc938f uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Open Backport PR - name: Open Backport PR
uses: zeebe-io/backport-action@a759fd2d7d3314c9bb57d97a0350a12e878d3c7a uses: zeebe-io/backport-action@v0.0.9
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
github_workspace: ${{ github.workspace }} github_workspace: ${{ github.workspace }}
@ -91,7 +91,7 @@ jobs:
issues: write issues: write
steps: steps:
- name: Retest the current pull request - name: Retest the current pull request
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea
env: env:
PULL_REQUEST_ID: ${{ github.event.issue.number }} PULL_REQUEST_ID: ${{ github.event.issue.number }}
COMMENT_ID: ${{ github.event.comment.id }} COMMENT_ID: ${{ github.event.comment.id }}

View File

@ -10,7 +10,7 @@ jobs:
build: build:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6
- name: Get the version - name: Get the version
id: get_version id: get_version
run: | run: |
@ -25,24 +25,18 @@ jobs:
run: | run: |
echo "git_revision=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT echo "git_revision=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Login to DockerHub - name: Login to DockerHub
uses: docker/login-action@v1 uses: docker/login-action@v3.2.0
with: with:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to Aliyun Container Registry (ACR) - uses: docker/setup-qemu-action@v3.1.0
uses: docker/login-action@v1 - uses: docker/setup-buildx-action@v3.4.0
with:
registry: acr.kubevela.net
username: "${{ secrets.ACR_USERNAME }}"
password: "${{ secrets.ACR_PASSWORD }}"
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
with: with:
driver-opts: image=moby/buildkit:master driver-opts: image=moby/buildkit:master
- name: Build docker image - name: Build docker image
id: acr_build id: acr_build
uses: docker/build-push-action@v2 uses: docker/build-push-action@v6.3.0
with: with:
context: ./ context: ./
file: ./Dockerfile file: ./Dockerfile
@ -53,5 +47,4 @@ jobs:
VERSION=${{ steps.get_version.outputs.VERSION }} VERSION=${{ steps.get_version.outputs.VERSION }}
GOPROXY=https://proxy.golang.org GOPROXY=https://proxy.golang.org
tags: |- tags: |-
acr.kubevela.net/oamdev/velaux:${{ steps.get_version.outputs.VERSION }}
oamdev/velaux:${{ steps.get_version.outputs.VERSION }} oamdev/velaux:${{ steps.get_version.outputs.VERSION }}

View File

@ -15,7 +15,7 @@ on:
env: env:
# Common versions # Common versions
GO_VERSION: '1.19' GO_VERSION: '1.22.0'
permissions: permissions:
contents: read contents: read
@ -23,13 +23,13 @@ permissions:
jobs: jobs:
detect-noop: detect-noop:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
outputs: outputs:
noop: ${{ steps.noop.outputs.should_skip }} noop: ${{ steps.noop.outputs.should_skip }}
steps: steps:
- name: Detect No-op Changes - name: Detect No-op Changes
id: noop id: noop
uses: fkirc/skip-duplicate-actions@12aca0a884f6137d619d6a8a09fcc3406ced5281 uses: fkirc/skip-duplicate-actions@f75f66ce1886f00957d99748a42c724f4330bdcf
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]' paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]'
@ -37,24 +37,24 @@ jobs:
continue-on-error: true continue-on-error: true
server-unit-tests: server-unit-tests:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
needs: detect-noop needs: detect-noop
if: needs.detect-noop.outputs.noop != 'true' if: needs.detect-noop.outputs.noop != 'true'
steps: steps:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7
with: with:
go-version: ${{ env.GO_VERSION }} go-version: ${{ env.GO_VERSION }}
id: go id: go
- name: Check out code into the Go module directory - name: Check out code into the Go module directory
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6
with: with:
submodules: true submodules: true
- name: Cache Go Dependencies - name: Cache Go Dependencies
uses: actions/cache@6998d139ddd3e68c71e9e398d8e40b71a2f39812 uses: actions/cache@v4
with: with:
path: .work/pkg path: .work/pkg
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }} key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
@ -66,18 +66,32 @@ jobs:
sudo apt-get update sudo apt-get update
sudo apt-get install -y golang-ginkgo-dev sudo apt-get install -y golang-ginkgo-dev
- name : Set up MySQL
uses: mirromutth/mysql-action@v1.1
with:
mysql database: 'kubevela'
mysql root password: 'kubevelaSQL123'
- name: Set up Postgres
uses: Harmon758/postgresql-action@v1
with:
postgresql version: '11'
postgresql db: 'kubevela'
postgresql user: 'kubevela'
postgresql password: 'Kubevela-123'
- name: Start MongoDB - name: Start MongoDB
uses: supercharge/mongodb-github-action@d26215f71b2ce60420a2a3776a25893d11a65f85 # 1.9.0 uses: supercharge/mongodb-github-action@5a87bd81f88e2a8b195f8b7b656f5cda1350815a # 1.11.0
with: with:
mongodb-version: '5.0' mongodb-version: '5.0'
# TODO need update action version to resolve node 12 deprecated. # TODO need update action version to resolve node 12 deprecated.
- name: install Kubebuilder - name: install Kubebuilder
uses: RyanSiu1995/kubebuilder-action@ff52bff1bae252239223476e5ab0d71d6ba02343 uses: RyanSiu1995/kubebuilder-action@e7e4de1c1eaf1d089b9a186f7526239acadf0b40
with: with:
version: 3.1.0 version: 3.1.0
kubebuilderOnly: false kubebuilderOnly: false
kubernetesVersion: v1.21.2 kubernetesVersion: v1.26.0
- name: Run api server unit test - name: Run api server unit test
run: make unit-test-server run: make unit-test-server
@ -91,30 +105,30 @@ jobs:
name: codecov-umbrella name: codecov-umbrella
server-e2e-tests: server-e2e-tests:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
needs: [ detect-noop ] needs: [ detect-noop ]
if: needs.detect-noop.outputs.noop != 'true' if: needs.detect-noop.outputs.noop != 'true'
strategy: strategy:
matrix: matrix:
k8s-version: ["v1.21", "v1.26"] k8s-version: ["v1.26"]
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.k8s-version }} group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.k8s-version }}
cancel-in-progress: true cancel-in-progress: true
steps: steps:
- name: Set up Go - name: Set up Go
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7
with: with:
go-version: ${{ env.GO_VERSION }} go-version: ${{ env.GO_VERSION }}
id: go id: go
- name: Check out code into the Go module directory - name: Check out code into the Go module directory
uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6
with: with:
submodules: true submodules: true
- name: Build docker image - name: Build docker image
id: docker_build id: docker_build
uses: docker/build-push-action@v2 uses: docker/build-push-action@1a162644f9a7e87d8f4b053101d1d9a712edc18c
with: with:
context: ./ context: ./
build-args: | build-args: |
@ -179,7 +193,7 @@ jobs:
make enable-addon make enable-addon
- name: Upload coverage report - name: Upload coverage report
uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70 uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673
with: with:
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}
files: /tmp/e2e_apiserver_test.out files: /tmp/e2e_apiserver_test.out

View File

@ -12,17 +12,17 @@ on:
- release-* - release-*
env: env:
# Common versions # Common versions
GO_VERSION: '1.19' GO_VERSION: '1.22.0'
jobs: jobs:
detect-noop: detect-noop:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
outputs: outputs:
noop: ${{ steps.noop.outputs.should_skip }} noop: ${{ steps.noop.outputs.should_skip }}
steps: steps:
- name: Detect No-op Changes - name: Detect No-op Changes
id: noop id: noop
uses: fkirc/skip-duplicate-actions@v3.3.0 uses: fkirc/skip-duplicate-actions@v5.3.1
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]' paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]'
@ -30,17 +30,20 @@ jobs:
concurrent_skipping: false concurrent_skipping: false
check: check:
runs-on: ubuntu-20.04 runs-on: ubuntu-22.04
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@6ccd57f4c5d15bdc2fef309bd9fb6cc9db2ef1c6
- uses: actions/setup-node@v2 - uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b
with: with:
node-version: '16' node-version: '16'
cache: 'yarn'
- name: Set up Go - name: Set up Go
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7
with: with:
go-version: ${{ env.GO_VERSION }} go-version: ${{ env.GO_VERSION }}
id: go id: go
- name: Install Yarn
run: npm install --global yarn
- name: upgrade yarn - name: upgrade yarn
run: yarn set version 3.6.0 run: yarn set version 3.6.0
- run: yarn install - run: yarn install

View File

@ -1,6 +1,8 @@
include makefiles/const.mk include makefiles/const.mk
include makefiles/build.mk include makefiles/build.mk
all: docker-build
.PHONY: golangci .PHONY: golangci
golangci: golangci:
ifeq ($(shell $(GLOBAL_GOLANGCILINT) version --format short), $(GOLANGCILINT_VERSION)) ifeq ($(shell $(GLOBAL_GOLANGCILINT) version --format short), $(GOLANGCILINT_VERSION))
@ -25,7 +27,7 @@ ifeq (, $(shell which staticcheck))
@{ \ @{ \
set -e ;\ set -e ;\
echo 'installing honnef.co/go/tools/cmd/staticcheck ' ;\ echo 'installing honnef.co/go/tools/cmd/staticcheck ' ;\
go install honnef.co/go/tools/cmd/staticcheck@d7e217c1ff411395475b2971c0824e1e7cc1af98 ;\ go install honnef.co/go/tools/cmd/staticcheck@v0.4.7 ;\
} }
STATICCHECK=$(GOBIN)/staticcheck STATICCHECK=$(GOBIN)/staticcheck
else else

View File

@ -24,6 +24,8 @@ import (
"os/signal" "os/signal"
"syscall" "syscall"
"github.com/kubevela/pkg/util/profiling"
restfulspec "github.com/emicklei/go-restful-openapi/v2" restfulspec "github.com/emicklei/go-restful-openapi/v2"
"github.com/fatih/color" "github.com/fatih/color"
"github.com/go-openapi/spec" "github.com/go-openapi/spec"
@ -33,7 +35,6 @@ import (
"github.com/kubevela/velaux/cmd/server/app/options" "github.com/kubevela/velaux/cmd/server/app/options"
"github.com/kubevela/velaux/pkg/server" "github.com/kubevela/velaux/pkg/server"
"github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/version" "github.com/oam-dev/kubevela/version"
) )
@ -45,7 +46,7 @@ func NewAPIServerCommand() *cobra.Command {
Long: `The KubeVela API server validates and configures data for the API objects. Long: `The KubeVela API server validates and configures data for the API objects.
The API Server services REST operations and provides the frontend to the The API Server services REST operations and provides the frontend to the
cluster's shared state through which all other components interact.`, cluster's shared state through which all other components interact.`,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error { //nolint:revive,unused
if err := s.Validate(); err != nil { if err := s.Validate(); err != nil {
return err return err
} }
@ -63,7 +64,7 @@ cluster's shared state through which all other components interact.`,
buildSwaggerCmd := &cobra.Command{ buildSwaggerCmd := &cobra.Command{
Use: "build-swagger", Use: "build-swagger",
Short: "Build swagger documentation of KubeVela apiserver", Short: "Build swagger documentation of KubeVela apiserver",
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error { //nolint:revive,unused
name := "docs/apidoc/latest-swagger.json" name := "docs/apidoc/latest-swagger.json"
if len(args) > 0 { if len(args) > 0 {
name = args[0] name = args[0]
@ -111,9 +112,7 @@ func Run(s *options.ServerRunOptions) error {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
if s.GenericServerRunOptions.PprofAddr != "" { go profiling.StartProfilingServer(errChan)
go utils.EnablePprof(s.GenericServerRunOptions.PprofAddr, errChan)
}
go func() { go func() {
if err := run(ctx, s, errChan); err != nil { if err := run(ctx, s, errChan); err != nil {

19877
docs/apidoc/swagger-3.0.json Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
name: bar
version: 1.0.0
description: Vela test addon named bar
icon: https://www.nar.com/icon
url: https://www.bar.com

View File

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

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -7,8 +7,8 @@ entries:
icon: https://www.test.com icon: https://www.test.com
name: mock-be-dep-addon name: mock-be-dep-addon
urls: urls:
- http://127.0.0.1:9098/helm/mock-be-dep-addon-v1.0.0.tgz - http://127.0.0.1:9098/helm/mock-be-dep-addon-1.0.0.tgz
version: v1.0.0 version: 1.0.0
foo: foo:
- created: "2022-10-29T09:11:16.865230605Z" - created: "2022-10-29T09:11:16.865230605Z"
description: Vela test addon named foo description: Vela test addon named foo
@ -16,8 +16,8 @@ entries:
icon: https://www.foo.com icon: https://www.foo.com
name: foo name: foo
urls: urls:
- http://127.0.0.1:9098/helm/foo-v1.0.0.tgz - http://127.0.0.1:9098/helm/foo-1.0.0.tgz
version: v1.0.0 version: 1.0.0
bar: bar:
- created: "2022-10-29T09:11:16.865230605Z" - created: "2022-10-29T09:11:16.865230605Z"
description: Vela test addon named bar description: Vela test addon named bar
@ -25,14 +25,14 @@ entries:
icon: https://www.bar.com icon: https://www.bar.com
name: foo name: foo
urls: urls:
- http://127.0.0.1:9098/helm/bar-v1.0.0.tgz - http://127.0.0.1:9098/helm/bar-1.0.0.tgz
version: v1.0.0 version: 1.0.0
- created: "2022-10-29T09:11:16.865230605Z" - created: "2022-10-29T09:11:16.865230605Z"
description: Vela test addon named bar description: Vela test addon named bar
home: https://www.bar.com/icon home: https://www.bar.com/icon
icon: https://www.bar.com icon: https://www.bar.com
name: foo name: foo
urls: urls:
- http://127.0.0.1:9098/helm/bar-v2.0.0.tgz - http://127.0.0.1:9098/helm/bar-2.0.0.tgz
version: v2.0.0 version: 2.0.0
generated: "2022-06-15T13:17:04.733573+08:00" generated: "2022-06-15T13:17:04.733573+08:00"

View File

@ -114,44 +114,26 @@ var helmHandler http.HandlerFunc = func(rw http.ResponseWriter, req *http.Reques
_, _ = rw.Write([]byte(err.Error())) _, _ = rw.Write([]byte(err.Error()))
} }
_, _ = rw.Write(file) _, _ = rw.Write(file)
case strings.Contains(req.URL.Path, "fluxcd-test-version-1.0.0.tgz"): case strings.Contains(req.URL.Path, "foo-1.0.0.tgz"):
file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/fluxcd-test-version-1.0.0.tgz") file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/foo-1.0.0.tgz")
if err != nil { if err != nil {
_, _ = rw.Write([]byte(err.Error())) _, _ = rw.Write([]byte(err.Error()))
} }
_, _ = rw.Write(file) _, _ = rw.Write(file)
case strings.Contains(req.URL.Path, "fluxcd-test-version-2.0.0.tgz"): case strings.Contains(req.URL.Path, "bar-1.0.0.tgz"):
file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/fluxcd-test-version-2.0.0.tgz") file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/bar-1.0.0.tgz")
if err != nil { if err != nil {
_, _ = rw.Write([]byte(err.Error())) _, _ = rw.Write([]byte(err.Error()))
} }
_, _ = rw.Write(file) _, _ = rw.Write(file)
case strings.Contains(req.URL.Path, "vela-workflow-v0.3.5.tgz"): case strings.Contains(req.URL.Path, "bar-2.0.0.tgz"):
file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/vela-workflow-v0.3.5.tgz") file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/bar-2.0.0.tgz")
if err != nil { if err != nil {
_, _ = rw.Write([]byte(err.Error())) _, _ = rw.Write([]byte(err.Error()))
} }
_, _ = rw.Write(file) _, _ = rw.Write(file)
case strings.Contains(req.URL.Path, "foo-v1.0.0.tgz"): case strings.Contains(req.URL.Path, "mock-be-dep-addon-1.0.0.tgz"):
file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/foo-v1.0.0.tgz") file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/mock-be-dep-addon-1.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
_, _ = rw.Write(file)
case strings.Contains(req.URL.Path, "bar-v1.0.0.tgz"):
file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/bar-v1.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
_, _ = rw.Write(file)
case strings.Contains(req.URL.Path, "bar-v2.0.0.tgz"):
file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/bar-v2.0.0.tgz")
if err != nil {
_, _ = rw.Write([]byte(err.Error()))
}
_, _ = rw.Write(file)
case strings.Contains(req.URL.Path, "mock-be-dep-addon-v1.0.0.tgz"):
file, err := os.ReadFile("./e2e-test/addon/testrepo/helm-repo/mock-be-dep-addon-v1.0.0.tgz")
if err != nil { if err != nil {
_, _ = rw.Write([]byte(err.Error())) _, _ = rw.Write([]byte(err.Error()))
} }

View File

@ -23,7 +23,7 @@ import (
"strings" "strings"
"time" "time"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/oam-dev/kubevela/pkg/addon" "github.com/oam-dev/kubevela/pkg/addon"
@ -229,7 +229,7 @@ var _ = Describe("Test addon rest api", func() {
var newaddonStatus apisv1.AddonStatusResponse var newaddonStatus apisv1.AddonStatusResponse
g.Expect(decodeResponseBody(status, &newaddonStatus)).Should(Succeed()) g.Expect(decodeResponseBody(status, &newaddonStatus)).Should(Succeed())
g.Expect(newaddonStatus.Name).Should(BeEquivalentTo("bar")) g.Expect(newaddonStatus.Name).Should(BeEquivalentTo("bar"))
g.Expect(newaddonStatus.InstalledVersion).Should(BeEquivalentTo("v1.0.0")) g.Expect(newaddonStatus.InstalledVersion).Should(BeEquivalentTo("1.0.0"))
}, 30*time.Second, 300*time.Millisecond).Should(Succeed()) }, 30*time.Second, 300*time.Millisecond).Should(Succeed())
}) })
}) })
@ -248,7 +248,7 @@ var _ = Describe("Test addon rest api", func() {
var newaddonStatus apisv1.AddonStatusResponse var newaddonStatus apisv1.AddonStatusResponse
g.Expect(decodeResponseBody(status, &newaddonStatus)).Should(Succeed()) g.Expect(decodeResponseBody(status, &newaddonStatus)).Should(Succeed())
g.Expect(newaddonStatus.Name).Should(BeEquivalentTo("mock-dep-addon")) g.Expect(newaddonStatus.Name).Should(BeEquivalentTo("mock-dep-addon"))
g.Expect(newaddonStatus.InstalledVersion).Should(BeEquivalentTo("v1.0.0")) g.Expect(newaddonStatus.InstalledVersion).Should(BeEquivalentTo("1.0.0"))
g.Expect(newaddonStatus.Phase).Should(BeEquivalentTo(apisv1.AddonPhaseEnabled)) g.Expect(newaddonStatus.Phase).Should(BeEquivalentTo(apisv1.AddonPhaseEnabled))
}, 30*time.Second, 300*time.Millisecond).Should(Succeed()) }, 30*time.Second, 300*time.Millisecond).Should(Succeed())
}) })

View File

@ -22,7 +22,7 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common" "github.com/oam-dev/kubevela/apis/core.oam.dev/common"

View File

@ -22,7 +22,7 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"

View File

@ -22,7 +22,7 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"

View File

@ -21,7 +21,7 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/kubevela/workflow/api/v1alpha1" "github.com/kubevela/workflow/api/v1alpha1"

View File

@ -21,7 +21,7 @@ import (
"os" "os"
"time" "time"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/kubevela/pkg/util/rand" "github.com/kubevela/pkg/util/rand"

View File

@ -20,7 +20,7 @@ import (
"context" "context"
"fmt" "fmt"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/oam-dev/kubevela/apis/types" "github.com/oam-dev/kubevela/apis/types"

View File

@ -20,7 +20,7 @@ import (
"context" "context"
"fmt" "fmt"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"

View File

@ -21,7 +21,7 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/oam-dev/kubevela/pkg/multicluster" "github.com/oam-dev/kubevela/pkg/multicluster"

View File

@ -23,7 +23,7 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"

View File

@ -24,7 +24,7 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/kubevela/workflow/api/v1alpha1" "github.com/kubevela/workflow/api/v1alpha1"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"

View File

@ -20,7 +20,7 @@ import (
"fmt" "fmt"
"cuelang.org/go/pkg/strings" "cuelang.org/go/pkg/strings"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
@ -36,9 +36,7 @@ func enablePlugin(id string) {
} }
var _ = Describe("Test the plugin rest api", func() { var _ = Describe("Test the plugin rest api", func() {
Context("Test manage plugin API", func() { Context("Test manage plugin API. Request to /manage/plugins", func() {
By("Request to /manage/plugins")
It("Test list installed plugins", func() { It("Test list installed plugins", func() {
defer GinkgoRecover() defer GinkgoRecover()
res := get("/manage/plugins") res := get("/manage/plugins")
@ -109,9 +107,7 @@ var _ = Describe("Test the plugin rest api", func() {
}) })
}) })
Context("Test plugin API", func() { Context("Test plugin API. Request to /proxy/plugins", func() {
By("Request to /proxy/plugins")
It("Test to request the kube API", func() { It("Test to request the kube API", func() {
defer GinkgoRecover() defer GinkgoRecover()
By("Before enable the plugin, request the plugin API should return 400") By("Before enable the plugin, request the plugin API should return 400")
@ -131,9 +127,7 @@ var _ = Describe("Test the plugin rest api", func() {
}) })
}) })
Context("Test to request the plugin static files", func() { Context("Test to request the plugin static files. Request to /public/plugins", func() {
By("Request to /public/plugins")
It("Test to get the module file", func() { It("Test to get the module file", func() {
defer GinkgoRecover() defer GinkgoRecover()
res := get(baseDomain + "/public/plugins/app-demo/module.js") res := get(baseDomain + "/public/plugins/app-demo/module.js")

View File

@ -21,7 +21,7 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1" apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1"

View File

@ -19,7 +19,7 @@ package e2e_test
import ( import (
"io" "io"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
) )

View File

@ -29,7 +29,7 @@ import (
"time" "time"
"github.com/google/uuid" "github.com/google/uuid"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
@ -147,7 +147,7 @@ var _ = BeforeSuite(func() {
err = json.NewDecoder(resp.Body).Decode(code) err = json.NewDecoder(resp.Body).Decode(code)
Expect(err).Should(BeNil()) Expect(err).Should(BeNil())
return fmt.Errorf("rest service not ready code:%d message:%s", resp.StatusCode, code.Message) return fmt.Errorf("rest service not ready code:%d message:%s", resp.StatusCode, code.Message)
}, time.Second*60, time.Millisecond*200).Should(Succeed()) }).WithTimeout(time.Second * 60).WithPolling(time.Millisecond * 200).Should(Succeed())
var err error var err error
k8sClient, err = clients.GetKubeClient() k8sClient, err = clients.GetKubeClient()
Expect(err).ShouldNot(HaveOccurred()) Expect(err).ShouldNot(HaveOccurred())

View File

@ -17,7 +17,7 @@ limitations under the License.
package e2e_test package e2e_test
import ( import (
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1" apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1"

View File

@ -19,7 +19,7 @@ package e2e_test
import ( import (
"fmt" "fmt"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1" apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1"

View File

@ -24,7 +24,7 @@ import (
types2 "github.com/oam-dev/kubevela/pkg/velaql/providers/query/types" types2 "github.com/oam-dev/kubevela/pkg/velaql/providers/query/types"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/pkg/errors" "github.com/pkg/errors"
batchv1 "k8s.io/api/batch/v1" batchv1 "k8s.io/api/batch/v1"

200
go.mod
View File

@ -1,91 +1,83 @@
module github.com/kubevela/velaux module github.com/kubevela/velaux
go 1.19 go 1.22
require ( require (
cuelang.org/go v0.5.0 cuelang.org/go v0.5.0
github.com/AlecAivazis/survey/v2 v2.1.1 // indirect github.com/AlecAivazis/survey/v2 v2.1.1 // indirect
github.com/Masterminds/semver/v3 v3.2.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect
github.com/agiledragon/gomonkey/v2 v2.4.0 github.com/agiledragon/gomonkey/v2 v2.4.0
github.com/alibabacloud-go/cs-20151215/v3 v3.0.32 // indirect
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4 // indirect
github.com/alibabacloud-go/tea v1.1.20 // indirect
github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect github.com/aryann/difflib v0.0.0-20210328193216-ff5ff6dc229b // indirect
github.com/barnettZQG/inject v0.0.1 github.com/barnettZQG/inject v0.0.1
github.com/briandowns/spinner v1.11.1 // indirect github.com/briandowns/spinner v1.23.0 // indirect
github.com/chartmuseum/helm-push v0.10.3 // indirect github.com/chartmuseum/helm-push v0.10.4 // indirect
github.com/cloudtty/cloudtty v0.2.0 github.com/cloudtty/cloudtty v0.5.0
github.com/containerd/containerd v1.6.18 // indirect github.com/containerd/containerd v1.7.2 // indirect
github.com/coreos/go-oidc v2.2.1+incompatible github.com/coreos/go-oidc v2.2.1+incompatible
github.com/crossplane/crossplane-runtime v0.19.2 // indirect github.com/crossplane/crossplane-runtime v0.19.2 // indirect
github.com/cue-exp/kubevelafix v0.0.0-20220922150317-aead819d979d // indirect github.com/cue-exp/kubevelafix v0.0.0-20220922150317-aead819d979d // indirect
github.com/davecgh/go-spew v1.1.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect
github.com/deckarep/golang-set v1.8.0 // indirect
github.com/emicklei/go-restful-openapi/v2 v2.9.1 github.com/emicklei/go-restful-openapi/v2 v2.9.1
github.com/emicklei/go-restful/v3 v3.10.2 github.com/emicklei/go-restful/v3 v3.10.2
github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.6.0 // indirect github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
github.com/facebookgo/structtag v0.0.0-20150214074306-217e25fb9691 // indirect github.com/facebookgo/structtag v0.0.0-20150214074306-217e25fb9691 // indirect
github.com/fatih/color v1.13.0 github.com/fatih/color v1.15.0
github.com/felixge/httpsnoop v1.0.3 // indirect github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fluxcd/helm-controller/api v0.32.1 // indirect github.com/fluxcd/helm-controller/api v0.32.2 // indirect
github.com/fluxcd/source-controller/api v0.24.4 // indirect github.com/fluxcd/source-controller/api v0.24.4 // indirect
github.com/form3tech-oss/jwt-go v3.2.3+incompatible github.com/form3tech-oss/jwt-go v3.2.5+incompatible
github.com/getkin/kin-openapi v0.107.0 github.com/getkin/kin-openapi v0.118.0
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32
github.com/go-git/go-git/v5 v5.6.1 // indirect github.com/go-git/go-git/v5 v5.7.0 // indirect
github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/logr v1.2.4 // indirect
github.com/go-openapi/spec v0.20.7 github.com/go-openapi/spec v0.20.7
github.com/go-playground/validator/v10 v10.9.0 github.com/go-playground/validator/v10 v10.9.0
github.com/go-resty/resty/v2 v2.7.0 // indirect github.com/go-resty/resty/v2 v2.7.0 // indirect
github.com/golang/mock v1.6.0 // indirect github.com/golang/mock v1.6.0 // indirect
github.com/google/go-cmp v0.5.9 github.com/google/go-cmp v0.5.9
github.com/google/go-containerregistry v0.13.0 github.com/google/go-containerregistry v0.15.2
github.com/google/go-github/v32 v32.1.0 // indirect github.com/google/go-github/v32 v32.1.0 // indirect
github.com/google/uuid v1.3.0 github.com/google/uuid v1.3.0
github.com/gorilla/websocket v1.5.0 github.com/gorilla/websocket v1.5.0
github.com/gosuri/uitable v0.0.4 // indirect github.com/gosuri/uitable v0.0.4 // indirect
github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/go-version v1.6.0 // indirect
github.com/hashicorp/hcl/v2 v2.16.2 // indirect github.com/hashicorp/hcl/v2 v2.17.0 // indirect
github.com/imdario/mergo v0.3.13 // indirect github.com/imdario/mergo v0.3.16 // indirect
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
github.com/kubevela/pkg v1.8.1-0.20230410075324-9f0ba3b09495 github.com/kubevela/pkg v1.8.1-0.20230613075152-2cef0c31b14e
github.com/kubevela/prism v1.7.0-alpha.1 github.com/kubevela/prism v1.7.0-alpha.1.0.20230403030519-b7e45f7f842e
github.com/kubevela/workflow v0.5.1-0.20230412142923-1f15ba091699
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
github.com/oam-dev/cluster-gateway v1.9.0-alpha.2 github.com/oam-dev/cluster-gateway v1.9.0-alpha.2
github.com/oam-dev/cluster-register v1.0.4-0.20220928064144-5f76a9d7ca8c // indirect github.com/oam-dev/cluster-register v1.0.4-0.20230424040021-147f7c1fefe5 // indirect
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28 // indirect github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28 // indirect
github.com/oam-dev/terraform-controller v0.7.10 github.com/oam-dev/terraform-controller v0.7.11
github.com/onsi/ginkgo v1.16.5 github.com/onsi/gomega v1.27.8
github.com/onsi/gomega v1.27.5 github.com/openkruise/kruise-api v1.4.0 // indirect
github.com/openkruise/kruise-api v1.3.0 // indirect
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_golang v1.16.0 // indirect
github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/client_model v0.4.0 // indirect
github.com/robfig/cron/v3 v3.0.1 github.com/robfig/cron/v3 v3.0.1
github.com/sirupsen/logrus v1.9.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect
github.com/spf13/cobra v1.6.1 github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5 github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.8.2 github.com/stretchr/testify v1.8.4
github.com/tidwall/gjson v1.14.4 github.com/tidwall/gjson v1.14.4
github.com/wercker/stern v0.0.0-20190705090245-4fa46dd6987f // indirect github.com/wercker/stern v0.0.0-20190705090245-4fa46dd6987f // indirect
github.com/wonderflow/cert-manager-api v1.0.4-0.20210304051430-e08aa76f6c5f // indirect github.com/xanzy/go-gitlab v0.86.0 // indirect
github.com/xanzy/go-gitlab v0.83.0 // indirect
github.com/xlab/treeprint v1.2.0 // indirect github.com/xlab/treeprint v1.2.0 // indirect
go.mongodb.org/mongo-driver v1.11.2 go.mongodb.org/mongo-driver v1.11.2
go.uber.org/zap v1.24.0 // indirect go.uber.org/zap v1.24.0 // indirect
golang.org/x/crypto v0.6.0 golang.org/x/crypto v0.11.0
golang.org/x/oauth2 v0.6.0 golang.org/x/oauth2 v0.10.0
golang.org/x/term v0.6.0 // indirect golang.org/x/term v0.10.0 // indirect
golang.org/x/text v0.8.0 // indirect golang.org/x/text v0.11.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools v2.2.0+incompatible gotest.tools v2.2.0+incompatible
helm.sh/helm/v3 v3.11.2 helm.sh/helm/v3 v3.11.2
istio.io/client-go v1.13.4 // indirect
k8s.io/api v0.26.3 k8s.io/api v0.26.3
k8s.io/apiextensions-apiserver v0.26.3 k8s.io/apiextensions-apiserver v0.26.3
k8s.io/apimachinery v0.26.3 k8s.io/apimachinery v0.26.3
@ -94,24 +86,52 @@ require (
k8s.io/client-go v0.26.3 k8s.io/client-go v0.26.3
k8s.io/component-base v0.26.3 k8s.io/component-base v0.26.3
k8s.io/helm v2.17.0+incompatible // indirect k8s.io/helm v2.17.0+incompatible // indirect
k8s.io/klog/v2 v2.90.1 k8s.io/klog/v2 v2.100.1
k8s.io/kube-aggregator v0.26.3 // indirect k8s.io/kube-aggregator v0.26.3 // indirect
k8s.io/kubectl v0.26.3 // indirect k8s.io/kubectl v0.26.3 // indirect
k8s.io/metrics v0.26.3 // indirect k8s.io/metrics v0.26.3 // indirect
k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5
open-cluster-management.io/api v0.10.1 // indirect open-cluster-management.io/api v0.10.1 // indirect
sigs.k8s.io/controller-runtime v0.14.6 sigs.k8s.io/controller-runtime v0.14.6
sigs.k8s.io/gateway-api v0.4.3 // indirect sigs.k8s.io/gateway-api v0.7.1 // indirect
sigs.k8s.io/kind v0.17.0 // indirect sigs.k8s.io/kind v0.20.0 // indirect
sigs.k8s.io/yaml v1.3.0 sigs.k8s.io/yaml v1.3.0
) )
require github.com/oam-dev/kubevela v1.9.0-alpha.1.0.20230421061936-dab1618eef7d
require ( require (
github.com/alibabacloud-go/cs-20151215/v3 v3.0.35
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.4
github.com/alibabacloud-go/tea v1.2.0
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
github.com/grafana/grafana v1.9.2-0.20230216173926-a0bea04a0274 github.com/grafana/grafana v1.9.2-0.20230216173926-a0bea04a0274
github.com/julienschmidt/httprouter v1.3.0 github.com/julienschmidt/httprouter v1.3.0
github.com/kubevela/workflow v0.6.0
github.com/oam-dev/kubevela v1.9.4
github.com/onsi/ginkgo/v2 v2.11.0
gorm.io/driver/postgres v1.5.2
)
require (
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
github.com/alibabacloud-go/openapi-util v0.1.0 // indirect
github.com/alibabacloud-go/tea-utils v1.3.1 // indirect
github.com/alibabacloud-go/tea-utils/v2 v2.0.1 // indirect
github.com/alibabacloud-go/tea-xml v1.1.2 // indirect
github.com/aliyun/credentials-go v1.1.2 // indirect
github.com/clbanning/mxj/v2 v2.5.5 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgx/v5 v5.4.2 // indirect
github.com/jellydator/ttlcache/v3 v3.0.1 // indirect
github.com/perimeterx/marshmallow v1.1.4 // indirect
github.com/tjfoc/gmsm v1.3.2 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect
) )
require ( require (
@ -123,21 +143,13 @@ require (
github.com/Masterminds/sprig v2.22.0+incompatible // indirect github.com/Masterminds/sprig v2.22.0+incompatible // indirect
github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Masterminds/squirrel v1.5.3 // indirect github.com/Masterminds/squirrel v1.5.3 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 // indirect
github.com/acomagu/bufpipe v1.0.4 // indirect github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/agext/levenshtein v1.2.3 // indirect github.com/agext/levenshtein v1.2.3 // indirect
github.com/alessio/shellescape v1.4.1 // indirect github.com/alessio/shellescape v1.4.1 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.1 // indirect
github.com/alibabacloud-go/openapi-util v0.1.0 // indirect
github.com/alibabacloud-go/tea-utils v1.4.5 // indirect
github.com/alibabacloud-go/tea-utils/v2 v2.0.1 // indirect
github.com/alibabacloud-go/tea-xml v1.1.2 // indirect
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 // indirect
github.com/aliyun/credentials-go v1.1.2 // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
github.com/beorn7/perks v1.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect
@ -145,15 +157,14 @@ require (
github.com/buger/jsonparser v1.1.1 // indirect github.com/buger/jsonparser v1.1.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chai2010/gettext-go v1.0.2 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect
github.com/clbanning/mxj/v2 v2.5.5 // indirect github.com/cloudflare/circl v1.3.3 // indirect
github.com/cloudflare/circl v1.1.0 // indirect
github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect
github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect
github.com/cyphar/filepath-securejoin v0.2.3 // indirect github.com/cyphar/filepath-securejoin v0.2.3 // indirect
github.com/docker/cli v20.10.21+incompatible // indirect github.com/docker/cli v23.0.5+incompatible // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect
github.com/docker/docker v20.10.24+incompatible // indirect github.com/docker/docker v23.0.5+incompatible // indirect
github.com/docker/docker-credential-helpers v0.7.0 // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-metrics v0.0.1 // indirect
@ -164,7 +175,7 @@ require (
github.com/fluxcd/pkg/apis/meta v1.0.0 // indirect github.com/fluxcd/pkg/apis/meta v1.0.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/go-errors/errors v1.0.1 // indirect github.com/go-errors/errors v1.0.1 // indirect
github.com/go-git/gcfg v1.5.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.4.1 // indirect github.com/go-git/go-billy/v5 v5.4.1 // indirect
github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect github.com/go-openapi/jsonpointer v0.19.5 // indirect
@ -189,7 +200,7 @@ require (
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
github.com/huandu/xstrings v1.4.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect github.com/jinzhu/now v1.1.5 // indirect
@ -198,7 +209,7 @@ require (
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect github.com/json-iterator/go v1.1.12 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/klauspost/compress v1.16.3 // indirect github.com/klauspost/compress v1.16.5 // indirect
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect github.com/leodido/go-urn v1.2.1 // indirect
@ -207,7 +218,7 @@ require (
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect
@ -224,65 +235,60 @@ require (
github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de // indirect github.com/mpvl/unique v0.0.0-20150818121801-cbe035fff7de // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
github.com/nxadm/tail v1.4.8 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.0-rc2 // indirect github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
github.com/openshift/library-go v0.0.0-20230327085348-8477ec72b725 // indirect github.com/openshift/library-go v0.0.0-20230327085348-8477ec72b725 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/pquerna/cachecontrol v0.1.0 // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/prometheus/common v0.39.0 // indirect github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect
github.com/rivo/uniseg v0.4.3 // indirect github.com/rivo/uniseg v0.4.3 // indirect
github.com/rubenv/sql-migrate v1.3.1 // indirect github.com/rubenv/sql-migrate v1.3.1 // indirect
github.com/sergi/go-diff v1.2.0 // indirect github.com/sergi/go-diff v1.2.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect github.com/shopspring/decimal v1.3.1 // indirect
github.com/skeema/knownhosts v1.1.0 // indirect github.com/skeema/knownhosts v1.1.1 // indirect
github.com/spf13/cast v1.5.0 // indirect github.com/spf13/cast v1.5.0
github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.0 // indirect github.com/tidwall/pretty v1.2.0 // indirect
github.com/tjfoc/gmsm v1.3.2 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.1 // indirect github.com/xdg-go/scram v1.1.1 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect github.com/xdg-go/stringprep v1.0.3 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
github.com/zclconf/go-cty v1.12.1 // indirect github.com/zclconf/go-cty v1.13.0 // indirect
go.etcd.io/etcd/api/v3 v3.5.5 // indirect go.etcd.io/etcd/api/v3 v3.5.5 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.5 // indirect
go.etcd.io/etcd/client/v3 v3.5.5 // indirect go.etcd.io/etcd/client/v3 v3.5.5 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.37.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.40.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.35.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.40.0 // indirect
go.opentelemetry.io/otel v1.11.2 // indirect go.opentelemetry.io/otel v1.14.0 // indirect
go.opentelemetry.io/otel/metric v0.34.0 // indirect go.opentelemetry.io/otel/metric v0.37.0 // indirect
go.opentelemetry.io/otel/sdk v1.11.2 // indirect go.opentelemetry.io/otel/sdk v1.14.0 // indirect
go.opentelemetry.io/otel/trace v1.11.2 // indirect go.opentelemetry.io/otel/trace v1.14.0 // indirect
go.opentelemetry.io/proto/otlp v0.19.0 // indirect go.opentelemetry.io/proto/otlp v0.19.0 // indirect
go.starlark.net v0.0.0-20221020143700-22309ac47eac // indirect go.starlark.net v0.0.0-20221020143700-22309ac47eac // indirect
go.uber.org/multierr v1.7.0 // indirect go.uber.org/multierr v1.11.0 // indirect
golang.org/x/mod v0.9.0 // indirect golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.8.0 // indirect golang.org/x/net v0.12.0 // indirect
golang.org/x/sync v0.1.0 // indirect golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.6.0 // indirect golang.org/x/sys v0.10.0 // indirect
golang.org/x/time v0.3.0 // indirect golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.7.0 // indirect golang.org/x/tools v0.11.0 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
google.golang.org/grpc v1.51.0 // indirect google.golang.org/grpc v1.53.0 // indirect
google.golang.org/protobuf v1.29.1 // indirect google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect
gorm.io/gorm v1.25.1 gorm.io/gorm v1.25.2
istio.io/api v0.0.0-20220512212136-561ffec82582 // indirect
istio.io/gogo-genproto v0.0.0-20211208193508-5ab4acc9eb1e // indirect
k8s.io/klog v1.0.0 // indirect k8s.io/klog v1.0.0 // indirect
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
oras.land/oras-go v1.2.2 // indirect oras.land/oras-go v1.2.2 // indirect
@ -311,17 +317,17 @@ require (
github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect github.com/magiconair/properties v1.8.7 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/nacos-group/nacos-sdk-go/v2 v2.1.0 // indirect github.com/nacos-group/nacos-sdk-go/v2 v2.2.2 // indirect
github.com/openkruise/rollouts v0.1.1-0.20220622054609-149e5a48da5e // indirect github.com/openkruise/rollouts v0.3.0 // indirect
github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.11.2 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.11.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.14.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.11.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.14.0 // indirect
go.uber.org/atomic v1.10.0 // indirect go.uber.org/atomic v1.10.0 // indirect
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef // indirect google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gorm.io/driver/mysql v1.5.1 gorm.io/driver/mysql v1.5.1
k8s.io/kms v0.26.3 // indirect k8s.io/kms v0.26.3 // indirect

804
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
SHELL := /bin/bash SHELL := /bin/bash
GOLANGCILINT_VERSION ?= 1.49.0 GOLANGCILINT_VERSION ?= 1.59.1
# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN)) ifeq (,$(shell go env GOBIN))
@ -17,6 +17,7 @@ VELAUX_VERSION ?= main
# Repo info # Repo info
GIT_COMMIT ?= git-$(shell git rev-parse --short HEAD) GIT_COMMIT ?= git-$(shell git rev-parse --short HEAD)
GIT_COMMIT_LONG ?= $(shell git rev-parse HEAD) GIT_COMMIT_LONG ?= $(shell git rev-parse HEAD)
VELAUX_IMAGE ?= velaux:$(VELAUX_VERSION)
VELAUX_VERSION_KEY := github.com/kubevela/velaux/version.VelaVersion VELAUX_VERSION_KEY := github.com/kubevela/velaux/version.VelaVersion
VELAUX_GITVERSION_KEY := github.com/kubevela/velaux/version.GitRevision VELAUX_GITVERSION_KEY := github.com/kubevela/velaux/version.GitRevision
LDFLAGS ?= "-s -w -X $(VELAUX_VERSION_KEY)=$(VELAUX_VERSION) -X $(VELAUX_GITVERSION_KEY)=$(GIT_COMMIT)" LDFLAGS ?= "-s -w -X $(VELAUX_VERSION_KEY)=$(VELAUX_VERSION) -X $(VELAUX_GITVERSION_KEY)=$(GIT_COMMIT)"

View File

@ -14,6 +14,8 @@ const HelmValueShow: React.FC<Props> = (props: Props) => {
const [valueFile, setValueFile] = React.useState<string>('values.yaml'); const [valueFile, setValueFile] = React.useState<string>('values.yaml');
return ( return (
<Dialog <Dialog
style={{ width: '60vw' }}
closeMode={["close", "mask"]}
className={'helmValueDialog'} className={'helmValueDialog'}
overflowScroll={true} overflowScroll={true}
visible={true} visible={true}

View File

@ -192,9 +192,6 @@ class UISchema extends Component<Props, State> {
if (condition.action == 'enable' || !condition.action) { if (condition.action == 'enable' || !condition.action) {
enableConditionCount += 1; enableConditionCount += 1;
} }
if (value == undefined) {
return;
}
switch (condition.op) { switch (condition.op) {
case 'in': case 'in':
if (Array.isArray(condition.value) && condition.value.includes(value)) { if (Array.isArray(condition.value) && condition.value.includes(value)) {
@ -976,7 +973,7 @@ class UISchema extends Component<Props, State> {
}; };
const showAdvancedButton = couldBeDisabledParamCount != couldShowParamCount || requiredParamCount === 0; const showAdvancedButton = couldBeDisabledParamCount != couldShowParamCount || requiredParamCount === 0;
return ( return (
<Form field={this.form} className="ui-schema-container"> <Form field={this.form} className="ui-schema-container">
<If condition={disableRenderRow}>{items}</If> <If condition={disableRenderRow}>{items}</If>
<If condition={!disableRenderRow}> <If condition={!disableRenderRow}>

View File

@ -57,7 +57,7 @@ class Group extends React.Component<Props, State> {
initSwitchState = () => { initSwitchState = () => {
const { jsonKey = '', propertyValue = {}, alwaysShow = false, required, closed, initClose } = this.props; const { jsonKey = '', propertyValue = {}, alwaysShow = false, required, closed, initClose } = this.props;
const findKey = Object.keys(propertyValue).find((item) => item === jsonKey); const findKey = propertyValue && Object.keys(propertyValue).find((item) => item === jsonKey);
if (findKey || alwaysShow) { if (findKey || alwaysShow) {
this.setState({ enable: true, closed: false || initClose, checked: true }); this.setState({ enable: true, closed: false || initClose, checked: true });
} else if (required) { } else if (required) {

View File

@ -109,7 +109,7 @@ class EditPlatFormUserDialog extends Component<Props, State> {
{ {
required: true, required: true,
pattern: checkName, pattern: checkName,
message: <Translation>You must input a valid name</Translation>, message: <Translation>You must input a valid name with alphanumeric character only</Translation>,
}, },
], ],
})} })}
@ -139,7 +139,7 @@ class EditPlatFormUserDialog extends Component<Props, State> {
pattern: checkUserPassword, pattern: checkUserPassword,
message: ( message: (
<Translation> <Translation>
Password should be 8-16 bits and contain at least one number and one letter Password must be alphanumeric, contain at least one letter and one number, and be 8-16 characters long
</Translation> </Translation>
), ),
}, },

View File

@ -329,6 +329,7 @@
"Only support github repo urlmaster branch": "仅支持 GitHub repo主分支 链接", "Only support github repo urlmaster branch": "仅支持 GitHub repo主分支 链接",
"Are you sure to delete?": "确认要删除吗?", "Are you sure to delete?": "确认要删除吗?",
"Please enter a valid name": "请输入一个有效的名称", "Please enter a valid name": "请输入一个有效的名称",
"Please enter a valid name having alphanumeric characters only": "请输入仅包含字母数字字符的有效名称",
"This addon is experimental, please don't use it in production": "本插件是试用性,请不要在生产环境中使用", "This addon is experimental, please don't use it in production": "本插件是试用性,请不要在生产环境中使用",
"Dependencies": "依赖", "Dependencies": "依赖",
"Enable the addon to obtain the following extension capabilities": "启用插件以使用如下扩展能力", "Enable the addon to obtain the following extension capabilities": "启用插件以使用如下扩展能力",
@ -534,6 +535,7 @@
"Environment binding deleted successfully": "成功移除环境绑定", "Environment binding deleted successfully": "成功移除环境绑定",
"Retry": "重试", "Retry": "重试",
"Password should be 8-16 bits and contain at least one number and one letter": "密码应为8-16位, 并至少包含一个数字和一个字母", "Password should be 8-16 bits and contain at least one number and one letter": "密码应为8-16位, 并至少包含一个数字和一个字母",
"Password must be alphanumeric, contain at least one letter and one number, and be 8-16 characters long": "密码必须是字母数字,至少包含一个字母和一个数字,长度为 8-16 个字符",
"Please input a valid email": "请输入有效的电子邮件地址", "Please input a valid email": "请输入有效的电子邮件地址",
"Please input a email": "请输入电子邮箱地址", "Please input a email": "请输入电子邮箱地址",
"User updated successfully": "用户更新成功", "User updated successfully": "用户更新成功",
@ -652,4 +654,4 @@
"Click me to open the dex login page": "点击我打开 Dex 登录页面", "Click me to open the dex login page": "点击我打开 Dex 登录页面",
"Setting the default projects for the dex login user": "设置 Dex 登录用户的默认项目", "Setting the default projects for the dex login user": "设置 Dex 登录用户的默认项目",
"Join Time": "加入时间" "Join Time": "加入时间"
} }

View File

@ -517,7 +517,7 @@ class AddonDetailDialog extends React.Component<Props, State> {
schema schema
? [ ? [
<Button <Button
style={{ marginTop: '-12px', alignItems: 'center', display: 'flex' }} style={{ alignItems: 'center', display: 'flex' }}
onClick={() => { onClick={() => {
if (propertiesMode === 'native') { if (propertiesMode === 'native') {
this.setState({ propertiesMode: 'code' }); this.setState({ propertiesMode: 'code' });

View File

@ -195,14 +195,28 @@ class TraitDialog extends React.Component<Props, State> {
.then((re) => { .then((re) => {
if (re) { if (re) {
this.setState({ definitionDetail: re, definitionLoading: false }); this.setState({ definitionDetail: re, definitionLoading: false });
if (callback) { this.setDefaultProperties(re)
callback(); if (callback) {
} callback();
}
} }
}) })
.catch(() => this.setState({ definitionLoading: false })); .catch(() => this.setState({ definitionLoading: false }));
}; };
setDefaultProperties = (definitionDetail: any) => {
const properties = definitionDetail.schema?.properties;
if (properties) {
const defaultValues: Record<string, any> = {};
for (const key in properties) {
if (properties[key].default !== undefined) {
defaultValues[key] = properties[key].default;
}
}
this.field.setValues({ properties: defaultValues });
}
};
handleTypeChange = (value: string) => { handleTypeChange = (value: string) => {
this.removeProperties(); this.removeProperties();
this.field.setValues({ type: value }); this.field.setValues({ type: value });

View File

@ -55,7 +55,7 @@ class AddClusterDialog extends React.Component<Props, State> {
}); });
} }
}; };
onClose = () => { onClose = () => {
this.props.onClose(); this.props.onClose();
this.resetField(); this.resetField();
@ -69,13 +69,13 @@ class AddClusterDialog extends React.Component<Props, State> {
} }
if (editMode) { if (editMode) {
updateCluster({ updateCluster({
name: cluster.name, name: cluster?.name,
alias: values.alias, alias: values.alias,
icon: cluster.icon, icon: cluster?.icon,
description: values.description, description: values.description,
dashboardURL: values.dashboardURL, dashboardURL: values.dashboardURL,
kubeConfig: values.kubeConfig, kubeConfig: values.kubeConfig,
labels: cluster.labels, labels: cluster?.labels,
}).then((re: any) => { }).then((re: any) => {
if (re) { if (re) {
Message.success(<Translation>cluster update success</Translation>); Message.success(<Translation>cluster update success</Translation>);
@ -140,7 +140,7 @@ class AddClusterDialog extends React.Component<Props, State> {
}; };
const init = this.field.init; const init = this.field.init;
const values: { kubeConfig: string } = this.field.getValues(); const values: { kubeConfig: string } = this.field.getValues();
const valueInfo = cluster.kubeConfig || values.kubeConfig || ''; const valueInfo = cluster?.kubeConfig || values.kubeConfig || '';
return ( return (
<Dialog <Dialog
locale={locale().Dialog} locale={locale().Dialog}
@ -170,7 +170,7 @@ class AddClusterDialog extends React.Component<Props, State> {
name="name" name="name"
disabled={editMode} disabled={editMode}
{...init('name', { {...init('name', {
initValue: cluster.name, initValue: cluster?.name || editClusterName,
rules: [ rules: [
{ {
required: true, required: true,
@ -187,7 +187,7 @@ class AddClusterDialog extends React.Component<Props, State> {
<Input <Input
name="alias" name="alias"
{...init('alias', { {...init('alias', {
initValue: cluster.alias, initValue: cluster?.alias,
rules: [ rules: [
{ {
minLength: 2, minLength: 2,
@ -204,10 +204,10 @@ class AddClusterDialog extends React.Component<Props, State> {
<Col span={12} style={{ padding: '0 8px' }}> <Col span={12} style={{ padding: '0 8px' }}>
<FormItem label={<Translation>Description</Translation>}> <FormItem label={<Translation>Description</Translation>}>
<Input <Input
defaultValue={cluster.description} defaultValue={cluster?.description}
name="description" name="description"
{...init('description', { {...init('description', {
initValue: cluster.description, initValue: cluster?.description,
rules: [ rules: [
{ {
maxLength: 256, maxLength: 256,
@ -223,7 +223,7 @@ class AddClusterDialog extends React.Component<Props, State> {
<Input <Input
name="dashboardURL" name="dashboardURL"
{...init('dashboardURL', { {...init('dashboardURL', {
initValue: cluster.dashboardURL, initValue: cluster?.dashboardURL,
rules: [ rules: [
{ {
required: false, required: false,
@ -252,7 +252,7 @@ class AddClusterDialog extends React.Component<Props, State> {
language={'yaml'} language={'yaml'}
readOnly={false} readOnly={false}
{...init('kubeConfig', { {...init('kubeConfig', {
initValue: cluster.kubeConfig, initValue: cluster?.kubeConfig,
rules: [ rules: [
{ {
required: true, required: true,

View File

@ -101,7 +101,7 @@ class Cluster extends React.Component<Props, State> {
(enableAddon || []).forEach((ele: { name: string; phase: boolean }) => { (enableAddon || []).forEach((ele: { name: string; phase: boolean }) => {
addonList.forEach((item: Addon) => { addonList.forEach((item: Addon) => {
const isMatchName = ele.name === item.name; const isMatchName = ele.name === item.name;
const deploy = item.deployTo || { runtimeCluster: false, runtime_cluster: false }; const deploy = item.deployTo || { runtimeCluster: false };
if (isMatchName && deploy.runtimeCluster) { if (isMatchName && deploy.runtimeCluster) {
addonMessage.push({ name: item.name, path: item.url || '' }); addonMessage.push({ name: item.name, path: item.url || '' });
} }

View File

@ -168,7 +168,7 @@ class CreateUser extends React.Component<Props, State> {
{ {
required: true, required: true,
pattern: checkName, pattern: checkName,
message: <Translation>Please enter a valid name</Translation>, message: <Translation>Please enter a valid name having alphanumeric characters only</Translation>,
}, },
], ],
})} })}
@ -209,7 +209,7 @@ class CreateUser extends React.Component<Props, State> {
pattern: checkUserPassword, pattern: checkUserPassword,
message: ( message: (
<Translation> <Translation>
Password should be 8-16 bits and contain at least one number and one letter Password must be alphanumeric, contain at least one letter and one number, and be 8-16 characters long
</Translation> </Translation>
), ),
}, },

View File

@ -117,7 +117,7 @@ class ResetPassword extends React.Component<Props, State> {
pattern: checkUserPassword, pattern: checkUserPassword,
message: ( message: (
<Translation> <Translation>
Password should be 8-16 bits and contain at least one number and one letter Password must be alphanumeric, contain at least one letter and one number, and be 8-16 characters long
</Translation> </Translation>
), ),
}, },

227
pkg/cloudprovider/aliyun.go Normal file
View File

@ -0,0 +1,227 @@
/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cloudprovider
import (
"context"
"encoding/json"
"fmt"
"strings"
cs20151215 "github.com/alibabacloud-go/cs-20151215/v3/client"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/alibabacloud-go/tea/tea"
types "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
v1beta12 "github.com/oam-dev/terraform-controller/api/v1beta2"
"github.com/pkg/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog/v2"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/oam-dev/kubevela/pkg/utils/util"
)
const (
aliyunAPIEndpoint = "cs.cn-hangzhou.aliyuncs.com"
)
// AliyunCloudProvider describes the cloud provider in aliyun
type AliyunCloudProvider struct {
*cs20151215.Client
k8sClient client.Client
accessKeyID string
accessKeySecret string
}
// NewAliyunCloudProvider create aliyun cloud provider
func NewAliyunCloudProvider(accessKeyID string, accessKeySecret string, k8sClient client.Client) (*AliyunCloudProvider, error) {
config := &openapi.Config{
AccessKeyId: pointer.String(accessKeyID),
AccessKeySecret: pointer.String(accessKeySecret),
}
config.Endpoint = tea.String(aliyunAPIEndpoint)
c, err := cs20151215.NewClient(config)
if err != nil {
return nil, err
}
return &AliyunCloudProvider{Client: c, k8sClient: k8sClient, accessKeyID: accessKeyID, accessKeySecret: accessKeySecret}, nil
}
// IsInvalidKey check if error is InvalidAccessKey or InvalidSecretKey
func (provider *AliyunCloudProvider) IsInvalidKey(err error) bool {
return strings.Contains(err.Error(), "InvalidAccessKeyId") || strings.Contains(err.Error(), "Code: SignatureDoesNotMatch")
}
func (provider *AliyunCloudProvider) decodeClusterLabels(tags []*cs20151215.Tag) map[string]string {
labels := map[string]string{}
for _, tag := range tags {
if tag != nil {
labels[getString(tag.Key)] = getString(tag.Value)
}
}
return labels
}
func (provider *AliyunCloudProvider) decodeClusterURL(masterURL string) (url struct {
APIServerEndpoint string `json:"api_server_endpoint"`
IntranetAPIServerEndpoint string `json:"intranet_api_server_endpoint"`
}) {
if err := json.Unmarshal([]byte(masterURL), &url); err != nil {
klog.Info("failed to unmarshal masterUrl %s", masterURL)
}
return
}
func (provider *AliyunCloudProvider) getDashboardURL(clusterID string) string {
return fmt.Sprintf("https://cs.console.aliyun.com/#/k8s/cluster/%s/v2/info/overview", clusterID)
}
func getString(s *string) string {
if s == nil {
return ""
}
return *s
}
// ListCloudClusters list clusters with page info, return clusters, total count and error
func (provider *AliyunCloudProvider) ListCloudClusters(pageNumber int, pageSize int) ([]*CloudCluster, int, error) {
describeClustersV1Request := &cs20151215.DescribeClustersV1Request{
PageSize: pointer.Int64(int64(pageSize)),
PageNumber: pointer.Int64(int64(pageNumber)),
}
resp, err := provider.DescribeClustersV1(describeClustersV1Request)
if err != nil {
return nil, 0, err
}
var clusters []*CloudCluster
for _, cluster := range resp.Body.Clusters {
if cluster == nil {
continue
}
labels := provider.decodeClusterLabels(cluster.Tags)
url := provider.decodeClusterURL(getString(cluster.MasterUrl))
clusters = append(clusters, &CloudCluster{
ID: getString(cluster.ClusterId),
Name: getString(cluster.Name),
Type: getString(cluster.ClusterType),
Zone: getString(cluster.ZoneId),
ZoneID: getString(cluster.ZoneId),
RegionID: getString(cluster.RegionId),
VpcID: getString(cluster.VpcId),
Labels: labels,
Status: getString(cluster.State),
APIServerURL: url.APIServerEndpoint,
DashBoardURL: provider.getDashboardURL(getString(cluster.ClusterId)),
})
}
return clusters, int(*resp.Body.PageInfo.TotalCount), nil
}
// GetClusterKubeConfig get cluster kubeconfig by clusterID
func (provider *AliyunCloudProvider) GetClusterKubeConfig(clusterID string) (string, error) {
req := &cs20151215.DescribeClusterUserKubeconfigRequest{}
resp, err := provider.DescribeClusterUserKubeconfig(pointer.String(clusterID), req)
if err != nil {
return "", err
}
return *resp.Body.Config, nil
}
// GetClusterInfo retrieves cluster info by clusterID
func (provider *AliyunCloudProvider) GetClusterInfo(clusterID string) (*CloudCluster, error) {
resp, err := provider.DescribeClusterDetail(pointer.String(clusterID))
if err != nil {
return nil, err
}
cluster := resp.Body
labels := provider.decodeClusterLabels(cluster.Tags)
url := provider.decodeClusterURL(*cluster.MasterUrl)
return &CloudCluster{
Provider: ProviderAliyun,
ID: *cluster.ClusterId,
Name: *cluster.Name,
Type: *cluster.ClusterType,
Zone: *cluster.ZoneId,
ZoneID: *cluster.ZoneId,
RegionID: *cluster.RegionId,
VpcID: *cluster.VpcId,
Labels: labels,
Status: *cluster.State,
APIServerURL: url.APIServerEndpoint,
DashBoardURL: provider.getDashboardURL(*cluster.ClusterId),
}, nil
}
// CreateCloudCluster create cloud cluster
func (provider *AliyunCloudProvider) CreateCloudCluster(ctx context.Context, clusterName string, zone string, worker int, cpu int64, mem int64) (string, error) {
name := GetCloudClusterFullName(ProviderAliyun, clusterName)
ns := util.GetRuntimeNamespace()
terraformProviderName, err := bootstrapTerraformProvider(ctx, provider.k8sClient, ns, ProviderAliyun, "alibaba", provider.accessKeyID, provider.accessKeySecret, "cn-hongkong")
if err != nil {
return "", errors.Wrapf(err, "failed to bootstrap terraform provider")
}
properties := map[string]interface{}{
"k8s_name_prefix": clusterName,
}
if zone != "" {
properties["zone_id"] = zone
}
if cpu != 0 {
properties["cpu_core_count"] = cpu
}
if mem != 0 {
properties["memory_size"] = mem
}
if worker != 0 {
properties["k8s_worker_number"] = worker
}
bs, err := json.Marshal(properties)
if err != nil {
return name, errors.Wrapf(err, "failed to marshal cloud cluster app properties")
}
cfg := v1beta12.Configuration{
ObjectMeta: v1.ObjectMeta{
Name: name,
Namespace: ns,
Labels: map[string]string{
CloudClusterCreatorLabelKey: ProviderAliyun,
},
},
Spec: v1beta12.ConfigurationSpec{
ProviderReference: &types.Reference{
Name: terraformProviderName,
Namespace: ns,
},
Remote: "https://github.com/kubevela-contrib/terraform-modules.git",
Variable: &runtime.RawExtension{Raw: bs},
},
}
cfg.Spec.Path = "alibaba/cs/dedicated-kubernetes"
cfg.Spec.WriteConnectionSecretToReference = &types.SecretReference{
Name: name,
Namespace: ns,
}
if err = provider.k8sClient.Create(ctx, &cfg); err != nil {
return name, errors.Wrapf(err, "failed to create cloud cluster terraform configuration")
}
return name, nil
}

View File

@ -0,0 +1,48 @@
/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cloudprovider
import (
"context"
"github.com/pkg/errors"
"sigs.k8s.io/controller-runtime/pkg/client"
)
const (
// CloudClusterCreatorLabelKey labels the creator of cloud cluster
CloudClusterCreatorLabelKey = "api.core.oam.dev/cloud-cluster-creator"
)
// CloudClusterProvider abstracts the cloud provider to provide cluster access
type CloudClusterProvider interface {
IsInvalidKey(err error) bool
ListCloudClusters(pageNumber int, pageSize int) ([]*CloudCluster, int, error)
GetClusterKubeConfig(clusterID string) (string, error)
GetClusterInfo(clusterID string) (*CloudCluster, error)
CreateCloudCluster(ctx context.Context, clusterName string, zone string, worker int, cpu int64, mem int64) (string, error)
}
// GetClusterProvider creates interface for getting cloud cluster provider
func GetClusterProvider(provider string, accessKeyID string, accessKeySecret string, k8sClient client.Client) (CloudClusterProvider, error) {
switch provider {
case ProviderAliyun:
return NewAliyunCloudProvider(accessKeyID, accessKeySecret, k8sClient)
default:
return nil, errors.Errorf("cluster provider %s is not implemented", provider)
}
}

View File

@ -0,0 +1,94 @@
/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cloudprovider
import (
"context"
"crypto/sha256"
"fmt"
"strings"
types "github.com/oam-dev/terraform-controller/api/types/crossplane-runtime"
v1beta12 "github.com/oam-dev/terraform-controller/api/v1beta1"
"github.com/pkg/errors"
v12 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)
func computeProviderHashKey(provider string, accessKeyID string, accessKeySecret string) string {
return fmt.Sprintf("%x", sha256.Sum256([]byte(strings.Join([]string{provider, accessKeyID, accessKeySecret}, "::"))))[:8] // #nosec
}
// GetCloudClusterFullName construct the full name of cloud cluster which will be used as the name of terraform configuration
func GetCloudClusterFullName(provider string, clusterName string) string {
return fmt.Sprintf("cloud-cluster-%s-%s", provider, clusterName)
}
func bootstrapTerraformProvider(ctx context.Context, k8sClient client.Client, ns string, provider string, tfProvider string, accessKeyID string, accessKeySecret string, region string) (string, error) {
hashKey := computeProviderHashKey(provider, accessKeyID, accessKeySecret)
secretName := fmt.Sprintf("tf-provider-cred-%s-%s", provider, hashKey)
terraformProviderName := fmt.Sprintf("tf-provider-%s-%s", provider, hashKey)
secret := v12.Secret{
ObjectMeta: v1.ObjectMeta{
Name: secretName,
Namespace: ns,
},
StringData: map[string]string{"credentials": fmt.Sprintf("accessKeyID: %s\naccessKeySecret: %s\nsecurityToken:\n", accessKeyID, accessKeySecret)},
Type: v12.SecretTypeOpaque,
}
var err error
if err = k8sClient.Get(ctx, client.ObjectKeyFromObject(&secret), &v12.Secret{}); err != nil {
if kerrors.IsNotFound(err) {
err = k8sClient.Create(ctx, &secret)
}
if err != nil {
return "", errors.Wrapf(err, "failed to upsert terraform provider secret")
}
}
terraformProvider := v1beta12.Provider{
ObjectMeta: v1.ObjectMeta{
Name: terraformProviderName,
Namespace: ns,
},
Spec: v1beta12.ProviderSpec{
Credentials: v1beta12.ProviderCredentials{
SecretRef: &types.SecretKeySelector{
Key: "credentials",
SecretReference: types.SecretReference{
Name: secretName,
Namespace: ns,
},
},
Source: types.CredentialsSourceSecret,
},
Provider: tfProvider,
Region: region,
},
}
if err = k8sClient.Get(ctx, client.ObjectKeyFromObject(&terraformProvider), &v1beta12.Provider{}); err != nil {
if kerrors.IsNotFound(err) {
err = k8sClient.Create(ctx, &terraformProvider)
}
if err != nil {
return "", errors.Wrapf(err, "failed to upsert terraform provider")
}
}
return terraformProviderName, nil
}

View File

@ -0,0 +1,38 @@
/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cloudprovider
const (
// ProviderAliyun cloud provider aliyun
ProviderAliyun = "aliyun"
)
// CloudCluster describes the interface that cloud provider should return
type CloudCluster struct {
Provider string `json:"provider"`
ID string `json:"id"`
Name string `json:"name"`
Type string `json:"type"`
Zone string `json:"zone"`
ZoneID string `json:"zoneID"`
RegionID string `json:"regionID"`
VpcID string `json:"vpcID"`
Labels map[string]string `json:"labels"`
Status string `json:"status"`
APIServerURL string `json:"apiServerURL"`
DashBoardURL string `json:"dashboardURL"`
}

View File

@ -22,7 +22,7 @@ import (
"testing" "testing"
"time" "time"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -46,7 +46,7 @@ var k8sClient client.Client
var testEnv *envtest.Environment var testEnv *envtest.Environment
var testScheme = runtime.NewScheme() var testScheme = runtime.NewScheme()
var _ = BeforeSuite(func(done Done) { var _ = BeforeSuite(func(ctx SpecContext) {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
By("bootstrapping test environment") By("bootstrapping test environment")
@ -74,8 +74,7 @@ var _ = BeforeSuite(func(done Done) {
Expect(k8sClient.Create(context.TODO(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: kubevelatypes.DefaultKubeVelaNS}})).Should(BeNil()) Expect(k8sClient.Create(context.TODO(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: kubevelatypes.DefaultKubeVelaNS}})).Should(BeNil())
close(done) }, NodeTimeout(time.Minute))
}, 240)
var _ = AfterSuite(func() { var _ = AfterSuite(func() {
By("tearing down the test environment") By("tearing down the test environment")

View File

@ -23,7 +23,7 @@ import (
"net/url" "net/url"
kubevelatypes "github.com/oam-dev/kubevela/apis/types" kubevelatypes "github.com/oam-dev/kubevela/apis/types"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/rbac/v1" v1 "k8s.io/api/rbac/v1"

View File

@ -26,6 +26,6 @@ type staticServerProxy struct {
plugin *types.Plugin plugin *types.Plugin
} }
func (k *staticServerProxy) Handler(req *http.Request, res http.ResponseWriter) { func (k *staticServerProxy) Handler(_ *http.Request, _ http.ResponseWriter) {
// TODO: // TODO:
} }

View File

@ -48,11 +48,18 @@ func newDefaultRouter(h Handle, plugin *types.Plugin) *defaultRouter {
return &defaultRouter{h: h, plugin: plugin} return &defaultRouter{h: h, plugin: plugin}
} }
// GenerateHTTPRouter create and return the plugin backend router // GetPluginHandler get the plugin backend router, if not exist, will create and cache it
func GenerateHTTPRouter(plugin *types.Plugin, pathPrefix string, h Handle) http.Handler { func GetPluginHandler(plugin *types.Plugin, h Handle) http.Handler {
if r, e := cachePluginRouter[plugin.PluginID()]; e { if r, e := cachePluginRouter[plugin.PluginID()]; e {
return r return r
} }
router := GeneratePluginHandler(plugin, h)
cachePluginRouter[plugin.PluginID()] = router
return router
}
// GeneratePluginHandler create and return the plugin backend router
func GeneratePluginHandler(plugin *types.Plugin, h Handle) http.Handler {
var router http.Handler var router http.Handler
if len(plugin.Routes) == 0 { if len(plugin.Routes) == 0 {
klog.Warningf("plugin %s don't define the routes, will proxy all path requests and not check the permission.", plugin.PluginID()) klog.Warningf("plugin %s don't define the routes, will proxy all path requests and not check the permission.", plugin.PluginID())
@ -60,7 +67,7 @@ func GenerateHTTPRouter(plugin *types.Plugin, pathPrefix string, h Handle) http.
} else { } else {
r := httprouter.New() r := httprouter.New()
for _, route := range plugin.Routes { for _, route := range plugin.Routes {
routePath := path.Join(pathPrefix+"/:"+DefaultPluginResourceKey, route.Path) routePath := path.Join(types.PluginProxyRoutePath+"/:"+DefaultPluginResourceKey, route.Path)
method := route.Method method := route.Method
if method == "" { if method == "" {
method = "GET" method = "GET"
@ -72,6 +79,5 @@ func GenerateHTTPRouter(plugin *types.Plugin, pathPrefix string, h Handle) http.
} }
router = r router = r
} }
cachePluginRouter[plugin.PluginID()] = router
return router return router
} }

View File

@ -31,11 +31,11 @@ import (
func TestDefaultGenerateHTTPRouter(t *testing.T) { func TestDefaultGenerateHTTPRouter(t *testing.T) {
var res = &httptest.ResponseRecorder{} var res = &httptest.ResponseRecorder{}
var req = &http.Request{Method: "GET", URL: &url.URL{Scheme: "http", Path: "/proxy/plugins/default-router/test", Host: "127.0.0.1"}} var req = &http.Request{Method: "GET", URL: &url.URL{Scheme: "http", Path: "/proxy/plugins/default-router/test", Host: "127.0.0.1"}}
defaultRouter := GenerateHTTPRouter(&types.Plugin{ defaultRouter := GetPluginHandler(&types.Plugin{
JSONData: types.JSONData{ JSONData: types.JSONData{
ID: "default-router", ID: "default-router",
}, },
}, "/proxy/plugins", func(w http.ResponseWriter, r1 *http.Request, p1 httprouter.Params, p2 *types.Plugin, r2 *types.Route) { }, func(w http.ResponseWriter, r1 *http.Request, p1 httprouter.Params, p2 *types.Plugin, r2 *types.Route) {
if r1.URL.Path == "/proxy/plugins/default-router/test" { if r1.URL.Path == "/proxy/plugins/default-router/test" {
w.WriteHeader(403) w.WriteHeader(403)
return return
@ -50,7 +50,7 @@ func TestRouteGenerateHTTPRouter(t *testing.T) {
var req = &http.Request{Method: "GET", URL: &url.URL{Scheme: "http", Path: "/proxy/plugins/route-router/nodes/t", Host: "127.0.0.1"}} var req = &http.Request{Method: "GET", URL: &url.URL{Scheme: "http", Path: "/proxy/plugins/route-router/nodes/t", Host: "127.0.0.1"}}
var reqMethodNotAllow = &http.Request{Method: "PUT", URL: &url.URL{Scheme: "http", Path: "/proxy/plugins/route-router/nodes/t", Host: "127.0.0.1"}} var reqMethodNotAllow = &http.Request{Method: "PUT", URL: &url.URL{Scheme: "http", Path: "/proxy/plugins/route-router/nodes/t", Host: "127.0.0.1"}}
var req404 = &http.Request{Method: "GET", URL: &url.URL{Scheme: "http", Path: "/proxy/plugins/route-router/nodes", Host: "127.0.0.1"}} var req404 = &http.Request{Method: "GET", URL: &url.URL{Scheme: "http", Path: "/proxy/plugins/route-router/nodes", Host: "127.0.0.1"}}
router := GenerateHTTPRouter(&types.Plugin{ router := GetPluginHandler(&types.Plugin{
JSONData: types.JSONData{ JSONData: types.JSONData{
ID: "route-router", ID: "route-router",
Routes: []*types.Route{ Routes: []*types.Route{
@ -64,7 +64,7 @@ func TestRouteGenerateHTTPRouter(t *testing.T) {
}, },
}, },
}, },
}, "/proxy/plugins", func(w http.ResponseWriter, r1 *http.Request, p1 httprouter.Params, p2 *types.Plugin, r2 *types.Route) { }, func(w http.ResponseWriter, r1 *http.Request, p1 httprouter.Params, p2 *types.Plugin, r2 *types.Route) {
assert.Equal(t, p1.ByName("node"), "t") assert.Equal(t, p1.ByName("node"), "t")
assert.Equal(t, len(r2.ProxyHeaders), 1) assert.Equal(t, len(r2.ProxyHeaders), 1)
assert.Equal(t, r2.ProxyHeaders[0].Name, "Authorization") assert.Equal(t, r2.ProxyHeaders[0].Name, "Authorization")

View File

@ -20,6 +20,9 @@ import (
rbacv1 "k8s.io/api/rbac/v1" rbacv1 "k8s.io/api/rbac/v1"
) )
// PluginProxyRoutePath the route prefix to request the plugin backend server.
const PluginProxyRoutePath = "/proxy/plugins/"
// Plugin VelaUX plugin model // Plugin VelaUX plugin model
type Plugin struct { type Plugin struct {
JSONData JSONData
@ -145,7 +148,7 @@ type KubernetesService struct {
// If namespace is not specified, find the service from the vela system namespace // If namespace is not specified, find the service from the vela system namespace
Namespace string `json:"namespace"` Namespace string `json:"namespace"`
// If port is not specified, find the first port from the service // If port is not specified, find the first port from the service
Port int32 Port int32 `json:"port"`
} }
// KubernetesSecret define one kubernetes secret // KubernetesSecret define one kubernetes secret

View File

@ -20,9 +20,9 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/spf13/pflag"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/kubevela/pkg/util/profiling"
"github.com/spf13/pflag"
"github.com/kubevela/velaux/pkg/server/infrastructure/datastore" "github.com/kubevela/velaux/pkg/server/infrastructure/datastore"
) )
@ -52,15 +52,15 @@ type Config struct {
// KubeQPS the QPS of kube client // KubeQPS the QPS of kube client
KubeQPS float64 KubeQPS float64
// PprofAddr the address for pprof to use while exporting profiling results.
PprofAddr string
// WorkflowVersion is the version of workflow // WorkflowVersion is the version of workflow
WorkflowVersion string WorkflowVersion string
PluginConfig PluginConfig PluginConfig PluginConfig
DexServerURL string DexServerURL string
// ExitOnLostLeader will exit the process if this server lost the leader election, set this to true for debugging
ExitOnLostLeader bool
} }
// PluginConfig the plugin directory config // PluginConfig the plugin directory config
@ -92,14 +92,14 @@ func NewConfig() *Config {
}, },
AddonCacheTime: time.Minute * 10, AddonCacheTime: time.Minute * 10,
DisableStatisticCronJob: false, DisableStatisticCronJob: false,
PprofAddr: "",
KubeQPS: 100, KubeQPS: 100,
KubeBurst: 300, KubeBurst: 300,
PluginConfig: PluginConfig{ PluginConfig: PluginConfig{
CorePluginPath: "core-plugins", CorePluginPath: "core-plugins",
CustomPluginPath: []string{"plugins"}, CustomPluginPath: []string{"plugins"},
}, },
DexServerURL: "http://dex.vela-system:5556", DexServerURL: "http://dex.vela-system:5556",
ExitOnLostLeader: true,
} }
} }
@ -107,7 +107,7 @@ func NewConfig() *Config {
func (s *Config) Validate() []error { func (s *Config) Validate() []error {
var errs []error var errs []error
if s.Datastore.Type != "mongodb" && s.Datastore.Type != "kubeapi" { if s.Datastore.Type != "mongodb" && s.Datastore.Type != "kubeapi" && s.Datastore.Type != "postgres" {
errs = append(errs, fmt.Errorf("not support datastore type %s", s.Datastore.Type)) errs = append(errs, fmt.Errorf("not support datastore type %s", s.Datastore.Type))
} }
@ -126,10 +126,11 @@ func (s *Config) AddFlags(fs *pflag.FlagSet, c *Config) {
fs.DurationVar(&s.LeaderConfig.Duration, "duration", c.LeaderConfig.Duration, "the lease lock resource name") fs.DurationVar(&s.LeaderConfig.Duration, "duration", c.LeaderConfig.Duration, "the lease lock resource name")
fs.DurationVar(&s.AddonCacheTime, "addon-cache-duration", c.AddonCacheTime, "how long between two addon cache operation") fs.DurationVar(&s.AddonCacheTime, "addon-cache-duration", c.AddonCacheTime, "how long between two addon cache operation")
fs.BoolVar(&s.DisableStatisticCronJob, "disable-statistic-cronJob", c.DisableStatisticCronJob, "close the system statistic info calculating cronJob") fs.BoolVar(&s.DisableStatisticCronJob, "disable-statistic-cronJob", c.DisableStatisticCronJob, "close the system statistic info calculating cronJob")
fs.StringVar(&s.PprofAddr, "pprof-addr", c.PprofAddr, "The address for pprof to use while exporting profiling results. The default value is empty which means do not expose it. Set it to address like :6666 to expose it.")
fs.Float64Var(&s.KubeQPS, "kube-api-qps", c.KubeQPS, "the qps for kube clients. Low qps may lead to low throughput. High qps may give stress to api-server.") fs.Float64Var(&s.KubeQPS, "kube-api-qps", c.KubeQPS, "the qps for kube clients. Low qps may lead to low throughput. High qps may give stress to api-server.")
fs.IntVar(&s.KubeBurst, "kube-api-burst", c.KubeBurst, "the burst for kube clients. Recommend setting it qps*3.") fs.IntVar(&s.KubeBurst, "kube-api-burst", c.KubeBurst, "the burst for kube clients. Recommend setting it qps*3.")
fs.StringVar(&s.WorkflowVersion, "workflow-version", c.WorkflowVersion, "the version of workflow to meet controller requirement.") fs.StringVar(&s.WorkflowVersion, "workflow-version", c.WorkflowVersion, "the version of workflow to meet controller requirement.")
fs.StringVar(&s.DexServerURL, "dex-server", c.DexServerURL, "the URL of the dex server.") fs.StringVar(&s.DexServerURL, "dex-server", c.DexServerURL, "the URL of the dex server.")
fs.StringArrayVar(&s.PluginConfig.CustomPluginPath, "plugin-path", c.PluginConfig.CustomPluginPath, "the path of the plugin directory") fs.StringArrayVar(&s.PluginConfig.CustomPluginPath, "plugin-path", c.PluginConfig.CustomPluginPath, "the path of the plugin directory")
fs.BoolVar(&s.ExitOnLostLeader, "exit-on-lost-leader", c.ExitOnLostLeader, "exit the process if this server lost the leader election")
profiling.AddFlags(fs)
} }

View File

@ -33,13 +33,13 @@ func init() {
// Application application delivery model // Application application delivery model
type Application struct { type Application struct {
BaseModel BaseModel
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Project string `json:"project"` Project string `json:"project"`
Description string `json:"description"` Description string `json:"description"`
Icon string `json:"icon"` Icon string `json:"icon"`
Labels map[string]string `json:"labels,omitempty"` Labels map[string]string `json:"labels,omitempty" gorm:"serializer:json"`
Annotations map[string]string `json:"annotations,omitempty"` Annotations map[string]string `json:"annotations,omitempty" gorm:"serializer:json"`
} }
// TableName return custom table name // TableName return custom table name
@ -117,27 +117,27 @@ type ComponentSelector struct {
// ApplicationComponent component database model // ApplicationComponent component database model
type ApplicationComponent struct { type ApplicationComponent struct {
BaseModel BaseModel
AppPrimaryKey string `json:"appPrimaryKey"` AppPrimaryKey string `json:"appPrimaryKey" gorm:"primaryKey"`
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
Labels map[string]string `json:"labels,omitempty"` Labels map[string]string `json:"labels,omitempty" gorm:"serializer:json"`
Icon string `json:"icon,omitempty"` Icon string `json:"icon,omitempty"`
Creator string `json:"creator"` Creator string `json:"creator"`
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Type string `json:"type"` Type string `json:"type"`
Main bool `json:"main"` Main bool `json:"main"`
// ExternalRevision specified the component revisionName // ExternalRevision specified the component revisionName
ExternalRevision string `json:"externalRevision,omitempty"` ExternalRevision string `json:"externalRevision,omitempty"`
Properties *JSONStruct `json:"properties,omitempty"` Properties *JSONStruct `json:"properties,omitempty" gorm:"serializer:json"`
DependsOn []string `json:"dependsOn,omitempty"` DependsOn []string `json:"dependsOn,omitempty" gorm:"serializer:json"`
Inputs workflowv1alpha1.StepInputs `json:"inputs,omitempty"` Inputs workflowv1alpha1.StepInputs `json:"inputs,omitempty" gorm:"serializer:json"`
Outputs workflowv1alpha1.StepOutputs `json:"outputs,omitempty"` Outputs workflowv1alpha1.StepOutputs `json:"outputs,omitempty" gorm:"serializer:json"`
// Traits define the trait of one component, the type must be array to keep the order. // Traits define the trait of one component, the type must be array to keep the order.
Traits []ApplicationTrait `json:"traits,omitempty"` Traits []ApplicationTrait `json:"traits,omitempty" gorm:"serializer:json"`
// scopes in ApplicationComponent defines the component-level scopes // scopes in ApplicationComponent defines the component-level scopes
// the format is <scope-type:scope-instance-name> pairs, the key represents type of `ScopeDefinition` while the value represent the name of scope instance. // the format is <scope-type:scope-instance-name> pairs, the key represents type of `ScopeDefinition` while the value represent the name of scope instance.
Scopes map[string]string `json:"scopes,omitempty"` Scopes map[string]string `json:"scopes,omitempty" gorm:"serializer:json"`
WorkloadType common.WorkloadTypeDescriptor `json:"workloadType,omitempty"` WorkloadType common.WorkloadTypeDescriptor `json:"workloadType,omitempty" gorm:"serializer:json"`
} }
// TableName return custom table name // TableName return custom table name
@ -176,13 +176,13 @@ func (a *ApplicationComponent) Index() map[string]interface{} {
// ApplicationPolicy app policy // ApplicationPolicy app policy
type ApplicationPolicy struct { type ApplicationPolicy struct {
BaseModel BaseModel
AppPrimaryKey string `json:"appPrimaryKey"` AppPrimaryKey string `json:"appPrimaryKey" gorm:"primaryKey"`
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Description string `json:"description"` Description string `json:"description"`
Type string `json:"type"` Type string `json:"type"`
Creator string `json:"creator"` Creator string `json:"creator"`
Properties *JSONStruct `json:"properties,omitempty"` Properties *JSONStruct `json:"properties,omitempty" gorm:"serializer:json"`
// EnvName if it is not empty, the policy is only belong to this environment // EnvName if it is not empty, the policy is only belong to this environment
// For auto created policies, this field will be assigned a value // For auto created policies, this field will be assigned a value
EnvName string `json:"envName"` EnvName string `json:"envName"`
@ -226,7 +226,7 @@ type ApplicationTrait struct {
Alias string `json:"alias"` Alias string `json:"alias"`
Description string `json:"description"` Description string `json:"description"`
Type string `json:"type"` Type string `json:"type"`
Properties *JSONStruct `json:"properties,omitempty"` Properties *JSONStruct `json:"properties,omitempty" gorm:"serializer:json"`
CreateTime time.Time `json:"createTime"` CreateTime time.Time `json:"createTime"`
UpdateTime time.Time `json:"updateTime"` UpdateTime time.Time `json:"updateTime"`
} }
@ -255,8 +255,8 @@ var WorkflowStepPhaseStopped workflowv1alpha1.WorkflowStepPhase = "stopped"
// ApplicationRevision be created when an application initiates deployment and describes the phased version of the application. // ApplicationRevision be created when an application initiates deployment and describes the phased version of the application.
type ApplicationRevision struct { type ApplicationRevision struct {
BaseModel BaseModel
AppPrimaryKey string `json:"appPrimaryKey"` AppPrimaryKey string `json:"appPrimaryKey" gorm:"primaryKey"`
Version string `json:"version"` Version string `json:"version" gorm:"primaryKey"`
RollbackVersion string `json:"rollbackVersion,omitempty"` RollbackVersion string `json:"rollbackVersion,omitempty"`
// ApplyAppConfig Stores the application configuration during the current deploy. // ApplyAppConfig Stores the application configuration during the current deploy.
ApplyAppConfig string `json:"applyAppConfig,omitempty"` ApplyAppConfig string `json:"applyAppConfig,omitempty"`
@ -281,9 +281,9 @@ type ApplicationRevision struct {
// EnvName is the env name of this application revision // EnvName is the env name of this application revision
EnvName string `json:"envName"` EnvName string `json:"envName"`
// CodeInfo is the code info of this application revision // CodeInfo is the code info of this application revision
CodeInfo *CodeInfo `json:"codeInfo,omitempty"` CodeInfo *CodeInfo `json:"codeInfo,omitempty" gorm:"serializer:json"`
// ImageInfo is the image info of this application revision // ImageInfo is the image info of this application revision
ImageInfo *ImageInfo `json:"imageInfo,omitempty"` ImageInfo *ImageInfo `json:"imageInfo,omitempty" gorm:"serializer:json"`
} }
// CodeInfo is the code info for webhook request // CodeInfo is the code info for webhook request
@ -384,7 +384,7 @@ type ApplicationTrigger struct {
Name string `json:"name"` Name string `json:"name"`
Alias string `json:"alias,omitempty"` Alias string `json:"alias,omitempty"`
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
Token string `json:"token"` Token string `json:"token" gorm:"primaryKey"`
Type string `json:"type"` Type string `json:"type"`
PayloadType string `json:"payloadType"` PayloadType string `json:"payloadType"`
ComponentName string `json:"componentName"` ComponentName string `json:"componentName"`

View File

@ -53,14 +53,14 @@ var (
// Cluster describes the model of cluster in apiserver // Cluster describes the model of cluster in apiserver
type Cluster struct { type Cluster struct {
BaseModel BaseModel
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Description string `json:"description"` Description string `json:"description"`
Icon string `json:"icon"` Icon string `json:"icon"`
Labels map[string]string `json:"labels"` Labels map[string]string `json:"labels" gorm:"serializer:json"`
Status string `json:"status"` Status string `json:"status"`
Reason string `json:"reason"` Reason string `json:"reason"`
Provider ProviderInfo `json:"provider"` Provider ProviderInfo `json:"provider" gorm:"serializer:json"`
APIServerURL string `json:"apiServerURL"` APIServerURL string `json:"apiServerURL"`
DashboardURL string `json:"dashboardURL"` DashboardURL string `json:"dashboardURL"`
KubeConfig string `json:"kubeConfig"` KubeConfig string `json:"kubeConfig"`

View File

@ -23,7 +23,7 @@ func init() {
// Env models the data of env in database // Env models the data of env in database
type Env struct { type Env struct {
BaseModel BaseModel
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
@ -34,7 +34,7 @@ type Env struct {
// Targets defines the name of delivery target that belongs to this env // Targets defines the name of delivery target that belongs to this env
// In one project, a delivery target can only belong to one env. // In one project, a delivery target can only belong to one env.
Targets []string `json:"targets,omitempty"` Targets []string `json:"targets,omitempty" gorm:"serializer:json"`
} }
// TableName return custom table name // TableName return custom table name

View File

@ -25,10 +25,10 @@ func init() {
// EnvBinding application env binding // EnvBinding application env binding
type EnvBinding struct { type EnvBinding struct {
BaseModel BaseModel
AppPrimaryKey string `json:"appPrimaryKey"` AppPrimaryKey string `json:"appPrimaryKey" gorm:"primaryKey"`
AppDeployName string `json:"appDeployName"` AppDeployName string `json:"appDeployName"`
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
ComponentsPatch []ComponentPatch `json:"componentsPatchs"` ComponentsPatch []ComponentPatch `json:"componentsPatchs" gorm:"serializer:json"`
} }
// ComponentPatch Define differential patches for components in the environment. // ComponentPatch Define differential patches for components in the environment.

View File

@ -38,11 +38,11 @@ type WorkflowSpec struct {
// Pipeline is the model of pipeline // Pipeline is the model of pipeline
type Pipeline struct { type Pipeline struct {
BaseModel BaseModel
Spec WorkflowSpec Spec WorkflowSpec `gorm:"serializer:json"`
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Project string `json:"project"` Project string `json:"project" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Description string `json:"description"` Description string `json:"description"`
} }
// PrimaryKey return custom primary key // PrimaryKey return custom primary key
@ -81,9 +81,9 @@ type Value struct {
// PipelineContext is pipeline's context groups // PipelineContext is pipeline's context groups
type PipelineContext struct { type PipelineContext struct {
BaseModel BaseModel
PipelineName string `json:"pipelineName"` PipelineName string `json:"pipelineName" gorm:"primaryKey"`
ProjectName string `json:"projectName"` ProjectName string `json:"projectName" gorm:"primaryKey"`
Contexts map[string][]Value `json:"contexts"` Contexts map[string][]Value `json:"contexts" gorm:"serializer:json"`
} }
// TableName return custom table name // TableName return custom table name

View File

@ -23,10 +23,10 @@ func init() {
// PluginSetting save the setting data of the plugin // PluginSetting save the setting data of the plugin
type PluginSetting struct { type PluginSetting struct {
BaseModel BaseModel
ID string `json:"id"` ID string `json:"id" gorm:"primaryKey"`
Enabled bool `json:"enabled"` Enabled bool `json:"enabled"`
JSONData map[string]interface{} `json:"jsonData"` JSONData map[string]interface{} `json:"jsonData" gorm:"serializer:json"`
SecureJSONData map[string]interface{} `json:"secureJsonData"` SecureJSONData map[string]interface{} `json:"secureJsonData" gorm:"serializer:json"`
} }
// PrimaryKey return custom primary key // PrimaryKey return custom primary key

View File

@ -23,7 +23,7 @@ func init() {
// Project basic model // Project basic model
type Project struct { type Project struct {
BaseModel BaseModel
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Owner string `json:"owner"` Owner string `json:"owner"`
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`

View File

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

View File

@ -24,12 +24,12 @@ func init() {
// It includes kubernetes clusters or cloud service providers // It includes kubernetes clusters or cloud service providers
type Target struct { type Target struct {
BaseModel BaseModel
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias,omitempty"` Alias string `json:"alias,omitempty"`
Project string `json:"project"` Project string `json:"project"`
Description string `json:"description,omitempty"` Description string `json:"description,omitempty"`
Cluster *ClusterTarget `json:"cluster,omitempty"` Cluster *ClusterTarget `json:"cluster,omitempty" gorm:"serializer:json"`
Variable map[string]interface{} `json:"variable,omitempty"` Variable map[string]interface{} `json:"variable,omitempty" gorm:"serializer:json"`
} }
// TableName return custom table name // TableName return custom table name

View File

@ -40,14 +40,14 @@ const RoleAdmin = "admin"
// User is the model of user // User is the model of user
type User struct { type User struct {
BaseModel BaseModel
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Email string `json:"email"` Email string `json:"email"`
Alias string `json:"alias,omitempty"` Alias string `json:"alias,omitempty"`
Password string `json:"password,omitempty"` Password string `json:"password,omitempty"`
Disabled bool `json:"disabled"` Disabled bool `json:"disabled"`
LastLoginTime time.Time `json:"lastLoginTime,omitempty"` LastLoginTime time.Time `json:"lastLoginTime,omitempty" gorm:"default:'2020-01-01'"`
// UserRoles binding the platform level roles // UserRoles binding the platform level roles
UserRoles []string `json:"userRoles"` UserRoles []string `json:"userRoles" gorm:"serializer:json"`
DexSub string `json:"dexSub,omitempty"` DexSub string `json:"dexSub,omitempty"`
} }
@ -94,10 +94,10 @@ func (u *User) IsAdmin() bool {
// ProjectUser is the model of user in project // ProjectUser is the model of user in project
type ProjectUser struct { type ProjectUser struct {
BaseModel BaseModel
Username string `json:"username"` Username string `json:"username" gorm:"primaryKey"`
ProjectName string `json:"projectName"` ProjectName string `json:"projectName" gorm:"primaryKey"`
// UserRoles binding the project level roles // UserRoles binding the project level roles
UserRoles []string `json:"userRoles"` UserRoles []string `json:"userRoles" gorm:"serializer:json"`
} }
// TableName return custom table name // TableName return custom table name
@ -137,24 +137,24 @@ type CustomClaims struct {
// Role is a model for a new RBAC mode. // Role is a model for a new RBAC mode.
type Role struct { type Role struct {
BaseModel BaseModel
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Project string `json:"project,omitempty"` Project string `json:"project,omitempty"`
Permissions []string `json:"permissions"` Permissions []string `json:"permissions" gorm:"serializer:json"`
} }
// Permission is a model for a new RBAC mode. // Permission is a model for a new RBAC mode.
type Permission struct { type Permission struct {
BaseModel BaseModel
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Project string `json:"project,omitempty"` Project string `json:"project,omitempty" gorm:"primaryKey"`
Resources []string `json:"resources"` Resources []string `json:"resources" gorm:"serializer:json"`
Actions []string `json:"actions"` Actions []string `json:"actions" gorm:"serializer:json"`
// Effect option values: Allow,Deny // Effect option values: Allow,Deny
Effect string `json:"effect"` Effect string `json:"effect"`
Principal *Principal `json:"principal,omitempty"` Principal *Principal `json:"principal,omitempty" gorm:"serializer:json"`
Condition *Condition `json:"condition,omitempty"` Condition *Condition `json:"condition,omitempty" gorm:"serializer:json"`
} }
// Principal is a model for a new RBAC mode. // Principal is a model for a new RBAC mode.
@ -234,14 +234,14 @@ func (p *Permission) Index() map[string]interface{} {
// PermissionTemplate is a model for a new RBAC mode. // PermissionTemplate is a model for a new RBAC mode.
type PermissionTemplate struct { type PermissionTemplate struct {
BaseModel BaseModel
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
// Scope options: project or platform // Scope options: project or platform
Scope string `json:"scope"` Scope string `json:"scope"`
Resources []string `json:"resources"` Resources []string `json:"resources" gorm:"serializer:json"`
Actions []string `json:"actions"` Actions []string `json:"actions" gorm:"serializer:json"`
Effect string `json:"effect"` Effect string `json:"effect"`
Condition *Condition `json:"condition,omitempty"` Condition *Condition `json:"condition,omitempty" gorm:"serializer:json"`
} }
// TableName return custom table name // TableName return custom table name

View File

@ -37,15 +37,15 @@ const UnFinished = "false"
// Workflow application delivery database model // Workflow application delivery database model
type Workflow struct { type Workflow struct {
BaseModel BaseModel
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Alias string `json:"alias"` Alias string `json:"alias"`
Description string `json:"description"` Description string `json:"description"`
// Workflow used by the default // Workflow used by the default
Default *bool `json:"default"` Default *bool `json:"default"`
AppPrimaryKey string `json:"appPrimaryKey"` AppPrimaryKey string `json:"appPrimaryKey" gorm:"primaryKey"`
EnvName string `json:"envName"` EnvName string `json:"envName"`
Mode workflowv1alpha1.WorkflowExecuteMode `json:"mode,omitempty"` Mode workflowv1alpha1.WorkflowExecuteMode `json:"mode,omitempty" gorm:"serializer:json"`
Steps []WorkflowStep `json:"steps,omitempty"` Steps []WorkflowStep `json:"steps,omitempty" gorm:"serializer:json"`
} }
// WorkflowStep defines how to execute a workflow step. // WorkflowStep defines how to execute a workflow step.
@ -114,16 +114,16 @@ type WorkflowRecord struct {
AppPrimaryKey string `json:"appPrimaryKey"` AppPrimaryKey string `json:"appPrimaryKey"`
// RevisionPrimaryKey: should be assigned the version(PublishVersion) // RevisionPrimaryKey: should be assigned the version(PublishVersion)
RevisionPrimaryKey string `json:"revisionPrimaryKey"` RevisionPrimaryKey string `json:"revisionPrimaryKey"`
Name string `json:"name"` Name string `json:"name" gorm:"primaryKey"`
Namespace string `json:"namespace"` Namespace string `json:"namespace"`
StartTime time.Time `json:"startTime,omitempty"` StartTime time.Time `json:"startTime,omitempty" gorm:"default:'2020-01-01'"`
EndTime time.Time `json:"endTime,omitempty"` EndTime time.Time `json:"endTime,omitempty" gorm:"default:'2020-01-01'"`
Finished string `json:"finished"` Finished string `json:"finished"`
Steps []WorkflowStepStatus `json:"steps,omitempty"` Steps []WorkflowStepStatus `json:"steps,omitempty" gorm:"serializer:json"`
Status string `json:"status"` Status string `json:"status"`
Message string `json:"message"` Message string `json:"message"`
Mode string `json:"mode"` Mode string `json:"mode"`
ContextValue map[string]string `json:"contextValue,omitempty"` ContextValue map[string]string `json:"contextValue,omitempty" gorm:"serializer:json"`
} }
// WorkflowStepStatus is the workflow step status database model // WorkflowStepStatus is the workflow step status database model

View File

@ -63,10 +63,7 @@ func CreateEnv(ctx context.Context, kubeClient client.Client, ds datastore.DataS
klog.Errorf("update namespace label failure %s", err.Error()) klog.Errorf("update namespace label failure %s", err.Error())
return bcode.ErrEnvNamespaceFail return bcode.ErrEnvNamespaceFail
} }
if err = ds.Add(ctx, env); err != nil { return ds.Add(ctx, env)
return err
}
return nil
} }
// GetEnv get the environment // GetEnv get the environment

View File

@ -23,7 +23,7 @@ import (
"testing" "testing"
"time" "time"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
@ -52,7 +52,7 @@ func TestService(t *testing.T) {
RunSpecs(t, "Service Suite") RunSpecs(t, "Service Suite")
} }
var _ = BeforeSuite(func(done Done) { var _ = BeforeSuite(func(ctx SpecContext) {
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
By("bootstrapping test environment") By("bootstrapping test environment")
@ -90,8 +90,8 @@ var _ = BeforeSuite(func(done Done) {
} else { } else {
Expect(err).Should(BeNil()) Expect(err).Should(BeNil())
} }
close(done)
}, 240) }, NodeTimeout(time.Minute))
var _ = AfterSuite(func() { var _ = AfterSuite(func() {
By("tearing down the test environment") By("tearing down the test environment")

View File

@ -44,7 +44,7 @@ func CreateTargetNamespace(ctx context.Context, k8sClient client.Client, cluster
} }
// DeleteTargetNamespace delete the namespace of the target // DeleteTargetNamespace delete the namespace of the target
func DeleteTargetNamespace(ctx context.Context, k8sClient client.Client, clusterName, namespace, targetName string) error { func DeleteTargetNamespace(ctx context.Context, k8sClient client.Client, clusterName, namespace string) error {
err := utils.UpdateNamespace(multicluster.ContextWithClusterName(ctx, clusterName), k8sClient, namespace, err := utils.UpdateNamespace(multicluster.ContextWithClusterName(ctx, clusterName), k8sClient, namespace,
utils.MergeOverrideLabels(map[string]string{ utils.MergeOverrideLabels(map[string]string{
oam.LabelRuntimeNamespaceUsage: "", oam.LabelRuntimeNamespaceUsage: "",

View File

@ -19,7 +19,7 @@ package repository
import ( import (
"context" "context"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/kubevela/velaux/pkg/server/domain/model" "github.com/kubevela/velaux/pkg/server/domain/model"

View File

@ -23,6 +23,8 @@ import (
"fmt" "fmt"
"strings" "strings"
"github.com/kubevela/velaux/pkg/server/utils"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1" workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
k8stypes "k8s.io/apimachinery/pkg/types" k8stypes "k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2" "k8s.io/klog/v2"
@ -289,7 +291,7 @@ func compareWorkflowSteps(old, new steps) steps {
} }
} }
_, needDeleted, needAdded := pkgUtils.ThreeWaySliceCompare(oldTargets, newTargets) _, needDeleted, needAdded := utils.ThreeWaySliceCompare(oldTargets, newTargets)
var workflowSteps []*workflowStep var workflowSteps []*workflowStep
var deployCloudResourcePolicyExist = false var deployCloudResourcePolicyExist = false
@ -298,7 +300,7 @@ func compareWorkflowSteps(old, new steps) steps {
var deletedPolicyCount = 0 var deletedPolicyCount = 0
for i := range oldStep.policies { for i := range oldStep.policies {
p := oldStep.policies[i] p := oldStep.policies[i]
if pkgUtils.SliceIncludeSlice(needDeleted, cacheTarget(oldStep.stepType, p.targets)) { if utils.SliceIncludeSlice(needDeleted, cacheTarget(oldStep.stepType, p.targets)) {
p.state = deleteState p.state = deleteState
deletedPolicyCount++ deletedPolicyCount++
} }
@ -317,7 +319,7 @@ func compareWorkflowSteps(old, new steps) steps {
newStep := new[j] newStep := new[j]
for i := range newStep.policies { for i := range newStep.policies {
p := newStep.policies[i] p := newStep.policies[i]
if pkgUtils.SliceIncludeSlice(needAdded, cacheTarget(newStep.stepType, p.targets)) { if utils.SliceIncludeSlice(needAdded, cacheTarget(newStep.stepType, p.targets)) {
if p.policyType == v1alpha1.EnvBindingPolicyType && deployCloudResourcePolicyExist { if p.policyType == v1alpha1.EnvBindingPolicyType && deployCloudResourcePolicyExist {
p.state = updateState p.state = updateState
} else { } else {

View File

@ -21,7 +21,7 @@ import (
"fmt" "fmt"
"testing" "testing"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@ -24,7 +24,7 @@ import (
"github.com/oam-dev/kubevela/pkg/oam/util" "github.com/oam-dev/kubevela/pkg/oam/util"
"github.com/oam-dev/kubevela/pkg/utils/schema" "github.com/oam-dev/kubevela/pkg/utils/schema"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@ -26,6 +26,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/kubevela/pkg/util/slices"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1" workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
@ -42,9 +43,8 @@ import (
"github.com/oam-dev/kubevela/pkg/appfile" "github.com/oam-dev/kubevela/pkg/appfile"
"github.com/oam-dev/kubevela/pkg/appfile/dryrun" "github.com/oam-dev/kubevela/pkg/appfile/dryrun"
"github.com/oam-dev/kubevela/pkg/oam" "github.com/oam-dev/kubevela/pkg/oam"
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
pkgUtils "github.com/oam-dev/kubevela/pkg/utils" pkgUtils "github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/app" appUtil "github.com/oam-dev/kubevela/pkg/utils/app"
"github.com/oam-dev/kubevela/pkg/utils/apply" "github.com/oam-dev/kubevela/pkg/utils/apply"
commonutil "github.com/oam-dev/kubevela/pkg/utils/common" commonutil "github.com/oam-dev/kubevela/pkg/utils/common"
@ -211,7 +211,7 @@ func (c *applicationServiceImpl) ListApplications(ctx context.Context, listOptio
return []*apisv1.ApplicationBase{}, nil return []*apisv1.ApplicationBase{}, nil
} }
if len(listOptions.Projects) > 0 { if len(listOptions.Projects) > 0 {
if !pkgUtils.SliceIncludeSlice(availableProjectNames, listOptions.Projects) { if !utils.SliceIncludeSlice(availableProjectNames, listOptions.Projects) {
return []*apisv1.ApplicationBase{}, nil return []*apisv1.ApplicationBase{}, nil
} }
} }
@ -389,8 +389,8 @@ func (c *applicationServiceImpl) GetApplicationCR(ctx context.Context, appModel
return apps, nil return apps, nil
} }
// PublishApplicationTemplate publish app template // PublishApplicationTemplate publish appUtil template
func (c *applicationServiceImpl) PublishApplicationTemplate(ctx context.Context, app *model.Application) (*apisv1.ApplicationTemplateBase, error) { func (c *applicationServiceImpl) PublishApplicationTemplate(_ context.Context, _ *model.Application) (*apisv1.ApplicationTemplateBase, error) {
// TODO: // TODO:
return nil, nil return nil, nil
} }
@ -404,7 +404,7 @@ func (c *applicationServiceImpl) CreateApplication(ctx context.Context, req apis
Icon: req.Icon, Icon: req.Icon,
Labels: req.Labels, Labels: req.Labels,
} }
// check app name. // check appUtil name.
exist, err := c.Store.IsExist(ctx, &application) exist, err := c.Store.IsExist(ctx, &application)
if err != nil { if err != nil {
klog.Errorf("check application name is exist failure %s", err.Error()) klog.Errorf("check application name is exist failure %s", err.Error())
@ -450,7 +450,7 @@ func (c *applicationServiceImpl) CreateApplication(ctx context.Context, req apis
} }
return nil, err return nil, err
} }
// render app base info. // render appUtil base info.
base := assembler.ConvertAppModelToBase(&application, []*apisv1.ProjectBase{project}) base := assembler.ConvertAppModelToBase(&application, []*apisv1.ProjectBase{project})
return base, nil return base, nil
} }
@ -499,7 +499,7 @@ func (c *applicationServiceImpl) DeleteApplicationTrigger(ctx context.Context, a
if errors.Is(err, datastore.ErrRecordNotExist) { if errors.Is(err, datastore.ErrRecordNotExist) {
return bcode.ErrApplicationTriggerNotExist return bcode.ErrApplicationTriggerNotExist
} }
klog.Warningf("delete app trigger failure %s", err.Error()) klog.Warningf("delete appUtil trigger failure %s", err.Error())
return err return err
} }
return nil return nil
@ -515,7 +515,7 @@ func (c *applicationServiceImpl) UpdateApplicationTrigger(ctx context.Context, a
if errors.Is(err, datastore.ErrRecordNotExist) { if errors.Is(err, datastore.ErrRecordNotExist) {
return nil, bcode.ErrApplicationTriggerNotExist return nil, bcode.ErrApplicationTriggerNotExist
} }
klog.Warningf("get app trigger failure %s", err.Error()) klog.Warningf("get appUtil trigger failure %s", err.Error())
return nil, err return nil, err
} }
// checking the workflow // checking the workflow
@ -655,7 +655,7 @@ func (c *applicationServiceImpl) ListRecords(ctx context.Context, appName string
return resp, nil return resp, nil
} }
func (c *applicationServiceImpl) ListComponents(ctx context.Context, app *model.Application, op apisv1.ListApplicationComponentOptions) ([]*apisv1.ComponentBase, error) { func (c *applicationServiceImpl) ListComponents(ctx context.Context, app *model.Application, _ apisv1.ListApplicationComponentOptions) ([]*apisv1.ComponentBase, error) {
var component = model.ApplicationComponent{ var component = model.ApplicationComponent{
AppPrimaryKey: app.PrimaryKey(), AppPrimaryKey: app.PrimaryKey(),
} }
@ -681,7 +681,7 @@ func (c *applicationServiceImpl) ListComponents(ctx context.Context, app *model.
return list, nil return list, nil
} }
// DetailComponent detail app component // DetailComponent detail appUtil component
func (c *applicationServiceImpl) DetailComponent(ctx context.Context, app *model.Application, compName string) (*apisv1.DetailComponentResponse, error) { func (c *applicationServiceImpl) DetailComponent(ctx context.Context, app *model.Application, compName string) (*apisv1.DetailComponentResponse, error) {
var component = model.ApplicationComponent{ var component = model.ApplicationComponent{
AppPrimaryKey: app.PrimaryKey(), AppPrimaryKey: app.PrimaryKey(),
@ -716,7 +716,7 @@ func (c *applicationServiceImpl) ListPolicies(ctx context.Context, app *model.Ap
return list, nil return list, nil
} }
// DetailPolicy detail app policy // DetailPolicy detail appUtil policy
func (c *applicationServiceImpl) DetailPolicy(ctx context.Context, app *model.Application, policyName string) (*apisv1.DetailPolicyResponse, error) { func (c *applicationServiceImpl) DetailPolicy(ctx context.Context, app *model.Application, policyName string) (*apisv1.DetailPolicyResponse, error) {
var policy = model.ApplicationPolicy{ var policy = model.ApplicationPolicy{
AppPrimaryKey: app.PrimaryKey(), AppPrimaryKey: app.PrimaryKey(),
@ -736,7 +736,7 @@ func (c *applicationServiceImpl) DetailPolicy(ctx context.Context, app *model.Ap
}, nil }, nil
} }
// Deploy deploys app to cluster // Deploy deploys appUtil to cluster
// means to render oam application config and apply to cluster. // means to render oam application config and apply to cluster.
// An event record is generated for each deploy. // An event record is generated for each deploy.
func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Application, req apisv1.ApplicationDeployRequest) (*apisv1.ApplicationDeployResponse, error) { func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Application, req apisv1.ApplicationDeployRequest) (*apisv1.ApplicationDeployResponse, error) {
@ -770,7 +770,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
list, err := c.Store.List(ctx, &lastVersion, &datastore.ListOptions{ list, err := c.Store.List(ctx, &lastVersion, &datastore.ListOptions{
PageSize: 1, Page: 1, SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}}}) PageSize: 1, Page: 1, SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}}})
if err != nil && !errors.Is(err, datastore.ErrRecordNotExist) { if err != nil && !errors.Is(err, datastore.ErrRecordNotExist) {
klog.Errorf("query app latest revision failure %s", err.Error()) klog.Errorf("query appUtil latest revision failure %s", err.Error())
return nil, bcode.ErrDeployConflict return nil, bcode.ErrDeployConflict
} }
if len(list) > 0 { if len(list) > 0 {
@ -788,7 +788,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
status = revision.Status status = revision.Status
} }
if status != model.RevisionStatusComplete && status != model.RevisionStatusTerminated && status != model.RevisionStatusFail { if status != model.RevisionStatusComplete && status != model.RevisionStatusTerminated && status != model.RevisionStatusFail {
klog.Warningf("last app revision can not complete %s/%s,the current status is %s", list[0].(*model.ApplicationRevision).AppPrimaryKey, list[0].(*model.ApplicationRevision).Version, status) klog.Warningf("last appUtil revision can not complete %s/%s,the current status is %s", list[0].(*model.ApplicationRevision).AppPrimaryKey, list[0].(*model.ApplicationRevision).Version, status)
return nil, bcode.ErrDeployConflict return nil, bcode.ErrDeployConflict
} }
} }
@ -830,7 +830,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
klog.Warningf("update deploy event failure %s", err.Error()) klog.Warningf("update deploy event failure %s", err.Error())
} }
klog.Errorf("deploy app %s failure %s", app.PrimaryKey(), err.Error()) klog.Errorf("deploy appUtil %s failure %s", app.PrimaryKey(), err.Error())
return nil, bcode.ErrDeployApplyFail return nil, bcode.ErrDeployApplyFail
} }
@ -840,10 +840,10 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
klog.Warningf("create workflow record failure %s", err.Error()) klog.Warningf("create workflow record failure %s", err.Error())
} }
// step6: update app revision status // step6: update appUtil revision status
appRevision.Status = model.RevisionStatusRunning appRevision.Status = model.RevisionStatusRunning
if err := c.Store.Put(ctx, appRevision); err != nil { if err := c.Store.Put(ctx, appRevision); err != nil {
klog.Warningf("update app revision failure %s", err.Error()) klog.Warningf("update appUtil revision failure %s", err.Error())
} }
// step7: change the source of trust // step7: change the source of trust
@ -852,7 +852,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
} }
app.Labels[velatypes.LabelSourceOfTruth] = velatypes.FromUX app.Labels[velatypes.LabelSourceOfTruth] = velatypes.FromUX
if err := c.Store.Put(ctx, app); err != nil { if err := c.Store.Put(ctx, app); err != nil {
klog.Warningf("failed to update app %s", err.Error()) klog.Warningf("failed to update appUtil %s", err.Error())
} }
res := &apisv1.ApplicationDeployResponse{ res := &apisv1.ApplicationDeployResponse{
@ -906,7 +906,7 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
if deployAppName == "" { if deployAppName == "" {
deployAppName = appModel.Name deployAppName = appModel.Name
} }
var app = &v1beta1.Application{ var application = &v1beta1.Application{
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
Kind: "Application", Kind: "Application",
APIVersion: "core.oam.dev/v1beta1", APIVersion: "core.oam.dev/v1beta1",
@ -926,8 +926,8 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
} }
for key, value := range appModel.Annotations { for key, value := range appModel.Annotations {
if _, exists := app.ObjectMeta.Annotations[key]; !exists { if _, exists := application.ObjectMeta.Annotations[key]; !exists {
app.ObjectMeta.Annotations[key] = value application.ObjectMeta.Annotations[key] = value
} }
} }
@ -936,7 +936,7 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
Name: appModel.Name, Name: appModel.Name,
Namespace: env.Namespace, Namespace: env.Namespace,
}, originalApp); err == nil { }, originalApp); err == nil {
app.ResourceVersion = originalApp.ResourceVersion application.ResourceVersion = originalApp.ResourceVersion
} }
var component = model.ApplicationComponent{ var component = model.ApplicationComponent{
@ -987,7 +987,7 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
if component.Properties != nil { if component.Properties != nil {
bc.Properties = component.Properties.RawExtension() bc.Properties = component.Properties.RawExtension()
} }
app.Spec.Components = append(app.Spec.Components, bc) application.Spec.Components = append(application.Spec.Components, bc)
} }
for _, policy := range policies { for _, policy := range policies {
@ -998,10 +998,10 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
if policy.Properties != nil { if policy.Properties != nil {
appPolicy.Properties = policy.Properties.RawExtension() appPolicy.Properties = policy.Properties.RawExtension()
} }
app.Spec.Policies = append(app.Spec.Policies, appPolicy) application.Spec.Policies = append(application.Spec.Policies, appPolicy)
} }
if workflow != nil { if workflow != nil {
app.Annotations[oam.AnnotationWorkflowName] = workflow.Name application.Annotations[oam.AnnotationWorkflowName] = workflow.Name
var steps []workflowv1alpha1.WorkflowStep var steps []workflowv1alpha1.WorkflowStep
for _, step := range workflow.Steps { for _, step := range workflow.Steps {
workflowStep := workflowv1alpha1.WorkflowStep{ workflowStep := workflowv1alpha1.WorkflowStep{
@ -1013,12 +1013,12 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
} }
steps = append(steps, workflowStep) steps = append(steps, workflowStep)
} }
app.Spec.Workflow = &v1beta1.Workflow{ application.Spec.Workflow = &v1beta1.Workflow{
Steps: steps, Steps: steps,
Mode: &workflow.Mode, Mode: &workflow.Mode,
} }
} }
return app, nil return application, nil
} }
func convertWorkflowModel2WorkflowSpec(step model.WorkflowStepBase) workflowv1alpha1.WorkflowStepBase { func convertWorkflowModel2WorkflowSpec(step model.WorkflowStepBase) workflowv1alpha1.WorkflowStepBase {
@ -1089,32 +1089,32 @@ func (c *applicationServiceImpl) DeleteApplication(ctx context.Context, app *mod
for _, component := range components { for _, component := range components {
err := c.Store.Delete(ctx, &model.ApplicationComponent{AppPrimaryKey: app.PrimaryKey(), Name: component.Name}) err := c.Store.Delete(ctx, &model.ApplicationComponent{AppPrimaryKey: app.PrimaryKey(), Name: component.Name})
if err != nil && !errors.Is(err, datastore.ErrRecordNotExist) { if err != nil && !errors.Is(err, datastore.ErrRecordNotExist) {
klog.Errorf("delete component %s in app %s failure %s", component.Name, app.Name, err.Error()) klog.Errorf("delete component %s in appUtil %s failure %s", component.Name, app.Name, err.Error())
} }
} }
for _, policy := range policies { for _, policy := range policies {
err := c.Store.Delete(ctx, &model.ApplicationPolicy{AppPrimaryKey: app.PrimaryKey(), Name: policy.Name}) err := c.Store.Delete(ctx, &model.ApplicationPolicy{AppPrimaryKey: app.PrimaryKey(), Name: policy.Name})
if err != nil && errors.Is(err, datastore.ErrRecordNotExist) { if err != nil && errors.Is(err, datastore.ErrRecordNotExist) {
klog.Errorf("delete policy %s in app %s failure %s", policy.Name, app.Name, err.Error()) klog.Errorf("delete policy %s in appUtil %s failure %s", policy.Name, app.Name, err.Error())
} }
} }
for _, entity := range revisions { for _, entity := range revisions {
revision := entity.(*model.ApplicationRevision) revision := entity.(*model.ApplicationRevision)
if err := c.Store.Delete(ctx, &model.ApplicationRevision{AppPrimaryKey: app.PrimaryKey(), Version: revision.Version}); err != nil { if err := c.Store.Delete(ctx, &model.ApplicationRevision{AppPrimaryKey: app.PrimaryKey(), Version: revision.Version}); err != nil {
klog.Errorf("delete revision %s in app %s failure %s", revision.Version, app.Name, err.Error()) klog.Errorf("delete revision %s in appUtil %s failure %s", revision.Version, app.Name, err.Error())
} }
} }
for _, trigger := range triggers { for _, trigger := range triggers {
if err := c.Store.Delete(ctx, &model.ApplicationTrigger{AppPrimaryKey: app.PrimaryKey(), Name: trigger.Name, Token: trigger.Token}); err != nil { if err := c.Store.Delete(ctx, &model.ApplicationTrigger{AppPrimaryKey: app.PrimaryKey(), Name: trigger.Name, Token: trigger.Token}); err != nil {
klog.Errorf("delete trigger %s in app %s failure %s", trigger.Name, app.Name, err.Error()) klog.Errorf("delete trigger %s in appUtil %s failure %s", trigger.Name, app.Name, err.Error())
} }
} }
if err := c.EnvBindingService.BatchDeleteEnvBinding(ctx, app); err != nil { if err := c.EnvBindingService.BatchDeleteEnvBinding(ctx, app); err != nil {
klog.Errorf("delete envbindings in app %s failure %s", app.Name, err.Error()) klog.Errorf("delete envbindings in appUtil %s failure %s", app.Name, err.Error())
} }
return c.Store.Delete(ctx, app) return c.Store.Delete(ctx, app)
@ -1135,7 +1135,7 @@ func (c *applicationServiceImpl) GetApplicationComponent(ctx context.Context, ap
return &component, nil return &component, nil
} }
func (c *applicationServiceImpl) UpdateComponent(ctx context.Context, app *model.Application, component *model.ApplicationComponent, req apisv1.UpdateApplicationComponentRequest) (*apisv1.ComponentBase, error) { func (c *applicationServiceImpl) UpdateComponent(ctx context.Context, _ *model.Application, component *model.ApplicationComponent, req apisv1.UpdateApplicationComponentRequest) (*apisv1.ComponentBase, error) {
if req.Alias != nil { if req.Alias != nil {
component.Alias = *req.Alias component.Alias = *req.Alias
} }
@ -1223,7 +1223,7 @@ func (c *applicationServiceImpl) createComponent(ctx context.Context, app *model
if errors.Is(err, datastore.ErrRecordExist) { if errors.Is(err, datastore.ErrRecordExist) {
return nil, bcode.ErrApplicationComponentExist return nil, bcode.ErrApplicationComponentExist
} }
klog.Warningf("add component for app %s failure %s", pkgUtils.Sanitize(app.PrimaryKey()), err.Error()) klog.Warningf("add component for appUtil %s failure %s", pkgUtils.Sanitize(app.PrimaryKey()), err.Error())
return nil, err return nil, err
} }
// update the env workflow, the automatically generated workflow is determined by the component type. // update the env workflow, the automatically generated workflow is determined by the component type.
@ -1264,7 +1264,7 @@ func (c *applicationServiceImpl) DeleteComponent(ctx context.Context, app *model
if errors.Is(err, datastore.ErrRecordNotExist) { if errors.Is(err, datastore.ErrRecordNotExist) {
return bcode.ErrApplicationComponentNotExist return bcode.ErrApplicationComponentNotExist
} }
klog.Warningf("delete app component %s failure %s", app.PrimaryKey(), err.Error()) klog.Warningf("delete appUtil component %s failure %s", app.PrimaryKey(), err.Error())
return err return err
} }
if err := repository.UpdateAppEnvWorkflow(ctx, c.KubeClient, c.Store, app); err != nil { if err := repository.UpdateAppEnvWorkflow(ctx, c.KubeClient, c.Store, app); err != nil {
@ -1293,7 +1293,7 @@ func (c *applicationServiceImpl) CreatePolicy(ctx context.Context, app *model.Ap
if errors.Is(err, datastore.ErrRecordExist) { if errors.Is(err, datastore.ErrRecordExist) {
return nil, bcode.ErrApplicationPolicyExist return nil, bcode.ErrApplicationPolicyExist
} }
klog.Warningf("add policy for app %s failure %s", app.PrimaryKey(), err.Error()) klog.Warningf("add policy for appUtil %s failure %s", app.PrimaryKey(), err.Error())
return nil, err return nil, err
} }
if err = c.handlePolicyBindingWorkflowStep(ctx, app, createPolicy.Name, createPolicy.WorkflowPolicyBindings); err != nil { if err = c.handlePolicyBindingWorkflowStep(ctx, app, createPolicy.Name, createPolicy.WorkflowPolicyBindings); err != nil {
@ -1320,7 +1320,7 @@ func (c *applicationServiceImpl) DeletePolicy(ctx context.Context, app *model.Ap
if errors.Is(err, datastore.ErrRecordNotExist) { if errors.Is(err, datastore.ErrRecordNotExist) {
return bcode.ErrApplicationPolicyNotExist return bcode.ErrApplicationPolicyNotExist
} }
klog.Warningf("delete app policy %s failure %s", app.PrimaryKey(), err.Error()) klog.Warningf("delete appUtil policy %s failure %s", app.PrimaryKey(), err.Error())
return err return err
} }
return c.handlePolicyBindingWorkflowStep(ctx, app, policyName, nil) return c.handlePolicyBindingWorkflowStep(ctx, app, policyName, nil)
@ -1336,7 +1336,7 @@ func (c *applicationServiceImpl) UpdatePolicy(ctx context.Context, app *model.Ap
if errors.Is(err, datastore.ErrRecordNotExist) { if errors.Is(err, datastore.ErrRecordNotExist) {
return nil, bcode.ErrApplicationPolicyNotExist return nil, bcode.ErrApplicationPolicyNotExist
} }
klog.Warningf("update app policy %s failure %s", app.PrimaryKey(), err.Error()) klog.Warningf("update appUtil policy %s failure %s", app.PrimaryKey(), err.Error())
return nil, err return nil, err
} }
policy.Type = policyUpdate.Type policy.Type = policyUpdate.Type
@ -1397,10 +1397,7 @@ func (c *applicationServiceImpl) DeleteApplicationTrait(ctx context.Context, app
for i, trait := range comp.Traits { for i, trait := range comp.Traits {
if trait.Type == traitType { if trait.Type == traitType {
comp.Traits = append(comp.Traits[:i], comp.Traits[i+1:]...) comp.Traits = append(comp.Traits[:i], comp.Traits[i+1:]...)
if err := c.Store.Put(ctx, &comp); err != nil { return c.Store.Put(ctx, &comp)
return err
}
return nil
} }
} }
return bcode.ErrTraitNotExist return bcode.ErrTraitNotExist
@ -1501,7 +1498,7 @@ func (c *applicationServiceImpl) Statistics(ctx context.Context, app *model.Appl
var targetMap = make(map[string]int) var targetMap = make(map[string]int)
envbinding, err := c.EnvBindingService.GetEnvBindings(ctx, app) envbinding, err := c.EnvBindingService.GetEnvBindings(ctx, app)
if err != nil { if err != nil {
klog.Errorf("query app envbinding failure %s", err.Error()) klog.Errorf("query appUtil envbinding failure %s", err.Error())
} }
for _, env := range envbinding { for _, env := range envbinding {
for _, target := range env.TargetNames { for _, target := range env.TargetNames {
@ -1558,7 +1555,7 @@ func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model
} }
base, envNameByRevision, err = c.getAppModelFromRevision(ctx, appModel.Name, revision) base, envNameByRevision, err = c.getAppModelFromRevision(ctx, appModel.Name, revision)
if err != nil { if err != nil {
klog.Errorf("failed to get the app model from the revision %s", err.Error()) klog.Errorf("failed to get the appUtil model from the revision %s", err.Error())
break break
} }
} }
@ -1611,7 +1608,7 @@ func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model
args.SetClient(c.KubeClient) args.SetClient(c.KubeClient)
diffResult, buff, err := compare(ctx, args, compareTarget, base) diffResult, buff, err := compare(ctx, args, compareTarget, base)
if err != nil { if err != nil {
klog.Errorf("fail to compare the app %s", err.Error()) klog.Errorf("fail to compare the appUtil %s", err.Error())
compareResponse.IsDiff = false compareResponse.IsDiff = false
return compareResponse, nil return compareResponse, nil
} }
@ -1620,7 +1617,7 @@ func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model
return compareResponse, nil return compareResponse, nil
} }
// ResetAppToLatestRevision reset app's component to last revision // ResetAppToLatestRevision reset appUtil's component to last revision
func (c *applicationServiceImpl) ResetAppToLatestRevision(ctx context.Context, appName string) (*apisv1.AppResetResponse, error) { func (c *applicationServiceImpl) ResetAppToLatestRevision(ctx context.Context, appName string) (*apisv1.AppResetResponse, error) {
targetApp, _, err := c.getAppModelFromRevision(ctx, appName, "") targetApp, _, err := c.getAppModelFromRevision(ctx, appName, "")
if err != nil { if err != nil {
@ -1672,12 +1669,13 @@ func (c *applicationServiceImpl) DryRunAppOrRevision(ctx context.Context, appMod
} }
func genWebhookToken() string { func genWebhookToken() string {
rand.Seed(time.Now().UnixNano()) source := rand.NewSource(time.Now().UnixNano()) //nolint:gosec
rng := rand.New(source) //nolint:gosec
runes := []rune("abcdefghijklmnopqrstuvwxyz0123456789") runes := []rune("abcdefghijklmnopqrstuvwxyz0123456789")
b := make([]rune, defaultTokenLen) b := make([]rune, defaultTokenLen)
for i := range b { for i := range b {
b[i] = runes[rand.Intn(len(runes))] // #nosec b[i] = runes[rng.Intn(len(runes))] //nolint:gosec
} }
return string(b) return string(b)
} }
@ -1714,9 +1712,9 @@ func (c *applicationServiceImpl) resetApp(ctx context.Context, targetApp *v1beta
targetCompNames = append(targetCompNames, comp.Name) targetCompNames = append(targetCompNames, comp.Name)
} }
readyToUpdate, readyToDelete, readyToAdd := pkgUtils.ThreeWaySliceCompare(originCompNames, targetCompNames) readyToUpdate, readyToDelete, readyToAdd := utils.ThreeWaySliceCompare(originCompNames, targetCompNames)
// delete new app's components // delete new appUtil's components
for _, compName := range readyToDelete { for _, compName := range readyToDelete {
var component = model.ApplicationComponent{ var component = model.ApplicationComponent{
AppPrimaryKey: appPrimaryKey, AppPrimaryKey: appPrimaryKey,
@ -1726,13 +1724,13 @@ func (c *applicationServiceImpl) resetApp(ctx context.Context, targetApp *v1beta
if errors.Is(err, datastore.ErrRecordNotExist) { if errors.Is(err, datastore.ErrRecordNotExist) {
continue continue
} }
klog.Warningf("delete app %s comp %s failure %s", appPrimaryKey, compName, err.Error()) klog.Warningf("delete appUtil %s comp %s failure %s", appPrimaryKey, compName, err.Error())
} }
} }
for _, comp := range targetComps { for _, comp := range targetComps {
// add or update new app's components from old app // add or update new appUtil's components from old appUtil
if pkgUtils.StringsContain(readyToAdd, comp.Name) || pkgUtils.StringsContain(readyToUpdate, comp.Name) { if slices.Contains(readyToAdd, comp.Name) || slices.Contains(readyToUpdate, comp.Name) {
compModel, err := convert.FromCRComponent(appPrimaryKey, comp) compModel, err := convert.FromCRComponent(appPrimaryKey, comp)
if err != nil { if err != nil {
return &apisv1.AppResetResponse{}, bcode.ErrInvalidProperties return &apisv1.AppResetResponse{}, bcode.ErrInvalidProperties
@ -1746,11 +1744,11 @@ func (c *applicationServiceImpl) resetApp(ctx context.Context, targetApp *v1beta
if errors.Is(err, datastore.ErrRecordExist) { if errors.Is(err, datastore.ErrRecordExist) {
err := c.Store.Put(ctx, &compModel) err := c.Store.Put(ctx, &compModel)
if err != nil { if err != nil {
klog.Warningf("update comp %s for app %s failure %s", comp.Name, pkgUtils.Sanitize(appPrimaryKey), err.Error()) klog.Warningf("update comp %s for appUtil %s failure %s", comp.Name, pkgUtils.Sanitize(appPrimaryKey), err.Error())
} }
return &apisv1.AppResetResponse{IsReset: true}, err return &apisv1.AppResetResponse{IsReset: true}, err
} }
klog.Warningf("add comp %s for app %s failure %s", comp.Name, pkgUtils.Sanitize(appPrimaryKey), err.Error()) klog.Warningf("add comp %s for appUtil %s failure %s", comp.Name, pkgUtils.Sanitize(appPrimaryKey), err.Error())
return &apisv1.AppResetResponse{}, err return &apisv1.AppResetResponse{}, err
} }
} }
@ -1782,12 +1780,12 @@ func (c *applicationServiceImpl) RollbackWithRevision(ctx context.Context, appli
if err := c.Store.Put(ctx, &revision); err != nil { if err := c.Store.Put(ctx, &revision); err != nil {
return nil, err return nil, err
} }
_, appCR, err := app.RollbackApplicationWithRevision(context.WithValue(ctx, &app.RevisionContextKey, utils.WithProject(ctx, "")), c.KubeClient, appCR.Name, appCR.Namespace, revision.RevisionCRName, publishVersion) _, appCR, err := appUtil.RollbackApplicationWithRevision(context.WithValue(ctx, &appUtil.RevisionContextKey, utils.WithProject(ctx, "")), c.KubeClient, appCR.Name, appCR.Namespace, revision.RevisionCRName, publishVersion)
if err != nil { if err != nil {
switch { switch {
case errors.Is(err, app.ErrNotMatchRevision): case errors.Is(err, appUtil.ErrNotMatchRevision):
noRevision = true noRevision = true
case errors.Is(err, app.ErrRevisionNotChange): case errors.Is(err, appUtil.ErrRevisionNotChange):
return nil, bcode.ErrApplicationRevisionConflict return nil, bcode.ErrApplicationRevisionConflict
default: default:
revision.RevisionCRName = revisionCRName revision.RevisionCRName = revisionCRName
@ -1815,7 +1813,7 @@ func (c *applicationServiceImpl) RollbackWithRevision(ctx context.Context, appli
} }
err = c.Apply.Apply(ctx, rollBackApp) err = c.Apply.Apply(ctx, rollBackApp)
if err != nil { if err != nil {
klog.Errorf("rollback the app %s failure %s", application.PrimaryKey(), err.Error()) klog.Errorf("rollback the appUtil %s failure %s", application.PrimaryKey(), err.Error())
return nil, err return nil, err
} }
rollbackApplication = rollBackApp rollbackApplication = rollBackApp
@ -1845,7 +1843,7 @@ func dryRunApplication(ctx context.Context, c commonutil.Args, app *v1beta1.Appl
} }
result, err := yaml.Marshal(app) result, err := yaml.Marshal(app)
if err != nil { if err != nil {
return buff, fmt.Errorf("marshal app: %w", err) return buff, fmt.Errorf("marshal appUtil: %w", err)
} }
buff.Write(result) buff.Write(result)
@ -1862,11 +1860,7 @@ func dryRunApplication(ctx context.Context, c commonutil.Args, app *v1beta1.Appl
if err != nil { if err != nil {
return buff, err return buff, err
} }
dm, err := discoverymapper.New(config) dryRunOpt := dryrun.NewDryRunOption(newClient, config, pd, objects, true)
if err != nil {
return buff, err
}
dryRunOpt := dryrun.NewDryRunOption(newClient, config, dm, pd, objects, true)
dryRunOpt.GenerateAppFile = func(ctx context.Context, app *v1beta1.Application) (*appfile.Appfile, error) { dryRunOpt.GenerateAppFile = func(ctx context.Context, app *v1beta1.Application) (*appfile.Appfile, error) {
generateCtx := utils.WithProject(ctx, "") generateCtx := utils.WithProject(ctx, "")
return dryRunOpt.Parser.GenerateAppFileFromApp(generateCtx, app) return dryRunOpt.Parser.GenerateAppFileFromApp(generateCtx, app)
@ -1881,7 +1875,7 @@ func dryRunApplication(ctx context.Context, c commonutil.Args, app *v1beta1.Appl
return buff, nil return buff, nil
} }
// ignoreSomeParams ignore some parameters before comparing the app changes. // ignoreSomeParams ignore some parameters before comparing the appUtil changes.
// ignore the workflow spec // ignore the workflow spec
func ignoreSomeParams(o *v1beta1.Application) { func ignoreSomeParams(o *v1beta1.Application) {
var defaultApplication = v1beta1.Application{} var defaultApplication = v1beta1.Application{}
@ -1912,16 +1906,12 @@ func compare(ctx context.Context, c commonutil.Args, targetApp *v1beta1.Applicat
if err != nil { if err != nil {
return nil, buff, err return nil, buff, err
} }
dm, err := discoverymapper.New(config)
if err != nil {
return nil, buff, err
}
var objs []oam.Object var objs []oam.Object
client, err := c.GetClient() client, err := c.GetClient()
if err != nil { if err != nil {
return nil, buff, err return nil, buff, err
} }
liveDiffOption := dryrun.NewLiveDiffOption(client, config, dm, pd, objs) liveDiffOption := dryrun.NewLiveDiffOption(client, config, pd, objs)
diffResult, err := liveDiffOption.DiffApps(ctx, baseApp, targetApp) diffResult, err := liveDiffOption.DiffApps(ctx, baseApp, targetApp)
if err != nil { if err != nil {
return nil, buff, err return nil, buff, err

View File

@ -28,7 +28,7 @@ import (
"github.com/google/go-cmp/cmp/cmpopts" "github.com/google/go-cmp/cmp/cmpopts"
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1" workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
wfTypes "github.com/kubevela/workflow/pkg/types" wfTypes "github.com/kubevela/workflow/pkg/types"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@ -211,7 +211,7 @@ func (a *authenticationServiceImpl) generateJWTToken(username, grantType string,
return token.SignedString([]byte(signedKey)) return token.SignedString([]byte(signedKey))
} }
func (a *authenticationServiceImpl) RefreshToken(ctx context.Context, refreshToken string) (*apisv1.RefreshTokenResponse, error) { func (a *authenticationServiceImpl) RefreshToken(_ context.Context, refreshToken string) (*apisv1.RefreshTokenResponse, error) {
claim, err := ParseToken(refreshToken) claim, err := ParseToken(refreshToken)
if err != nil { if err != nil {
if errors.Is(err, bcode.ErrTokenExpired) { if errors.Is(err, bcode.ErrTokenExpired) {
@ -235,7 +235,7 @@ func (a *authenticationServiceImpl) RefreshToken(ctx context.Context, refreshTok
// ParseToken parses and verifies a token // ParseToken parses and verifies a token
func ParseToken(tokenString string) (*model.CustomClaims, error) { func ParseToken(tokenString string) (*model.CustomClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &model.CustomClaims{}, func(token *jwt.Token) (interface{}, error) { token, err := jwt.ParseWithClaims(tokenString, &model.CustomClaims{}, func(token *jwt.Token) (interface{}, error) { //nolint:revive,unused
return []byte(signedKey), nil return []byte(signedKey), nil
}) })
if err != nil { if err != nil {
@ -449,6 +449,14 @@ func (a *authenticationServiceImpl) GetLoginType(ctx context.Context) (*apisv1.G
}, nil }, nil
} }
func getUserName(sub string) string {
username := strings.ToLower(sub)
if len(sub) > datastore.PrimaryKeyMaxLength {
return sub[:datastore.PrimaryKeyMaxLength]
}
return username
}
func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) { func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) {
var claims struct { var claims struct {
Email string `json:"email"` Email string `json:"email"`
@ -492,14 +500,8 @@ func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) {
klog.Errorf("failed to get the system info %s", err.Error()) klog.Errorf("failed to get the system info %s", err.Error())
} }
user := &model.User{ user := &model.User{
Email: claims.Email, Email: claims.Email,
Name: func() string { Name: getUserName(claims.Sub),
sub := strings.ToLower(claims.Sub)
if len(sub) > datastore.PrimaryKeyMaxLength {
return sub[:datastore.PrimaryKeyMaxLength]
}
return sub
}(),
DexSub: claims.Sub, DexSub: claims.Sub,
Alias: claims.Name, Alias: claims.Name,
LastLoginTime: time.Now(), LastLoginTime: time.Now(),
@ -514,7 +516,7 @@ func (d *dexHandlerImpl) login(ctx context.Context) (*apisv1.UserBase, error) {
if systemInfo != nil { if systemInfo != nil {
for _, project := range systemInfo.DexUserDefaultProjects { for _, project := range systemInfo.DexUserDefaultProjects {
_, err := d.projectService.AddProjectUser(ctx, project.Name, apisv1.AddProjectUserRequest{ _, err := d.projectService.AddProjectUser(ctx, project.Name, apisv1.AddProjectUserRequest{
UserName: strings.ToLower(claims.Sub), UserName: getUserName(claims.Sub),
UserRoles: project.Roles, UserRoles: project.Roles,
}) })
if err != nil { if err != nil {

View File

@ -31,7 +31,7 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/oam-dev/kubevela/pkg/multicluster" "github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/oam" "github.com/oam-dev/kubevela/pkg/oam"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@ -26,6 +26,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/kubevela/pkg/util/slices"
"github.com/kubevela/velaux/pkg/server/infrastructure/datastore" "github.com/kubevela/velaux/pkg/server/infrastructure/datastore"
"github.com/cloudtty/cloudtty/pkg/apis/cloudshell/v1alpha1" "github.com/cloudtty/cloudtty/pkg/apis/cloudshell/v1alpha1"
@ -43,7 +45,6 @@ import (
kubevelatypes "github.com/oam-dev/kubevela/apis/types" kubevelatypes "github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/auth" "github.com/oam-dev/kubevela/pkg/auth"
pkgutils "github.com/oam-dev/kubevela/pkg/utils"
"github.com/kubevela/velaux/pkg/server/domain/model" "github.com/kubevela/velaux/pkg/server/domain/model"
apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1" apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1"
@ -134,11 +135,11 @@ func (c *cloudShellServiceImpl) Prepare(ctx context.Context) (*apisv1.CloudShell
if err := c.prepareKubeConfig(ctx); err != nil { if err := c.prepareKubeConfig(ctx); err != nil {
return res, fmt.Errorf("failed to prepare the kubeconfig for the user: %w", err) return res, fmt.Errorf("failed to prepare the kubeconfig for the user: %w", err)
} }
new, err := c.newCloudShell(ctx) newCS, err := c.newCloudShell(ctx)
if err != nil { if err != nil {
return res, err return res, err
} }
if err := c.KubeClient.Create(ctx, new); err != nil { if err := c.KubeClient.Create(ctx, newCS); err != nil {
if meta.IsNoMatchError(err) { if meta.IsNoMatchError(err) {
return nil, bcode.ErrCloudShellAddonNotEnabled return nil, bcode.ErrCloudShellAddonNotEnabled
} }
@ -263,7 +264,7 @@ func (c *cloudShellServiceImpl) prepareKubeConfig(ctx context.Context) error {
} }
groups = append(groups, utils.TemplateReaderGroup) groups = append(groups, utils.TemplateReaderGroup)
if pkgutils.StringsContain(user.UserRoles, model.RoleAdmin) { if slices.Contains(user.UserRoles, model.RoleAdmin) {
groups = append(groups, utils.KubeVelaAdminGroupPrefix+"admin") groups = append(groups, utils.KubeVelaAdminGroupPrefix+"admin")
} }
@ -380,7 +381,7 @@ func (c *cloudShellServiceImpl) newCloudShell(ctx context.Context) (*v1alpha1.Cl
func checkReadOnly(projectName string, permissions []*model.Permission) bool { func checkReadOnly(projectName string, permissions []*model.Permission) bool {
ra := &RequestResourceAction{} ra := &RequestResourceAction{}
ra.SetResourceWithName("project:{projectName}/application:*", func(name string) string { ra.SetResourceWithName("project:{projectName}/application:*", func(name string) string { //nolint:revive,unused
return projectName return projectName
}) })
ra.SetActions([]string{"deploy"}) ra.SetActions([]string{"deploy"})

View File

@ -22,11 +22,13 @@ import (
"os" "os"
"time" "time"
"github.com/kubevela/pkg/util/slices"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api" clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
v1alpha1 "github.com/cloudtty/cloudtty/pkg/apis/cloudshell/v1alpha1" v1alpha1 "github.com/cloudtty/cloudtty/pkg/apis/cloudshell/v1alpha1"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1" rbacv1 "k8s.io/api/rbac/v1"
@ -36,7 +38,6 @@ import (
kubevelatypes "github.com/oam-dev/kubevela/apis/types" kubevelatypes "github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/auth" "github.com/oam-dev/kubevela/pkg/auth"
pkgutils "github.com/oam-dev/kubevela/pkg/utils"
"github.com/kubevela/velaux/pkg/server/domain/model" "github.com/kubevela/velaux/pkg/server/domain/model"
apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1" apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1"
@ -131,8 +132,8 @@ var _ = Describe("Test cloudshell service function", func() {
var identity auth.Identity var identity auth.Identity
err = yaml.Unmarshal([]byte(cm.Data["identity"]), &identity) err = yaml.Unmarshal([]byte(cm.Data["identity"]), &identity)
Expect(err).Should(BeNil()) Expect(err).Should(BeNil())
Expect(pkgutils.StringsContain(identity.Groups, utils.KubeVelaAdminGroupPrefix+"admin")).Should(BeTrue()) Expect(slices.Contains(identity.Groups, utils.KubeVelaAdminGroupPrefix+"admin")).Should(BeTrue())
Expect(pkgutils.StringsContain(identity.Groups, utils.TemplateReaderGroup)).Should(BeTrue()) Expect(slices.Contains(identity.Groups, utils.TemplateReaderGroup)).Should(BeTrue())
} }
checkConfig() checkConfig()

View File

@ -37,11 +37,11 @@ import (
"github.com/oam-dev/terraform-controller/api/types" "github.com/oam-dev/terraform-controller/api/types"
"github.com/oam-dev/terraform-controller/api/v1beta1" "github.com/oam-dev/terraform-controller/api/v1beta1"
"github.com/oam-dev/kubevela/pkg/cloudprovider"
"github.com/oam-dev/kubevela/pkg/multicluster" "github.com/oam-dev/kubevela/pkg/multicluster"
"github.com/oam-dev/kubevela/pkg/utils" "github.com/oam-dev/kubevela/pkg/utils"
"github.com/oam-dev/kubevela/pkg/utils/util" "github.com/oam-dev/kubevela/pkg/utils/util"
"github.com/kubevela/velaux/pkg/cloudprovider"
"github.com/kubevela/velaux/pkg/server/domain/model" "github.com/kubevela/velaux/pkg/server/domain/model"
"github.com/kubevela/velaux/pkg/server/infrastructure/clients" "github.com/kubevela/velaux/pkg/server/infrastructure/clients"
"github.com/kubevela/velaux/pkg/server/infrastructure/datastore" "github.com/kubevela/velaux/pkg/server/infrastructure/datastore"
@ -492,7 +492,7 @@ func (c *clusterServiceImpl) getClusterResourceInfoFromK8s(ctx context.Context,
return clusterResourceInfo, nil return clusterResourceInfo, nil
} }
func (c *clusterServiceImpl) ListCloudClusters(ctx context.Context, provider string, req apis.AccessKeyRequest, pageNumber int, pageSize int) (*apis.ListCloudClusterResponse, error) { func (c *clusterServiceImpl) ListCloudClusters(_ context.Context, provider string, req apis.AccessKeyRequest, pageNumber int, pageSize int) (*apis.ListCloudClusterResponse, error) {
p, err := cloudprovider.GetClusterProvider(provider, req.AccessKeyID, req.AccessKeySecret, c.K8sClient) p, err := cloudprovider.GetClusterProvider(provider, req.AccessKeyID, req.AccessKeySecret, c.K8sClient)
if err != nil { if err != nil {
klog.Errorf("failed to get cluster provider: %s", err.Error()) klog.Errorf("failed to get cluster provider: %s", err.Error())

View File

@ -20,7 +20,7 @@ import (
"context" "context"
"time" "time"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

View File

@ -48,6 +48,17 @@ type ConfigService interface {
ListConfigDistributions(ctx context.Context, project string) ([]*config.Distribution, error) ListConfigDistributions(ctx context.Context, project string) ([]*config.Distribution, error)
} }
var (
// GlobalConfigNamespace is the namespace for global config, global config should be seen by all projects
GlobalConfigNamespace = types.DefaultKubeVelaNS
// NoProject is the project name to pass when query global config
NoProject = ""
)
func isGlobal(project string) bool {
return project == NoProject
}
// NewConfigService returns a config use case // NewConfigService returns a config use case
func NewConfigService() ConfigService { func NewConfigService() ConfigService {
return &configServiceImpl{} return &configServiceImpl{}
@ -62,8 +73,8 @@ type configServiceImpl struct {
// ListTemplates list the config templates // ListTemplates list the config templates
func (u *configServiceImpl) ListTemplates(ctx context.Context, project, scope string) ([]*apis.ConfigTemplate, error) { func (u *configServiceImpl) ListTemplates(ctx context.Context, project, scope string) ([]*apis.ConfigTemplate, error) {
listCtx := utils.WithProject(ctx, "") listCtx := utils.WithProject(ctx, NoProject)
queryTemplates, err := u.Factory.ListTemplates(listCtx, types.DefaultKubeVelaNS, scope) queryTemplates, err := u.Factory.ListTemplates(listCtx, GlobalConfigNamespace, scope)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -99,9 +110,9 @@ func (u *configServiceImpl) ListTemplates(ctx context.Context, project, scope st
// GetTemplate detail a template // GetTemplate detail a template
func (u *configServiceImpl) GetTemplate(ctx context.Context, tem config.NamespacedName) (*apis.ConfigTemplateDetail, error) { func (u *configServiceImpl) GetTemplate(ctx context.Context, tem config.NamespacedName) (*apis.ConfigTemplateDetail, error) {
if tem.Namespace == "" { if tem.Namespace == "" {
tem.Namespace = types.DefaultKubeVelaNS tem.Namespace = GlobalConfigNamespace
} }
getCtx := utils.WithProject(ctx, "") getCtx := utils.WithProject(ctx, NoProject)
template, err := u.Factory.LoadTemplate(getCtx, tem.Name, tem.Namespace) template, err := u.Factory.LoadTemplate(getCtx, tem.Name, tem.Namespace)
if err != nil { if err != nil {
if errors.Is(err, config.ErrTemplateNotFound) { if errors.Is(err, config.ErrTemplateNotFound) {
@ -128,8 +139,8 @@ func (u *configServiceImpl) GetTemplate(ctx context.Context, tem config.Namespac
} }
func (u *configServiceImpl) CreateConfig(ctx context.Context, project string, req apis.CreateConfigRequest) (*apis.Config, error) { func (u *configServiceImpl) CreateConfig(ctx context.Context, project string, req apis.CreateConfigRequest) (*apis.Config, error) {
ns := types.DefaultKubeVelaNS ns := GlobalConfigNamespace
if project != "" { if !isGlobal(project) {
pro, err := u.ProjectService.GetProject(ctx, project) pro, err := u.ProjectService.GetProject(ctx, project)
if err != nil { if err != nil {
return nil, err return nil, err
@ -138,7 +149,7 @@ func (u *configServiceImpl) CreateConfig(ctx context.Context, project string, re
} }
exist, err := u.Factory.IsExist(ctx, ns, req.Name) exist, err := u.Factory.IsExist(ctx, ns, req.Name)
if err != nil { if err != nil {
klog.Errorf("check config name is exist failure %s", err.Error()) klog.Errorf("check config name exist fail %s", err.Error())
return nil, bcode.ErrConfigExist return nil, bcode.ErrConfigExist
} }
if exist { if exist {
@ -149,7 +160,7 @@ func (u *configServiceImpl) CreateConfig(ctx context.Context, project string, re
return nil, err return nil, err
} }
if req.Template.Namespace == "" { if req.Template.Namespace == "" {
req.Template.Namespace = types.DefaultKubeVelaNS req.Template.Namespace = GlobalConfigNamespace
} }
configItem, err := u.Factory.ParseConfig(ctx, config.NamespacedName(req.Template), config.Metadata{ configItem, err := u.Factory.ParseConfig(ctx, config.NamespacedName(req.Template), config.Metadata{
NamespacedName: config.NamespacedName{Name: req.Name, Namespace: ns}, NamespacedName: config.NamespacedName{Name: req.Name, Namespace: ns},
@ -169,8 +180,8 @@ func (u *configServiceImpl) CreateConfig(ctx context.Context, project string, re
} }
func (u *configServiceImpl) UpdateConfig(ctx context.Context, project string, name string, req apis.UpdateConfigRequest) (*apis.Config, error) { func (u *configServiceImpl) UpdateConfig(ctx context.Context, project string, name string, req apis.UpdateConfigRequest) (*apis.Config, error) {
ns := types.DefaultKubeVelaNS ns := GlobalConfigNamespace
if project != "" { if !isGlobal(project) {
pro, err := u.ProjectService.GetProject(ctx, project) pro, err := u.ProjectService.GetProject(ctx, project)
if err != nil { if err != nil {
return nil, err return nil, err
@ -217,8 +228,8 @@ func (u *configServiceImpl) ListConfigs(ctx context.Context, project string, tem
var list []*apis.Config var list []*apis.Config
scope := "" scope := ""
var projectNamespace string var projectNamespace string
listCtx := utils.WithProject(ctx, "") listCtx := utils.WithProject(ctx, NoProject)
if project != "" { if !isGlobal(project) {
scope = "project" scope = "project"
pro, err := u.ProjectService.GetProject(ctx, project) pro, err := u.ProjectService.GetProject(ctx, project)
if err != nil { if err != nil {
@ -235,7 +246,7 @@ func (u *configServiceImpl) ListConfigs(ctx context.Context, project string, tem
} }
} }
configs, err := u.Factory.ListConfigs(listCtx, types.DefaultKubeVelaNS, template, scope, true) configs, err := u.Factory.ListConfigs(listCtx, GlobalConfigNamespace, template, scope, true)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -283,7 +294,7 @@ func (u *configServiceImpl) CreateConfigDistribution(ctx context.Context, projec
}) })
} }
// ListDistributeConfigs list the all distributions // ListConfigDistributions list the all distributions
func (u *configServiceImpl) ListConfigDistributions(ctx context.Context, project string) ([]*config.Distribution, error) { func (u *configServiceImpl) ListConfigDistributions(ctx context.Context, project string) ([]*config.Distribution, error) {
pro, err := u.ProjectService.GetProject(ctx, project) pro, err := u.ProjectService.GetProject(ctx, project)
if err != nil { if err != nil {
@ -324,8 +335,8 @@ func convertConfig(project string, config config.Config) *apis.Config {
} }
func (u *configServiceImpl) GetConfig(ctx context.Context, project, name string) (*apis.Config, error) { func (u *configServiceImpl) GetConfig(ctx context.Context, project, name string) (*apis.Config, error) {
ns := types.DefaultKubeVelaNS ns := GlobalConfigNamespace
if project != "" { if !isGlobal(project) {
pro, err := u.ProjectService.GetProject(ctx, project) pro, err := u.ProjectService.GetProject(ctx, project)
if err != nil { if err != nil {
return nil, err return nil, err
@ -335,21 +346,25 @@ func (u *configServiceImpl) GetConfig(ctx context.Context, project, name string)
it, err := u.Factory.GetConfig(ctx, ns, name, true) it, err := u.Factory.GetConfig(ctx, ns, name, true)
if err != nil { if err != nil {
if errors.Is(err, config.ErrSensitiveConfig) { switch {
case errors.Is(err, config.ErrSensitiveConfig):
return nil, bcode.ErrSensitiveConfig return nil, bcode.ErrSensitiveConfig
} case errors.Is(err, config.ErrConfigNotFound):
if errors.Is(err, config.ErrConfigNotFound) { if !isGlobal(project) {
// Try to get global config if the config is not found in the project scope.
return u.GetConfig(ctx, NoProject, name)
}
return nil, bcode.ErrConfigNotFound return nil, bcode.ErrConfigNotFound
default:
return nil, err
} }
return nil, err
} }
return convertConfig(project, *it), nil return convertConfig(project, *it), nil
} }
func (u *configServiceImpl) DeleteConfig(ctx context.Context, project, name string) error { func (u *configServiceImpl) DeleteConfig(ctx context.Context, project, name string) error {
ns := types.DefaultKubeVelaNS ns := GlobalConfigNamespace
if project != "" { if !isGlobal(project) {
pro, err := u.ProjectService.GetProject(ctx, project) pro, err := u.ProjectService.GetProject(ctx, project)
if err != nil { if err != nil {
return err return err

View File

@ -21,7 +21,7 @@ import (
"errors" "errors"
terraformapi "github.com/oam-dev/terraform-controller/api/v1beta1" terraformapi "github.com/oam-dev/terraform-controller/api/v1beta1"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
apitypes "k8s.io/apimachinery/pkg/types" apitypes "k8s.io/apimachinery/pkg/types"
@ -101,6 +101,69 @@ template: {
} }
} }
` `
var (
helmTemplateName = "helm-repository"
helmTemplate = `
import (
"vela/config"
)
metadata: {
name: "helm-repository"
alias: "Helm Repository"
description: "Config information to authenticate helm chart repository"
sensitive: false
scope: "project"
}
template: {
output: {
apiVersion: "v1"
kind: "Secret"
metadata: {
name: context.name
namespace: context.namespace
labels: {
"config.oam.dev/catalog": "velacore-config"
"config.oam.dev/type": "helm-repository"
"config.oam.dev/multi-cluster": "true"
"config.oam.dev/sub-type": "helm"
}
}
type: "Opaque"
stringData: {
url: parameter.url
if parameter.username != _|_ {
username: parameter.username
}
if parameter.password != _|_ {
password: parameter.password
}
}
data: {
if parameter.caFile != _|_ {
caFile: parameter.caFile
}
}
}
// skip the validation here for config.#HelmRepository requires the repository actually exists which can be flaky in unit test
//validation: config.#HelmRepository & {
// $params: parameter
//}
parameter: {
// +usage=The public url of the helm chart repository.
url: string
// +usage=The username of basic auth repo.
username?: string
// +usage=The password of basic auth repo.
password?: string
// +usage=The ca certificate of helm repository. Please encode this data with base64.
caFile?: string
}
}`
)
var _ = Describe("Test config service", func() { var _ = Describe("Test config service", func() {
var factory config.Factory var factory config.Factory
@ -180,9 +243,42 @@ var _ = Describe("Test config service", func() {
Expect(len(list)).To(Equal(0)) Expect(len(list)).To(Equal(0))
}) })
It("Test detail a config", func() { Context("Test get config", func() {
_, err := configService.GetConfig(context.TODO(), "", "alibaba-test") It("Simple get", func() {
Expect(err).To(Equal(bcode.ErrSensitiveConfig)) _, err := configService.GetConfig(context.TODO(), "", "alibaba-test")
Expect(err).To(Equal(bcode.ErrSensitiveConfig))
})
It("Get config in project and fall back to get global config", func() {
By("apply helm template")
tem, err := factory.ParseTemplate(helmTemplateName, []byte(helmTemplate))
Expect(err).To(BeNil())
Expect(factory.CreateOrUpdateConfigTemplate(context.Background(), types.DefaultKubeVelaNS, tem)).To(BeNil())
By("create a project")
_, err = projectService.CreateProject(context.TODO(), v1.CreateProjectRequest{Name: "some-project"})
Expect(err).To(BeNil())
defer func() {
Expect(projectService.DeleteProject(context.Background(), "some-project")).To(BeNil())
}()
By("create a common global config")
_, err = configService.CreateConfig(context.TODO(), NoProject, v1.CreateConfigRequest{
Name: "helm-test",
Template: v1.NamespacedName{
Name: helmTemplateName,
},
Properties: `{"username":"test","password":"test","url":"https://helm.kubevela.com/charts"}`,
})
Expect(err).To(BeNil())
defer func() {
Expect(configService.DeleteConfig(context.Background(), NoProject, "helm-test")).To(BeNil())
}()
By("try to get the config in project, should success")
config, err := configService.GetConfig(context.TODO(), "some-project", "helm-test")
Expect(err).To(BeNil())
Expect(config.Name).To(Equal("helm-test"))
})
}) })
It("Test delete a config", func() { It("Test delete a config", func() {

View File

@ -23,6 +23,8 @@ import (
"sort" "sort"
"strings" "strings"
"github.com/kubevela/pkg/util/stringtools"
"github.com/oam-dev/kubevela/pkg/utils/addon" "github.com/oam-dev/kubevela/pkg/utils/addon"
"github.com/oam-dev/kubevela/pkg/utils/filters" "github.com/oam-dev/kubevela/pkg/utils/filters"
"github.com/oam-dev/kubevela/pkg/utils/schema" "github.com/oam-dev/kubevela/pkg/utils/schema"
@ -38,9 +40,9 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/kubevela/pkg/util/slices"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types" "github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/utils"
apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1" apisv1 "github.com/kubevela/velaux/pkg/server/interfaces/api/dto/v1"
"github.com/kubevela/velaux/pkg/server/utils/bcode" "github.com/kubevela/velaux/pkg/server/utils/bcode"
@ -85,6 +87,9 @@ const (
kindTraitDefinition = "TraitDefinition" kindTraitDefinition = "TraitDefinition"
kindWorkflowStepDefinition = "WorkflowStepDefinition" kindWorkflowStepDefinition = "WorkflowStepDefinition"
kindPolicyDefinition = "PolicyDefinition" kindPolicyDefinition = "PolicyDefinition"
// LabelDefinitionScope is the label key for definition scope, with this key, we know if the definition is for Application or WorkflowRun
LabelDefinitionScope = "custom.definition.oam.dev/scope"
) )
// NewDefinitionService new definition service // NewDefinitionService new definition service
@ -120,7 +125,7 @@ func (d *definitionServiceImpl) listDefinitions(ctx context.Context, list *unstr
filterScope = "Application" filterScope = "Application"
} }
matchLabels.MatchExpressions = append(matchLabels.MatchExpressions, metav1.LabelSelectorRequirement{ matchLabels.MatchExpressions = append(matchLabels.MatchExpressions, metav1.LabelSelectorRequirement{
Key: types.LabelDefinitionScope, Key: LabelDefinitionScope,
Operator: metav1.LabelSelectorOpNotIn, Operator: metav1.LabelSelectorOpNotIn,
Values: []string{filterScope}, Values: []string{filterScope},
}) })
@ -441,7 +446,7 @@ func renderDefaultUISchema(apiSchema *openapi3.Schema) []*schema.UIParameter {
var params []*schema.UIParameter var params []*schema.UIParameter
for key, property := range apiSchema.Properties { for key, property := range apiSchema.Properties {
if property.Value != nil { if property.Value != nil {
param := renderUIParameter(key, schema.FirstUpper(key), property, apiSchema.Required) param := renderUIParameter(key, stringtools.Capitalize(key), property, apiSchema.Required)
params = append(params, param) params = append(params, param)
} }
} }
@ -490,17 +495,18 @@ func renderUIParameter(key, label string, property *openapi3.SchemaRef, required
if property.Value.Properties != nil { if property.Value.Properties != nil {
parameter.SubParameters = renderDefaultUISchema(property.Value) parameter.SubParameters = renderDefaultUISchema(property.Value)
} }
if property.Value.AdditionalProperties != nil { var ap = property.Value.AdditionalProperties
parameter.SubParameters = renderDefaultUISchema(property.Value.AdditionalProperties.Value) if ap.Schema != nil && ap.Schema.Value != nil {
value := ap.Schema.Value
parameter.SubParameters = renderDefaultUISchema(value)
var enable = true var enable = true
value := property.Value.AdditionalProperties.Value parameter.AdditionalParameter = renderUIParameter(value.Title, stringtools.Capitalize(value.Title), property.Value.AdditionalProperties.Schema, value.Required)
parameter.AdditionalParameter = renderUIParameter(value.Title, schema.FirstUpper(value.Title), property.Value.AdditionalProperties, value.Required)
parameter.Additional = &enable parameter.Additional = &enable
} }
parameter.Validate = &schema.Validate{} parameter.Validate = &schema.Validate{}
parameter.Validate.DefaultValue = property.Value.Default parameter.Validate.DefaultValue = property.Value.Default
for _, enum := range property.Value.Enum { for _, enum := range property.Value.Enum {
parameter.Validate.Options = append(parameter.Validate.Options, schema.Option{Label: schema.RenderLabel(enum), Value: enum}) parameter.Validate.Options = append(parameter.Validate.Options, schema.Option{Label: RenderLabel(enum), Value: enum})
} }
parameter.JSONKey = key parameter.JSONKey = key
parameter.Description = property.Value.Description parameter.Description = property.Value.Description
@ -511,7 +517,19 @@ func renderUIParameter(key, label string, property *openapi3.SchemaRef, required
parameter.Validate.Min = property.Value.Min parameter.Validate.Min = property.Value.Min
parameter.Validate.MinLength = property.Value.MinLength parameter.Validate.MinLength = property.Value.MinLength
parameter.Validate.Pattern = property.Value.Pattern parameter.Validate.Pattern = property.Value.Pattern
parameter.Validate.Required = utils.StringsContain(required, property.Value.Title) parameter.Validate.Required = slices.Contains(required, property.Value.Title)
parameter.Sort = 100 parameter.Sort = 100
return &parameter return &parameter
} }
// RenderLabel render option label
func RenderLabel(source interface{}) string {
switch v := source.(type) {
case int:
return fmt.Sprintf("%d", v)
case string:
return stringtools.Capitalize(v)
default:
return stringtools.Capitalize(fmt.Sprintf("%v", v))
}
}

View File

@ -24,7 +24,7 @@ import (
"github.com/getkin/kin-openapi/openapi3" "github.com/getkin/kin-openapi/openapi3"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"

View File

@ -27,6 +27,7 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client"
"github.com/kubevela/pkg/util/slices"
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1" "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
"github.com/oam-dev/kubevela/apis/types" "github.com/oam-dev/kubevela/apis/types"
"github.com/oam-dev/kubevela/pkg/auth" "github.com/oam-dev/kubevela/pkg/auth"
@ -96,11 +97,7 @@ func (p *envServiceImpl) DeleteEnv(ctx context.Context, envName string) error {
return err return err
} }
if err := managePrivilegesForEnvironment(ctx, p.KubeClient, env, true); err != nil { return managePrivilegesForEnvironment(ctx, p.KubeClient, env, true)
return err
}
return nil
} }
// ListEnvs list envs // ListEnvs list envs
@ -123,7 +120,7 @@ func (p *envServiceImpl) ListEnvs(ctx context.Context, page, pageSize int, listO
return &apisv1.ListEnvResponse{Envs: []*apisv1.Env{}, Total: 0}, nil return &apisv1.ListEnvResponse{Envs: []*apisv1.Env{}, Total: 0}, nil
} }
if listOption.Project != "" { if listOption.Project != "" {
if !util.StringsContain(availableProjectNames, listOption.Project) { if !slices.Contains(availableProjectNames, listOption.Project) {
return &apisv1.ListEnvResponse{Envs: []*apisv1.Env{}, Total: 0}, nil return &apisv1.ListEnvResponse{Envs: []*apisv1.Env{}, Total: 0}, nil
} }
} }
@ -208,7 +205,7 @@ func (p *envServiceImpl) UpdateEnv(ctx context.Context, name string, req apisv1.
} }
var targets []*model.Target var targets []*model.Target
if len(req.Targets) > 0 { if len(req.Targets) > 0 {
_, _, deleted := util.ThreeWaySliceCompare(req.Targets, env.Targets) _, _, deleted := utils.ThreeWaySliceCompare(req.Targets, env.Targets)
if len(deleted) > 0 { if len(deleted) > 0 {
count, err := p.GetAppCountInEnv(ctx, env) count, err := p.GetAppCountInEnv(ctx, env)
if err != nil { if err != nil {

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