mirror of
https://github.com/kubevela/kubevela.git
synced 2026-03-01 17:20:45 +00:00
Compare commits
91 Commits
v1.7.0-alp
...
release-1.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4209080adc | ||
|
|
61348b9d45 | ||
|
|
aa5e825683 | ||
|
|
95d04c370d | ||
|
|
a583f66b0d | ||
|
|
7ae1aff648 | ||
|
|
0ff40d75e5 | ||
|
|
3d410fed5f | ||
|
|
f8285df49d | ||
|
|
e4cd1ffd1d | ||
|
|
592f8b8e8f | ||
|
|
94c215c361 | ||
|
|
1723a1795d | ||
|
|
0861498ab8 | ||
|
|
52c9a8f0a3 | ||
|
|
c7f337fd35 | ||
|
|
9dca76e0de | ||
|
|
348f540a82 | ||
|
|
1c2df10299 | ||
|
|
918ed9727b | ||
|
|
fa78cb7632 | ||
|
|
f3cdbcf203 | ||
|
|
7bd2cf4dbc | ||
|
|
969babdd9e | ||
|
|
94c46a179b | ||
|
|
bec288c6b4 | ||
|
|
9a44be9788 | ||
|
|
9c7f4b7e03 | ||
|
|
539f1ed02b | ||
|
|
9e95122387 | ||
|
|
f49f11dd72 | ||
|
|
191d9038f1 | ||
|
|
e10e43b6c8 | ||
|
|
b9cc523267 | ||
|
|
7f1743ef58 | ||
|
|
dd39c38cf1 | ||
|
|
0851454c6f | ||
|
|
cd3577db53 | ||
|
|
d578adfe6e | ||
|
|
4b88cd201e | ||
|
|
492e7d7f0d | ||
|
|
0742ca9ee5 | ||
|
|
1cf4ae3fc3 | ||
|
|
444d315143 | ||
|
|
2e3a89f6b1 | ||
|
|
d94293ac59 | ||
|
|
cc604cfadb | ||
|
|
8ef2513b2e | ||
|
|
657e3b1bde | ||
|
|
004e2a814d | ||
|
|
6dcba5ef11 | ||
|
|
fd39804dc9 | ||
|
|
ce57fbb752 | ||
|
|
80b2b2c2d3 | ||
|
|
49d97e5c2b | ||
|
|
1ee5915546 | ||
|
|
3f6b38cc7f | ||
|
|
c2c7ab91f9 | ||
|
|
866ffb9689 | ||
|
|
61afb366ee | ||
|
|
a2a8d73a58 | ||
|
|
fc3b428788 | ||
|
|
500dc52b34 | ||
|
|
789aa38476 | ||
|
|
17adf35717 | ||
|
|
586f266798 | ||
|
|
b8dcbe4964 | ||
|
|
778579c79b | ||
|
|
69293f4094 | ||
|
|
3a917cb6af | ||
|
|
1c43c6d1c5 | ||
|
|
9bbf7bf01b | ||
|
|
5a845104fb | ||
|
|
693eb3cb1d | ||
|
|
78f5827fa6 | ||
|
|
af8a7eb695 | ||
|
|
97ce8ba500 | ||
|
|
03d892bcf1 | ||
|
|
360c9e24b2 | ||
|
|
ba0a726cfc | ||
|
|
b2f4e237c2 | ||
|
|
5f71d05db1 | ||
|
|
340059989b | ||
|
|
5b636e451a | ||
|
|
ecc77f8cae | ||
|
|
8a5239575a | ||
|
|
6461625832 | ||
|
|
28f6f42ed4 | ||
|
|
7bc2f4e8d1 | ||
|
|
d588def0af | ||
|
|
6c12b968a7 |
2
.github/bot.md
vendored
2
.github/bot.md
vendored
@@ -1,6 +1,6 @@
|
||||
### GitHub & kubevela automation
|
||||
|
||||
The bot is configured via [issue-commands.json](https://github.com/kubevela/kubevela/blob/master/.github/workflows/issue-commands.json)
|
||||
The bot is configured via [issue-commands.json](https://github.com/kubevela/kubevela/blob/master/.github/issue-commands.json)
|
||||
and some other GitHub [workflows](https://github.com/kubevela/kubevela/blob/master/.github/workflows).
|
||||
By default, users with write access to the repo is allowed to use the comments,
|
||||
the [userlist](https://github.com/kubevela/kubevela/blob/master/.github/comment.userlist)
|
||||
|
||||
4
.github/workflows/apiserver-test.yml
vendored
4
.github/workflows/apiserver-test.yml
vendored
@@ -64,6 +64,8 @@ jobs:
|
||||
|
||||
- name: Install ginkgo
|
||||
run: |
|
||||
sudo sed -i 's/azure\.//' /etc/apt/sources.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y golang-ginkgo-dev
|
||||
|
||||
- name: Start MongoDB
|
||||
@@ -184,7 +186,7 @@ jobs:
|
||||
uses: codecov/codecov-action@d9f34f8cd5cb3b3eb79b3e4b5dae3a16df499a70
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: /tmp/e2e_apiserver_test.out
|
||||
files: /tmp/e2e-profile.out, /tmp/e2e_apiserver_test.out
|
||||
flags: apiserver-e2etests
|
||||
name: codecov-umbrella
|
||||
|
||||
|
||||
151
.github/workflows/release.yml
vendored
151
.github/workflows/release.yml
vendored
@@ -7,7 +7,6 @@ on:
|
||||
workflow_dispatch: { }
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
BUCKET: ${{ secrets.CLI_OSS_BUCKET }}
|
||||
ENDPOINT: ${{ secrets.CLI_OSS_ENDPOINT }}
|
||||
ACCESS_KEY: ${{ secrets.CLI_OSS_ACCESS_KEY }}
|
||||
@@ -18,106 +17,46 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: write
|
||||
actions: read
|
||||
checks: write
|
||||
issues: read
|
||||
packages: write
|
||||
pull-requests: read
|
||||
repository-projects: read
|
||||
statuses: read
|
||||
runs-on: ubuntu-latest
|
||||
name: build
|
||||
strategy:
|
||||
matrix:
|
||||
TARGETS: [ linux/amd64, darwin/amd64, windows/amd64, linux/arm64, darwin/arm64 ]
|
||||
env:
|
||||
VELA_VERSION_KEY: github.com/oam-dev/kubevela/version.VelaVersion
|
||||
VELA_GITVERSION_KEY: github.com/oam-dev/kubevela/version.GitRevision
|
||||
GO_BUILD_ENV: GO111MODULE=on CGO_ENABLED=0
|
||||
DIST_DIRS: find * -type d -exec
|
||||
name: goreleaser
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: git fetch --force --tags
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568
|
||||
with:
|
||||
go-version: 1.19
|
||||
- name: Get release
|
||||
id: get_release
|
||||
uses: bruceadams/get-release@74c3d60f5a28f358ccf241a00c9021ea16f0569f # v1.3.2
|
||||
cache: true
|
||||
- uses: goreleaser/goreleaser-action@9754a253a8673b0ea869c2e863b4e975497efd0c # v4.1.1
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: 1.14.1
|
||||
args: release --rm-dist --timeout 60m
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Since goreleaser haven't supported aliyun OSS, we need to upload the release manually
|
||||
- name: Get version
|
||||
run: echo "VELA_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
||||
- name: Get matrix
|
||||
id: get_matrix
|
||||
run: |
|
||||
TARGETS=${{matrix.TARGETS}}
|
||||
echo "OS=${TARGETS%/*}" >> $GITHUB_OUTPUT
|
||||
echo "ARCH=${TARGETS#*/}" >> $GITHUB_OUTPUT
|
||||
- name: Get ldflags
|
||||
id: get_ldflags
|
||||
run: |
|
||||
LDFLAGS="-s -w -X ${{ env.VELA_VERSION_KEY }}=${{ env.VELA_VERSION }} -X ${{ env.VELA_GITVERSION_KEY }}=git-$(git rev-parse --short HEAD)"
|
||||
echo "LDFLAGS=${LDFLAGS}" >> $GITHUB_ENV
|
||||
- name: Build
|
||||
run: |
|
||||
${{ env.GO_BUILD_ENV }} GOOS=${{ steps.get_matrix.outputs.OS }} GOARCH=${{ steps.get_matrix.outputs.ARCH }} \
|
||||
go build -ldflags "${{ env.LDFLAGS }}" \
|
||||
-o _bin/vela/${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}/vela -v \
|
||||
./references/cmd/cli/main.go
|
||||
${{ env.GO_BUILD_ENV }} GOOS=${{ steps.get_matrix.outputs.OS }} GOARCH=${{ steps.get_matrix.outputs.ARCH }} \
|
||||
go build -ldflags "${{ env.LDFLAGS }}" \
|
||||
-o _bin/kubectl-vela/${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}/kubectl-vela -v \
|
||||
./cmd/plugin/main.go
|
||||
- name: Compress
|
||||
run: |
|
||||
echo "\n## Release Info\nVERSION: ${{ env.VELA_VERSION }}" >> README.md && \
|
||||
echo "GIT_COMMIT: ${GITHUB_SHA}\n" >> README.md && \
|
||||
cd _bin/vela && \
|
||||
${{ env.DIST_DIRS }} cp ../../LICENSE {} \; && \
|
||||
${{ env.DIST_DIRS }} cp ../../README.md {} \; && \
|
||||
${{ env.DIST_DIRS }} tar -zcf vela-{}.tar.gz {} \; && \
|
||||
${{ env.DIST_DIRS }} zip -r vela-{}.zip {} \; && \
|
||||
cd ../kubectl-vela && \
|
||||
${{ env.DIST_DIRS }} cp ../../LICENSE {} \; && \
|
||||
${{ env.DIST_DIRS }} cp ../../README.md {} \; && \
|
||||
${{ env.DIST_DIRS }} tar -zcf kubectl-vela-{}.tar.gz {} \; && \
|
||||
${{ env.DIST_DIRS }} zip -r kubectl-vela-{}.zip {} \; && \
|
||||
cd .. && \
|
||||
sha256sum vela/vela-* kubectl-vela/kubectl-vela-* >> sha256-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.txt \
|
||||
- name: Upload Vela tar.gz
|
||||
uses: kubevela/vela-upload-release-asset@9b3858e67d3205e056d6220e5972abb32fc47289 # v1.0.0
|
||||
with:
|
||||
release_id: ${{ steps.get_release.outputs.id }}
|
||||
asset_path: ./_bin/vela/vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
|
||||
asset_name: vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
|
||||
- name: Upload Vela zip
|
||||
uses: kubevela/vela-upload-release-asset@9b3858e67d3205e056d6220e5972abb32fc47289 # v1.0.0
|
||||
with:
|
||||
release_id: ${{ steps.get_release.outputs.id }}
|
||||
asset_path: ./_bin/vela/vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
|
||||
asset_name: vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
|
||||
- name: Upload Kubectl-Vela tar.gz
|
||||
uses: kubevela/vela-upload-release-asset@9b3858e67d3205e056d6220e5972abb32fc47289 # v1.0.0
|
||||
with:
|
||||
release_id: ${{ steps.get_release.outputs.id }}
|
||||
asset_path: ./_bin/kubectl-vela/kubectl-vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
|
||||
asset_name: kubectl-vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
|
||||
- name: Upload Kubectl-Vela zip
|
||||
uses: kubevela/vela-upload-release-asset@9b3858e67d3205e056d6220e5972abb32fc47289 # v1.0.0
|
||||
with:
|
||||
release_id: ${{ steps.get_release.outputs.id }}
|
||||
asset_path: ./_bin/kubectl-vela/kubectl-vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
|
||||
asset_name: kubectl-vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
|
||||
- name: Post sha256
|
||||
uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
|
||||
with:
|
||||
name: sha256sums
|
||||
path: ./_bin/sha256-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.txt
|
||||
retention-days: 1
|
||||
- name: clear the asset
|
||||
run: |
|
||||
rm -rf ./_bin/vela/${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}
|
||||
mv ./_bin/vela/vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz ./_bin/vela/vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.tar.gz
|
||||
mv ./_bin/vela/vela-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip ./_bin/vela/vela-${{ env.VELA_VERSION }}-${{ steps.get_matrix.outputs.OS }}-${{ steps.get_matrix.outputs.ARCH }}.zip
|
||||
- name: Install ossutil
|
||||
run: wget http://gosspublic.alicdn.com/ossutil/1.7.0/ossutil64 && chmod +x ossutil64 && mv ossutil64 ossutil
|
||||
- name: Configure Alibaba Cloud OSSUTIL
|
||||
run: ./ossutil --config-file .ossutilconfig config -i ${ACCESS_KEY} -k ${ACCESS_KEY_SECRET} -e ${ENDPOINT} -c .ossutilconfig
|
||||
run: ./ossutil --config-file .ossutilconfig config -i ${ACCESS_KEY} -k ${ACCESS_KEY_SECRET} -e ${ENDPOINT}
|
||||
- name: split files to be upload
|
||||
run: mkdir -p ./dist/files_upload && mv ./dist/*.tar.gz ./dist/files_upload && mv ./dist/*.zip ./dist/files_upload
|
||||
- name: sync local to cloud
|
||||
run: ./ossutil --config-file .ossutilconfig sync ./_bin/vela oss://$BUCKET/binary/vela/${{ env.VELA_VERSION }}
|
||||
run: ./ossutil --config-file .ossutilconfig sync ./dist/files_upload oss://$BUCKET/binary/vela/${{ env.VELA_VERSION }}
|
||||
- name: sync the latest version file
|
||||
if: ${{ !contains(env.VELA_VERSION,'alpha') && !contains(env.VELA_VERSION,'beta') }}
|
||||
run: |
|
||||
@@ -128,42 +67,22 @@ jobs:
|
||||
verlte ${{ env.VELA_VERSION }} $LATEST_VERSION && echo "${{ env.VELA_VERSION }} <= $LATEST_VERSION, skip update" && exit 0
|
||||
echo ${{ env.VELA_VERSION }} > ./latest_version
|
||||
./ossutil --config-file .ossutilconfig cp -u ./latest_version oss://$BUCKET/binary/vela/latest_version
|
||||
|
||||
upload-plugin-homebrew:
|
||||
permissions:
|
||||
contents: write
|
||||
actions: read
|
||||
checks: write
|
||||
issues: read
|
||||
packages: write
|
||||
pull-requests: read
|
||||
repository-projects: read
|
||||
statuses: read
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
name: upload-sha256sums
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@755da8c3cf115ac066823e79a1e1788f8940201b
|
||||
- name: Get release
|
||||
id: get_release
|
||||
uses: bruceadams/get-release@74c3d60f5a28f358ccf241a00c9021ea16f0569f # v1.3.2
|
||||
- name: Download sha256sums
|
||||
uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3.0.1
|
||||
with:
|
||||
name: sha256sums
|
||||
path: cli-artifacts
|
||||
- name: Display structure of downloaded files
|
||||
run: ls -R
|
||||
working-directory: cli-artifacts
|
||||
- name: Get version
|
||||
run: echo "VELA_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
|
||||
- shell: bash
|
||||
working-directory: cli-artifacts
|
||||
run: |
|
||||
for file in *
|
||||
do
|
||||
sed -i "s/\/vela/-${{ env.VELA_VERSION }}/g" ${file}
|
||||
sed -i "s/\/kubectl-vela/-${{ env.VELA_VERSION }}/g" ${file}
|
||||
cat ${file} >> sha256sums.txt
|
||||
done
|
||||
- name: Upload Checksums
|
||||
uses: kubevela/vela-upload-release-asset@9b3858e67d3205e056d6220e5972abb32fc47289 # v1.0.0
|
||||
with:
|
||||
release_id: ${{ steps.get_release.outputs.id }}
|
||||
asset_path: cli-artifacts/sha256sums.txt
|
||||
asset_name: sha256sums.txt
|
||||
- name: Update kubectl plugin version in krew-index
|
||||
uses: rajatjindal/krew-release-bot@3320c0b546b5d2320613c46762bd3f73e2801bdc # v0.0.38
|
||||
- name: Update Homebrew formula
|
||||
|
||||
2
.github/workflows/unit-test.yml
vendored
2
.github/workflows/unit-test.yml
vendored
@@ -61,6 +61,8 @@ jobs:
|
||||
|
||||
- name: Install ginkgo
|
||||
run: |
|
||||
sudo sed -i 's/azure\.//' /etc/apt/sources.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y golang-ginkgo-dev
|
||||
|
||||
- name: Setup K3d
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -53,3 +53,5 @@ git-page/
|
||||
# e2e rollout runtime image build
|
||||
runtime/rollout/e2e/tmp
|
||||
vela.json
|
||||
|
||||
dist/
|
||||
|
||||
76
.goreleaser.yaml
Normal file
76
.goreleaser.yaml
Normal file
@@ -0,0 +1,76 @@
|
||||
# This is an example .goreleaser.yml file with some sensible defaults.
|
||||
# Make sure to check the documentation at https://goreleaser.com
|
||||
builds:
|
||||
- id: vela-cli
|
||||
binary: vela
|
||||
goos:
|
||||
- linux
|
||||
- windows
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
main: ./references/cmd/cli/main.go
|
||||
ldflags:
|
||||
- -s -w -X github.com/oam-dev/kubevela/version.VelaVersion={{ .Version }} -X github.com/oam-dev/kubevela/version.GitRevision=git-{{.ShortCommit}}
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
|
||||
- id: kubectl-vela
|
||||
binary: kubectl-vela
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
goos:
|
||||
- linux
|
||||
- windows
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
- arm64
|
||||
main: ./cmd/plugin/main.go
|
||||
ldflags:
|
||||
- -s -w -X github.com/oam-dev/kubevela/version.VelaVersion={{ .Version }} -X github.com/oam-dev/kubevela/version.GitRevision=git-{{.ShortCommit}}
|
||||
|
||||
archives:
|
||||
- format: tar.gz
|
||||
id: vela-cli-tgz
|
||||
wrap_in_directory: '{{ .Os }}-{{ .Arch }}'
|
||||
builds:
|
||||
- vela-cli
|
||||
name_template: '{{ trimsuffix .ArtifactName ".exe" }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}'
|
||||
files: [ LICENSE, README.md ]
|
||||
- format: zip
|
||||
id: vela-cli-zip
|
||||
builds:
|
||||
- vela-cli
|
||||
wrap_in_directory: '{{ .Os }}-{{ .Arch }}'
|
||||
name_template: '{{ trimsuffix .ArtifactName ".exe" }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}'
|
||||
files: [ LICENSE, README.md ]
|
||||
- format: tar.gz
|
||||
id: plugin-tgz
|
||||
builds:
|
||||
- kubectl-vela
|
||||
wrap_in_directory: '{{ .Os }}-{{ .Arch }}'
|
||||
name_template: '{{ trimsuffix .ArtifactName ".exe" }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}'
|
||||
files: [ LICENSE, README.md ]
|
||||
- format: zip
|
||||
id: plugin-zip
|
||||
builds:
|
||||
- kubectl-vela
|
||||
wrap_in_directory: '{{ .Os }}-{{ .Arch }}'
|
||||
name_template: '{{ trimsuffix .ArtifactName ".exe" }}-{{ .Tag }}-{{ .Os }}-{{ .Arch }}'
|
||||
files: [ LICENSE, README.md ]
|
||||
|
||||
checksum:
|
||||
name_template: 'sha256sums.txt'
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
|
||||
# The lines beneath this are called `modelines`. See `:help modeline`
|
||||
# Feel free to remove those if you don't want/use them.
|
||||
# yaml-language-server: $schema=https://goreleaser.com/static/schema.json
|
||||
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
|
||||
@@ -33,8 +33,8 @@ spec:
|
||||
arch: amd64
|
||||
{{addURIAndSha "https://github.com/oam-dev/kubevela/releases/download/{{ .TagName }}/kubectl-vela-{{ .TagName }}-windows-amd64.zip" .TagName }}
|
||||
files:
|
||||
- from: "*/kubectl-vela"
|
||||
to: "kubectl-vela.exe"
|
||||
- from: "*/kubectl-vela.exe"
|
||||
to: "."
|
||||
- from: "*/LICENSE"
|
||||
to: "."
|
||||
bin: "kubectl-vela.exe"
|
||||
|
||||
@@ -336,7 +336,8 @@ type WorkflowStatus struct {
|
||||
Steps []workflowv1alpha1.WorkflowStepStatus `json:"steps,omitempty"`
|
||||
|
||||
StartTime metav1.Time `json:"startTime,omitempty"`
|
||||
EndTime metav1.Time `json:"endTime,omitempty"`
|
||||
// +nullable
|
||||
EndTime metav1.Time `json:"endTime,omitempty"`
|
||||
}
|
||||
|
||||
// DefinitionType describes the type of DefinitionRevision.
|
||||
|
||||
@@ -135,6 +135,8 @@ type ApplicationRevisionStatus struct {
|
||||
Succeeded bool `json:"succeeded"`
|
||||
// Workflow the running status of the workflow
|
||||
Workflow *common.WorkflowStatus `json:"workflow,omitempty"`
|
||||
// Record the context values to the revision.
|
||||
WorkflowContext map[string]string `json:"workflowContext,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
@@ -293,6 +293,13 @@ func (in *ApplicationRevisionStatus) DeepCopyInto(out *ApplicationRevisionStatus
|
||||
*out = new(common.WorkflowStatus)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.WorkflowContext != nil {
|
||||
in, out := &in.WorkflowContext, &out.WorkflowContext
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ApplicationRevisionStatus.
|
||||
|
||||
@@ -99,6 +99,7 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
|
||||
| `featureGates.multiStageComponentApply` | if enabled, the multiStageComponentApply feature will be combined with the stage field in TraitDefinition to complete the multi-stage apply. | `false` |
|
||||
| `featureGates.gzipApplicationRevision` | compress apprev using gzip (good) before being stored. This is reduces network throughput when dealing with huge apprevs. | `false` |
|
||||
| `featureGates.zstdApplicationRevision` | compress apprev using zstd (fast and good) before being stored. This is reduces network throughput when dealing with huge apprevs. Note that zstd will be prioritized if you enable other compression options. | `true` |
|
||||
| `featureGates.preDispatchDryRun` | enable dryrun before dispatching resources. Enable this flag can help prevent unsuccessful dispatch resources entering resourcetracker and improve the user experiences of gc but at the cost of increasing network requests. | `true` |
|
||||
|
||||
|
||||
### MultiCluster parameters
|
||||
@@ -110,7 +111,7 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
|
||||
| `multicluster.clusterGateway.replicaCount` | ClusterGateway replica count | `1` |
|
||||
| `multicluster.clusterGateway.port` | ClusterGateway port | `9443` |
|
||||
| `multicluster.clusterGateway.image.repository` | ClusterGateway image repository | `oamdev/cluster-gateway` |
|
||||
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.4.0` |
|
||||
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.7.0` |
|
||||
| `multicluster.clusterGateway.image.pullPolicy` | ClusterGateway image pull policy | `IfNotPresent` |
|
||||
| `multicluster.clusterGateway.resources.limits.cpu` | ClusterGateway cpu limit | `100m` |
|
||||
| `multicluster.clusterGateway.resources.limits.memory` | ClusterGateway memory limit | `200Mi` |
|
||||
@@ -149,7 +150,7 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
|
||||
| `kubeClient.qps` | The qps for reconcile clients, default is 100 | `100` |
|
||||
| `kubeClient.burst` | The burst for reconcile clients, default is 200 | `200` |
|
||||
| `authentication.enabled` | Enable authentication for application | `false` |
|
||||
| `authentication.withUser` | Application authentication will impersonate as the request User | `false` |
|
||||
| `authentication.withUser` | Application authentication will impersonate as the request User | `true` |
|
||||
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided in Application | `kubevela:vela-core` |
|
||||
| `authentication.groupPattern` | Application authentication will impersonate as the request Group that matches the pattern | `kubevela:*` |
|
||||
|
||||
|
||||
@@ -848,6 +848,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -2806,6 +2807,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -4942,6 +4944,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -5042,6 +5045,11 @@ spec:
|
||||
- suspend
|
||||
- terminated
|
||||
type: object
|
||||
workflowContext:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Record the context values to the revision.
|
||||
type: object
|
||||
required:
|
||||
- succeeded
|
||||
type: object
|
||||
|
||||
@@ -774,6 +774,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -1535,6 +1536,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
|
||||
@@ -32,6 +32,7 @@ spec:
|
||||
- "--secure-port={{ .Values.multicluster.clusterGateway.port }}"
|
||||
- "--secret-namespace={{ .Release.Namespace }}"
|
||||
- "--feature-gates=APIPriorityAndFairness=false,ClientIdentityPenetration={{ .Values.authentication.enabled }}"
|
||||
- "--cluster-gateway-proxy-config=/etc/proxy-config/config.yaml"
|
||||
{{- if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
- "--tls-cert-file={{ .Values.multicluster.clusterGateway.secureTLS.certPath }}/tls.crt"
|
||||
- "--tls-private-key-file={{ .Values.multicluster.clusterGateway.secureTLS.certPath }}/tls.key"
|
||||
@@ -42,14 +43,20 @@ spec:
|
||||
{{- toYaml .Values.multicluster.clusterGateway.resources | nindent 12 }}
|
||||
ports:
|
||||
- containerPort: {{ .Values.multicluster.clusterGateway.port }}
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
volumeMounts:
|
||||
- mountPath: /etc/proxy-config
|
||||
name: proxy-config
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
- mountPath: {{ .Values.multicluster.clusterGateway.secureTLS.certPath }}
|
||||
name: tls-cert-vol
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
volumes:
|
||||
- configMap:
|
||||
defaultMode: 420
|
||||
name: {{ .Release.Name }}-cluster-gateway-proxy-config
|
||||
name: proxy-config
|
||||
{{ if .Values.multicluster.clusterGateway.secureTLS.enabled }}
|
||||
- name: tls-cert-vol
|
||||
secret:
|
||||
defaultMode: 420
|
||||
@@ -74,6 +81,23 @@ spec:
|
||||
maxUnavailable: 1
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-cluster-gateway-proxy-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
data:
|
||||
config.yaml: |
|
||||
apiVersion: cluster.core.oam.dev/v1alpha1
|
||||
kind: ClusterGatewayProxyConfiguration
|
||||
spec:
|
||||
clientIdentityExchanger:
|
||||
rules:
|
||||
- name: super-user
|
||||
source:
|
||||
group: kubevela:ux
|
||||
type: PrivilegedIdentityExchanger
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-cluster-gateway-service
|
||||
|
||||
@@ -7,7 +7,6 @@ metadata:
|
||||
definition.oam.dev/description: Apply a specific component and its corresponding traits in application
|
||||
labels:
|
||||
custom.definition.oam.dev/scope: Application
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: apply-component
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -116,7 +116,7 @@ spec:
|
||||
#ECProvider: {
|
||||
type: "ec"
|
||||
apiKey: *"" | string
|
||||
name: "ec-provider" | string
|
||||
name: *"ec-provider" | string
|
||||
}
|
||||
#GCPProvider: {
|
||||
credentials: string
|
||||
|
||||
@@ -72,7 +72,7 @@ spec:
|
||||
}]
|
||||
}
|
||||
}
|
||||
parameter: *#PatchParams | close({
|
||||
parameter: #PatchParams | close({
|
||||
// +usage=Specify the container image for multiple containers
|
||||
containers: [...#PatchParams]
|
||||
})
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Wait for the specified Application to complete.
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: depends-on-app
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Export data to specified Kubernetes ConfigMap in your workflow.
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: export2config
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Export data to Kubernetes Secret in your workflow.
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: export2secret
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -53,7 +53,10 @@ spec:
|
||||
}
|
||||
if service.spec.type == "LoadBalancer" {
|
||||
status: service.status
|
||||
isHealth: status != _|_ && status.loadBalancer != _|_ && status.loadBalancer.ingress != _|_ && len(status.loadBalancer.ingress) > 0
|
||||
isHealth: *false | bool
|
||||
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
|
||||
isHealth: true
|
||||
}
|
||||
if !isHealth {
|
||||
message: "ExternalIP: Pending"
|
||||
}
|
||||
@@ -62,10 +65,15 @@ spec:
|
||||
}
|
||||
}
|
||||
healthPolicy: |-
|
||||
isHealth: *true | bool
|
||||
service: context.outputs.service
|
||||
if service.spec.type == "LoadBalancer" {
|
||||
status: service.status
|
||||
isHealth: status != _|_ && status.loadBalancer != _|_ && status.loadBalancer.ingress != _|_ && len(status.loadBalancer.ingress) > 0
|
||||
isHealth: *false | bool
|
||||
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
|
||||
isHealth: true
|
||||
}
|
||||
}
|
||||
if service.spec.type != "LoadBalancer" {
|
||||
isHealth: true
|
||||
}
|
||||
|
||||
|
||||
@@ -113,19 +113,20 @@ spec:
|
||||
}
|
||||
if context.outputs.ingress.status.loadBalancer.ingress != _|_ {
|
||||
let igs = context.outputs.ingress.status.loadBalancer.ingress
|
||||
let host = context.outputs.ingress.spec.rules[0].host
|
||||
if igs[0].ip != _|_ {
|
||||
if igs[0].host != _|_ {
|
||||
if host != _|_ {
|
||||
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host + ", IP: " + igs[0].ip
|
||||
}
|
||||
if igs[0].host == _|_ {
|
||||
if host == _|_ {
|
||||
message: "Host not specified, visit the cluster or load balancer in front of the cluster with IP: " + igs[0].ip
|
||||
}
|
||||
}
|
||||
if igs[0].ip == _|_ {
|
||||
if igs[0].host != _|_ {
|
||||
if host != _|_ {
|
||||
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host
|
||||
}
|
||||
if igs[0].host != _|_ {
|
||||
if host != _|_ {
|
||||
message: "Host not specified, visit the cluster or load balancer in front of the cluster"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Generate a JDBC connection based on Component of alibaba-rds
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: generate-jdbc-connection
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
110
charts/vela-core/templates/defwithtemplate/hpa.yaml
Normal file
110
charts/vela-core/templates/defwithtemplate/hpa.yaml
Normal file
@@ -0,0 +1,110 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
|
||||
# Definition source cue file: vela-templates/definitions/internal/hpa.cue
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Configure k8s HPA for Deployment or Statefulsets
|
||||
name: hpa
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
appliesToWorkloads:
|
||||
- deployments.apps
|
||||
- statefulsets.apps
|
||||
podDisruptive: false
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
outputs: hpa: {
|
||||
if context.clusterVersion.minor < 23 {
|
||||
apiVersion: "autoscaling/v2beta2"
|
||||
}
|
||||
if context.clusterVersion.minor >= 23 {
|
||||
apiVersion: "autoscaling/v2"
|
||||
}
|
||||
kind: "HorizontalPodAutoscaler"
|
||||
metadata: name: context.name
|
||||
spec: {
|
||||
scaleTargetRef: {
|
||||
apiVersion: parameter.targetAPIVersion
|
||||
kind: parameter.targetKind
|
||||
name: context.name
|
||||
}
|
||||
minReplicas: parameter.min
|
||||
maxReplicas: parameter.max
|
||||
metrics: [
|
||||
{
|
||||
type: "Resource"
|
||||
resource: {
|
||||
name: "cpu"
|
||||
target: {
|
||||
type: parameter.cpu.type
|
||||
if parameter.cpu.type == "Utilization" {
|
||||
averageUtilization: parameter.cpu.value
|
||||
}
|
||||
if parameter.cpu.type == "AverageValue" {
|
||||
averageValue: parameter.cpu.value
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
if parameter.mem != _|_ {
|
||||
{
|
||||
type: "Resource"
|
||||
resource: {
|
||||
name: "memory"
|
||||
target: {
|
||||
type: parameter.mem.type
|
||||
if parameter.cpu.type == "Utilization" {
|
||||
averageUtilization: parameter.cpu.value
|
||||
}
|
||||
if parameter.cpu.type == "AverageValue" {
|
||||
averageValue: parameter.cpu.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
if parameter.podCustomMetrics != _|_ for m in parameter.podCustomMetrics {
|
||||
type: "Pods"
|
||||
pods: {
|
||||
metric: name: m.name
|
||||
target: {
|
||||
type: "AverageValue"
|
||||
averageValue: m.value
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the minimal number of replicas to which the autoscaler can scale down
|
||||
min: *1 | int
|
||||
// +usage=Specify the maximum number of of replicas to which the autoscaler can scale up
|
||||
max: *10 | int
|
||||
// +usage=Specify the apiVersion of scale target
|
||||
targetAPIVersion: *"apps/v1" | string
|
||||
// +usage=Specify the kind of scale target
|
||||
targetKind: *"Deployment" | string
|
||||
cpu: {
|
||||
// +usage=Specify resource metrics in terms of percentage("Utilization") or direct value("AverageValue")
|
||||
type: *"Utilization" | "AverageValue"
|
||||
// +usage=Specify the value of CPU utilization or averageValue
|
||||
value: *50 | int
|
||||
}
|
||||
mem?: {
|
||||
// +usage=Specify resource metrics in terms of percentage("Utilization") or direct value("AverageValue")
|
||||
type: *"Utilization" | "AverageValue"
|
||||
// +usage=Specify the value of MEM utilization or averageValue
|
||||
value: *50 | int
|
||||
}
|
||||
// +usage=Specify custom metrics of pod type
|
||||
podCustomMetrics?: [...{
|
||||
// +usage=Specify name of custom metrics
|
||||
name: string
|
||||
// +usage=Specify target value of custom metrics
|
||||
value: string
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
|
||||
# Definition source cue file: vela-templates/definitions/internal/k8s-update-strategy.cue
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/alias: ""
|
||||
definition.oam.dev/description: Set k8s update strategy for Deployment/DaemonSet/StatefulSet
|
||||
name: k8s-update-strategy
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
appliesToWorkloads:
|
||||
- deployments.apps
|
||||
- statefulsets.apps
|
||||
- daemonsets.apps
|
||||
conflictsWith: []
|
||||
podDisruptive: false
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
patch: spec: {
|
||||
if parameter.targetKind == "Deployment" && parameter.strategy.type != "OnDelete" {
|
||||
// +patchStrategy=retainKeys
|
||||
strategy: {
|
||||
type: parameter.strategy.type
|
||||
if parameter.strategy.type == "RollingUpdate" {
|
||||
rollingUpdate: {
|
||||
maxSurge: parameter.strategy.rollingStrategy.maxSurge
|
||||
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if parameter.targetKind == "StatefulSet" && parameter.strategy.type != "Recreate" {
|
||||
// +patchStrategy=retainKeys
|
||||
updateStrategy: {
|
||||
type: parameter.strategy.type
|
||||
if parameter.strategy.type == "RollingUpdate" {
|
||||
rollingUpdate: partition: parameter.strategy.rollingStrategy.partition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if parameter.targetKind == "DaemonSet" && parameter.strategy.type != "Recreate" {
|
||||
// +patchStrategy=retainKeys
|
||||
updateStrategy: {
|
||||
type: parameter.strategy.type
|
||||
if parameter.strategy.type == "RollingUpdate" {
|
||||
rollingUpdate: {
|
||||
maxSurge: parameter.strategy.rollingStrategy.maxSurge
|
||||
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the apiVersion of target
|
||||
targetAPIVersion: *"apps/v1" | string
|
||||
// +usage=Specify the kind of target
|
||||
targetKind: *"Deployment" | "StatefulSet" | "DaemonSet"
|
||||
// +usage=Specify the strategy of update
|
||||
strategy: {
|
||||
// +usage=Specify the strategy type
|
||||
type: *"RollingUpdate" | "Recreate" | "OnDelete"
|
||||
// +usage=Specify the parameters of rollong update strategy
|
||||
rollingStrategy?: {
|
||||
maxSurge: *"25%" | string
|
||||
maxUnavailable: *"25%" | string
|
||||
partition: *0 | int
|
||||
}
|
||||
}
|
||||
}
|
||||
workloadRefPath: ""
|
||||
|
||||
@@ -56,44 +56,41 @@ spec:
|
||||
// +usage=Specify the message that you want to sent, refer to [dingtalk messaging](https://developers.dingtalk.com/document/robots/custom-robot-access/title-72m-8ag-pqw)
|
||||
message: {
|
||||
// +usage=Specify the message content of dingtalk notification
|
||||
text?: *null | close({
|
||||
text?: close({
|
||||
content: string
|
||||
})
|
||||
// +usage=msgType can be text, link, mardown, actionCard, feedCard
|
||||
msgtype: *"text" | "link" | "markdown" | "actionCard" | "feedCard"
|
||||
link?: *null | close({
|
||||
#link: {
|
||||
text?: string
|
||||
title?: string
|
||||
messageUrl?: string
|
||||
picUrl?: string
|
||||
})
|
||||
markdown?: *null | close({
|
||||
}
|
||||
|
||||
link?: #link
|
||||
markdown?: close({
|
||||
text: string
|
||||
title: string
|
||||
})
|
||||
at?: *null | close({
|
||||
atMobiles?: *null | [...string]
|
||||
isAtAll?: bool
|
||||
at?: close({
|
||||
atMobiles?: [...string]
|
||||
isAtAll?: bool
|
||||
})
|
||||
actionCard?: *null | close({
|
||||
actionCard?: close({
|
||||
text: string
|
||||
title: string
|
||||
hideAvatar: string
|
||||
btnOrientation: string
|
||||
singleTitle: string
|
||||
singleURL: string
|
||||
btns: *null | close([...*null | close({
|
||||
btns?: [...close({
|
||||
title: string
|
||||
actionURL: string
|
||||
})])
|
||||
})]
|
||||
})
|
||||
feedCard?: *null | close({
|
||||
links: *null | close([...*null | close({
|
||||
text?: string
|
||||
title?: string
|
||||
messageUrl?: string
|
||||
picUrl?: string
|
||||
})])
|
||||
feedCard?: close({
|
||||
links: [...#link]
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -114,11 +111,11 @@ spec:
|
||||
// +usage=Specify the message that you want to sent, refer to [slack messaging](https://api.slack.com/reference/messaging/payload)
|
||||
message: {
|
||||
// +usage=Specify the message text for slack notification
|
||||
text: string
|
||||
blocks?: *null | close([...block])
|
||||
attachments?: *null | close({
|
||||
blocks?: *null | close([...block])
|
||||
color?: string
|
||||
text: string
|
||||
blocks?: [...block]
|
||||
attachments?: close({
|
||||
blocks?: [...block]
|
||||
color?: string
|
||||
})
|
||||
thread_ts?: string
|
||||
// +usage=Specify the message text format in markdown for slack notification
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: print message in workflow step status
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: print-message-in-status
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Read Kubernetes objects from cluster for your workflow steps
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: read-object
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -13,7 +13,7 @@ spec:
|
||||
template: |
|
||||
#PolicyRule: {
|
||||
// +usage=Specify how to select the targets of the rule
|
||||
selector: [...#RuleSelector]
|
||||
selector: #RuleSelector
|
||||
}
|
||||
#RuleSelector: {
|
||||
// +usage=Select resources by component names
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: A special step that you can declare 'subSteps' in it, 'subSteps' is an array containing any step type whose valid parameters do not include the `step-group` step type itself. The sub steps were executed in parallel.
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: step-group
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -54,6 +54,12 @@ spec:
|
||||
emptyDir: medium: v.medium
|
||||
}
|
||||
},
|
||||
if parameter.hostPath != _|_ for v in parameter.hostPath {
|
||||
{
|
||||
name: "hostpath-" + v.name
|
||||
path: v.path
|
||||
}
|
||||
},
|
||||
]
|
||||
volumeMountsList: [
|
||||
if parameter.pvc != _|_ for v in parameter.pvc {
|
||||
@@ -94,6 +100,12 @@ spec:
|
||||
}
|
||||
}
|
||||
},
|
||||
if parameter.hostPath != _|_ for v in parameter.hostPath {
|
||||
{
|
||||
name: "hostpath-" + v.name
|
||||
mountPath: v.mountPath
|
||||
}
|
||||
},
|
||||
]
|
||||
envList: [
|
||||
if parameter.configMap != _|_ for v in parameter.configMap if v.mountToEnv != _|_ {
|
||||
@@ -311,7 +323,7 @@ spec:
|
||||
envName: string
|
||||
secretKey: string
|
||||
}]
|
||||
mountPath?: string
|
||||
mountPath: string
|
||||
subPath?: string
|
||||
defaultMode: *420 | int
|
||||
readOnly: *false | bool
|
||||
@@ -331,5 +343,13 @@ spec:
|
||||
subPath?: string
|
||||
medium: *"" | "Memory"
|
||||
}]
|
||||
|
||||
// +usage=Declare host path type storage
|
||||
hostPath?: [...{
|
||||
name: string
|
||||
path: string
|
||||
mountPath: string
|
||||
type: *"Directory" | "DirectoryOrCreate" | "FileOrCreate" | "File" | "Socket" | "CharDevice" | "BlockDevice"
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
@@ -19,18 +19,24 @@ spec:
|
||||
mountsArray: [
|
||||
if parameter.storage != _|_ && parameter.storage.secret != _|_ for v in parameter.storage.secret {
|
||||
{
|
||||
name: "secret-" + v.name
|
||||
mountPath: v.mountPath
|
||||
if v.subPath != _|_ {
|
||||
subPath: v.subPath
|
||||
}
|
||||
name: v.name
|
||||
}
|
||||
},
|
||||
if parameter.storage != _|_ && parameter.storage.hostPath != _|_ for v in parameter.storage.hostPath {
|
||||
{
|
||||
name: "hostpath-" + v.name
|
||||
mountPath: v.mountPath
|
||||
}
|
||||
},
|
||||
]
|
||||
volumesList: [
|
||||
if parameter.storage != _|_ && parameter.storage.secret != _|_ for v in parameter.storage.secret {
|
||||
{
|
||||
name: v.name
|
||||
name: "secret-" + v.name
|
||||
secret: {
|
||||
defaultMode: v.defaultMode
|
||||
secretName: v.secretName
|
||||
@@ -39,6 +45,12 @@ spec:
|
||||
}
|
||||
}
|
||||
}
|
||||
if parameter.storage != _|_ && parameter.storage.hostPath != _|_ for v in parameter.storage.hostPath {
|
||||
{
|
||||
name: "hostpath-" + v.name
|
||||
path: v.path
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
deDupVolumesArray: [
|
||||
@@ -69,7 +81,7 @@ spec:
|
||||
spec: {
|
||||
backoffLimit: 3
|
||||
template: {
|
||||
labels: "workflow.oam.dev/step-name": "\(context.name)-\(context.stepName)"
|
||||
metadata: labels: "workflow.oam.dev/step-name": "\(context.name)-\(context.stepName)"
|
||||
spec: {
|
||||
containers: [
|
||||
{
|
||||
@@ -125,6 +137,13 @@ spec:
|
||||
mode: *511 | int
|
||||
}]
|
||||
}]
|
||||
// +usage=Declare host path type storage
|
||||
hostPath?: [...{
|
||||
name: string
|
||||
path: string
|
||||
mountPath: string
|
||||
type: *"Directory" | "DirectoryOrCreate" | "FileOrCreate" | "File" | "Socket" | "CharDevice" | "BlockDevice"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,21 +11,6 @@ metadata:
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
---
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:manager-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ if .Values.authentication.enabled }} {{ include "kubevela.fullname" . }}:manager {{ else }} "cluster-admin" {{ end }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "kubevela.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{ if .Values.authentication.enabled }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
@@ -66,9 +51,41 @@ rules:
|
||||
- apiGroups: ["authorization.k8s.io"]
|
||||
resources: ["subjectaccessreviews"]
|
||||
verbs: ["*"]
|
||||
{{ end }}
|
||||
|
||||
---
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:manager-authentication-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "kubevela.fullname" . }}:manager
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "kubevela.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{ else }}
|
||||
|
||||
---
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:manager-rolebinding
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: "cluster-admin"
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "kubevela.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{ end }}
|
||||
---
|
||||
# permissions to do leader election.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
@@ -255,8 +272,9 @@ spec:
|
||||
- "--feature-gates=ZstdResourceTracker={{- .Values.featureGates.zstdResourceTracker | toString -}}"
|
||||
- "--feature-gates=ApplyOnce={{- .Values.featureGates.applyOnce | toString -}}"
|
||||
- "--feature-gates=MultiStageComponentApply= {{- .Values.featureGates.multiStageComponentApply | toString -}}"
|
||||
- "--feature-gates=GzipApplicationRevision={{- .Values.featureGates.gzipResourceTracker | toString -}}"
|
||||
- "--feature-gates=ZstdApplicationRevision={{- .Values.featureGates.zstdResourceTracker | toString -}}"
|
||||
- "--feature-gates=GzipApplicationRevision={{- .Values.featureGates.gzipApplicationRevision | toString -}}"
|
||||
- "--feature-gates=ZstdApplicationRevision={{- .Values.featureGates.zstdApplicationRevision | toString -}}"
|
||||
- "--feature-gates=PreDispatchDryRun={{- .Values.featureGates.preDispatchDryRun | toString -}}"
|
||||
{{ if .Values.authentication.enabled }}
|
||||
{{ if .Values.authentication.withUser }}
|
||||
- "--authentication-with-user"
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
{{- if not (lookup "v1" "ConfigMap" (include "systemDefinitionNamespace" .) "component-pod-view") }}
|
||||
apiVersion: v1
|
||||
data:
|
||||
template: |
|
||||
import (
|
||||
"vela/ql"
|
||||
"vela/ql"
|
||||
)
|
||||
|
||||
parameter: {
|
||||
@@ -56,9 +55,15 @@ data:
|
||||
phase: pod.object.status.phase
|
||||
// refer to https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase
|
||||
if phase != "Pending" && phase != "Unknown" {
|
||||
podIP: pod.object.status.podIP
|
||||
hostIP: pod.object.status.hostIP
|
||||
nodeName: pod.object.spec.nodeName
|
||||
if pod.object.podIP != _|_ {
|
||||
podIP: pod.object.status.podIP
|
||||
}
|
||||
if pod.object.hostIP != _|_ {
|
||||
hostIP: pod.object.status.hostIP
|
||||
}
|
||||
if pod.object.nodeName != _|_ {
|
||||
nodeName: pod.object.spec.nodeName
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
@@ -74,4 +79,3 @@ kind: ConfigMap
|
||||
metadata:
|
||||
name: component-pod-view
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
{{- if not (lookup "v1" "ConfigMap" (include "systemDefinitionNamespace" .) "component-service-view") }}
|
||||
apiVersion: v1
|
||||
data:
|
||||
template: |
|
||||
@@ -47,4 +46,3 @@ kind: ConfigMap
|
||||
metadata:
|
||||
name: component-service-view
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
{{- end}}
|
||||
@@ -113,6 +113,7 @@ optimize:
|
||||
##@param featureGates.multiStageComponentApply if enabled, the multiStageComponentApply feature will be combined with the stage field in TraitDefinition to complete the multi-stage apply.
|
||||
##@param featureGates.gzipApplicationRevision compress apprev using gzip (good) before being stored. This is reduces network throughput when dealing with huge apprevs.
|
||||
##@param featureGates.zstdApplicationRevision compress apprev using zstd (fast and good) before being stored. This is reduces network throughput when dealing with huge apprevs. Note that zstd will be prioritized if you enable other compression options.
|
||||
##@param featureGates.preDispatchDryRun enable dryrun before dispatching resources. Enable this flag can help prevent unsuccessful dispatch resources entering resourcetracker and improve the user experiences of gc but at the cost of increasing network requests.
|
||||
##@param
|
||||
featureGates:
|
||||
enableLegacyComponentRevision: false
|
||||
@@ -122,6 +123,7 @@ featureGates:
|
||||
multiStageComponentApply: false
|
||||
gzipApplicationRevision: false
|
||||
zstdApplicationRevision: true
|
||||
preDispatchDryRun: true
|
||||
|
||||
## @section MultiCluster parameters
|
||||
|
||||
@@ -146,7 +148,7 @@ multicluster:
|
||||
port: 9443
|
||||
image:
|
||||
repository: oamdev/cluster-gateway
|
||||
tag: v1.4.0
|
||||
tag: v1.7.0
|
||||
pullPolicy: IfNotPresent
|
||||
resources:
|
||||
limits:
|
||||
@@ -263,6 +265,6 @@ kubeClient:
|
||||
## @param authentication.groupPattern Application authentication will impersonate as the request Group that matches the pattern
|
||||
authentication:
|
||||
enabled: false
|
||||
withUser: false
|
||||
withUser: true
|
||||
defaultUser: kubevela:vela-core
|
||||
groupPattern: kubevela:*
|
||||
|
||||
@@ -65,7 +65,6 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-minimal --
|
||||
| `controllerArgs.reSyncPeriod` | The period for resync the applications | `5m` |
|
||||
| `OAMSpecVer` | OAMSpecVer is the oam spec version controller want to setup | `minimal` |
|
||||
| `disableCaps` | Disable capability | `envbinding,rollout` |
|
||||
| `applyOnceOnly` | Valid applyOnceOnly values: true/false/on/off/force | `off` |
|
||||
| `dependCheckWait` | dependCheckWait is the time to wait for ApplicationConfiguration's dependent-resource ready | `30s` |
|
||||
|
||||
|
||||
@@ -97,20 +96,29 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-minimal --
|
||||
| `healthCheck.port` | KubeVela health check port | `9440` |
|
||||
|
||||
|
||||
### KubeVela controller optimization parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| `featureGates.applyOnce` | if enabled, the apply-once feature will be applied to all applications, no state-keep and no resource data storage in ResourceTracker | `false` |
|
||||
|
||||
|
||||
### MultiCluster parameters
|
||||
|
||||
| Name | Description | Value |
|
||||
| ----------------------------------------------------- | -------------------------------- | -------------------------------- |
|
||||
| `multicluster.enabled` | Whether to enable multi-cluster | `true` |
|
||||
| `multicluster.clusterGateway.replicaCount` | ClusterGateway replica count | `1` |
|
||||
| `multicluster.clusterGateway.port` | ClusterGateway port | `9443` |
|
||||
| `multicluster.clusterGateway.image.repository` | ClusterGateway image repository | `oamdev/cluster-gateway` |
|
||||
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.4.0` |
|
||||
| `multicluster.clusterGateway.image.pullPolicy` | ClusterGateway image pull policy | `IfNotPresent` |
|
||||
| `multicluster.clusterGateway.resources.limits.cpu` | ClusterGateway cpu limit | `100m` |
|
||||
| `multicluster.clusterGateway.resources.limits.memory` | ClusterGateway memory limit | `200Mi` |
|
||||
| `multicluster.clusterGateway.secureTLS.enabled` | Whether to enable secure TLS | `true` |
|
||||
| `multicluster.clusterGateway.secureTLS.certPath` | Path to the certificate file | `/etc/k8s-cluster-gateway-certs` |
|
||||
| Name | Description | Value |
|
||||
| ------------------------------------------------------- | -------------------------------- | -------------------------------- |
|
||||
| `multicluster.enabled` | Whether to enable multi-cluster | `true` |
|
||||
| `multicluster.clusterGateway.replicaCount` | ClusterGateway replica count | `1` |
|
||||
| `multicluster.clusterGateway.port` | ClusterGateway port | `9443` |
|
||||
| `multicluster.clusterGateway.image.repository` | ClusterGateway image repository | `oamdev/cluster-gateway` |
|
||||
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.8.0-alpha.3` |
|
||||
| `multicluster.clusterGateway.image.pullPolicy` | ClusterGateway image pull policy | `IfNotPresent` |
|
||||
| `multicluster.clusterGateway.resources.requests.cpu` | ClusterGateway cpu request | `50m` |
|
||||
| `multicluster.clusterGateway.resources.requests.memory` | ClusterGateway memory request | `20Mi` |
|
||||
| `multicluster.clusterGateway.resources.limits.cpu` | ClusterGateway cpu limit | `500m` |
|
||||
| `multicluster.clusterGateway.resources.limits.memory` | ClusterGateway memory limit | `200Mi` |
|
||||
| `multicluster.clusterGateway.secureTLS.enabled` | Whether to enable secure TLS | `true` |
|
||||
| `multicluster.clusterGateway.secureTLS.certPath` | Path to the certificate file | `/etc/k8s-cluster-gateway-certs` |
|
||||
|
||||
|
||||
### Test parameters
|
||||
|
||||
@@ -848,6 +848,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -2806,6 +2807,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -4942,6 +4944,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -5042,6 +5045,11 @@ spec:
|
||||
- suspend
|
||||
- terminated
|
||||
type: object
|
||||
workflowContext:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Record the context values to the revision.
|
||||
type: object
|
||||
required:
|
||||
- succeeded
|
||||
type: object
|
||||
|
||||
@@ -774,6 +774,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -1535,6 +1536,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
|
||||
@@ -7,7 +7,6 @@ metadata:
|
||||
definition.oam.dev/description: Apply a specific component and its corresponding traits in application
|
||||
labels:
|
||||
custom.definition.oam.dev/scope: Application
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: apply-component
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -116,7 +116,7 @@ spec:
|
||||
#ECProvider: {
|
||||
type: "ec"
|
||||
apiKey: *"" | string
|
||||
name: "ec-provider" | string
|
||||
name: *"ec-provider" | string
|
||||
}
|
||||
#GCPProvider: {
|
||||
credentials: string
|
||||
|
||||
@@ -72,7 +72,7 @@ spec:
|
||||
}]
|
||||
}
|
||||
}
|
||||
parameter: *#PatchParams | close({
|
||||
parameter: #PatchParams | close({
|
||||
// +usage=Specify the container image for multiple containers
|
||||
containers: [...#PatchParams]
|
||||
})
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Wait for the specified Application to complete.
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: depends-on-app
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Export data to specified Kubernetes ConfigMap in your workflow.
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: export2config
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Export data to Kubernetes Secret in your workflow.
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: export2secret
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -53,7 +53,10 @@ spec:
|
||||
}
|
||||
if service.spec.type == "LoadBalancer" {
|
||||
status: service.status
|
||||
isHealth: status != _|_ && status.loadBalancer != _|_ && status.loadBalancer.ingress != _|_ && len(status.loadBalancer.ingress) > 0
|
||||
isHealth: *false | bool
|
||||
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
|
||||
isHealth: true
|
||||
}
|
||||
if !isHealth {
|
||||
message: "ExternalIP: Pending"
|
||||
}
|
||||
@@ -62,10 +65,15 @@ spec:
|
||||
}
|
||||
}
|
||||
healthPolicy: |-
|
||||
isHealth: *true | bool
|
||||
service: context.outputs.service
|
||||
if service.spec.type == "LoadBalancer" {
|
||||
status: service.status
|
||||
isHealth: status != _|_ && status.loadBalancer != _|_ && status.loadBalancer.ingress != _|_ && len(status.loadBalancer.ingress) > 0
|
||||
isHealth: *false | bool
|
||||
if status != _|_ if status.loadBalancer != _|_ if status.loadBalancer.ingress != _|_ if len(status.loadBalancer.ingress) > 0 if status.loadBalancer.ingress[0].ip != _|_ {
|
||||
isHealth: true
|
||||
}
|
||||
}
|
||||
if service.spec.type != "LoadBalancer" {
|
||||
isHealth: true
|
||||
}
|
||||
|
||||
|
||||
@@ -113,19 +113,20 @@ spec:
|
||||
}
|
||||
if context.outputs.ingress.status.loadBalancer.ingress != _|_ {
|
||||
let igs = context.outputs.ingress.status.loadBalancer.ingress
|
||||
let host = context.outputs.ingress.spec.rules[0].host
|
||||
if igs[0].ip != _|_ {
|
||||
if igs[0].host != _|_ {
|
||||
if host != _|_ {
|
||||
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host + ", IP: " + igs[0].ip
|
||||
}
|
||||
if igs[0].host == _|_ {
|
||||
if host == _|_ {
|
||||
message: "Host not specified, visit the cluster or load balancer in front of the cluster with IP: " + igs[0].ip
|
||||
}
|
||||
}
|
||||
if igs[0].ip == _|_ {
|
||||
if igs[0].host != _|_ {
|
||||
if host != _|_ {
|
||||
message: "Visiting URL: " + context.outputs.ingress.spec.rules[0].host
|
||||
}
|
||||
if igs[0].host != _|_ {
|
||||
if host != _|_ {
|
||||
message: "Host not specified, visit the cluster or load balancer in front of the cluster"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Generate a JDBC connection based on Component of alibaba-rds
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: generate-jdbc-connection
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
110
charts/vela-minimal/templates/defwithtemplate/hpa.yaml
Normal file
110
charts/vela-minimal/templates/defwithtemplate/hpa.yaml
Normal file
@@ -0,0 +1,110 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
|
||||
# Definition source cue file: vela-templates/definitions/internal/hpa.cue
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Configure k8s HPA for Deployment or Statefulsets
|
||||
name: hpa
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
appliesToWorkloads:
|
||||
- deployments.apps
|
||||
- statefulsets.apps
|
||||
podDisruptive: false
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
outputs: hpa: {
|
||||
if context.clusterVersion.minor < 23 {
|
||||
apiVersion: "autoscaling/v2beta2"
|
||||
}
|
||||
if context.clusterVersion.minor >= 23 {
|
||||
apiVersion: "autoscaling/v2"
|
||||
}
|
||||
kind: "HorizontalPodAutoscaler"
|
||||
metadata: name: context.name
|
||||
spec: {
|
||||
scaleTargetRef: {
|
||||
apiVersion: parameter.targetAPIVersion
|
||||
kind: parameter.targetKind
|
||||
name: context.name
|
||||
}
|
||||
minReplicas: parameter.min
|
||||
maxReplicas: parameter.max
|
||||
metrics: [
|
||||
{
|
||||
type: "Resource"
|
||||
resource: {
|
||||
name: "cpu"
|
||||
target: {
|
||||
type: parameter.cpu.type
|
||||
if parameter.cpu.type == "Utilization" {
|
||||
averageUtilization: parameter.cpu.value
|
||||
}
|
||||
if parameter.cpu.type == "AverageValue" {
|
||||
averageValue: parameter.cpu.value
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
if parameter.mem != _|_ {
|
||||
{
|
||||
type: "Resource"
|
||||
resource: {
|
||||
name: "memory"
|
||||
target: {
|
||||
type: parameter.mem.type
|
||||
if parameter.cpu.type == "Utilization" {
|
||||
averageUtilization: parameter.cpu.value
|
||||
}
|
||||
if parameter.cpu.type == "AverageValue" {
|
||||
averageValue: parameter.cpu.value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
if parameter.podCustomMetrics != _|_ for m in parameter.podCustomMetrics {
|
||||
type: "Pods"
|
||||
pods: {
|
||||
metric: name: m.name
|
||||
target: {
|
||||
type: "AverageValue"
|
||||
averageValue: m.value
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the minimal number of replicas to which the autoscaler can scale down
|
||||
min: *1 | int
|
||||
// +usage=Specify the maximum number of of replicas to which the autoscaler can scale up
|
||||
max: *10 | int
|
||||
// +usage=Specify the apiVersion of scale target
|
||||
targetAPIVersion: *"apps/v1" | string
|
||||
// +usage=Specify the kind of scale target
|
||||
targetKind: *"Deployment" | string
|
||||
cpu: {
|
||||
// +usage=Specify resource metrics in terms of percentage("Utilization") or direct value("AverageValue")
|
||||
type: *"Utilization" | "AverageValue"
|
||||
// +usage=Specify the value of CPU utilization or averageValue
|
||||
value: *50 | int
|
||||
}
|
||||
mem?: {
|
||||
// +usage=Specify resource metrics in terms of percentage("Utilization") or direct value("AverageValue")
|
||||
type: *"Utilization" | "AverageValue"
|
||||
// +usage=Specify the value of MEM utilization or averageValue
|
||||
value: *50 | int
|
||||
}
|
||||
// +usage=Specify custom metrics of pod type
|
||||
podCustomMetrics?: [...{
|
||||
// +usage=Specify name of custom metrics
|
||||
name: string
|
||||
// +usage=Specify target value of custom metrics
|
||||
value: string
|
||||
}]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
|
||||
# Definition source cue file: vela-templates/definitions/internal/k8s-update-strategy.cue
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/alias: ""
|
||||
definition.oam.dev/description: Set k8s update strategy for Deployment/DaemonSet/StatefulSet
|
||||
name: k8s-update-strategy
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
appliesToWorkloads:
|
||||
- deployments.apps
|
||||
- statefulsets.apps
|
||||
- daemonsets.apps
|
||||
conflictsWith: []
|
||||
podDisruptive: false
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
patch: spec: {
|
||||
if parameter.targetKind == "Deployment" && parameter.strategy.type != "OnDelete" {
|
||||
// +patchStrategy=retainKeys
|
||||
strategy: {
|
||||
type: parameter.strategy.type
|
||||
if parameter.strategy.type == "RollingUpdate" {
|
||||
rollingUpdate: {
|
||||
maxSurge: parameter.strategy.rollingStrategy.maxSurge
|
||||
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if parameter.targetKind == "StatefulSet" && parameter.strategy.type != "Recreate" {
|
||||
// +patchStrategy=retainKeys
|
||||
updateStrategy: {
|
||||
type: parameter.strategy.type
|
||||
if parameter.strategy.type == "RollingUpdate" {
|
||||
rollingUpdate: partition: parameter.strategy.rollingStrategy.partition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if parameter.targetKind == "DaemonSet" && parameter.strategy.type != "Recreate" {
|
||||
// +patchStrategy=retainKeys
|
||||
updateStrategy: {
|
||||
type: parameter.strategy.type
|
||||
if parameter.strategy.type == "RollingUpdate" {
|
||||
rollingUpdate: {
|
||||
maxSurge: parameter.strategy.rollingStrategy.maxSurge
|
||||
maxUnavailable: parameter.strategy.rollingStrategy.maxUnavailable
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
parameter: {
|
||||
// +usage=Specify the apiVersion of target
|
||||
targetAPIVersion: *"apps/v1" | string
|
||||
// +usage=Specify the kind of target
|
||||
targetKind: *"Deployment" | "StatefulSet" | "DaemonSet"
|
||||
// +usage=Specify the strategy of update
|
||||
strategy: {
|
||||
// +usage=Specify the strategy type
|
||||
type: *"RollingUpdate" | "Recreate" | "OnDelete"
|
||||
// +usage=Specify the parameters of rollong update strategy
|
||||
rollingStrategy?: {
|
||||
maxSurge: *"25%" | string
|
||||
maxUnavailable: *"25%" | string
|
||||
partition: *0 | int
|
||||
}
|
||||
}
|
||||
}
|
||||
workloadRefPath: ""
|
||||
|
||||
@@ -56,44 +56,41 @@ spec:
|
||||
// +usage=Specify the message that you want to sent, refer to [dingtalk messaging](https://developers.dingtalk.com/document/robots/custom-robot-access/title-72m-8ag-pqw)
|
||||
message: {
|
||||
// +usage=Specify the message content of dingtalk notification
|
||||
text?: *null | close({
|
||||
text?: close({
|
||||
content: string
|
||||
})
|
||||
// +usage=msgType can be text, link, mardown, actionCard, feedCard
|
||||
msgtype: *"text" | "link" | "markdown" | "actionCard" | "feedCard"
|
||||
link?: *null | close({
|
||||
#link: {
|
||||
text?: string
|
||||
title?: string
|
||||
messageUrl?: string
|
||||
picUrl?: string
|
||||
})
|
||||
markdown?: *null | close({
|
||||
}
|
||||
|
||||
link?: #link
|
||||
markdown?: close({
|
||||
text: string
|
||||
title: string
|
||||
})
|
||||
at?: *null | close({
|
||||
atMobiles?: *null | [...string]
|
||||
isAtAll?: bool
|
||||
at?: close({
|
||||
atMobiles?: [...string]
|
||||
isAtAll?: bool
|
||||
})
|
||||
actionCard?: *null | close({
|
||||
actionCard?: close({
|
||||
text: string
|
||||
title: string
|
||||
hideAvatar: string
|
||||
btnOrientation: string
|
||||
singleTitle: string
|
||||
singleURL: string
|
||||
btns: *null | close([...*null | close({
|
||||
btns?: [...close({
|
||||
title: string
|
||||
actionURL: string
|
||||
})])
|
||||
})]
|
||||
})
|
||||
feedCard?: *null | close({
|
||||
links: *null | close([...*null | close({
|
||||
text?: string
|
||||
title?: string
|
||||
messageUrl?: string
|
||||
picUrl?: string
|
||||
})])
|
||||
feedCard?: close({
|
||||
links: [...#link]
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -114,11 +111,11 @@ spec:
|
||||
// +usage=Specify the message that you want to sent, refer to [slack messaging](https://api.slack.com/reference/messaging/payload)
|
||||
message: {
|
||||
// +usage=Specify the message text for slack notification
|
||||
text: string
|
||||
blocks?: *null | close([...block])
|
||||
attachments?: *null | close({
|
||||
blocks?: *null | close([...block])
|
||||
color?: string
|
||||
text: string
|
||||
blocks?: [...block]
|
||||
attachments?: close({
|
||||
blocks?: [...block]
|
||||
color?: string
|
||||
})
|
||||
thread_ts?: string
|
||||
// +usage=Specify the message text format in markdown for slack notification
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: print message in workflow step status
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: print-message-in-status
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Read Kubernetes objects from cluster for your workflow steps
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: read-object
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -13,7 +13,7 @@ spec:
|
||||
template: |
|
||||
#PolicyRule: {
|
||||
// +usage=Specify how to select the targets of the rule
|
||||
selector: [...#RuleSelector]
|
||||
selector: #RuleSelector
|
||||
}
|
||||
#RuleSelector: {
|
||||
// +usage=Select resources by component names
|
||||
|
||||
@@ -5,8 +5,6 @@ kind: WorkflowStepDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: A special step that you can declare 'subSteps' in it, 'subSteps' is an array containing any step type whose valid parameters do not include the `step-group` step type itself. The sub steps were executed in parallel.
|
||||
labels:
|
||||
custom.definition.oam.dev/ui-hidden: "true"
|
||||
name: step-group
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
|
||||
@@ -54,6 +54,12 @@ spec:
|
||||
emptyDir: medium: v.medium
|
||||
}
|
||||
},
|
||||
if parameter.hostPath != _|_ for v in parameter.hostPath {
|
||||
{
|
||||
name: "hostpath-" + v.name
|
||||
path: v.path
|
||||
}
|
||||
},
|
||||
]
|
||||
volumeMountsList: [
|
||||
if parameter.pvc != _|_ for v in parameter.pvc {
|
||||
@@ -94,6 +100,12 @@ spec:
|
||||
}
|
||||
}
|
||||
},
|
||||
if parameter.hostPath != _|_ for v in parameter.hostPath {
|
||||
{
|
||||
name: "hostpath-" + v.name
|
||||
mountPath: v.mountPath
|
||||
}
|
||||
},
|
||||
]
|
||||
envList: [
|
||||
if parameter.configMap != _|_ for v in parameter.configMap if v.mountToEnv != _|_ {
|
||||
@@ -311,7 +323,7 @@ spec:
|
||||
envName: string
|
||||
secretKey: string
|
||||
}]
|
||||
mountPath?: string
|
||||
mountPath: string
|
||||
subPath?: string
|
||||
defaultMode: *420 | int
|
||||
readOnly: *false | bool
|
||||
@@ -331,5 +343,13 @@ spec:
|
||||
subPath?: string
|
||||
medium: *"" | "Memory"
|
||||
}]
|
||||
|
||||
// +usage=Declare host path type storage
|
||||
hostPath?: [...{
|
||||
name: string
|
||||
path: string
|
||||
mountPath: string
|
||||
type: *"Directory" | "DirectoryOrCreate" | "FileOrCreate" | "File" | "Socket" | "CharDevice" | "BlockDevice"
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
@@ -19,18 +19,24 @@ spec:
|
||||
mountsArray: [
|
||||
if parameter.storage != _|_ && parameter.storage.secret != _|_ for v in parameter.storage.secret {
|
||||
{
|
||||
name: "secret-" + v.name
|
||||
mountPath: v.mountPath
|
||||
if v.subPath != _|_ {
|
||||
subPath: v.subPath
|
||||
}
|
||||
name: v.name
|
||||
}
|
||||
},
|
||||
if parameter.storage != _|_ && parameter.storage.hostPath != _|_ for v in parameter.storage.hostPath {
|
||||
{
|
||||
name: "hostpath-" + v.name
|
||||
mountPath: v.mountPath
|
||||
}
|
||||
},
|
||||
]
|
||||
volumesList: [
|
||||
if parameter.storage != _|_ && parameter.storage.secret != _|_ for v in parameter.storage.secret {
|
||||
{
|
||||
name: v.name
|
||||
name: "secret-" + v.name
|
||||
secret: {
|
||||
defaultMode: v.defaultMode
|
||||
secretName: v.secretName
|
||||
@@ -39,6 +45,12 @@ spec:
|
||||
}
|
||||
}
|
||||
}
|
||||
if parameter.storage != _|_ && parameter.storage.hostPath != _|_ for v in parameter.storage.hostPath {
|
||||
{
|
||||
name: "hostpath-" + v.name
|
||||
path: v.path
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
deDupVolumesArray: [
|
||||
@@ -69,7 +81,7 @@ spec:
|
||||
spec: {
|
||||
backoffLimit: 3
|
||||
template: {
|
||||
labels: "workflow.oam.dev/step-name": "\(context.name)-\(context.stepName)"
|
||||
metadata: labels: "workflow.oam.dev/step-name": "\(context.name)-\(context.stepName)"
|
||||
spec: {
|
||||
containers: [
|
||||
{
|
||||
@@ -125,6 +137,13 @@ spec:
|
||||
mode: *511 | int
|
||||
}]
|
||||
}]
|
||||
// +usage=Declare host path type storage
|
||||
hostPath?: [...{
|
||||
name: string
|
||||
path: string
|
||||
mountPath: string
|
||||
type: *"Directory" | "DirectoryOrCreate" | "FileOrCreate" | "File" | "Socket" | "CharDevice" | "BlockDevice"
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -166,10 +166,8 @@ spec:
|
||||
- "--use-webhook=true"
|
||||
- "--webhook-port={{ .Values.webhookService.port }}"
|
||||
- "--webhook-cert-dir={{ .Values.admissionWebhooks.certificate.mountPath }}"
|
||||
- "--autogen-workload-definition={{ .Values.admissionWebhooks.autoGenWorkloadDefinition }}"
|
||||
{{ end }}
|
||||
- "--health-addr=:{{ .Values.healthCheck.port }}"
|
||||
- "--apply-once-only={{ .Values.applyOnceOnly }}"
|
||||
{{ if ne .Values.disableCaps "" }}
|
||||
- "--disable-caps={{ .Values.disableCaps }}"
|
||||
{{ end }}
|
||||
@@ -188,6 +186,7 @@ spec:
|
||||
- "--max-workflow-step-error-retry-times={{ .Values.workflow.step.errorRetryTimes }}"
|
||||
- "--feature-gates=EnableSuspendOnFailure={{- .Values.workflow.enableSuspendOnFailure | toString -}}"
|
||||
- "--feature-gates=AuthenticateApplication={{- .Values.authentication.enabled | toString -}}"
|
||||
- "--feature-gates=ApplyOnce={{- .Values.featureGates.applyOnce | toString -}}"
|
||||
{{ if .Values.authentication.enabled }}
|
||||
{{ if .Values.authentication.withUser }}
|
||||
- "--authentication-with-user"
|
||||
|
||||
@@ -26,9 +26,6 @@ OAMSpecVer: "minimal"
|
||||
## @param disableCaps Disable capability
|
||||
disableCaps: "envbinding,rollout"
|
||||
|
||||
## @param applyOnceOnly Valid applyOnceOnly values: true/false/on/off/force
|
||||
applyOnceOnly: "off"
|
||||
|
||||
## @param dependCheckWait dependCheckWait is the time to wait for ApplicationConfiguration's dependent-resource ready
|
||||
dependCheckWait: 30s
|
||||
|
||||
@@ -86,6 +83,11 @@ webhookService:
|
||||
healthCheck:
|
||||
port: 9440
|
||||
|
||||
## @section KubeVela controller optimization parameters
|
||||
|
||||
##@param featureGates.applyOnce if enabled, the apply-once feature will be applied to all applications, no state-keep and no resource data storage in ResourceTracker
|
||||
featureGates:
|
||||
applyOnce: false
|
||||
|
||||
## @section MultiCluster parameters
|
||||
|
||||
@@ -95,6 +97,8 @@ healthCheck:
|
||||
## @param multicluster.clusterGateway.image.repository ClusterGateway image repository
|
||||
## @param multicluster.clusterGateway.image.tag ClusterGateway image tag
|
||||
## @param multicluster.clusterGateway.image.pullPolicy ClusterGateway image pull policy
|
||||
## @param multicluster.clusterGateway.resources.requests.cpu ClusterGateway cpu request
|
||||
## @param multicluster.clusterGateway.resources.requests.memory ClusterGateway memory request
|
||||
## @param multicluster.clusterGateway.resources.limits.cpu ClusterGateway cpu limit
|
||||
## @param multicluster.clusterGateway.resources.limits.memory ClusterGateway memory limit
|
||||
## @param multicluster.clusterGateway.secureTLS.enabled Whether to enable secure TLS
|
||||
@@ -106,11 +110,14 @@ multicluster:
|
||||
port: 9443
|
||||
image:
|
||||
repository: oamdev/cluster-gateway
|
||||
tag: v1.4.0
|
||||
tag: v1.8.0-alpha.3
|
||||
pullPolicy: IfNotPresent
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 20Mi
|
||||
limits:
|
||||
cpu: 100m
|
||||
cpu: 500m
|
||||
memory: 200Mi
|
||||
secureTLS:
|
||||
enabled: true
|
||||
|
||||
@@ -17,10 +17,13 @@ limitations under the License.
|
||||
package options
|
||||
|
||||
import (
|
||||
"k8s.io/apiserver/pkg/util/feature"
|
||||
"flag"
|
||||
|
||||
cliflag "k8s.io/component-base/cli/flag"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/config"
|
||||
"github.com/oam-dev/kubevela/pkg/features"
|
||||
)
|
||||
|
||||
// ServerRunOptions contains everything necessary to create and run api server
|
||||
@@ -40,6 +43,9 @@ func NewServerRunOptions() *ServerRunOptions {
|
||||
func (s *ServerRunOptions) Flags() (fss cliflag.NamedFlagSets) {
|
||||
fs := fss.FlagSet("generic")
|
||||
s.GenericServerRunOptions.AddFlags(fs, s.GenericServerRunOptions)
|
||||
feature.DefaultMutableFeatureGate.AddFlag(fss.FlagSet("featuregate"))
|
||||
features.APIServerMutableFeatureGate.AddFlag(fss.FlagSet("featuregate"))
|
||||
local := flag.NewFlagSet("klog", flag.ExitOnError)
|
||||
klog.InitFlags(local)
|
||||
fs.AddGoFlagSet(local)
|
||||
return fss
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/kubevela/pkg/util/compression"
|
||||
"github.com/kubevela/pkg/util/k8s"
|
||||
"github.com/kubevela/pkg/util/singleton"
|
||||
"k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/klog/v2"
|
||||
@@ -55,7 +56,7 @@ func (in *SystemCRDValidationHook) Run(ctx context.Context) error {
|
||||
feature.DefaultMutableFeatureGate.Enabled(features.GzipApplicationRevision) {
|
||||
appRev := &v1beta1.ApplicationRevision{}
|
||||
appRev.Name = fmt.Sprintf("core.pre-check.%d", time.Now().UnixNano())
|
||||
appRev.Namespace = types.DefaultKubeVelaNS
|
||||
appRev.Namespace = k8s.GetRuntimeNamespace()
|
||||
key := client.ObjectKeyFromObject(appRev)
|
||||
appRev.SetLabels(map[string]string{oam.LabelPreCheck: types.VelaCoreName})
|
||||
appRev.Spec.Application.Name = appRev.Name
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
pkgclient "github.com/kubevela/pkg/controller/client"
|
||||
ctrlrec "github.com/kubevela/pkg/controller/reconciler"
|
||||
pkgmulticluster "github.com/kubevela/pkg/multicluster"
|
||||
wfTypes "github.com/kubevela/workflow/pkg/types"
|
||||
@@ -171,6 +172,7 @@ func (s *CoreOptions) Flags() cliflag.NamedFlagSets {
|
||||
local := flag.NewFlagSet("klog", flag.ExitOnError)
|
||||
klog.InitFlags(local)
|
||||
kfs.AddGoFlagSet(local)
|
||||
pkgclient.AddTimeoutControllerClientFlags(fss.FlagSet("controllerclient"))
|
||||
|
||||
if s.LogDebug {
|
||||
_ = kfs.Set("v", strconv.Itoa(int(commonconfig.LogDebug)))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -74,6 +74,12 @@ var _ = Describe("Addon Test", func() {
|
||||
Expect(output).To(ContainSubstring("enabled successfully."))
|
||||
})
|
||||
|
||||
It("Enable addon with specified registry ", func() {
|
||||
output, err := e2e.LongTimeExec("vela addon enable KubeVela/test-addon", 300*time.Second)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(output).To(ContainSubstring("enabled successfully."))
|
||||
})
|
||||
|
||||
It("Disable addon test-addon", func() {
|
||||
output, err := e2e.LongTimeExec("vela addon disable test-addon", 600*time.Second)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
@@ -199,7 +199,7 @@ var ApplicationDeleteWithWaitOptions = func(context string, appName string) bool
|
||||
cli := fmt.Sprintf("vela delete %s --wait -y", appName)
|
||||
output, err := e2e.ExecAndTerminate(cli)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
gomega.Expect(output).To(gomega.ContainSubstring("deleted"))
|
||||
gomega.Expect(output).To(gomega.ContainSubstring("succeeded"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ var (
|
||||
cli := fmt.Sprintf("vela delete %s -y", applicationName)
|
||||
output, err := Exec(cli)
|
||||
gomega.Expect(err).NotTo(gomega.HaveOccurred())
|
||||
gomega.Expect(output).To(gomega.ContainSubstring("deleted from namespace"))
|
||||
gomega.Expect(output).To(gomega.ContainSubstring("succeeded"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
33
go.mod
33
go.mod
@@ -3,7 +3,7 @@ module github.com/oam-dev/kubevela
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
cuelang.org/go v0.5.0-alpha.1
|
||||
cuelang.org/go v0.5.0-beta.5
|
||||
github.com/AlecAivazis/survey/v2 v2.1.1
|
||||
github.com/FogDong/uitable v0.0.5
|
||||
github.com/Masterminds/semver/v3 v3.1.1
|
||||
@@ -49,23 +49,21 @@ require (
|
||||
github.com/google/go-github/v32 v32.1.0
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/gosuri/uilive v0.0.4
|
||||
github.com/gosuri/uitable v0.0.4
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/hashicorp/hcl/v2 v2.12.0
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174
|
||||
github.com/imdario/mergo v0.3.13
|
||||
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
|
||||
github.com/kubevela/pkg v0.0.0-20221220022408-126a9c58aa3a
|
||||
github.com/kubevela/pkg v0.0.0-20230316114047-e2b41b377bac
|
||||
github.com/kubevela/prism v1.7.0-alpha.1
|
||||
github.com/kubevela/workflow v0.3.6-0.20221228071359-3da7f1a4df6b
|
||||
github.com/kubevela/workflow v0.4.3
|
||||
github.com/kyokomi/emoji v2.2.4+incompatible
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.1
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
|
||||
github.com/oam-dev/cluster-gateway v1.7.0-alpha.1
|
||||
github.com/oam-dev/cluster-register v1.0.4-0.20220928064144-5f76a9d7ca8c
|
||||
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28
|
||||
github.com/oam-dev/terraform-controller v0.7.8
|
||||
github.com/oam-dev/terraform-controller v0.7.10
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/ginkgo/v2 v2.1.6
|
||||
@@ -89,9 +87,9 @@ require (
|
||||
go.mongodb.org/mongo-driver v1.5.1
|
||||
go.uber.org/zap v1.21.0 // indirect
|
||||
golang.org/x/crypto v0.4.0
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2
|
||||
golang.org/x/term v0.3.0
|
||||
golang.org/x/text v0.5.0
|
||||
golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c
|
||||
golang.org/x/term v0.5.0
|
||||
golang.org/x/text v0.7.0
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gotest.tools v2.2.0+incompatible
|
||||
@@ -101,14 +99,14 @@ require (
|
||||
k8s.io/apiextensions-apiserver v0.25.2
|
||||
k8s.io/apimachinery v0.25.3
|
||||
k8s.io/apiserver v0.25.3
|
||||
k8s.io/cli-runtime v0.25.2
|
||||
k8s.io/cli-runtime v0.25.3
|
||||
k8s.io/client-go v0.25.3
|
||||
k8s.io/component-base v0.25.3
|
||||
k8s.io/helm v2.17.0+incompatible
|
||||
k8s.io/klog/v2 v2.70.1
|
||||
k8s.io/kube-aggregator v0.25.3
|
||||
k8s.io/kubectl v0.25.2
|
||||
k8s.io/metrics v0.25.2
|
||||
k8s.io/kubectl v0.25.3
|
||||
k8s.io/metrics v0.25.3
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed
|
||||
open-cluster-management.io/api v0.7.0
|
||||
sigs.k8s.io/controller-runtime v0.12.3
|
||||
@@ -118,6 +116,8 @@ require (
|
||||
sigs.k8s.io/yaml v1.3.0
|
||||
)
|
||||
|
||||
require github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
@@ -302,14 +302,14 @@ require (
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
golang.org/x/mod v0.6.0 // indirect
|
||||
golang.org/x/net v0.3.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect
|
||||
golang.org/x/sys v0.3.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
|
||||
golang.org/x/tools v0.2.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/grpc v1.48.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
@@ -349,7 +349,6 @@ require (
|
||||
|
||||
replace (
|
||||
cloud.google.com/go => cloud.google.com/go v0.100.2
|
||||
cuelang.org/go => github.com/kubevela/cue v0.4.4-0.20221107123854-a976b0e340be
|
||||
github.com/docker/cli => github.com/docker/cli v20.10.9+incompatible
|
||||
github.com/docker/docker => github.com/moby/moby v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible
|
||||
github.com/wercker/stern => github.com/oam-dev/stern v1.13.2
|
||||
|
||||
57
go.sum
57
go.sum
@@ -34,6 +34,8 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
|
||||
collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.6.0/go.mod h1:zmKjrJcdo0aYcVS7bmEeSEBLPA9YJp5bjrofdU3pIXs=
|
||||
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
|
||||
cuelang.org/go v0.5.0-beta.5 h1:TAV4ZjXw2M6xf6jI8XyAAXCqWJ82Y0oxhlf9w3l544A=
|
||||
cuelang.org/go v0.5.0-beta.5/go.mod h1:okjJBHFQFer+a41sAe2SaGm1glWS8oEb6CmJvn5Zdws=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/AlecAivazis/survey/v2 v2.1.1 h1:LEMbHE0pLj75faaVEKClEX1TM4AJmmnOh9eimREzLWI=
|
||||
github.com/AlecAivazis/survey/v2 v2.1.1/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
|
||||
@@ -1060,8 +1062,6 @@ github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/g
|
||||
github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=
|
||||
github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M=
|
||||
github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU=
|
||||
github.com/gosuri/uilive v0.0.4 h1:hUEBpQDj8D8jXgtCdBu7sWsy5sbW/5GhuO8KBwJ2jyY=
|
||||
github.com/gosuri/uilive v0.0.4/go.mod h1:V/epo5LjjlDE5RJUcqx8dbw+zc93y5Ya3yg8tfZ74VI=
|
||||
github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=
|
||||
github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
|
||||
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
@@ -1285,14 +1285,12 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kubevela/cue v0.4.4-0.20221107123854-a976b0e340be h1:0xj/Rh4yVy54mUD2nLmAuN1AYgBkkHxBh4PoLGbIg5g=
|
||||
github.com/kubevela/cue v0.4.4-0.20221107123854-a976b0e340be/go.mod h1:Ya12qn7FZc+LSN0qgEhzEpnzQsvnGHVgoDrqe9i3eNg=
|
||||
github.com/kubevela/pkg v0.0.0-20221220022408-126a9c58aa3a h1:kWBTjpxcA6ZQTGyk1Mm+1/MT2+3Fv3ffQnK/1GYdXo4=
|
||||
github.com/kubevela/pkg v0.0.0-20221220022408-126a9c58aa3a/go.mod h1:IQ0/t6H7+580nwFlkt08gbPyH9S4zQNxnKTM2eiK0TI=
|
||||
github.com/kubevela/pkg v0.0.0-20230316114047-e2b41b377bac h1:TLQchMx+BRTnHyebDpOWF2RpF2eTczFBtJro3/H9vwI=
|
||||
github.com/kubevela/pkg v0.0.0-20230316114047-e2b41b377bac/go.mod h1:GilLxt+9L4sU2tLeZAGHga8wiYmjjfPX/Q6JkyuuXSM=
|
||||
github.com/kubevela/prism v1.7.0-alpha.1 h1:oeZFn1Oy6gxSSFzMTfsWjLOCKaaooMVm1JGNK4j4Mlo=
|
||||
github.com/kubevela/prism v1.7.0-alpha.1/go.mod h1:AJSDfdA+RkRSnWx3xEcogbmOTpX+l7RSIwqVHxwUtaI=
|
||||
github.com/kubevela/workflow v0.3.6-0.20221228071359-3da7f1a4df6b h1:zbBG/fTXIyhwyS3XfoYxEWJ3F1xGGQN7bCZQhlI0KYI=
|
||||
github.com/kubevela/workflow v0.3.6-0.20221228071359-3da7f1a4df6b/go.mod h1:AX/WL3G/YBkpmNpA/SKKm9M3Y0T9y95gZA8mFWylkyM=
|
||||
github.com/kubevela/workflow v0.4.3 h1:1WAMb4xrRXQW5hK5bXwV2WFHlxn2+ezkblai8oC5DmY=
|
||||
github.com/kubevela/workflow v0.4.3/go.mod h1:U94Hz5rlHPAatN+Birhumly26zjAguMumdhrYk+e5mo=
|
||||
github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U=
|
||||
github.com/kunwardeep/paralleltest v1.0.3/go.mod h1:vLydzomDFpk7yu5UX02RmP0H8QfRPOV/oFhWN85Mjb4=
|
||||
github.com/kylelemons/godebug v0.0.0-20160406211939-eadb3ce320cb/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
@@ -1437,8 +1435,8 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/hashstructure v0.0.0-20170609045927-2bca23e0e452/go.mod h1:QjSHrPWS+BGUVBYkbTZWEnOh3G1DutKwClXU/ABz6AQ=
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.1 h1:L60q1+q7cXE4JeEJJKMnh2brFIe3rZxCihYAB61ypAY=
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.1/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
@@ -1525,8 +1523,8 @@ github.com/oam-dev/stern v1.13.2 h1:jlGgtJbKmIVhzkH44ft5plkgs8XEfvxbFrQdX60CQR4=
|
||||
github.com/oam-dev/stern v1.13.2/go.mod h1:0pLjZt0amXE/ErF16Rdrgd98H2owN8Hmn3/7CX5+AeA=
|
||||
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28 h1:tD8HiFKnt0jnwdTWjeqUnfnUYLD/+Nsmj8ZGIxqDWiU=
|
||||
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28/go.mod h1:Mu8i0/DdplvnjwRbAYPsc8+LRR27n/mp8VWdkN10GzE=
|
||||
github.com/oam-dev/terraform-controller v0.7.8 h1:4Kss5EnMljKecw8o2aPCpZdOTP1L1ODgf8BjmgN/cMI=
|
||||
github.com/oam-dev/terraform-controller v0.7.8/go.mod h1:83eY+m0ehYAnQytilG9TVjuCgDQWl3+pnE6oIJ9EujE=
|
||||
github.com/oam-dev/terraform-controller v0.7.10 h1:e2STz6Od53S4Ra4+QQs65lujF50vIb6eQtTMuvvofjk=
|
||||
github.com/oam-dev/terraform-controller v0.7.10/go.mod h1:xvgChKG0pij0WEKRrX7w30SdVBPVOlRl/+Mv7+2C1cI=
|
||||
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
@@ -2302,8 +2300,8 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk=
|
||||
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -2321,8 +2319,8 @@ golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0=
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||
golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c h1:q3gFqPqH7NVofKo3c3yETAP//pPI+G5mvB7qqj1Y5kY=
|
||||
golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -2486,8 +2484,8 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@@ -2496,8 +2494,8 @@ golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuX
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
|
||||
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180805044716-cb6730876b98/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -2509,8 +2507,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
|
||||
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.0.0-20161028155119-f51c12702a4d/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -2815,8 +2813,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
@@ -2971,8 +2970,8 @@ k8s.io/apiserver v0.22.2/go.mod h1:vrpMmbyjWrgdyOvZTSpsusQq5iigKNWv9o9KlDAbBHI=
|
||||
k8s.io/apiserver v0.22.6/go.mod h1:OlL1rGa2kKWGj2JEXnwBcul/BwC9Twe95gm4ohtiIIs=
|
||||
k8s.io/apiserver v0.25.3 h1:m7+xGuG5+KYAnEsqaFtDyWMkmMMEOFYlu+NlWv5qSBI=
|
||||
k8s.io/apiserver v0.25.3/go.mod h1:9bT47iM2fzRuhICJpM/RcQR9sqDDfZ7Yw60h0p3JW08=
|
||||
k8s.io/cli-runtime v0.25.2 h1:XOx+SKRjBpYMLY/J292BHTkmyDffl/qOx3YSuFZkTuc=
|
||||
k8s.io/cli-runtime v0.25.2/go.mod h1:OQx3+/0st6x5YpkkJQlEWLC73V0wHsOFMC1/roxV8Oc=
|
||||
k8s.io/cli-runtime v0.25.3 h1:Zs7P7l7db/5J+KDePOVtDlArAa9pZXaDinGWGZl0aM8=
|
||||
k8s.io/cli-runtime v0.25.3/go.mod h1:InHHsjkyW5hQsILJGpGjeruiDZT/R0OkROQgD6GzxO4=
|
||||
k8s.io/client-go v0.0.0-20190620085101-78d2af792bab/go.mod h1:E95RaSlHr79aHaX0aGSwcPNfygDiPKOVXdmivCIZT0k=
|
||||
k8s.io/client-go v0.0.0-20190918160344-1fbdaa4c8d90/go.mod h1:J69/JveO6XESwVgG53q3Uz5OSfgsv4uxpScmmyYOOlk=
|
||||
k8s.io/client-go v0.0.0-20191122220542-ed16ecbdf3a0/go.mod h1:tyxNgOmR/Xi39HrlQ/9LQgiHJgBvmY7gp95o5GpBA4o=
|
||||
@@ -3065,11 +3064,11 @@ k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2R
|
||||
k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk=
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 h1:MQ8BAZPZlWk3S9K4a9NCkIFQtZShWqoha7snGixVgEA=
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU=
|
||||
k8s.io/kubectl v0.25.2 h1:2993lTeVimxKSWx/7z2PiJxUILygRa3tmC4QhFaeioA=
|
||||
k8s.io/kubectl v0.25.2/go.mod h1:eoBGJtKUj7x38KXelz+dqVtbtbKwCqyKzJWmBHU0prg=
|
||||
k8s.io/kubectl v0.25.3 h1:HnWJziEtmsm4JaJiKT33kG0kadx68MXxUE8UEbXnN4U=
|
||||
k8s.io/kubectl v0.25.3/go.mod h1:glU7PiVj/R6Ud4A9FJdTcJjyzOtCJyc0eO7Mrbh3jlI=
|
||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
||||
k8s.io/metrics v0.25.2 h1:105TuPaIFfr4EHzN56WwZJO7r1UesuDytNTzeMqGySo=
|
||||
k8s.io/metrics v0.25.2/go.mod h1:4NDAauOuEJ+NWO2+hWkhFE4rWBx/plLWJOYU3vGl0sA=
|
||||
k8s.io/metrics v0.25.3 h1:fp5RuALkbwI3UbKITdNYu6sa3LF4JPANR/ofq3oe+Fg=
|
||||
k8s.io/metrics v0.25.3/go.mod h1:5j5FKJb8RHsb3Q2PLsD/p1mLiA1fTrl+a62Les+KDhc=
|
||||
k8s.io/utils v0.0.0-20190221042446-c2654d5206da/go.mod h1:8k8uAuAQ0rXslZKaEWd0c3oVhZz7sSzSiPnVZayjIX0=
|
||||
k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
|
||||
|
||||
@@ -848,6 +848,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -2806,6 +2807,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -4942,6 +4944,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -5042,6 +5045,11 @@ spec:
|
||||
- suspend
|
||||
- terminated
|
||||
type: object
|
||||
workflowContext:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Record the context values to the revision.
|
||||
type: object
|
||||
required:
|
||||
- succeeded
|
||||
type: object
|
||||
|
||||
@@ -774,6 +774,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
@@ -1535,6 +1536,7 @@ spec:
|
||||
x-kubernetes-map-type: atomic
|
||||
endTime:
|
||||
format: date-time
|
||||
nullable: true
|
||||
type: string
|
||||
finished:
|
||||
type: boolean
|
||||
|
||||
@@ -60,6 +60,7 @@ import (
|
||||
common2 "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
apiutils "github.com/oam-dev/kubevela/pkg/apiserver/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/config"
|
||||
"github.com/oam-dev/kubevela/pkg/cue/script"
|
||||
"github.com/oam-dev/kubevela/pkg/definition"
|
||||
@@ -910,7 +911,6 @@ func NewAddonInstaller(ctx context.Context, cli client.Client, discoveryClient *
|
||||
func (h *Installer) enableAddon(addon *InstallPackage) (string, error) {
|
||||
var err error
|
||||
h.addon = addon
|
||||
|
||||
if !h.skipVersionValidate {
|
||||
err = checkAddonVersionMeetRequired(h.ctx, addon.SystemRequirements, h.cli, h.dc)
|
||||
if err != nil {
|
||||
@@ -1075,23 +1075,25 @@ func (h *Installer) checkDependency(addon *InstallPackage) ([]string, error) {
|
||||
|
||||
// createOrUpdate will return true if updated
|
||||
func (h *Installer) createOrUpdate(app *v1beta1.Application) (bool, error) {
|
||||
var getapp v1beta1.Application
|
||||
err := h.cli.Get(h.ctx, client.ObjectKey{Name: app.Name, Namespace: app.Namespace}, &getapp)
|
||||
// Set the publish version for the addon application
|
||||
oam.SetPublishVersion(app, apiutils.GenerateVersion("addon"))
|
||||
var existApp v1beta1.Application
|
||||
err := h.cli.Get(h.ctx, client.ObjectKey{Name: app.Name, Namespace: app.Namespace}, &existApp)
|
||||
if apierrors.IsNotFound(err) {
|
||||
return false, h.cli.Create(h.ctx, app)
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
getapp.Spec = app.Spec
|
||||
getapp.Labels = app.Labels
|
||||
getapp.Annotations = app.Annotations
|
||||
err = h.cli.Update(h.ctx, &getapp)
|
||||
existApp.Spec = app.Spec
|
||||
existApp.Labels = app.Labels
|
||||
existApp.Annotations = app.Annotations
|
||||
err = h.cli.Update(h.ctx, &existApp)
|
||||
if err != nil {
|
||||
klog.Errorf("fail to create application: %v", err)
|
||||
return false, errors.Wrap(err, "fail to create application")
|
||||
}
|
||||
getapp.DeepCopyInto(app)
|
||||
existApp.DeepCopyInto(app)
|
||||
return true, nil
|
||||
}
|
||||
|
||||
@@ -1208,6 +1210,9 @@ func (h *Installer) dispatchAddonResource(addon *InstallPackage) error {
|
||||
}
|
||||
|
||||
func (h *Installer) renderNotes(addon *InstallPackage) (string, error) {
|
||||
if len(addon.Notes.Data) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
r := addonCueTemplateRender{
|
||||
addon: addon,
|
||||
inputArgs: h.args,
|
||||
@@ -1219,7 +1224,7 @@ func (h *Installer) renderNotes(addon *InstallPackage) (string, error) {
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
notesFile := addon.Notes.Data + "\n" + contextFile
|
||||
notesFile := contextFile + "\n" + addon.Notes.Data
|
||||
val, err := value.NewValue(notesFile, nil, "")
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "build values for NOTES.cue")
|
||||
|
||||
@@ -67,13 +67,18 @@ func NewCache(ds RegistryDataStore) *Cache {
|
||||
}
|
||||
|
||||
// DiscoverAndRefreshLoop will run a loop to automatically discovery and refresh addons from registry
|
||||
func (u *Cache) DiscoverAndRefreshLoop(cacheTime time.Duration) {
|
||||
func (u *Cache) DiscoverAndRefreshLoop(ctx context.Context, cacheTime time.Duration) {
|
||||
ticker := time.NewTicker(cacheTime)
|
||||
defer ticker.Stop()
|
||||
|
||||
// This is infinite loop, we can receive a channel for close
|
||||
for ; true; <-ticker.C {
|
||||
u.discoverAndRefreshRegistry()
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
u.discoverAndRefreshRegistry()
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,9 @@ func EnableAddon(ctx context.Context, name string, version string, cli client.Cl
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := validateAddonPackage(pkg); err != nil {
|
||||
return "", errors.Wrap(err, fmt.Sprintf("failed to enable addon: %s", name))
|
||||
}
|
||||
return h.enableAddon(pkg)
|
||||
}
|
||||
|
||||
@@ -106,6 +109,9 @@ func EnableAddonByLocalDir(ctx context.Context, name string, dir string, cli cli
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := validateAddonPackage(pkg); err != nil {
|
||||
return "", errors.Wrap(err, fmt.Sprintf("failed to enable addon by local dir: %s", dir))
|
||||
}
|
||||
h := NewAddonInstaller(ctx, cli, dc, applicator, config, &Registry{Name: LocalAddonRegistryName}, args, nil, nil, opts...)
|
||||
needEnableAddonNames, err := h.checkDependency(pkg)
|
||||
if err != nil {
|
||||
|
||||
@@ -17,9 +17,12 @@ limitations under the License.
|
||||
package addon
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
@@ -29,6 +32,38 @@ import (
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func setupMockServer() *httptest.Server {
|
||||
var listenURL string
|
||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
fileList := []string{
|
||||
"index.yaml",
|
||||
"fluxcd-test-version-1.0.0.tgz",
|
||||
"fluxcd-test-version-2.0.0.tgz",
|
||||
"vela-workflow-v0.3.5.tgz",
|
||||
"foo-v1.0.0.tgz",
|
||||
"bar-v1.0.0.tgz",
|
||||
"bar-v2.0.0.tgz",
|
||||
"mock-be-dep-addon-v1.0.0.tgz",
|
||||
}
|
||||
for _, f := range fileList {
|
||||
if strings.Contains(req.URL.Path, f) {
|
||||
file, err := os.ReadFile("../../e2e/addon/mock/testrepo/helm-repo/" + f)
|
||||
if err != nil {
|
||||
_, _ = w.Write([]byte(err.Error()))
|
||||
}
|
||||
if f == "index.yaml" {
|
||||
// in index.yaml, url is hardcoded to 127.0.0.1:9098,
|
||||
// so we need to replace it with the real random listen url
|
||||
file = bytes.ReplaceAll(file, []byte("http://127.0.0.1:9098"), []byte(listenURL))
|
||||
}
|
||||
_, _ = w.Write(file)
|
||||
}
|
||||
}
|
||||
}))
|
||||
listenURL = s.URL
|
||||
return s
|
||||
}
|
||||
|
||||
var _ = Describe("test FindAddonPackagesDetailFromRegistry", func() {
|
||||
Describe("when no registry is added, no matter what you do, it will just return error", func() {
|
||||
Context("when empty addonNames and registryNames is supplied", func() {
|
||||
@@ -50,12 +85,15 @@ var _ = Describe("test FindAddonPackagesDetailFromRegistry", func() {
|
||||
})
|
||||
|
||||
Describe("one versioned registry is added", func() {
|
||||
var s *httptest.Server
|
||||
|
||||
BeforeEach(func() {
|
||||
// Prepare KubeVela registry
|
||||
s = setupMockServer()
|
||||
// Prepare registry
|
||||
reg := &Registry{
|
||||
Name: "KubeVela",
|
||||
Name: "addon_helper_test",
|
||||
Helm: &HelmSource{
|
||||
URL: "https://addons.kubevela.net",
|
||||
URL: s.URL,
|
||||
},
|
||||
}
|
||||
ds := NewRegistryDataStore(k8sClient)
|
||||
@@ -63,38 +101,36 @@ var _ = Describe("test FindAddonPackagesDetailFromRegistry", func() {
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
// Clean up KubeVela registry
|
||||
// Clean up registry
|
||||
ds := NewRegistryDataStore(k8sClient)
|
||||
Expect(ds.DeleteRegistry(context.Background(), "KubeVela")).To(Succeed())
|
||||
Expect(ds.DeleteRegistry(context.Background(), "addon_helper_test")).To(Succeed())
|
||||
s.Close()
|
||||
})
|
||||
|
||||
Context("when empty addonNames and registryNames is supplied", func() {
|
||||
It("should return error, empty addonNames are not allowed", func() {
|
||||
_, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{}, []string{"KubeVela"})
|
||||
_, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{}, []string{"addon_helper_test"})
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
It("should return error, empty addonNames are not allowed", func() {
|
||||
_, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, nil, []string{"KubeVela"})
|
||||
_, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, nil, []string{"addon_helper_test"})
|
||||
Expect(err).To(HaveOccurred())
|
||||
})
|
||||
})
|
||||
|
||||
Context("one existing addon name provided", func() {
|
||||
It("should return one valid result, matching all registries", func() {
|
||||
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"velaux"}, nil)
|
||||
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"foo"}, nil)
|
||||
|
||||
Expect(err).To(Succeed())
|
||||
Expect(res).To(HaveLen(1))
|
||||
Expect(res[0].Name).To(Equal("velaux"))
|
||||
Expect(res[0].InstallPackage).ToNot(BeNil())
|
||||
Expect(res[0].APISchema).ToNot(BeNil())
|
||||
Expect(res[0].Name).To(Equal("foo"))
|
||||
})
|
||||
It("should return one valid result, matching one registry", func() {
|
||||
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"velaux"}, []string{"KubeVela"})
|
||||
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"foo"}, []string{"addon_helper_test"})
|
||||
Expect(err).To(Succeed())
|
||||
Expect(res).To(HaveLen(1))
|
||||
Expect(res[0].Name).To(Equal("velaux"))
|
||||
Expect(res[0].InstallPackage).ToNot(BeNil())
|
||||
Expect(res[0].APISchema).ToNot(BeNil())
|
||||
Expect(res[0].Name).To(Equal("foo"))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -108,26 +144,20 @@ var _ = Describe("test FindAddonPackagesDetailFromRegistry", func() {
|
||||
|
||||
Context("two existing addon names provided", func() {
|
||||
It("should return two valid result", func() {
|
||||
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"velaux", "traefik"}, nil)
|
||||
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"foo", "bar"}, nil)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(res).To(HaveLen(2))
|
||||
Expect(res[0].Name).To(Equal("velaux"))
|
||||
Expect(res[0].InstallPackage).ToNot(BeNil())
|
||||
Expect(res[0].APISchema).ToNot(BeNil())
|
||||
Expect(res[1].Name).To(Equal("traefik"))
|
||||
Expect(res[1].InstallPackage).ToNot(BeNil())
|
||||
Expect(res[1].APISchema).ToNot(BeNil())
|
||||
Expect(res[0].Name).To(Equal("foo"))
|
||||
Expect(res[1].Name).To(Equal("bar"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("one existing addon name and one non-existent addon name provided", func() {
|
||||
It("should return only one valid result", func() {
|
||||
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"velaux", "non-existent-addon"}, nil)
|
||||
res, err := FindAddonPackagesDetailFromRegistry(context.Background(), k8sClient, []string{"foo", "non-existent-addon"}, nil)
|
||||
Expect(err).To(Succeed())
|
||||
Expect(res).To(HaveLen(1))
|
||||
Expect(res[0].Name).To(Equal("velaux"))
|
||||
Expect(res[0].InstallPackage).ToNot(BeNil())
|
||||
Expect(res[0].APISchema).ToNot(BeNil())
|
||||
Expect(res[0].Name).To(Equal("foo"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -196,9 +196,13 @@ func (cmd *InitCmd) createHelmComponent() error {
|
||||
tmpl := helmComponentTmpl{}
|
||||
tmpl.Type = "helm"
|
||||
tmpl.Properties.RepoType = "helm"
|
||||
if strings.HasPrefix(cmd.HelmRepoURL, "oci") {
|
||||
tmpl.Properties.RepoType = "oci"
|
||||
}
|
||||
tmpl.Properties.URL = cmd.HelmRepoURL
|
||||
tmpl.Properties.Chart = cmd.HelmChartName
|
||||
tmpl.Properties.Version = cmd.HelmChartVersion
|
||||
tmpl.Name = "addon-" + cmd.AddonName
|
||||
|
||||
str, err := toCUEResourceString(tmpl)
|
||||
if err != nil {
|
||||
@@ -383,6 +387,7 @@ func (cmd *InitCmd) writeFiles() error {
|
||||
|
||||
// helmComponentTmpl is a template for a helm component .cue in an addon
|
||||
type helmComponentTmpl struct {
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Properties struct {
|
||||
RepoType string `json:"repoType"`
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -503,6 +504,19 @@ func checkBondComponentExist(u unstructured.Unstructured, app v1beta1.Applicatio
|
||||
return false
|
||||
}
|
||||
|
||||
func validateAddonPackage(addonPkg *InstallPackage) error {
|
||||
if reflect.DeepEqual(addonPkg.Meta, Meta{}) {
|
||||
return fmt.Errorf("the addon package doesn't have `metadata.yaml`")
|
||||
}
|
||||
if addonPkg.Name == "" {
|
||||
return fmt.Errorf("`matadata.yaml` must define the name of addon")
|
||||
}
|
||||
if addonPkg.Version == "" {
|
||||
return fmt.Errorf("`matadata.yaml` must define the version of addon")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// FilterDependencyRegistries will return all registries besides the target registry itself
|
||||
func FilterDependencyRegistries(i int, rs []Registry) []Registry {
|
||||
if i >= len(rs) {
|
||||
|
||||
@@ -17,9 +17,11 @@ limitations under the License.
|
||||
package addon
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -402,6 +404,30 @@ func TestFilterDependencyRegistries(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckAddonPackageValid(t *testing.T) {
|
||||
testCases := []struct {
|
||||
testCase Meta
|
||||
err error
|
||||
}{{
|
||||
testCase: Meta{},
|
||||
err: fmt.Errorf("the addon package doesn't have `metadata.yaml`"),
|
||||
}, {
|
||||
testCase: Meta{Version: "v1.4.0"},
|
||||
err: fmt.Errorf("`matadata.yaml` must define the name of addon"),
|
||||
}, {
|
||||
testCase: Meta{Name: "test-addon"},
|
||||
err: fmt.Errorf("`matadata.yaml` must define the version of addon"),
|
||||
}, {
|
||||
testCase: Meta{Name: "test-addon", Version: "1.4.5"},
|
||||
err: nil,
|
||||
},
|
||||
}
|
||||
for _, testCase := range testCases {
|
||||
err := validateAddonPackage(&InstallPackage{Meta: testCase.testCase})
|
||||
assert.Equal(t, reflect.DeepEqual(err, testCase.err), true)
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
compDefYaml = `
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
|
||||
@@ -149,7 +149,7 @@ func (i versionedRegistry) loadAddon(ctx context.Context, name, version string)
|
||||
if addonVersion == nil {
|
||||
return nil, errors.Errorf("specified version %s not exist", utils.Sanitize(version))
|
||||
}
|
||||
klog.Infof("Addon '%s' with version '%s' found from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
|
||||
klog.V(5).Infof("Addon '%s' with version '%s' found from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
|
||||
for _, chartURL := range addonVersion.URLs {
|
||||
if !utils.IsValidURL(chartURL) {
|
||||
chartURL, err = utils.JoinURL(i.url, chartURL)
|
||||
@@ -159,10 +159,12 @@ func (i versionedRegistry) loadAddon(ctx context.Context, name, version string)
|
||||
}
|
||||
archive, err := common.HTTPGetWithOption(ctx, chartURL, i.Opts)
|
||||
if err != nil {
|
||||
klog.Warningf("failed to download the addon package %s:%s", chartURL, err.Error())
|
||||
continue
|
||||
}
|
||||
bufferedFile, err := loader.LoadArchiveFiles(bytes.NewReader(archive))
|
||||
if err != nil {
|
||||
klog.Warningf("failed to load the addon package:%s", err.Error())
|
||||
continue
|
||||
}
|
||||
addonPkg, err := loadAddonPackage(name, bufferedFile)
|
||||
@@ -172,6 +174,7 @@ func (i versionedRegistry) loadAddon(ctx context.Context, name, version string)
|
||||
addonPkg.AvailableVersions = availableVersions
|
||||
addonPkg.RegistryName = i.name
|
||||
addonPkg.Meta.SystemRequirements = LoadSystemRequirements(addonVersion.Annotations)
|
||||
klog.V(5).Infof("Addon '%s' with version '%s' loaded successfully from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
|
||||
return addonPkg, nil
|
||||
}
|
||||
return nil, ErrFetch
|
||||
|
||||
@@ -59,8 +59,8 @@ func (a *Application) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (a *Application) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (a *Application) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if a.Name != "" {
|
||||
index["name"] = a.Name
|
||||
}
|
||||
@@ -154,8 +154,8 @@ func (a *ApplicationComponent) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (a *ApplicationComponent) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (a *ApplicationComponent) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if a.Name != "" {
|
||||
index["name"] = a.Name
|
||||
}
|
||||
@@ -202,8 +202,8 @@ func (a *ApplicationPolicy) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (a *ApplicationPolicy) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (a *ApplicationPolicy) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if a.Name != "" {
|
||||
index["name"] = a.Name
|
||||
}
|
||||
@@ -348,8 +348,8 @@ func (a *ApplicationRevision) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (a *ApplicationRevision) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (a *ApplicationRevision) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if a.Version != "" {
|
||||
index["version"] = a.Version
|
||||
}
|
||||
@@ -434,8 +434,8 @@ func (w *ApplicationTrigger) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (w *ApplicationTrigger) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (w *ApplicationTrigger) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if w.AppPrimaryKey != "" {
|
||||
index["appPrimaryKey"] = w.AppPrimaryKey
|
||||
}
|
||||
|
||||
@@ -93,8 +93,8 @@ func (c *Cluster) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index set to nil for list
|
||||
func (c *Cluster) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (c *Cluster) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if c.Name != "" {
|
||||
index["name"] = c.Name
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ func (p *Env) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (p *Env) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (p *Env) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if p.Name != "" {
|
||||
index["name"] = p.Name
|
||||
}
|
||||
|
||||
@@ -62,8 +62,8 @@ func (e *EnvBinding) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (e *EnvBinding) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (e *EnvBinding) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if e.Name != "" {
|
||||
index["name"] = e.Name
|
||||
}
|
||||
|
||||
@@ -106,6 +106,11 @@ func (j *JSONStruct) JSON() string {
|
||||
return string(b)
|
||||
}
|
||||
|
||||
// Properties return the map
|
||||
func (j *JSONStruct) Properties() map[string]interface{} {
|
||||
return *j
|
||||
}
|
||||
|
||||
// RawExtension Encoded as a RawExtension
|
||||
func (j *JSONStruct) RawExtension() *runtime.RawExtension {
|
||||
yamlByte, err := yaml.Marshal(j)
|
||||
|
||||
@@ -61,8 +61,8 @@ func (p Pipeline) ShortTableName() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (p Pipeline) Index() map[string]string {
|
||||
var index = make(map[string]string)
|
||||
func (p Pipeline) Index() map[string]interface{} {
|
||||
var index = make(map[string]interface{})
|
||||
if p.Project != "" {
|
||||
index["project"] = p.Project
|
||||
}
|
||||
@@ -102,8 +102,8 @@ func (c *PipelineContext) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (c *PipelineContext) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (c *PipelineContext) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if c.ProjectName != "" {
|
||||
index["project_name"] = c.ProjectName
|
||||
}
|
||||
|
||||
@@ -54,8 +54,8 @@ func (p *Project) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (p *Project) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (p *Project) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if p.Name != "" {
|
||||
index["name"] = p.Name
|
||||
}
|
||||
|
||||
@@ -146,8 +146,8 @@ func (u *SystemInfo) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (u *SystemInfo) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (u *SystemInfo) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if u.InstallID != "" {
|
||||
index["installID"] = u.InstallID
|
||||
}
|
||||
|
||||
@@ -48,8 +48,8 @@ func (d *Target) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (d *Target) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (d *Target) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if d.Name != "" {
|
||||
index["name"] = d.Name
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ func (u *User) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (u *User) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (u *User) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if u.Name != "" {
|
||||
index["name"] = u.Name
|
||||
}
|
||||
@@ -106,8 +106,8 @@ func (u *ProjectUser) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (u *ProjectUser) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (u *ProjectUser) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if u.Username != "" {
|
||||
index["username"] = u.Username
|
||||
}
|
||||
@@ -177,8 +177,8 @@ func (r *Role) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (r *Role) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (r *Role) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if r.Name != "" {
|
||||
index["name"] = r.Name
|
||||
}
|
||||
@@ -207,8 +207,8 @@ func (p *Permission) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (p *Permission) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (p *Permission) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if p.Name != "" {
|
||||
index["name"] = p.Name
|
||||
}
|
||||
@@ -250,8 +250,8 @@ func (p *PermissionTemplate) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom index
|
||||
func (p *PermissionTemplate) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (p *PermissionTemplate) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if p.Name != "" {
|
||||
index["name"] = p.Name
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ const (
|
||||
|
||||
// LabelSyncGeneration describes the generation synced from
|
||||
LabelSyncGeneration = "ux.oam.dev/synced-generation"
|
||||
// LabelSyncRevision describes the revision name synced from
|
||||
LabelSyncRevision = "ux.oam.dev/synced-revision"
|
||||
// LabelSyncNamespace describes the namespace synced from
|
||||
LabelSyncNamespace = "ux.oam.dev/from-namespace"
|
||||
)
|
||||
@@ -56,26 +58,16 @@ const (
|
||||
FromInner = "from-inner-system"
|
||||
)
|
||||
|
||||
// DataStoreApp is a memory struct that describes the model of an application in datastore
|
||||
type DataStoreApp struct {
|
||||
AppMeta *Application
|
||||
Env *Env
|
||||
Eb *EnvBinding
|
||||
Comps []*ApplicationComponent
|
||||
Policies []*ApplicationPolicy
|
||||
Workflow *Workflow
|
||||
Targets []*Target
|
||||
Record *WorkflowRecord
|
||||
Revision *ApplicationRevision
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
// DefaultInitName is default object name for initialization
|
||||
DefaultInitName = "default"
|
||||
|
||||
// DefaultAddonProject is default addon projects
|
||||
DefaultAddonProject = "addons"
|
||||
// DefaultSystemProject is project name for the system
|
||||
DefaultSystemProject = "system"
|
||||
|
||||
// DefaultSystemProjectAlias is project alias for the system
|
||||
DefaultSystemProjectAlias = "System"
|
||||
|
||||
// DefaultInitNamespace is default namespace name for initialization
|
||||
DefaultInitNamespace = "default"
|
||||
|
||||
@@ -18,7 +18,6 @@ package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
|
||||
@@ -42,15 +41,16 @@ type Workflow struct {
|
||||
Alias string `json:"alias"`
|
||||
Description string `json:"description"`
|
||||
// Workflow used by the default
|
||||
Default *bool `json:"default"`
|
||||
AppPrimaryKey string `json:"appPrimaryKey"`
|
||||
EnvName string `json:"envName"`
|
||||
Steps []WorkflowStep `json:"steps,omitempty"`
|
||||
Default *bool `json:"default"`
|
||||
AppPrimaryKey string `json:"appPrimaryKey"`
|
||||
EnvName string `json:"envName"`
|
||||
Mode workflowv1alpha1.WorkflowExecuteMode `json:"mode,omitempty"`
|
||||
Steps []WorkflowStep `json:"steps,omitempty"`
|
||||
}
|
||||
|
||||
// WorkflowStep defines how to execute a workflow step.
|
||||
type WorkflowStep struct {
|
||||
WorkflowStepBase `json:",inline"`
|
||||
WorkflowStepBase `json:",inline" bson:",inline"`
|
||||
SubSteps []WorkflowStepBase `json:"subSteps,omitempty"`
|
||||
}
|
||||
|
||||
@@ -87,8 +87,8 @@ func (w *Workflow) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom primary key
|
||||
func (w *Workflow) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (w *Workflow) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if w.Name != "" {
|
||||
index["name"] = w.Name
|
||||
}
|
||||
@@ -99,7 +99,7 @@ func (w *Workflow) Index() map[string]string {
|
||||
index["envName"] = w.EnvName
|
||||
}
|
||||
if w.Default != nil {
|
||||
index["default"] = strconv.FormatBool(*w.Default)
|
||||
index["default"] = *w.Default
|
||||
}
|
||||
|
||||
return index
|
||||
@@ -116,14 +116,18 @@ type WorkflowRecord struct {
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace"`
|
||||
StartTime time.Time `json:"startTime,omitempty"`
|
||||
EndTime time.Time `json:"endTime,omitempty"`
|
||||
Finished string `json:"finished"`
|
||||
Steps []WorkflowStepStatus `json:"steps,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Message string `json:"message"`
|
||||
Mode string `json:"mode"`
|
||||
ContextValue map[string]string `json:"contextValue,omitempty"`
|
||||
}
|
||||
|
||||
// WorkflowStepStatus is the workflow step status database model
|
||||
type WorkflowStepStatus struct {
|
||||
StepStatus `json:",inline"`
|
||||
StepStatus `json:",inline" bson:",inline"`
|
||||
SubStepsStatus []StepStatus `json:"subSteps,omitempty"`
|
||||
}
|
||||
|
||||
@@ -156,8 +160,8 @@ func (w *WorkflowRecord) PrimaryKey() string {
|
||||
}
|
||||
|
||||
// Index return custom primary key
|
||||
func (w *WorkflowRecord) Index() map[string]string {
|
||||
index := make(map[string]string)
|
||||
func (w *WorkflowRecord) Index() map[string]interface{} {
|
||||
index := make(map[string]interface{})
|
||||
if w.Name != "" {
|
||||
index["name"] = w.Name
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func CreateEnv(ctx context.Context, kubeClient client.Client, ds datastore.DataS
|
||||
env.Namespace = env.Name
|
||||
}
|
||||
|
||||
// create namespace at first
|
||||
// Creating the namespace at first.
|
||||
err = util.CreateOrUpdateNamespace(ctx, kubeClient, env.Namespace,
|
||||
util.MergeOverrideLabels(map[string]string{
|
||||
oam.LabelControlPlaneNamespaceUsage: oam.VelaNamespaceUsageEnv,
|
||||
|
||||
@@ -67,6 +67,10 @@ func ListFullEnvBinding(ctx context.Context, ds datastore.DataStore, option EnvL
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
workflows, err := ListWorkflowForApp(ctx, ds, option.AppPrimaryKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var list []*apisv1.EnvBindingBase
|
||||
for _, eb := range envBindings {
|
||||
env, err := pickEnv(envs, eb.Name)
|
||||
@@ -74,7 +78,11 @@ func ListFullEnvBinding(ctx context.Context, ds datastore.DataStore, option EnvL
|
||||
klog.Errorf("envbinding invalid %s", err.Error())
|
||||
continue
|
||||
}
|
||||
list = append(list, assembler.ConvertEnvBindingModelToBase(eb, env, targets))
|
||||
workflow, err := pickEnvWorkflow(workflows, eb.Name)
|
||||
if err != nil {
|
||||
klog.Errorf("workflow invalid %s", err.Error())
|
||||
}
|
||||
list = append(list, assembler.ConvertEnvBindingModelToBase(eb, env, targets, workflow))
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
@@ -111,3 +119,12 @@ func pickEnv(envs []*model.Env, name string) (*model.Env, error) {
|
||||
}
|
||||
return nil, bcode.ErrEnvNotExisted
|
||||
}
|
||||
|
||||
func pickEnvWorkflow(workflows []*model.Workflow, name string) (*model.Workflow, error) {
|
||||
for _, w := range workflows {
|
||||
if w.EnvName == name {
|
||||
return w, nil
|
||||
}
|
||||
}
|
||||
return nil, bcode.ErrWorkflowNotExist
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ func NewDatastore(cfg datastore.Config) (ds datastore.DataStore, err error) {
|
||||
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
|
||||
}
|
||||
case "kubeapi":
|
||||
ds, err = kubeapi.New(context.Background(), cfg)
|
||||
ds, err = kubeapi.New(context.Background(), cfg, k8sClient)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create mongodb datastore instance failure %w", err)
|
||||
}
|
||||
|
||||
@@ -639,6 +639,38 @@ func GetWorkflowForApp(ctx context.Context, ds datastore.DataStore, app *model.A
|
||||
return &workflow, nil
|
||||
}
|
||||
|
||||
// GetWorkflowByEnv get the workflow by specified environment name.
|
||||
func GetWorkflowByEnv(ctx context.Context, ds datastore.DataStore, app *model.Application, envName string) (*model.Workflow, error) {
|
||||
var workflow = model.Workflow{
|
||||
AppPrimaryKey: app.PrimaryKey(),
|
||||
EnvName: envName,
|
||||
}
|
||||
res, err := ds.List(ctx, &workflow, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(res) > 0 {
|
||||
return res[0].(*model.Workflow), nil
|
||||
}
|
||||
return nil, bcode.ErrWorkflowNotExist
|
||||
}
|
||||
|
||||
// ListWorkflowForApp list all workflows of the application
|
||||
func ListWorkflowForApp(ctx context.Context, ds datastore.DataStore, appPrimaryKey string) ([]*model.Workflow, error) {
|
||||
var workflow = model.Workflow{
|
||||
AppPrimaryKey: appPrimaryKey,
|
||||
}
|
||||
workflows, err := ds.List(ctx, &workflow, &datastore.ListOptions{SortBy: []datastore.SortOption{{Key: "createTime", Order: datastore.SortOrderDescending}}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var res []*model.Workflow
|
||||
for _, w := range workflows {
|
||||
res = append(res, w.(*model.Workflow))
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
// ConvertWorkflowName generate the workflow name
|
||||
func ConvertWorkflowName(envName string) string {
|
||||
return fmt.Sprintf("workflow-%s", envName)
|
||||
|
||||
@@ -67,6 +67,7 @@ type AddonService interface {
|
||||
DisableAddon(ctx context.Context, name string, force bool) error
|
||||
ListEnabledAddon(ctx context.Context) ([]*apis.AddonBaseStatus, error)
|
||||
UpdateAddon(ctx context.Context, name string, args apis.EnableAddonRequest) error
|
||||
Init(ctx context.Context) error
|
||||
}
|
||||
|
||||
// AddonImpl2AddonRes convert pkgaddon.UIData to the type apiserver need
|
||||
@@ -116,44 +117,35 @@ func AddonImpl2AddonRes(impl *pkgaddon.UIData, config *rest.Config) (*apis.Detai
|
||||
|
||||
// NewAddonService returns an addon service
|
||||
func NewAddonService(cacheTime time.Duration) AddonService {
|
||||
config, err := clients.GetKubeConfig()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
kubecli, err := clients.GetKubeClient()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
dc, err := clients.GetDiscoveryClient()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ds := pkgaddon.NewRegistryDataStore(kubecli)
|
||||
cache := pkgaddon.NewCache(ds)
|
||||
|
||||
// TODO(@wonderflow): it's better to add a close channel here, but it should be fine as it's only invoke once in APIServer.
|
||||
go cache.DiscoverAndRefreshLoop(cacheTime)
|
||||
|
||||
return &addonServiceImpl{
|
||||
addonRegistryCache: cache,
|
||||
addonRegistryDS: ds,
|
||||
kubeClient: kubecli,
|
||||
config: config,
|
||||
apply: apply.NewAPIApplicator(kubecli),
|
||||
mutex: new(sync.RWMutex),
|
||||
discoveryClient: dc,
|
||||
cacheTime: cacheTime,
|
||||
mutex: new(sync.RWMutex),
|
||||
discoveryClient: dc,
|
||||
}
|
||||
}
|
||||
|
||||
type addonServiceImpl struct {
|
||||
cacheTime time.Duration
|
||||
addonRegistryCache *pkgaddon.Cache
|
||||
addonRegistryDS pkgaddon.RegistryDataStore
|
||||
kubeClient client.Client
|
||||
config *rest.Config
|
||||
apply apply.Applicator
|
||||
RegistryDS pkgaddon.RegistryDataStore `inject:"registryDatastore"`
|
||||
KubeClient client.Client `inject:"kubeClient"`
|
||||
KubeConfig *rest.Config `inject:"kubeConfig"`
|
||||
Apply apply.Applicator `inject:"apply"`
|
||||
discoveryClient *discovery.DiscoveryClient
|
||||
mutex *sync.RWMutex
|
||||
}
|
||||
|
||||
mutex *sync.RWMutex
|
||||
func (u *addonServiceImpl) Init(ctx context.Context) error {
|
||||
cache := pkgaddon.NewCache(u.RegistryDS)
|
||||
// TODO(@wonderflow): it's better to add a close channel here, but it should be fine as it's only invoke once in APIServer.
|
||||
go cache.DiscoverAndRefreshLoop(ctx, u.cacheTime)
|
||||
u.addonRegistryCache = cache
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAddon will get addon information
|
||||
@@ -161,7 +153,7 @@ func (u *addonServiceImpl) GetAddon(ctx context.Context, name string, registry s
|
||||
var addon *pkgaddon.UIData
|
||||
var err error
|
||||
if registry == "" {
|
||||
registries, err := u.addonRegistryDS.ListRegistries(ctx)
|
||||
registries, err := u.RegistryDS.ListRegistries(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -175,7 +167,7 @@ func (u *addonServiceImpl) GetAddon(ctx context.Context, name string, registry s
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addonRegistry, err := u.addonRegistryDS.GetRegistry(ctx, registry)
|
||||
addonRegistry, err := u.RegistryDS.GetRegistry(ctx, registry)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -189,9 +181,9 @@ func (u *addonServiceImpl) GetAddon(ctx context.Context, name string, registry s
|
||||
return nil, bcode.ErrAddonNotExist
|
||||
}
|
||||
|
||||
addon.UISchema = renderAddonCustomUISchema(ctx, u.kubeClient, name, renderDefaultUISchema(addon.APISchema))
|
||||
addon.UISchema = renderAddonCustomUISchema(ctx, u.KubeClient, name, renderDefaultUISchema(addon.APISchema))
|
||||
|
||||
a, err := AddonImpl2AddonRes(addon, u.config)
|
||||
a, err := AddonImpl2AddonRes(addon, u.KubeConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -199,12 +191,12 @@ func (u *addonServiceImpl) GetAddon(ctx context.Context, name string, registry s
|
||||
}
|
||||
|
||||
func (u *addonServiceImpl) StatusAddon(ctx context.Context, name string) (*apis.AddonStatusResponse, error) {
|
||||
status, err := pkgaddon.GetAddonStatus(ctx, u.kubeClient, name)
|
||||
status, err := pkgaddon.GetAddonStatus(ctx, u.KubeClient, name)
|
||||
if err != nil {
|
||||
return nil, bcode.ErrGetAddonApplication
|
||||
}
|
||||
var allClusters []apis.NameAlias
|
||||
clusters, err := multicluster.ListVirtualClusters(ctx, u.kubeClient)
|
||||
clusters, err := multicluster.ListVirtualClusters(ctx, u.KubeClient)
|
||||
if err != nil {
|
||||
klog.Errorf("err while list all clusters: %v", err)
|
||||
}
|
||||
@@ -235,7 +227,7 @@ func (u *addonServiceImpl) StatusAddon(ctx context.Context, name string) (*apis.
|
||||
}
|
||||
|
||||
var sec v1.Secret
|
||||
err = u.kubeClient.Get(ctx, client.ObjectKey{
|
||||
err = u.KubeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: types.DefaultKubeVelaNS,
|
||||
Name: addonutil.Addon2SecName(name),
|
||||
}, &sec)
|
||||
@@ -255,7 +247,7 @@ func (u *addonServiceImpl) StatusAddon(ctx context.Context, name string) (*apis.
|
||||
|
||||
func (u *addonServiceImpl) ListAddons(ctx context.Context, registry, query string) ([]*apis.DetailAddonResponse, error) {
|
||||
var addons []*pkgaddon.UIData
|
||||
rs, err := u.addonRegistryDS.ListRegistries(ctx)
|
||||
rs, err := u.RegistryDS.ListRegistries(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -300,7 +292,7 @@ func (u *addonServiceImpl) ListAddons(ctx context.Context, registry, query strin
|
||||
|
||||
var addonResources []*apis.DetailAddonResponse
|
||||
for _, a := range addons {
|
||||
addonRes, err := AddonImpl2AddonRes(a, u.config)
|
||||
addonRes, err := AddonImpl2AddonRes(a, u.KubeConfig)
|
||||
if err != nil {
|
||||
klog.Errorf("err while converting AddonImpl to DetailAddonResponse: %v", err)
|
||||
continue
|
||||
@@ -314,13 +306,13 @@ func (u *addonServiceImpl) ListAddons(ctx context.Context, registry, query strin
|
||||
}
|
||||
|
||||
func (u *addonServiceImpl) DeleteAddonRegistry(ctx context.Context, name string) error {
|
||||
return u.addonRegistryDS.DeleteRegistry(ctx, name)
|
||||
return u.RegistryDS.DeleteRegistry(ctx, name)
|
||||
}
|
||||
|
||||
func (u *addonServiceImpl) CreateAddonRegistry(ctx context.Context, req apis.CreateAddonRegistryRequest) (*apis.AddonRegistry, error) {
|
||||
r := addonRegistryModelFromCreateAddonRegistryRequest(req)
|
||||
|
||||
err := u.addonRegistryDS.AddRegistry(ctx, r)
|
||||
err := u.RegistryDS.AddRegistry(ctx, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -340,7 +332,7 @@ func convertAddonRegistry(r pkgaddon.Registry) *apis.AddonRegistry {
|
||||
}
|
||||
|
||||
func (u *addonServiceImpl) GetAddonRegistry(ctx context.Context, name string) (*apis.AddonRegistry, error) {
|
||||
r, err := u.addonRegistryDS.GetRegistry(ctx, name)
|
||||
r, err := u.RegistryDS.GetRegistry(ctx, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -348,7 +340,7 @@ func (u *addonServiceImpl) GetAddonRegistry(ctx context.Context, name string) (*
|
||||
}
|
||||
|
||||
func (u addonServiceImpl) UpdateAddonRegistry(ctx context.Context, name string, req apis.UpdateAddonRegistryRequest) (*apis.AddonRegistry, error) {
|
||||
r, err := u.addonRegistryDS.GetRegistry(ctx, name)
|
||||
r, err := u.RegistryDS.GetRegistry(ctx, name)
|
||||
if err != nil {
|
||||
return nil, bcode.ErrAddonRegistryNotExist
|
||||
}
|
||||
@@ -365,7 +357,7 @@ func (u addonServiceImpl) UpdateAddonRegistry(ctx context.Context, name string,
|
||||
r.Gitlab = req.Gitlab
|
||||
}
|
||||
|
||||
err = u.addonRegistryDS.UpdateRegistry(ctx, r)
|
||||
err = u.RegistryDS.UpdateRegistry(ctx, r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -376,7 +368,7 @@ func (u addonServiceImpl) UpdateAddonRegistry(ctx context.Context, name string,
|
||||
func (u *addonServiceImpl) ListAddonRegistries(ctx context.Context) ([]*apis.AddonRegistry, error) {
|
||||
|
||||
var list []*apis.AddonRegistry
|
||||
registries, err := u.addonRegistryDS.ListRegistries(ctx)
|
||||
registries, err := u.RegistryDS.ListRegistries(ctx)
|
||||
if err != nil {
|
||||
// the storage configmap still not exist, don't return error add registry will create the configmap
|
||||
if errors2.IsNotFound(err) {
|
||||
@@ -396,7 +388,7 @@ func (u *addonServiceImpl) ListAddonRegistries(ctx context.Context) ([]*apis.Add
|
||||
|
||||
func (u *addonServiceImpl) EnableAddon(ctx context.Context, name string, args apis.EnableAddonRequest) error {
|
||||
var err error
|
||||
registries, err := u.addonRegistryDS.ListRegistries(ctx)
|
||||
registries, err := u.RegistryDS.ListRegistries(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -416,7 +408,7 @@ func (u *addonServiceImpl) EnableAddon(ctx context.Context, name string, args ap
|
||||
continue
|
||||
}
|
||||
// TODO: response the additional info to velaux users
|
||||
_, err = pkgaddon.EnableAddon(ctx, name, args.Version, u.kubeClient, u.discoveryClient, u.apply, u.config, r, args.Args, u.addonRegistryCache, pkgaddon.FilterDependencyRegistries(i, registries))
|
||||
_, err = pkgaddon.EnableAddon(ctx, name, args.Version, u.KubeClient, u.discoveryClient, u.Apply, u.KubeConfig, r, args.Args, u.addonRegistryCache, pkgaddon.FilterDependencyRegistries(i, registries))
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -441,7 +433,7 @@ func (u *addonServiceImpl) EnableAddon(ctx context.Context, name string, args ap
|
||||
}
|
||||
|
||||
func (u *addonServiceImpl) DisableAddon(ctx context.Context, name string, force bool) error {
|
||||
err := pkgaddon.DisableAddon(ctx, u.kubeClient, name, u.config, force)
|
||||
err := pkgaddon.DisableAddon(ctx, u.KubeClient, name, u.KubeConfig, force)
|
||||
if err != nil {
|
||||
klog.Errorf("delete application fail: %s", err.Error())
|
||||
return err
|
||||
@@ -451,7 +443,7 @@ func (u *addonServiceImpl) DisableAddon(ctx context.Context, name string, force
|
||||
|
||||
func (u *addonServiceImpl) ListEnabledAddon(ctx context.Context) ([]*apis.AddonBaseStatus, error) {
|
||||
apps := &v1beta1.ApplicationList{}
|
||||
if err := u.kubeClient.List(ctx, apps, client.InNamespace(types.DefaultKubeVelaNS), client.HasLabels{oam.LabelAddonName}); err != nil {
|
||||
if err := u.KubeClient.List(ctx, apps, client.InNamespace(types.DefaultKubeVelaNS), client.HasLabels{oam.LabelAddonName}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var response []*apis.AddonBaseStatus
|
||||
@@ -470,10 +462,9 @@ func (u *addonServiceImpl) ListEnabledAddon(ctx context.Context) ([]*apis.AddonB
|
||||
}
|
||||
|
||||
func (u *addonServiceImpl) UpdateAddon(ctx context.Context, name string, args apis.EnableAddonRequest) error {
|
||||
|
||||
var app v1beta1.Application
|
||||
// check addon application whether exist
|
||||
err := u.kubeClient.Get(ctx, client.ObjectKey{
|
||||
err := u.KubeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: types.DefaultKubeVelaNS,
|
||||
Name: addonutil.Addon2AppName(name),
|
||||
}, &app)
|
||||
@@ -481,22 +472,20 @@ func (u *addonServiceImpl) UpdateAddon(ctx context.Context, name string, args ap
|
||||
return err
|
||||
}
|
||||
|
||||
registries, err := u.addonRegistryDS.ListRegistries(ctx)
|
||||
registries, err := u.RegistryDS.ListRegistries(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, r := range registries {
|
||||
// TODO: response the additional info to velaux users
|
||||
_, err = pkgaddon.EnableAddon(ctx, name, args.Version, u.kubeClient, u.discoveryClient, u.apply, u.config, r, args.Args, u.addonRegistryCache, pkgaddon.FilterDependencyRegistries(i, registries))
|
||||
_, err = pkgaddon.EnableAddon(ctx, name, args.Version, u.KubeClient, u.discoveryClient, u.Apply, u.KubeConfig, r, args.Args, u.addonRegistryCache, pkgaddon.FilterDependencyRegistries(i, registries))
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if errors.Is(err, pkgaddon.ErrNotExist) {
|
||||
continue
|
||||
}
|
||||
|
||||
// wrap this error with special bcode
|
||||
if errors.As(err, &pkgaddon.VersionUnMatchError{}) {
|
||||
return bcode.ErrAddonSystemVersionMismatch
|
||||
|
||||
@@ -19,7 +19,6 @@ package service
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
@@ -42,7 +41,7 @@ import (
|
||||
velatypes "github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/domain/repository"
|
||||
syncconvert "github.com/oam-dev/kubevela/pkg/apiserver/event/sync/convert"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/event/sync/convert"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
|
||||
assembler "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/assembler/v1"
|
||||
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
|
||||
@@ -52,6 +51,7 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
pkgUtils "github.com/oam-dev/kubevela/pkg/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/app"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/apply"
|
||||
commonutil "github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
)
|
||||
@@ -90,6 +90,7 @@ type ApplicationService interface {
|
||||
UpdateApplicationTrait(ctx context.Context, app *model.Application, component *model.ApplicationComponent, traitType string, req apisv1.UpdateApplicationTraitRequest) (*apisv1.ApplicationTrait, error)
|
||||
ListRevisions(ctx context.Context, appName, envName, status string, page, pageSize int) (*apisv1.ListRevisionsResponse, error)
|
||||
DetailRevision(ctx context.Context, appName, revisionName string) (*apisv1.DetailRevisionResponse, error)
|
||||
RollbackWithRevision(ctx context.Context, app *model.Application, revisionName string) (*apisv1.ApplicationRollbackResponse, error)
|
||||
Statistics(ctx context.Context, app *model.Application) (*apisv1.ApplicationStatisticsResponse, error)
|
||||
ListRecords(ctx context.Context, appName string) (*apisv1.ListWorkflowRecordsResponse, error)
|
||||
CompareApp(ctx context.Context, app *model.Application, compareReq apisv1.AppCompareReq) (*apisv1.AppCompareResponse, error)
|
||||
@@ -98,6 +99,7 @@ type ApplicationService interface {
|
||||
CreateApplicationTrigger(ctx context.Context, app *model.Application, req apisv1.CreateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error)
|
||||
ListApplicationTriggers(ctx context.Context, app *model.Application) ([]*apisv1.ApplicationTriggerBase, error)
|
||||
DeleteApplicationTrigger(ctx context.Context, app *model.Application, triggerName string) error
|
||||
UpdateApplicationTrigger(ctx context.Context, app *model.Application, token string, req apisv1.UpdateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error)
|
||||
}
|
||||
|
||||
type applicationServiceImpl struct {
|
||||
@@ -409,6 +411,18 @@ func (c *applicationServiceImpl) CreateApplication(ctx context.Context, req apis
|
||||
|
||||
// CreateApplicationTrigger create application trigger
|
||||
func (c *applicationServiceImpl) CreateApplicationTrigger(ctx context.Context, app *model.Application, req apisv1.CreateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error) {
|
||||
// checking the workflow
|
||||
_, err := c.WorkflowService.GetWorkflow(ctx, app, req.WorkflowName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if req.ComponentName != "" {
|
||||
_, err := c.GetApplicationComponent(ctx, app, req.ComponentName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
trigger := &model.ApplicationTrigger{
|
||||
AppPrimaryKey: app.Name,
|
||||
WorkflowName: req.WorkflowName,
|
||||
@@ -426,18 +440,7 @@ func (c *applicationServiceImpl) CreateApplicationTrigger(ctx context.Context, a
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &apisv1.ApplicationTriggerBase{
|
||||
WorkflowName: req.WorkflowName,
|
||||
Name: req.Name,
|
||||
Alias: req.Alias,
|
||||
Description: req.Description,
|
||||
Type: req.Type,
|
||||
PayloadType: req.PayloadType,
|
||||
Token: trigger.Token,
|
||||
ComponentName: trigger.ComponentName,
|
||||
CreateTime: trigger.CreateTime,
|
||||
UpdateTime: trigger.UpdateTime,
|
||||
}, nil
|
||||
return assembler.ConvertTrigger2DTO(*trigger), nil
|
||||
}
|
||||
|
||||
// DeleteApplicationTrigger delete application trigger
|
||||
@@ -456,6 +459,42 @@ func (c *applicationServiceImpl) DeleteApplicationTrigger(ctx context.Context, a
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateApplicationTrigger update application trigger
|
||||
func (c *applicationServiceImpl) UpdateApplicationTrigger(ctx context.Context, app *model.Application, token string, req apisv1.UpdateApplicationTriggerRequest) (*apisv1.ApplicationTriggerBase, error) {
|
||||
trigger := model.ApplicationTrigger{
|
||||
AppPrimaryKey: app.PrimaryKey(),
|
||||
Token: token,
|
||||
}
|
||||
if err := c.Store.Get(ctx, &trigger); err != nil {
|
||||
if errors.Is(err, datastore.ErrRecordNotExist) {
|
||||
return nil, bcode.ErrApplicationTriggerNotExist
|
||||
}
|
||||
klog.Warningf("get app trigger failure %s", err.Error())
|
||||
return nil, err
|
||||
}
|
||||
// checking the workflow
|
||||
_, err := c.WorkflowService.GetWorkflow(ctx, app, req.WorkflowName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if req.ComponentName != "" {
|
||||
_, err := c.GetApplicationComponent(ctx, app, req.ComponentName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
trigger.Alias = req.Alias
|
||||
trigger.ComponentName = req.ComponentName
|
||||
trigger.Description = req.Description
|
||||
trigger.WorkflowName = req.WorkflowName
|
||||
trigger.Registry = req.Registry
|
||||
trigger.PayloadType = req.PayloadType
|
||||
if err := c.Store.Put(ctx, &trigger); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return assembler.ConvertTrigger2DTO(trigger), nil
|
||||
}
|
||||
|
||||
// ListApplicationTrigger list application triggers
|
||||
func (c *applicationServiceImpl) ListApplicationTriggers(ctx context.Context, app *model.Application) ([]*apisv1.ApplicationTriggerBase, error) {
|
||||
trigger := &model.ApplicationTrigger{
|
||||
@@ -538,7 +577,9 @@ func (c *applicationServiceImpl) ListRecords(ctx context.Context, appName string
|
||||
AppPrimaryKey: appName,
|
||||
Finished: model.UnFinished,
|
||||
}
|
||||
records, err := c.Store.List(ctx, &record, &datastore.ListOptions{})
|
||||
records, err := c.Store.List(ctx, &record, &datastore.ListOptions{SortBy: []datastore.SortOption{
|
||||
{Key: "createTime", Order: datastore.SortOrderDescending},
|
||||
}})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -604,7 +645,8 @@ func (c *applicationServiceImpl) DetailComponent(ctx context.Context, app *model
|
||||
return nil, err
|
||||
}
|
||||
var cd v1beta1.ComponentDefinition
|
||||
if err := c.KubeClient.Get(ctx, types.NamespacedName{Name: component.Type, Namespace: velatypes.DefaultKubeVelaNS}, &cd); err != nil {
|
||||
loadCtx := utils.WithProject(ctx, "")
|
||||
if err := c.KubeClient.Get(loadCtx, types.NamespacedName{Name: component.Type, Namespace: velatypes.DefaultKubeVelaNS}, &cd); err != nil {
|
||||
klog.Warningf("component definition %s get failure. %s", pkgUtils.Sanitize(component.Type), err.Error())
|
||||
}
|
||||
|
||||
@@ -672,7 +714,7 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// step2: check and create deploy event
|
||||
// step2: check and create application revision
|
||||
if !req.Force {
|
||||
var lastVersion = model.ApplicationRevision{
|
||||
AppPrimaryKey: app.PrimaryKey(),
|
||||
@@ -698,17 +740,18 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
|
||||
} else {
|
||||
status = revision.Status
|
||||
}
|
||||
if status != model.RevisionStatusComplete && status != model.RevisionStatusTerminated {
|
||||
klog.Warningf("last app revision can not complete %s/%s", list[0].(*model.ApplicationRevision).AppPrimaryKey, list[0].(*model.ApplicationRevision).Version)
|
||||
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)
|
||||
return nil, bcode.ErrDeployConflict
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var appRevision = &model.ApplicationRevision{
|
||||
AppPrimaryKey: app.PrimaryKey(),
|
||||
Version: version,
|
||||
RevisionCRName: version,
|
||||
AppPrimaryKey: app.PrimaryKey(),
|
||||
Version: version,
|
||||
// Setting it when syncing the workflow status
|
||||
RevisionCRName: "",
|
||||
ApplyAppConfig: string(configByte),
|
||||
Status: model.RevisionStatusInit,
|
||||
DeployUser: userName,
|
||||
@@ -745,7 +788,8 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
|
||||
}
|
||||
|
||||
// step5: create workflow record
|
||||
if err := c.WorkflowService.CreateWorkflowRecord(ctx, app, oamApp, workflow); err != nil {
|
||||
record, err := c.WorkflowService.CreateWorkflowRecord(ctx, app, oamApp, workflow)
|
||||
if err != nil {
|
||||
klog.Warningf("create workflow record failure %s", err.Error())
|
||||
}
|
||||
|
||||
@@ -764,9 +808,14 @@ func (c *applicationServiceImpl) Deploy(ctx context.Context, app *model.Applicat
|
||||
klog.Warningf("failed to update app %s", err.Error())
|
||||
}
|
||||
|
||||
return &apisv1.ApplicationDeployResponse{
|
||||
res := &apisv1.ApplicationDeployResponse{
|
||||
ApplicationRevisionBase: c.convertRevisionModelToBase(ctx, appRevision),
|
||||
}, nil
|
||||
}
|
||||
if record != nil {
|
||||
res.WorkflowRecord = assembler.ConvertFromRecordModel(record).WorkflowRecordBase
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appModel *model.Application, reqWorkflowName, envName, version string) (*v1beta1.Application, error) {
|
||||
@@ -901,26 +950,41 @@ func (c *applicationServiceImpl) renderOAMApplication(ctx context.Context, appMo
|
||||
app.Annotations[oam.AnnotationWorkflowName] = workflow.Name
|
||||
var steps []workflowv1alpha1.WorkflowStep
|
||||
for _, step := range workflow.Steps {
|
||||
var workflowStep = workflowv1alpha1.WorkflowStep{
|
||||
WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{
|
||||
Name: step.Name,
|
||||
Type: step.Type,
|
||||
Inputs: step.Inputs,
|
||||
Outputs: step.Outputs,
|
||||
},
|
||||
workflowStep := workflowv1alpha1.WorkflowStep{
|
||||
WorkflowStepBase: convertWorkflowModel2WorkflowSpec(step.WorkflowStepBase),
|
||||
}
|
||||
if step.Properties != nil {
|
||||
workflowStep.Properties = step.Properties.RawExtension()
|
||||
for _, subStep := range step.SubSteps {
|
||||
workflowStep.SubSteps = append(workflowStep.SubSteps, convertWorkflowModel2WorkflowSpec(subStep))
|
||||
}
|
||||
steps = append(steps, workflowStep)
|
||||
}
|
||||
app.Spec.Workflow = &v1beta1.Workflow{
|
||||
Steps: steps,
|
||||
Mode: &workflow.Mode,
|
||||
}
|
||||
}
|
||||
return app, nil
|
||||
}
|
||||
|
||||
func convertWorkflowModel2WorkflowSpec(step model.WorkflowStepBase) workflowv1alpha1.WorkflowStepBase {
|
||||
var workflowStep = workflowv1alpha1.WorkflowStepBase{
|
||||
Name: step.Name,
|
||||
Type: step.Type,
|
||||
Inputs: step.Inputs,
|
||||
Outputs: step.Outputs,
|
||||
If: step.If,
|
||||
Timeout: step.Timeout,
|
||||
DependsOn: step.DependsOn,
|
||||
Meta: &workflowv1alpha1.WorkflowStepMeta{
|
||||
Alias: step.Alias,
|
||||
},
|
||||
}
|
||||
if step.Properties != nil {
|
||||
workflowStep.Properties = step.Properties.RawExtension()
|
||||
}
|
||||
return workflowStep
|
||||
}
|
||||
|
||||
func (c *applicationServiceImpl) convertRevisionModelToBase(ctx context.Context, revision *model.ApplicationRevision) apisv1.ApplicationRevisionBase {
|
||||
var deployUser *model.User
|
||||
if revision.DeployUser != "" {
|
||||
@@ -1047,7 +1111,8 @@ func (c *applicationServiceImpl) UpdateComponent(ctx context.Context, app *model
|
||||
|
||||
func (c *applicationServiceImpl) createComponent(ctx context.Context, app *model.Application, com apisv1.CreateComponentRequest, main bool) (*apisv1.ComponentBase, error) {
|
||||
var cd v1beta1.ComponentDefinition
|
||||
if err := c.KubeClient.Get(ctx, types.NamespacedName{Name: com.ComponentType, Namespace: velatypes.DefaultKubeVelaNS}, &cd); err != nil {
|
||||
loadCtx := utils.WithProject(ctx, "")
|
||||
if err := c.KubeClient.Get(loadCtx, types.NamespacedName{Name: com.ComponentType, Namespace: velatypes.DefaultKubeVelaNS}, &cd); err != nil {
|
||||
klog.Warningf("component definition %s get failure. %s", pkgUtils.Sanitize(com.ComponentType), err.Error())
|
||||
return nil, bcode.ErrComponentTypeNotSupport
|
||||
}
|
||||
@@ -1405,13 +1470,29 @@ func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model
|
||||
var base, compareTarget *v1beta1.Application
|
||||
var err error
|
||||
var envNameByRevision string
|
||||
|
||||
getRunningApp := func() *v1beta1.Application {
|
||||
var envName string
|
||||
if compareReq.CompareLatestWithRunning != nil {
|
||||
envName = compareReq.CompareLatestWithRunning.Env
|
||||
}
|
||||
if compareReq.CompareRevisionWithRunning != nil {
|
||||
envName = envNameByRevision
|
||||
}
|
||||
if envName == "" {
|
||||
return nil
|
||||
}
|
||||
app, err := c.GetApplicationCRInEnv(ctx, appModel, envName)
|
||||
if err != nil {
|
||||
klog.Errorf("failed to query the application CR %s", err.Error())
|
||||
return nil
|
||||
}
|
||||
return app
|
||||
}
|
||||
switch {
|
||||
case compareReq.CompareLatestWithRunning != nil:
|
||||
base, err = c.renderOAMApplication(ctx, appModel, "", compareReq.CompareLatestWithRunning.Env, "")
|
||||
if err != nil {
|
||||
klog.Errorf("failed to build the latest application %s", err.Error())
|
||||
break
|
||||
}
|
||||
base = getRunningApp()
|
||||
|
||||
case compareReq.CompareRevisionWithRunning != nil || compareReq.CompareRevisionWithLatest != nil:
|
||||
var revision = ""
|
||||
if compareReq.CompareRevisionWithRunning != nil {
|
||||
@@ -1428,23 +1509,9 @@ func (c *applicationServiceImpl) CompareApp(ctx context.Context, appModel *model
|
||||
}
|
||||
|
||||
switch {
|
||||
case compareReq.CompareLatestWithRunning != nil || compareReq.CompareRevisionWithRunning != nil:
|
||||
var envName string
|
||||
if compareReq.CompareLatestWithRunning != nil {
|
||||
envName = compareReq.CompareLatestWithRunning.Env
|
||||
}
|
||||
if compareReq.CompareRevisionWithRunning != nil {
|
||||
envName = envNameByRevision
|
||||
}
|
||||
if envName == "" {
|
||||
break
|
||||
}
|
||||
compareTarget, err = c.GetApplicationCRInEnv(ctx, appModel, envName)
|
||||
if err != nil {
|
||||
klog.Errorf("failed to query the application CR %s", err.Error())
|
||||
break
|
||||
}
|
||||
case compareReq.CompareRevisionWithLatest != nil:
|
||||
case compareReq.CompareRevisionWithRunning != nil:
|
||||
compareTarget = getRunningApp()
|
||||
case compareReq.CompareRevisionWithLatest != nil || compareReq.CompareLatestWithRunning != nil:
|
||||
compareTarget, err = c.renderOAMApplication(ctx, appModel, "", envNameByRevision, "")
|
||||
if err != nil {
|
||||
klog.Errorf("failed to build the latest application %s", err.Error())
|
||||
@@ -1513,6 +1580,13 @@ func (c *applicationServiceImpl) DryRunAppOrRevision(ctx context.Context, appMod
|
||||
}
|
||||
case "REVISION":
|
||||
app, _, err = c.getAppModelFromRevision(ctx, appModel.Name, dryRunReq.Version)
|
||||
originalApp := &v1beta1.Application{}
|
||||
if err := c.KubeClient.Get(ctx, types.NamespacedName{
|
||||
Name: app.Name,
|
||||
Namespace: app.Namespace,
|
||||
}, originalApp); err == nil {
|
||||
app.ResourceVersion = originalApp.ResourceVersion
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1598,7 +1672,7 @@ func (c *applicationServiceImpl) resetApp(ctx context.Context, targetApp *v1beta
|
||||
for _, comp := range targetComps {
|
||||
// add or update new app's components from old app
|
||||
if utils.StringsContain(readyToAdd, comp.Name) || utils.StringsContain(readyToUpdate, comp.Name) {
|
||||
compModel, err := syncconvert.FromCRComponent(appPrimaryKey, comp)
|
||||
compModel, err := convert.FromCRComponent(appPrimaryKey, comp)
|
||||
if err != nil {
|
||||
return &apisv1.AppResetResponse{}, bcode.ErrInvalidProperties
|
||||
}
|
||||
@@ -1623,6 +1697,75 @@ func (c *applicationServiceImpl) resetApp(ctx context.Context, targetApp *v1beta
|
||||
return &apisv1.AppResetResponse{IsReset: true}, nil
|
||||
}
|
||||
|
||||
func (c *applicationServiceImpl) RollbackWithRevision(ctx context.Context, application *model.Application, revisionVersion string) (*apisv1.ApplicationRollbackResponse, error) {
|
||||
revision, err := c.DetailRevision(ctx, application.Name, revisionVersion)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
appCR, err := c.GetApplicationCRInEnv(ctx, application, revision.EnvName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var publishVersion = utils.GenerateVersion(revision.WorkflowName)
|
||||
noRevision := false
|
||||
var rollbackApplication *v1beta1.Application
|
||||
if appCR != nil {
|
||||
// The RevisionCRName is incorrect in the old version, ignore it.
|
||||
if revision.RevisionCRName == revision.Version || revision.RevisionCRName == "" {
|
||||
noRevision = true
|
||||
} else {
|
||||
_, appCR, err := app.RollbackApplicationWithRevision(ctx, c.KubeClient, appCR.Name, appCR.Namespace, revision.RevisionCRName, publishVersion)
|
||||
if err != nil {
|
||||
switch {
|
||||
case errors.Is(err, app.ErrNotMatchRevision):
|
||||
noRevision = true
|
||||
case errors.Is(err, app.ErrRevisionNotChange):
|
||||
return nil, bcode.ErrApplicationRevisionConflict
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
rollbackApplication = appCR
|
||||
}
|
||||
}
|
||||
|
||||
// Rollback by the local revision
|
||||
if appCR == nil || noRevision {
|
||||
rollBackApp := &v1beta1.Application{}
|
||||
if err := yaml.Unmarshal([]byte(revision.ApplyAppConfig), rollBackApp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
oam.SetPublishVersion(rollBackApp, publishVersion)
|
||||
if appCR != nil {
|
||||
rollBackApp.ResourceVersion = appCR.ResourceVersion
|
||||
} else {
|
||||
rollBackApp.ResourceVersion = ""
|
||||
}
|
||||
err = c.Apply.Apply(ctx, rollBackApp)
|
||||
if err != nil {
|
||||
klog.Errorf("rollback the app %s failure %s", application.PrimaryKey(), err.Error())
|
||||
return nil, err
|
||||
}
|
||||
rollbackApplication = rollBackApp
|
||||
}
|
||||
|
||||
work, _, err := convert.FromCRWorkflow(ctx, c.KubeClient, application.PrimaryKey(), rollbackApplication, revision.EnvName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// The deploy version is the primary key of the revision
|
||||
if rollbackApplication.Annotations[oam.AnnotationDeployVersion] == "" {
|
||||
rollbackApplication.Annotations[oam.AnnotationDeployVersion] = publishVersion
|
||||
}
|
||||
record, err := c.WorkflowService.CreateWorkflowRecord(ctx, application, rollbackApplication, &work)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create workflow record failure %w", err)
|
||||
}
|
||||
return &apisv1.ApplicationRollbackResponse{
|
||||
WorkflowRecord: assembler.ConvertFromRecordModel(record).WorkflowRecordBase,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func dryRunApplication(ctx context.Context, c commonutil.Args, app *v1beta1.Application) (bytes.Buffer, error) {
|
||||
var buff = bytes.Buffer{}
|
||||
if _, err := fmt.Fprintf(&buff, "---\n# Application(%s) \n---\n\n", app.Name); err != nil {
|
||||
@@ -1666,9 +1809,7 @@ func dryRunApplication(ctx context.Context, c commonutil.Args, app *v1beta1.Appl
|
||||
// ignore the workflow spec
|
||||
func ignoreSomeParams(o *v1beta1.Application) {
|
||||
var defaultApplication = v1beta1.Application{}
|
||||
// only compare the spec without the workflow
|
||||
defaultApplication.Spec = o.Spec
|
||||
defaultApplication.Spec.Workflow = nil
|
||||
defaultApplication.Name = o.Name
|
||||
defaultApplication.Namespace = o.Namespace
|
||||
|
||||
@@ -1800,11 +1941,7 @@ func (c *applicationServiceImpl) handlePolicyBindingWorkflowStep(ctx context.Con
|
||||
}
|
||||
if added || deleted {
|
||||
properties["policies"] = policies
|
||||
pStr, err := json.Marshal(properties)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
w.Steps[i].Properties = string(pStr)
|
||||
w.Steps[i].Properties = properties
|
||||
needUpdate = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import (
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
|
||||
wfTypes "github.com/kubevela/workflow/pkg/types"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
@@ -206,15 +208,17 @@ var _ = Describe("Test application service function", func() {
|
||||
appModel, err := appService.GetApplication(context.TODO(), testApp)
|
||||
Expect(err).Should(BeNil())
|
||||
_, err = appService.CreateApplicationTrigger(context.TODO(), appModel, v1.CreateApplicationTriggerRequest{
|
||||
Name: "trigger-name",
|
||||
Name: "trigger-name",
|
||||
WorkflowName: repository.ConvertWorkflowName("app-dev"),
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
base, err := appService.CreateApplicationTrigger(context.TODO(), appModel, v1.CreateApplicationTriggerRequest{
|
||||
Name: "trigger-name-2",
|
||||
ComponentName: "trigger-component",
|
||||
ComponentName: "component-name",
|
||||
WorkflowName: repository.ConvertWorkflowName("app-dev"),
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(base.ComponentName).Should(Equal("trigger-component"))
|
||||
Expect(base.ComponentName).Should(Equal("component-name"))
|
||||
})
|
||||
|
||||
It("Test ListTriggers function", func() {
|
||||
@@ -297,6 +301,33 @@ var _ = Describe("Test application service function", func() {
|
||||
Expect(cmp.Diff(len(detailResponse.Traits), 2)).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test UpdateTrigger function", func() {
|
||||
appModel, err := appService.GetApplication(context.TODO(), testApp)
|
||||
Expect(err).Should(BeNil())
|
||||
triggers, err := appService.ListApplicationTriggers(context.TODO(), appModel)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(len(triggers)).Should(Equal(2))
|
||||
_, err = appService.UpdateApplicationTrigger(context.TODO(), appModel, triggers[1].Token, v1.UpdateApplicationTriggerRequest{
|
||||
ComponentName: "notfound",
|
||||
WorkflowName: repository.ConvertWorkflowName("app-dev"),
|
||||
})
|
||||
Expect(err).Should(Equal(bcode.ErrApplicationComponentNotExist))
|
||||
_, err = appService.UpdateApplicationTrigger(context.TODO(), appModel, triggers[1].Token, v1.UpdateApplicationTriggerRequest{
|
||||
WorkflowName: "notfound",
|
||||
})
|
||||
Expect(err).Should(Equal(bcode.ErrWorkflowNotExist))
|
||||
base, err := appService.UpdateApplicationTrigger(context.TODO(), appModel, triggers[1].Token, v1.UpdateApplicationTriggerRequest{
|
||||
Alias: triggers[1].Alias,
|
||||
Description: triggers[1].Description,
|
||||
ComponentName: "test2",
|
||||
WorkflowName: repository.ConvertWorkflowName("app-dev"),
|
||||
PayloadType: triggers[1].PayloadType,
|
||||
Registry: triggers[1].Registry,
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(base.ComponentName, "test2")).Should(BeEmpty())
|
||||
})
|
||||
|
||||
It("Test DetailComponent function", func() {
|
||||
appModel, err := appService.GetApplication(context.TODO(), testApp)
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -530,8 +561,10 @@ var _ = Describe("Test application service function", func() {
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(cmp.Diff(compareResponse.IsDiff, true)).Should(BeEmpty())
|
||||
Expect(cmp.Diff(compareResponse.TargetAppYAML, "")).Should(BeEmpty())
|
||||
Expect(cmp.Diff(compareResponse.BaseAppYAML, "")).ShouldNot(BeEmpty())
|
||||
// The target represents the latest config
|
||||
Expect(cmp.Diff(compareResponse.TargetAppYAML, "")).ShouldNot(BeEmpty())
|
||||
// The base represents the running config
|
||||
Expect(cmp.Diff(compareResponse.BaseAppYAML, "")).Should(BeEmpty())
|
||||
|
||||
By("compare when app's env add target, should return false")
|
||||
_, err = targetService.CreateTarget(context.TODO(), v1.CreateTargetRequest{Name: "dev-target1", Project: appModel.Project, Cluster: &v1.ClusterTarget{ClusterName: "local", Namespace: "dev-target1"}})
|
||||
@@ -850,21 +883,21 @@ var _ = Describe("Test apiserver policy rest api", func() {
|
||||
WorkflowStepBase: v1.WorkflowStepBase{
|
||||
Name: "default",
|
||||
Type: "deploy",
|
||||
Properties: `{"policies":["local"]}`,
|
||||
Properties: map[string]interface{}{"policies": []string{"local"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
WorkflowStepBase: v1.WorkflowStepBase{
|
||||
Name: "suspend",
|
||||
Type: "suspend",
|
||||
Properties: `{"duration": "10m"}`,
|
||||
Properties: map[string]interface{}{"duration": "10m"},
|
||||
},
|
||||
},
|
||||
{
|
||||
WorkflowStepBase: v1.WorkflowStepBase{
|
||||
Name: "second",
|
||||
Type: "deploy",
|
||||
Properties: `{"policies":["cluster1"]}`,
|
||||
Properties: map[string]interface{}{"policies": []string{"cluster1"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -880,7 +913,7 @@ var _ = Describe("Test apiserver policy rest api", func() {
|
||||
WorkflowStepBase: v1.WorkflowStepBase{
|
||||
Name: "second",
|
||||
Type: "deploy",
|
||||
Properties: `{"policies":["cluster3"]}`,
|
||||
Properties: map[string]interface{}{"policies": []string{"cluster3"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1015,11 +1048,32 @@ func createTestSuspendApp(ctx context.Context, appName, envName, revisionVersion
|
||||
Traits: []common.ApplicationTrait{},
|
||||
Scopes: map[string]string{},
|
||||
}},
|
||||
Workflow: &v1beta1.Workflow{
|
||||
Steps: []workflowv1alpha1.WorkflowStep{
|
||||
{
|
||||
WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{
|
||||
Type: wfTypes.WorkflowStepTypeSuspend,
|
||||
Name: "first",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Status: common.AppStatus{
|
||||
Workflow: &common.WorkflowStatus{
|
||||
AppRevision: recordName,
|
||||
Suspend: true,
|
||||
Phase: workflowv1alpha1.WorkflowStateSuspending,
|
||||
Steps: []workflowv1alpha1.WorkflowStepStatus{
|
||||
{
|
||||
StepStatus: workflowv1alpha1.StepStatus{
|
||||
Type: wfTypes.WorkflowStepTypeSuspend,
|
||||
Name: "first",
|
||||
ID: "first",
|
||||
Phase: workflowv1alpha1.WorkflowStepPhaseRunning,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -37,7 +37,6 @@ import (
|
||||
"github.com/oam-dev/terraform-controller/api/types"
|
||||
"github.com/oam-dev/terraform-controller/api/v1beta1"
|
||||
|
||||
velatypes "github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/clients"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
|
||||
@@ -207,7 +206,7 @@ func joinClusterByKubeConfigString(ctx context.Context, k8sClient client.Client,
|
||||
defer func() {
|
||||
_ = os.Remove(tmpFileName)
|
||||
}()
|
||||
clusterConfig, err := multicluster.JoinClusterByKubeConfig(ctx, k8sClient, tmpFileName, clusterName, multicluster.JoinClusterCreateNamespaceOption(velatypes.DefaultKubeVelaNS))
|
||||
clusterConfig, err := multicluster.JoinClusterByKubeConfig(ctx, k8sClient, tmpFileName, clusterName, multicluster.JoinClusterCreateNamespaceOption(""))
|
||||
if err != nil {
|
||||
if errors.Is(err, multicluster.ErrClusterExists) {
|
||||
return "", bcode.ErrClusterExistsInKubernetes
|
||||
@@ -388,7 +387,10 @@ func (c *clusterServiceImpl) DeleteKubeCluster(ctx context.Context, clusterName
|
||||
cluster, err := c.getClusterFromDataStore(ctx, clusterName)
|
||||
if err != nil {
|
||||
if errors.Is(err, datastore.ErrRecordNotExist) {
|
||||
return nil, bcode.ErrClusterNotFoundInDataStore
|
||||
if err = multicluster.DetachCluster(ctx, c.K8sClient, clusterName); err != nil {
|
||||
return nil, bcode.ErrClusterNotFoundInDataStore
|
||||
}
|
||||
return &apis.ClusterBase{Name: clusterName}, nil
|
||||
}
|
||||
return nil, errors.Wrapf(err, "failed to found cluster %s in data store", clusterName)
|
||||
}
|
||||
|
||||
@@ -98,6 +98,27 @@ var _ = Describe("Test cluster service function", func() {
|
||||
Expect(err).Should(Equal(bcode.ErrClusterNotFoundInDataStore))
|
||||
})
|
||||
|
||||
It("Test delete kube cluster", func() {
|
||||
service := clusterServiceImpl{
|
||||
Store: ds,
|
||||
caches: cache,
|
||||
K8sClient: k8sClient,
|
||||
}
|
||||
Expect(createClusterSecret("prism-cluster", "prism-alias")).Should(Succeed())
|
||||
Expect(ds.Add(ctx, &model.Cluster{Name: "prism-cluster", Alias: "prism-alias", Icon: "prism-icon"})).Should(Succeed())
|
||||
resp, err := service.DeleteKubeCluster(ctx, "prism-cluster")
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(resp.Name).Should(Equal("prism-cluster"))
|
||||
Expect(resp.Alias).Should(Equal("prism-alias"))
|
||||
Expect(resp.Icon).Should(Equal("prism-icon"))
|
||||
_, err = service.DeleteKubeCluster(ctx, "non-exist-cluster")
|
||||
Expect(err).Should(Equal(bcode.ErrClusterNotFoundInDataStore))
|
||||
Expect(createClusterSecret("secret-exist-cm-non-exist-cluster", "secret-exist-cm-non-exist-cluster")).Should(Succeed())
|
||||
resp, err = service.DeleteKubeCluster(ctx, "secret-exist-cm-non-exist-cluster")
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(resp.Name).Should(Equal("secret-exist-cm-non-exist-cluster"))
|
||||
})
|
||||
|
||||
It("Test list kube clusters", func() {
|
||||
service := clusterServiceImpl{
|
||||
Store: ds,
|
||||
|
||||
@@ -22,15 +22,14 @@ import (
|
||||
"sort"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
apis "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
|
||||
"github.com/oam-dev/kubevela/pkg/config"
|
||||
"github.com/oam-dev/kubevela/pkg/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/apply"
|
||||
)
|
||||
|
||||
@@ -62,7 +61,8 @@ type configServiceImpl struct {
|
||||
|
||||
// ListTemplates list the config templates
|
||||
func (u *configServiceImpl) ListTemplates(ctx context.Context, project, scope string) ([]*apis.ConfigTemplate, error) {
|
||||
queryTemplates, err := u.Factory.ListTemplates(ctx, types.DefaultKubeVelaNS, scope)
|
||||
listCtx := utils.WithProject(ctx, "")
|
||||
queryTemplates, err := u.Factory.ListTemplates(listCtx, types.DefaultKubeVelaNS, scope)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -100,7 +100,8 @@ func (u *configServiceImpl) GetTemplate(ctx context.Context, tem config.Namespac
|
||||
if tem.Namespace == "" {
|
||||
tem.Namespace = types.DefaultKubeVelaNS
|
||||
}
|
||||
template, err := u.Factory.LoadTemplate(ctx, tem.Name, tem.Namespace)
|
||||
getCtx := utils.WithProject(ctx, "")
|
||||
template, err := u.Factory.LoadTemplate(getCtx, tem.Name, tem.Namespace)
|
||||
if err != nil {
|
||||
if errors.Is(err, config.ErrTemplateNotFound) {
|
||||
return nil, bcode.ErrTemplateNotFound
|
||||
@@ -133,9 +134,14 @@ func (u *configServiceImpl) CreateConfig(ctx context.Context, project string, re
|
||||
return nil, err
|
||||
}
|
||||
ns = pro.GetNamespace()
|
||||
if err := utils.CreateNamespace(ctx, u.KubeClient, ns); err != nil && !apierrors.IsAlreadyExists(err) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
exist, err := u.Factory.IsExist(ctx, ns, req.Name)
|
||||
if err != nil {
|
||||
klog.Errorf("check config name is exist failure %s", err.Error())
|
||||
return nil, bcode.ErrConfigExist
|
||||
}
|
||||
if exist {
|
||||
return nil, bcode.ErrConfigExist
|
||||
}
|
||||
var properties = make(map[string]interface{})
|
||||
if err := json.Unmarshal([]byte(req.Properties), &properties); err != nil {
|
||||
@@ -156,9 +162,6 @@ func (u *configServiceImpl) CreateConfig(ctx context.Context, project string, re
|
||||
return nil, err
|
||||
}
|
||||
if err := u.Factory.CreateOrUpdateConfig(ctx, configItem, ns); err != nil {
|
||||
if errors.Is(err, config.ErrConfigExist) {
|
||||
return nil, bcode.ErrConfigExist
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return convertConfig(project, *configItem), nil
|
||||
@@ -196,9 +199,12 @@ func (u *configServiceImpl) UpdateConfig(ctx context.Context, project string, na
|
||||
return nil, err
|
||||
}
|
||||
if err := u.Factory.CreateOrUpdateConfig(ctx, configItem, ns); err != nil {
|
||||
if errors.Is(err, config.ErrConfigExist) {
|
||||
if errors.Is(err, config.ErrChangeTemplate) {
|
||||
return nil, bcode.ErrChangeTemplate
|
||||
}
|
||||
if errors.Is(err, config.ErrChangeSecretType) {
|
||||
return nil, bcode.ErrChangeSecretType
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return convertConfig(project, *configItem), nil
|
||||
@@ -210,6 +216,7 @@ func (u *configServiceImpl) ListConfigs(ctx context.Context, project string, tem
|
||||
var list []*apis.Config
|
||||
scope := ""
|
||||
var projectNamespace string
|
||||
listCtx := utils.WithProject(ctx, "")
|
||||
if project != "" {
|
||||
scope = "project"
|
||||
pro, err := u.ProjectService.GetProject(ctx, project)
|
||||
@@ -218,7 +225,7 @@ func (u *configServiceImpl) ListConfigs(ctx context.Context, project string, tem
|
||||
}
|
||||
projectNamespace = pro.GetNamespace()
|
||||
// query the configs belong to the project scope from the system namespace
|
||||
configs, err := u.Factory.ListConfigs(ctx, pro.GetNamespace(), template, "", true)
|
||||
configs, err := u.Factory.ListConfigs(listCtx, pro.GetNamespace(), template, "", true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -227,7 +234,7 @@ func (u *configServiceImpl) ListConfigs(ctx context.Context, project string, tem
|
||||
}
|
||||
}
|
||||
|
||||
configs, err := u.Factory.ListConfigs(ctx, types.DefaultKubeVelaNS, template, scope, true)
|
||||
configs, err := u.Factory.ListConfigs(listCtx, types.DefaultKubeVelaNS, template, scope, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user