mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-14 18:10:21 +00:00
Compare commits
47 Commits
v1.7.0-bet
...
v1.7.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
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
|
||||
|
||||
|
||||
133
.github/workflows/release.yml
vendored
133
.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 }}
|
||||
@@ -28,105 +27,36 @@ jobs:
|
||||
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: |
|
||||
@@ -137,7 +67,6 @@ 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
|
||||
@@ -154,34 +83,6 @@ jobs:
|
||||
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.
|
||||
|
||||
@@ -111,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.7.0-alpha.3` |
|
||||
| `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` |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -272,8 +272,8 @@ 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 }}
|
||||
|
||||
@@ -2,7 +2,7 @@ apiVersion: v1
|
||||
data:
|
||||
template: |
|
||||
import (
|
||||
"vela/ql"
|
||||
"vela/ql"
|
||||
)
|
||||
|
||||
parameter: {
|
||||
@@ -55,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
|
||||
}
|
||||
}
|
||||
}
|
||||
}]
|
||||
|
||||
@@ -148,7 +148,7 @@ multicluster:
|
||||
port: 9443
|
||||
image:
|
||||
repository: oamdev/cluster-gateway
|
||||
tag: v1.7.0-alpha.3
|
||||
tag: v1.7.0
|
||||
pullPolicy: IfNotPresent
|
||||
resources:
|
||||
limits:
|
||||
|
||||
@@ -105,7 +105,7 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-minimal --
|
||||
| `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` |
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
})
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -106,7 +106,7 @@ multicluster:
|
||||
port: 9443
|
||||
image:
|
||||
repository: oamdev/cluster-gateway
|
||||
tag: v1.4.0
|
||||
tag: v1.7.0
|
||||
pullPolicy: IfNotPresent
|
||||
resources:
|
||||
limits:
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -2086,7 +2086,7 @@
|
||||
"tags": [
|
||||
"application"
|
||||
],
|
||||
"summary": "list application triggers",
|
||||
"summary": "List the application triggers",
|
||||
"operationId": "listApplicationTriggers",
|
||||
"parameters": [
|
||||
{
|
||||
@@ -2124,7 +2124,7 @@
|
||||
"tags": [
|
||||
"application"
|
||||
],
|
||||
"summary": "create one application trigger",
|
||||
"summary": "Create an application trigger",
|
||||
"operationId": "createApplicationTrigger",
|
||||
"parameters": [
|
||||
{
|
||||
@@ -2160,6 +2160,51 @@
|
||||
}
|
||||
},
|
||||
"/api/v1/applications/{appName}/triggers/{token}": {
|
||||
"put": {
|
||||
"consumes": [
|
||||
"application/xml",
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json",
|
||||
"application/xml"
|
||||
],
|
||||
"tags": [
|
||||
"application"
|
||||
],
|
||||
"summary": "Update an application trigger",
|
||||
"operationId": "updateApplicationTrigger",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "identifier of the application ",
|
||||
"name": "appName",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "identifier of the trigger",
|
||||
"name": "token",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.ApplicationTriggerBase"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/bcode.Bcode"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"consumes": [
|
||||
"application/xml",
|
||||
@@ -2172,7 +2217,7 @@
|
||||
"tags": [
|
||||
"application"
|
||||
],
|
||||
"summary": "delete one application trigger",
|
||||
"summary": "Delete an application trigger",
|
||||
"operationId": "deleteApplicationTrigger",
|
||||
"parameters": [
|
||||
{
|
||||
@@ -8964,8 +9009,8 @@
|
||||
},
|
||||
"model.ApplicationRevision": {
|
||||
"required": [
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"createTime",
|
||||
"appPrimaryKey",
|
||||
"version",
|
||||
"revisionCRName",
|
||||
@@ -9347,11 +9392,11 @@
|
||||
},
|
||||
"model.WorkflowStep": {
|
||||
"required": [
|
||||
"alias",
|
||||
"name",
|
||||
"dependsOn",
|
||||
"description",
|
||||
"orderIndex",
|
||||
"dependsOn",
|
||||
"name",
|
||||
"alias",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
@@ -9469,9 +9514,9 @@
|
||||
},
|
||||
"model.WorkflowStepStatus": {
|
||||
"required": [
|
||||
"id",
|
||||
"name",
|
||||
"alias"
|
||||
"alias",
|
||||
"id"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
@@ -10055,11 +10100,11 @@
|
||||
"v1.ApplicationDeployResponse": {
|
||||
"required": [
|
||||
"version",
|
||||
"status",
|
||||
"triggerType",
|
||||
"createTime",
|
||||
"status",
|
||||
"note",
|
||||
"envName",
|
||||
"triggerType",
|
||||
"record"
|
||||
],
|
||||
"properties": {
|
||||
@@ -10338,6 +10383,7 @@
|
||||
"type",
|
||||
"payloadType",
|
||||
"token",
|
||||
"registry",
|
||||
"createTime",
|
||||
"updateTime"
|
||||
],
|
||||
@@ -10361,6 +10407,9 @@
|
||||
"payloadType": {
|
||||
"type": "string"
|
||||
},
|
||||
"registry": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -10833,13 +10882,13 @@
|
||||
},
|
||||
"v1.ConfigTemplateDetail": {
|
||||
"required": [
|
||||
"sensitive",
|
||||
"createTime",
|
||||
"alias",
|
||||
"name",
|
||||
"namespace",
|
||||
"description",
|
||||
"scope",
|
||||
"sensitive",
|
||||
"createTime",
|
||||
"alias",
|
||||
"schema",
|
||||
"uiSchema"
|
||||
],
|
||||
@@ -11669,11 +11718,11 @@
|
||||
},
|
||||
"v1.DetailAddonResponse": {
|
||||
"required": [
|
||||
"invisible",
|
||||
"name",
|
||||
"version",
|
||||
"description",
|
||||
"icon",
|
||||
"invisible",
|
||||
"description",
|
||||
"schema",
|
||||
"uiSchema",
|
||||
"definitions",
|
||||
@@ -11753,12 +11802,12 @@
|
||||
},
|
||||
"v1.DetailApplicationResponse": {
|
||||
"required": [
|
||||
"project",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"name",
|
||||
"alias",
|
||||
"project",
|
||||
"description",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"icon",
|
||||
"policies",
|
||||
"envBindings",
|
||||
@@ -11816,20 +11865,20 @@
|
||||
},
|
||||
"v1.DetailClusterResponse": {
|
||||
"required": [
|
||||
"status",
|
||||
"provider",
|
||||
"dashboardURL",
|
||||
"description",
|
||||
"icon",
|
||||
"labels",
|
||||
"reason",
|
||||
"apiServerURL",
|
||||
"kubeConfigSecret",
|
||||
"alias",
|
||||
"status",
|
||||
"dashboardURL",
|
||||
"icon",
|
||||
"description",
|
||||
"reason",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"name",
|
||||
"kubeConfig",
|
||||
"labels",
|
||||
"provider",
|
||||
"apiServerURL",
|
||||
"createTime",
|
||||
"resourceInfo"
|
||||
],
|
||||
"properties": {
|
||||
@@ -11887,13 +11936,13 @@
|
||||
},
|
||||
"v1.DetailComponentResponse": {
|
||||
"required": [
|
||||
"name",
|
||||
"main",
|
||||
"alias",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"appPrimaryKey",
|
||||
"creator",
|
||||
"name",
|
||||
"main",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"alias",
|
||||
"type",
|
||||
"definition"
|
||||
],
|
||||
@@ -11982,12 +12031,12 @@
|
||||
},
|
||||
"v1.DetailDefinitionResponse": {
|
||||
"required": [
|
||||
"alias",
|
||||
"labels",
|
||||
"ownerAddon",
|
||||
"name",
|
||||
"alias",
|
||||
"icon",
|
||||
"labels",
|
||||
"description",
|
||||
"icon",
|
||||
"status",
|
||||
"schema",
|
||||
"uiSchema"
|
||||
@@ -12045,15 +12094,15 @@
|
||||
},
|
||||
"v1.DetailPolicyResponse": {
|
||||
"required": [
|
||||
"description",
|
||||
"creator",
|
||||
"envName",
|
||||
"name",
|
||||
"alias",
|
||||
"type",
|
||||
"description",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"type",
|
||||
"properties"
|
||||
"alias",
|
||||
"creator",
|
||||
"properties",
|
||||
"envName"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
@@ -12095,18 +12144,18 @@
|
||||
},
|
||||
"v1.DetailRevisionResponse": {
|
||||
"required": [
|
||||
"appPrimaryKey",
|
||||
"revisionCRName",
|
||||
"triggerType",
|
||||
"workflowName",
|
||||
"version",
|
||||
"status",
|
||||
"deployUser",
|
||||
"note",
|
||||
"createTime",
|
||||
"appPrimaryKey",
|
||||
"deployUser",
|
||||
"triggerType",
|
||||
"updateTime",
|
||||
"revisionCRName",
|
||||
"reason",
|
||||
"envName"
|
||||
"envName",
|
||||
"version",
|
||||
"workflowName",
|
||||
"createTime"
|
||||
],
|
||||
"properties": {
|
||||
"appPrimaryKey": {
|
||||
@@ -12163,10 +12212,10 @@
|
||||
},
|
||||
"v1.DetailTargetResponse": {
|
||||
"required": [
|
||||
"updateTime",
|
||||
"name",
|
||||
"project",
|
||||
"createTime",
|
||||
"updateTime"
|
||||
"project"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
@@ -12206,11 +12255,11 @@
|
||||
},
|
||||
"v1.DetailUserResponse": {
|
||||
"required": [
|
||||
"email",
|
||||
"disabled",
|
||||
"createTime",
|
||||
"lastLoginTime",
|
||||
"name",
|
||||
"email",
|
||||
"projects",
|
||||
"roles"
|
||||
],
|
||||
@@ -12252,12 +12301,12 @@
|
||||
"v1.DetailWorkflowRecordResponse": {
|
||||
"required": [
|
||||
"status",
|
||||
"mode",
|
||||
"workflowAlias",
|
||||
"applicationRevision",
|
||||
"namespace",
|
||||
"message",
|
||||
"mode",
|
||||
"name",
|
||||
"namespace",
|
||||
"workflowName",
|
||||
"deployTime",
|
||||
"deployUser",
|
||||
@@ -12321,15 +12370,15 @@
|
||||
"v1.DetailWorkflowResponse": {
|
||||
"required": [
|
||||
"name",
|
||||
"enable",
|
||||
"envName",
|
||||
"alias",
|
||||
"description",
|
||||
"default",
|
||||
"createTime",
|
||||
"updateTime",
|
||||
"subMode",
|
||||
"alias",
|
||||
"enable",
|
||||
"default",
|
||||
"envName",
|
||||
"mode"
|
||||
"mode",
|
||||
"subMode"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
@@ -12537,8 +12586,8 @@
|
||||
},
|
||||
"v1.EnvBindingTarget": {
|
||||
"required": [
|
||||
"name",
|
||||
"alias"
|
||||
"alias",
|
||||
"name"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
@@ -12565,11 +12614,11 @@
|
||||
"v1.GetPipelineResponse": {
|
||||
"required": [
|
||||
"spec",
|
||||
"description",
|
||||
"createTime",
|
||||
"name",
|
||||
"alias",
|
||||
"project",
|
||||
"description",
|
||||
"info"
|
||||
],
|
||||
"properties": {
|
||||
@@ -12612,10 +12661,10 @@
|
||||
},
|
||||
"v1.GetPipelineRunLogResponse": {
|
||||
"required": [
|
||||
"phase",
|
||||
"id",
|
||||
"name",
|
||||
"type",
|
||||
"phase",
|
||||
"source",
|
||||
"log"
|
||||
],
|
||||
@@ -13269,11 +13318,11 @@
|
||||
},
|
||||
"v1.LoginUserInfoResponse": {
|
||||
"required": [
|
||||
"createTime",
|
||||
"lastLoginTime",
|
||||
"name",
|
||||
"email",
|
||||
"disabled",
|
||||
"createTime",
|
||||
"lastLoginTime",
|
||||
"projects",
|
||||
"platformPermissions",
|
||||
"projectPermissions"
|
||||
@@ -13475,11 +13524,11 @@
|
||||
},
|
||||
"v1.PipelineBase": {
|
||||
"required": [
|
||||
"description",
|
||||
"createTime",
|
||||
"name",
|
||||
"alias",
|
||||
"project",
|
||||
"description",
|
||||
"spec"
|
||||
],
|
||||
"properties": {
|
||||
@@ -13578,11 +13627,11 @@
|
||||
},
|
||||
"v1.PipelineMetaResponse": {
|
||||
"required": [
|
||||
"name",
|
||||
"alias",
|
||||
"project",
|
||||
"description",
|
||||
"createTime",
|
||||
"name",
|
||||
"alias"
|
||||
"createTime"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
@@ -13605,13 +13654,13 @@
|
||||
},
|
||||
"v1.PipelineRun": {
|
||||
"required": [
|
||||
"contextName",
|
||||
"contextValues",
|
||||
"spec",
|
||||
"pipelineName",
|
||||
"project",
|
||||
"pipelineRunName",
|
||||
"record",
|
||||
"contextName",
|
||||
"contextValues",
|
||||
"spec",
|
||||
"status"
|
||||
],
|
||||
"properties": {
|
||||
@@ -14208,9 +14257,9 @@
|
||||
},
|
||||
"v1.SystemInfoResponse": {
|
||||
"required": [
|
||||
"loginType",
|
||||
"platformID",
|
||||
"enableCollection",
|
||||
"loginType",
|
||||
"systemVersion"
|
||||
],
|
||||
"properties": {
|
||||
@@ -14734,14 +14783,14 @@
|
||||
},
|
||||
"v1.WorkflowRecord": {
|
||||
"required": [
|
||||
"namespace",
|
||||
"message",
|
||||
"status",
|
||||
"mode",
|
||||
"name",
|
||||
"namespace",
|
||||
"workflowName",
|
||||
"workflowAlias",
|
||||
"applicationRevision"
|
||||
"applicationRevision",
|
||||
"mode",
|
||||
"message"
|
||||
],
|
||||
"properties": {
|
||||
"applicationRevision": {
|
||||
@@ -14832,8 +14881,8 @@
|
||||
},
|
||||
"v1.WorkflowStep": {
|
||||
"required": [
|
||||
"type",
|
||||
"name"
|
||||
"name",
|
||||
"type"
|
||||
],
|
||||
"properties": {
|
||||
"alias": {
|
||||
|
||||
@@ -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())
|
||||
|
||||
5
go.mod
5
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
|
||||
@@ -57,7 +57,7 @@ require (
|
||||
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
|
||||
github.com/kubevela/pkg v0.0.0-20230105054759-263dc191bf51
|
||||
github.com/kubevela/prism v1.7.0-alpha.1
|
||||
github.com/kubevela/workflow v0.3.6-0.20221230102636-6ae0c5cbc40f
|
||||
github.com/kubevela/workflow v0.4.1
|
||||
github.com/kyokomi/emoji v2.2.4+incompatible
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.1
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
|
||||
@@ -348,7 +348,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
|
||||
|
||||
8
go.sum
8
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=
|
||||
@@ -1283,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-20230105054759-263dc191bf51 h1:xrcNNaAjqC6tr1leSYcjLFgrXKpZ8u87jpB5TolhUIc=
|
||||
github.com/kubevela/pkg v0.0.0-20230105054759-263dc191bf51/go.mod h1:ZRnxY/gOcg/8FilZA+eYr+rtVXb1ijT5HFTe8zrv9zo=
|
||||
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.20221230102636-6ae0c5cbc40f h1:7EZWIfcTOgMlLgHkdDlf++hSjBTulfr4DYhZjeQbiJI=
|
||||
github.com/kubevela/workflow v0.3.6-0.20221230102636-6ae0c5cbc40f/go.mod h1:AX/WL3G/YBkpmNpA/SKKm9M3Y0T9y95gZA8mFWylkyM=
|
||||
github.com/kubevela/workflow v0.4.1 h1:lYeWE9KgSSkb368u8G7cGfyzCz41Am8MdxgViRFJxXE=
|
||||
github.com/kubevela/workflow v0.4.1/go.mod h1:AX/WL3G/YBkpmNpA/SKKm9M3Y0T9y95gZA8mFWylkyM=
|
||||
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=
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -911,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 {
|
||||
@@ -1076,6 +1075,8 @@ func (h *Installer) checkDependency(addon *InstallPackage) ([]string, error) {
|
||||
|
||||
// createOrUpdate will return true if updated
|
||||
func (h *Installer) createOrUpdate(app *v1beta1.Application) (bool, error) {
|
||||
// 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) {
|
||||
@@ -1087,8 +1088,6 @@ func (h *Installer) createOrUpdate(app *v1beta1.Application) (bool, error) {
|
||||
existApp.Spec = app.Spec
|
||||
existApp.Labels = app.Labels
|
||||
existApp.Annotations = app.Annotations
|
||||
// Set the publish version for the addon application
|
||||
oam.SetPublishVersion(&existApp, apiutils.GenerateVersion("addon"))
|
||||
err = h.cli.Update(h.ctx, &existApp)
|
||||
if err != nil {
|
||||
klog.Errorf("fail to create application: %v", err)
|
||||
@@ -1211,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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
@@ -18,7 +18,6 @@ package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
|
||||
@@ -88,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
|
||||
}
|
||||
@@ -100,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
|
||||
@@ -161,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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -99,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 {
|
||||
@@ -410,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,
|
||||
@@ -427,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
|
||||
@@ -457,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{
|
||||
@@ -607,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())
|
||||
}
|
||||
|
||||
@@ -1072,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
|
||||
}
|
||||
@@ -1713,6 +1753,10 @@ func (c *applicationServiceImpl) RollbackWithRevision(ctx context.Context, appli
|
||||
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)
|
||||
|
||||
@@ -208,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() {
|
||||
@@ -299,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())
|
||||
|
||||
@@ -135,6 +135,14 @@ func (u *configServiceImpl) CreateConfig(ctx context.Context, project string, re
|
||||
}
|
||||
ns = pro.GetNamespace()
|
||||
}
|
||||
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 {
|
||||
return nil, err
|
||||
@@ -154,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
|
||||
@@ -194,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
|
||||
|
||||
@@ -45,8 +45,9 @@ func NewHelmService() HelmService {
|
||||
type HelmService interface {
|
||||
ListChartNames(ctx context.Context, url string, secretName string, skipCache bool) ([]string, error)
|
||||
ListChartVersions(ctx context.Context, url string, chartName string, secretName string, skipCache bool) (repo.ChartVersions, error)
|
||||
GetChartValues(ctx context.Context, url string, chartName string, version string, secretName string, skipCache bool) (map[string]interface{}, error)
|
||||
ListChartValuesFiles(ctx context.Context, url string, chartName string, version string, secretName string, repoType string, skipCache bool) (map[string]string, error)
|
||||
ListChartRepo(ctx context.Context, projectName string) (*v1.ChartRepoResponseList, error)
|
||||
GetChartValues(ctx context.Context, repoURL string, chartName string, version string, secretName string, repoType string, skipCache bool) (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
type defaultHelmImpl struct {
|
||||
@@ -99,7 +100,7 @@ func (d defaultHelmImpl) ListChartVersions(ctx context.Context, repoURL string,
|
||||
return chartVersions, nil
|
||||
}
|
||||
|
||||
func (d defaultHelmImpl) GetChartValues(ctx context.Context, repoURL string, chartName string, version string, secretName string, skipCache bool) (map[string]interface{}, error) {
|
||||
func (d defaultHelmImpl) ListChartValuesFiles(ctx context.Context, repoURL string, chartName string, version string, secretName string, repoType string, skipCache bool) (map[string]string, error) {
|
||||
if !utils.IsValidURL(repoURL) {
|
||||
return nil, bcode.ErrRepoInvalidURL
|
||||
}
|
||||
@@ -111,13 +112,33 @@ func (d defaultHelmImpl) GetChartValues(ctx context.Context, repoURL string, cha
|
||||
return nil, bcode.ErrRepoBasicAuth
|
||||
}
|
||||
}
|
||||
v, err := d.helper.GetValuesFromChart(repoURL, chartName, version, skipCache, opts)
|
||||
v, err := d.helper.GetValuesFromChart(repoURL, chartName, version, skipCache, repoType, opts)
|
||||
if err != nil {
|
||||
klog.Errorf("cannot fetch chart values repo: %s, chart: %s, version: %s, error: %s", utils.Sanitize(repoURL), utils.Sanitize(chartName), utils.Sanitize(version), err.Error())
|
||||
return nil, bcode.ErrGetChartValues
|
||||
}
|
||||
res := make(map[string]interface{}, len(v))
|
||||
flattenKey("", v, res)
|
||||
return v.Data, nil
|
||||
}
|
||||
|
||||
func (d defaultHelmImpl) GetChartValues(ctx context.Context, repoURL string, chartName string, version string, secretName string, repoType string, skipCache bool) (map[string]interface{}, error) {
|
||||
if !utils.IsValidURL(repoURL) {
|
||||
return nil, bcode.ErrRepoInvalidURL
|
||||
}
|
||||
var opts *common.HTTPOption
|
||||
var err error
|
||||
if len(secretName) != 0 {
|
||||
opts, err = helm.SetHTTPOption(ctx, d.K8sClient, types2.NamespacedName{Namespace: types.DefaultKubeVelaNS, Name: secretName})
|
||||
if err != nil {
|
||||
return nil, bcode.ErrRepoBasicAuth
|
||||
}
|
||||
}
|
||||
v, err := d.helper.GetValuesFromChart(repoURL, chartName, version, skipCache, repoType, opts)
|
||||
if err != nil {
|
||||
klog.Errorf("cannot fetch chart values repo: %s, chart: %s, version: %s, error: %s", utils.Sanitize(repoURL), utils.Sanitize(chartName), utils.Sanitize(version), err.Error())
|
||||
return nil, bcode.ErrGetChartValues
|
||||
}
|
||||
res := make(map[string]interface{}, len(v.Values))
|
||||
flattenKey("", v.Values, res)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ var _ = Describe("test helm usecasae", func() {
|
||||
Expect(len(versions)).Should(BeEquivalentTo(1))
|
||||
Expect(versions[0].Version).Should(BeEquivalentTo("8.8.23"))
|
||||
|
||||
values, err := u.GetChartValues(ctx, mockServer.URL, "mysql", "8.8.23", "repo-secret", false)
|
||||
values, err := u.ListChartValuesFiles(ctx, mockServer.URL, "mysql", "8.8.23", "repo-secret", "helm", false)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(values).ShouldNot(BeNil())
|
||||
Expect(len(values)).ShouldNot(BeEquivalentTo(0))
|
||||
@@ -228,7 +228,7 @@ var _ = Describe("test helm usecasae", func() {
|
||||
_, err = u.ListChartVersions(ctx, "http://127.0.0.1:8080", "mysql", "repo-secret-notExist", false)
|
||||
Expect(err).ShouldNot(BeNil())
|
||||
|
||||
_, err = u.GetChartValues(ctx, "http://127.0.0.1:8080", "mysql", "8.8.23", "repo-secret-notExist", false)
|
||||
_, err = u.ListChartValuesFiles(ctx, "http://127.0.0.1:8080", "mysql", "8.8.23", "repo-secret-notExist", "helm", false)
|
||||
Expect(err).ShouldNot(BeNil())
|
||||
})
|
||||
})
|
||||
|
||||
@@ -104,7 +104,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)
|
||||
}
|
||||
|
||||
@@ -259,7 +259,9 @@ func managePrivilegesForTarget(ctx context.Context, cli client.Client, target *m
|
||||
f, msg = auth.RevokePrivileges, "RevokePrivileges"
|
||||
}
|
||||
if err := f(ctx, cli, []auth.PrivilegeDescription{p}, identity, writer); err != nil {
|
||||
return err
|
||||
klog.Warningf("error encountered for %s: %s", msg, err.Error())
|
||||
// for some cluster, authn/authz is not supported, ignore errors
|
||||
return client.IgnoreNotFound(err)
|
||||
}
|
||||
klog.Infof("%s: %s", msg, writer.String())
|
||||
return nil
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
|
||||
"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"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
|
||||
apisv1 "github.com/oam-dev/kubevela/pkg/apiserver/interfaces/api/dto/v1"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/utils/bcode"
|
||||
@@ -168,6 +169,7 @@ var _ = Describe("Test application service function", func() {
|
||||
Name: "test-acr",
|
||||
PayloadType: "acr",
|
||||
Type: "webhook",
|
||||
WorkflowName: repository.ConvertWorkflowName("webhook-dev"),
|
||||
ComponentName: "component-name-webhook",
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -202,6 +204,7 @@ var _ = Describe("Test application service function", func() {
|
||||
PayloadType: "acr",
|
||||
Type: "webhook",
|
||||
ComponentName: "component-name-webhook",
|
||||
WorkflowName: repository.ConvertWorkflowName("webhook-dev"),
|
||||
Registry: "test-enterprise-registry.test-region.cr.aliyuncs.com",
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -236,6 +239,7 @@ var _ = Describe("Test application service function", func() {
|
||||
PayloadType: "harbor",
|
||||
Type: "webhook",
|
||||
ComponentName: "component-name-webhook",
|
||||
WorkflowName: repository.ConvertWorkflowName("webhook-dev"),
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
@@ -274,6 +278,7 @@ var _ = Describe("Test application service function", func() {
|
||||
PayloadType: "dockerhub",
|
||||
Type: "webhook",
|
||||
ComponentName: "component-name-webhook",
|
||||
WorkflowName: repository.ConvertWorkflowName("webhook-dev"),
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
@@ -306,6 +311,7 @@ var _ = Describe("Test application service function", func() {
|
||||
PayloadType: "jfrog",
|
||||
Type: "webhook",
|
||||
ComponentName: "component-name-webhook",
|
||||
WorkflowName: repository.ConvertWorkflowName("webhook-dev"),
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
jfrogBody := apisv1.HandleApplicationTriggerJFrogRequest{
|
||||
|
||||
@@ -550,10 +550,10 @@ func (w *workflowServiceImpl) syncWorkflowStatus(ctx context.Context,
|
||||
record.Message = status.Message
|
||||
record.Mode = status.Mode
|
||||
|
||||
if cb := app.Status.Workflow.ContextBackend; cb != nil && workflowContext == nil {
|
||||
if cb := app.Status.Workflow.ContextBackend; cb != nil && workflowContext == nil && cb.Namespace != "" && cb.Name != "" {
|
||||
var cm corev1.ConfigMap
|
||||
if err := w.KubeClient.Get(ctx, types.NamespacedName{Namespace: cb.Namespace, Name: cb.Name}, &cm); err != nil {
|
||||
klog.Error(err, "failed to load the context values", "Application", app.Name)
|
||||
klog.Errorf("failed to load the context values of the application %s:%s", app.Name, err.Error())
|
||||
}
|
||||
record.ContextValue = cm.Data
|
||||
}
|
||||
@@ -866,8 +866,8 @@ func (w *workflowServiceImpl) RollbackRecord(ctx context.Context, appModel *mode
|
||||
if len(revisions) == 0 {
|
||||
return nil, bcode.ErrApplicationNoReadyRevision
|
||||
}
|
||||
revisionVersion = revisions[0].Index()["version"]
|
||||
klog.Infof("select lastest complete revision %s", revisions[0].Index()["version"])
|
||||
revisionVersion = pkgUtils.ToString(revisions[0].Index()["version"])
|
||||
klog.Infof("select lastest complete revision %s", revisionVersion)
|
||||
}
|
||||
|
||||
var record = &model.WorkflowRecord{
|
||||
|
||||
@@ -48,6 +48,7 @@ var _ = Describe("Test workflow service functions", func() {
|
||||
projectService *projectServiceImpl
|
||||
envService *envServiceImpl
|
||||
envBinding *envBindingServiceImpl
|
||||
targetService *targetServiceImpl
|
||||
testProject = "workflow-project"
|
||||
ds datastore.DataStore
|
||||
)
|
||||
@@ -60,6 +61,7 @@ var _ = Describe("Test workflow service functions", func() {
|
||||
rbacService := &rbacServiceImpl{Store: ds}
|
||||
projectService = &projectServiceImpl{Store: ds, RbacService: rbacService, K8sClient: k8sClient}
|
||||
envService = &envServiceImpl{Store: ds, KubeClient: k8sClient, ProjectService: projectService}
|
||||
targetService = &targetServiceImpl{Store: ds, K8sClient: k8sClient}
|
||||
envBinding = &envBindingServiceImpl{
|
||||
Store: ds,
|
||||
WorkflowService: workflowService,
|
||||
@@ -77,11 +79,20 @@ var _ = Describe("Test workflow service functions", func() {
|
||||
ProjectService: projectService,
|
||||
EnvService: envService,
|
||||
EnvBindingService: envBinding,
|
||||
WorkflowService: workflowService,
|
||||
}
|
||||
})
|
||||
It("Test CreateWorkflow function", func() {
|
||||
|
||||
_, err := projectService.CreateProject(context.TODO(), apisv1.CreateProjectRequest{Name: testProject})
|
||||
Expect(err).Should(BeNil())
|
||||
_, err = targetService.CreateTarget(context.TODO(), apisv1.CreateTargetRequest{
|
||||
Name: "dev-1", Project: testProject, Cluster: &apisv1.ClusterTarget{ClusterName: "local", Namespace: "dev-1"}})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
_, err = envService.CreateEnv(context.TODO(), apisv1.CreateEnvRequest{Name: "dev", Namespace: "dev-1", Targets: []string{"dev-1"}, Project: testProject})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
reqApp := apisv1.CreateApplicationRequest{
|
||||
Name: appName,
|
||||
Project: testProject,
|
||||
|
||||
@@ -89,7 +89,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)
|
||||
}
|
||||
|
||||
@@ -21,14 +21,13 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
client2 "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"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"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/clients"
|
||||
"github.com/oam-dev/kubevela/pkg/multicluster"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
|
||||
@@ -56,8 +55,9 @@ var waitBackOff = wait.Backoff{
|
||||
|
||||
// InfoCalculateCronJob is the cronJob to calculate the system info store in db
|
||||
type InfoCalculateCronJob struct {
|
||||
Store datastore.DataStore `inject:"datastore"`
|
||||
cron *cron.Cron
|
||||
KubeClient client.Client `inject:"kubeClient"`
|
||||
Store datastore.DataStore `inject:"datastore"`
|
||||
cron *cron.Cron
|
||||
}
|
||||
|
||||
// Start start the worker
|
||||
@@ -230,12 +230,8 @@ func (i InfoCalculateCronJob) calculateAppInfo(ctx context.Context) (int, []stri
|
||||
}
|
||||
|
||||
func (i InfoCalculateCronJob) calculateAddonInfo(ctx context.Context) (map[string]string, error) {
|
||||
client, err := clients.GetKubeClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
apps := &v1beta1.ApplicationList{}
|
||||
if err := client.List(ctx, apps, client2.InNamespace(types.DefaultKubeVelaNS), client2.HasLabels{oam.LabelAddonName}); err != nil {
|
||||
if err := i.KubeClient.List(ctx, apps, client.InNamespace(types.DefaultKubeVelaNS), client.HasLabels{oam.LabelAddonName}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := map[string]string{}
|
||||
@@ -257,11 +253,7 @@ func (i InfoCalculateCronJob) calculateAddonInfo(ctx context.Context) (map[strin
|
||||
}
|
||||
|
||||
func (i InfoCalculateCronJob) calculateClusterInfo(ctx context.Context) (int, error) {
|
||||
client, err := clients.GetKubeClient()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
cs, err := multicluster.ListVirtualClusters(ctx, client)
|
||||
cs, err := multicluster.ListVirtualClusters(ctx, i.KubeClient)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -83,7 +83,8 @@ var _ = Describe("Test calculate cronJob", func() {
|
||||
testProject = "test-cronjob-project"
|
||||
mockDataInDs()
|
||||
i = InfoCalculateCronJob{
|
||||
Store: ds,
|
||||
Store: ds,
|
||||
KubeClient: k8sClient,
|
||||
}
|
||||
systemInfo := model.SystemInfo{InstallID: "test-id", EnableCollection: true}
|
||||
Expect(ds.Add(ctx, &systemInfo)).Should(SatisfyAny(BeNil(), DataExistMatcher{}))
|
||||
|
||||
@@ -30,8 +30,8 @@ import (
|
||||
)
|
||||
|
||||
type cached struct {
|
||||
resourceVersion string
|
||||
targets int64
|
||||
revision string
|
||||
targets int64
|
||||
}
|
||||
|
||||
// initCache will initialize the cache
|
||||
@@ -48,9 +48,8 @@ func (c *CR2UX) initCache(ctx context.Context) error {
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
// Change the generation to resource version
|
||||
gen, ok := app.Labels[model.LabelSyncGeneration]
|
||||
if !ok || gen == "" {
|
||||
revision, ok := app.Labels[model.LabelSyncRevision]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
namespace := app.Labels[model.LabelSyncNamespace]
|
||||
@@ -60,7 +59,7 @@ func (c *CR2UX) initCache(ctx context.Context) error {
|
||||
}
|
||||
|
||||
// we should check targets if we synced from app status
|
||||
c.syncCache(key, gen, 0)
|
||||
c.syncCache(key, revision, 0)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -78,8 +77,10 @@ func (c *CR2UX) shouldSync(ctx context.Context, targetApp *v1beta1.Application,
|
||||
}
|
||||
|
||||
// if no LabelSourceOfTruth label, it means the app is existing ones, check the existing labels and annotations
|
||||
if _, appName := targetApp.Annotations[oam.AnnotationAppName]; appName {
|
||||
return false
|
||||
if targetApp.Annotations != nil {
|
||||
if _, exist := targetApp.Annotations[oam.AnnotationAppName]; exist {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
key := formatAppComposedName(targetApp.Name, targetApp.Namespace)
|
||||
@@ -90,16 +91,15 @@ func (c *CR2UX) shouldSync(ctx context.Context, targetApp *v1beta1.Application,
|
||||
_, _, err := c.getApp(ctx, targetApp.Name, targetApp.Namespace)
|
||||
if del || err != nil {
|
||||
c.cache.Delete(key)
|
||||
} else if cd.resourceVersion == targetApp.ResourceVersion {
|
||||
klog.Infof("app %s/%s with resource version(%v) hasn't updated, ignore the sync event..", targetApp.Name, targetApp.Namespace, targetApp.ResourceVersion)
|
||||
} else if cd.revision == getRevision(*targetApp) {
|
||||
klog.V(5).Infof("app %s/%s with resource revision(%v) hasn't updated, ignore the sync event..", targetApp.Name, targetApp.Namespace, targetApp.ResourceVersion)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (c *CR2UX) syncCache(key string, resourceVersion string, targets int64) {
|
||||
func (c *CR2UX) syncCache(key string, revision string, targets int64) {
|
||||
// update cache
|
||||
c.cache.Store(key, &cached{resourceVersion: resourceVersion, targets: targets})
|
||||
c.cache.Store(key, &cached{revision: revision, targets: targets})
|
||||
}
|
||||
|
||||
@@ -68,14 +68,18 @@ var _ = Describe("Test Cache", func() {
|
||||
app1 := &v1beta1.Application{}
|
||||
app1.Name = "app1"
|
||||
app1.Namespace = "app1-ns"
|
||||
app1.ResourceVersion = "1"
|
||||
Expect(cr2ux.shouldSync(ctx, app1, false)).Should(BeEquivalentTo(true))
|
||||
|
||||
app2 := &v1beta1.Application{}
|
||||
app2.Name = "app2"
|
||||
app2.Namespace = "app2-ns"
|
||||
app2.ResourceVersion = "1"
|
||||
app2.Generation = 1
|
||||
app2.Status.LatestRevision = &common.Revision{Name: "v1"}
|
||||
|
||||
Expect(cr2ux.shouldSync(ctx, app2, false)).Should(BeEquivalentTo(true))
|
||||
|
||||
// Only need to sync once.
|
||||
cr2ux.syncCache(formatAppComposedName(app2.Name, app2.Namespace), "v1", 1)
|
||||
Expect(cr2ux.shouldSync(ctx, app2, false)).Should(BeEquivalentTo(false))
|
||||
|
||||
app3 := &v1beta1.Application{}
|
||||
@@ -83,18 +87,17 @@ var _ = Describe("Test Cache", func() {
|
||||
app3.Namespace = "app3-ns"
|
||||
app3.ResourceVersion = "3"
|
||||
app3.Labels = map[string]string{
|
||||
model.LabelSyncGeneration: "1",
|
||||
model.LabelSyncNamespace: "app3-ns",
|
||||
model.LabelSourceOfTruth: model.FromUX,
|
||||
model.LabelSourceOfTruth: model.FromUX,
|
||||
}
|
||||
|
||||
Expect(cr2ux.shouldSync(ctx, app3, false)).Should(BeEquivalentTo(false))
|
||||
|
||||
Expect(ds.Put(ctx, &model.Application{Name: "app1", Labels: map[string]string{
|
||||
model.LabelSyncGeneration: "1",
|
||||
model.LabelSyncNamespace: "app1-ns",
|
||||
model.LabelSyncRevision: "v1",
|
||||
model.LabelSyncNamespace: "app1-ns",
|
||||
}})).Should(BeNil())
|
||||
cr2ux.syncCache(formatAppComposedName(app1.Name, app1.Namespace), "1", 0)
|
||||
cr2ux.syncCache(formatAppComposedName(app1.Name, app1.Namespace), "v1", 0)
|
||||
app1.Status.LatestRevision = &common.Revision{Name: "v1"}
|
||||
Expect(cr2ux.shouldSync(ctx, app1, false)).Should(BeEquivalentTo(false))
|
||||
Expect(cr2ux.shouldSync(ctx, app1, true)).Should(BeEquivalentTo(true))
|
||||
Expect(ds.Delete(ctx, &model.Application{Name: "app1"})).Should(BeNil())
|
||||
|
||||
@@ -46,11 +46,7 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
|
||||
}
|
||||
sourceOfTruth := model.FromCR
|
||||
if _, ok := targetApp.Labels[oam.LabelAddonName]; ok && strings.HasPrefix(targetApp.Name, "addon-") && targetApp.Namespace == apitypes.DefaultKubeVelaNS {
|
||||
project = v1.CreateProjectRequest{
|
||||
Name: model.DefaultSystemProject,
|
||||
Alias: model.DefaultSystemProjectAlias,
|
||||
Namespace: targetApp.Namespace,
|
||||
}
|
||||
project = c.generateSystemProject(ctx, targetApp.Namespace)
|
||||
sourceOfTruth = model.FromInner
|
||||
}
|
||||
|
||||
@@ -62,6 +58,7 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
|
||||
Labels: map[string]string{
|
||||
model.LabelSyncNamespace: targetApp.Namespace,
|
||||
model.LabelSyncGeneration: strconv.FormatInt(targetApp.Generation, 10),
|
||||
model.LabelSyncRevision: getRevision(*targetApp),
|
||||
model.LabelSourceOfTruth: sourceOfTruth,
|
||||
},
|
||||
}
|
||||
@@ -87,7 +84,7 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
klog.Infof("generate the environment %s for the application %s", env.Name, targetApp.Name)
|
||||
klog.V(5).Infof("generate the environment %s for the application %s", env.Name, targetApp.Name)
|
||||
dsApp.Env = env
|
||||
if newProject != "" {
|
||||
project = v1.CreateProjectRequest{
|
||||
@@ -149,6 +146,8 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
|
||||
// 7. convert the revision
|
||||
if revision := convert.FromCRApplicationRevision(ctx, cli, targetApp, *dsApp.Workflow, dsApp.Env.Name); revision != nil {
|
||||
dsApp.Revision = revision
|
||||
} else {
|
||||
klog.Warningf("can't generate the application revision(%s) for the app %s", getRevision(*targetApp), targetApp.Name)
|
||||
}
|
||||
// 8. convert the workflow record
|
||||
if record := convert.FromCRWorkflowRecord(targetApp, *dsApp.Workflow, dsApp.Revision); record != nil {
|
||||
@@ -157,6 +156,27 @@ func (c *CR2UX) ConvertApp2DatastoreApp(ctx context.Context, targetApp *v1beta1.
|
||||
return dsApp, nil
|
||||
}
|
||||
|
||||
// In order to maintain compatibility with old data,
|
||||
// if there is a project named addons, continue to use it, but change the alias to System.
|
||||
func (c *CR2UX) generateSystemProject(ctx context.Context, ns string) v1.CreateProjectRequest {
|
||||
var pro = model.Project{Name: "addons"}
|
||||
if err := c.ds.Get(ctx, &pro); err == nil {
|
||||
if pro.Alias == "Addons" {
|
||||
pro.Alias = model.DefaultSystemProjectAlias
|
||||
pro.Namespace = ns
|
||||
if err := c.ds.Put(ctx, &pro); err != nil {
|
||||
klog.Warningf("failed to update the project alias to System:%s", err.Error())
|
||||
}
|
||||
}
|
||||
return v1.CreateProjectRequest{Name: pro.Name, Alias: pro.Alias, Namespace: pro.Namespace}
|
||||
}
|
||||
return v1.CreateProjectRequest{
|
||||
Name: model.DefaultSystemProject,
|
||||
Alias: model.DefaultSystemProjectAlias,
|
||||
Namespace: ns,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CR2UX) generateEnv(ctx context.Context, defaultProject string, envNamespace string, envTargetNames map[string]string) (*model.Env, string, error) {
|
||||
existEnv := &model.Env{Namespace: envNamespace}
|
||||
existEnvs, err := c.ds.List(ctx, existEnv, nil)
|
||||
@@ -170,7 +190,7 @@ func (c *CR2UX) generateEnv(ctx context.Context, defaultProject string, envNames
|
||||
env.Targets = append(env.Targets, name)
|
||||
}
|
||||
}
|
||||
return env, "", nil
|
||||
return env, env.Project, nil
|
||||
}
|
||||
|
||||
// generate new environment
|
||||
@@ -212,3 +232,17 @@ func (c *CR2UX) generateEnv(ctx context.Context, defaultProject string, envNames
|
||||
}
|
||||
return env, "", nil
|
||||
}
|
||||
|
||||
func getRevision(app v1beta1.Application) string {
|
||||
if app.Status.LatestRevision == nil {
|
||||
return ""
|
||||
}
|
||||
return app.Status.LatestRevision.Name
|
||||
}
|
||||
|
||||
func getSyncedRevision(rev *model.ApplicationRevision) string {
|
||||
if rev == nil {
|
||||
return ""
|
||||
}
|
||||
return rev.Version
|
||||
}
|
||||
|
||||
@@ -133,7 +133,10 @@ func (c *CR2UX) AddOrUpdate(ctx context.Context, targetApp *v1beta1.Application)
|
||||
}
|
||||
|
||||
// update cache
|
||||
c.syncCache(dsApp.AppMeta.PrimaryKey(), targetApp.ResourceVersion, int64(len(dsApp.Targets)))
|
||||
key := formatAppComposedName(targetApp.Name, targetApp.Namespace)
|
||||
syncedVersion := getSyncedRevision(dsApp.Revision)
|
||||
c.syncCache(key, syncedVersion, int64(len(dsApp.Targets)))
|
||||
klog.Infof("application %s/%s revision %s synced successful", targetApp.Name, targetApp.Namespace, syncedVersion)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
||||
"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/pkg/apiserver/domain/model"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/domain/service"
|
||||
@@ -138,7 +139,7 @@ var _ = Describe("Test CR convert to ux", func() {
|
||||
app2 := &v1beta1.Application{}
|
||||
Expect(common2.ReadYamlToObject("testdata/test-app2.yaml", app2)).Should(BeNil())
|
||||
app1.Namespace = appNS1
|
||||
app1.Generation = 2
|
||||
app1.Status.LatestRevision = &common.Revision{Name: "v2"}
|
||||
app1.Spec = app2.Spec
|
||||
Expect(cr2ux.AddOrUpdate(context.Background(), app1)).Should(BeNil())
|
||||
comp3 := model.ApplicationComponent{AppPrimaryKey: apName1, Name: "blog"}
|
||||
@@ -216,6 +217,47 @@ var _ = Describe("Test CR convert to ux", func() {
|
||||
Expect(count).Should(Equal(int64(2)))
|
||||
})
|
||||
|
||||
It("Test to sync the project which existed env belongs", func() {
|
||||
dbNamespace := "update-app-db-ns1-test"
|
||||
ds, err := NewDatastore(datastore.Config{Type: "kubeapi", Database: dbNamespace})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
cr2ux := newCR2UX(ds)
|
||||
|
||||
projectName := "project-test"
|
||||
|
||||
_, err = cr2ux.projectService.CreateProject(context.TODO(), v1.CreateProjectRequest{
|
||||
Name: projectName,
|
||||
Owner: "admin",
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
_, err = cr2ux.targetService.CreateTarget(context.TODO(), v1.CreateTargetRequest{
|
||||
Name: "target-test1",
|
||||
Project: projectName,
|
||||
Cluster: &v1.ClusterTarget{
|
||||
ClusterName: "local",
|
||||
Namespace: "target-test1",
|
||||
},
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
_, err = cr2ux.envService.CreateEnv(context.TODO(), v1.CreateEnvRequest{
|
||||
Name: "env-test1",
|
||||
Project: projectName,
|
||||
Namespace: "env-test1",
|
||||
Targets: []string{"target-test1"},
|
||||
})
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
app5 := &v1beta1.Application{}
|
||||
Expect(common2.ReadYamlToObject("testdata/test-app5.yaml", app5)).Should(BeNil())
|
||||
app5.Namespace = "env-test1"
|
||||
Expect(cr2ux.AddOrUpdate(context.Background(), app5)).Should(BeNil())
|
||||
|
||||
app, err := cr2ux.applicationService.GetApplication(context.TODO(), app5.Name)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(app.Project).Should(Equal("project-test"))
|
||||
})
|
||||
})
|
||||
|
||||
func newCR2UX(ds datastore.DataStore) *CR2UX {
|
||||
|
||||
@@ -87,7 +87,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)
|
||||
}
|
||||
|
||||
16
pkg/apiserver/event/sync/testdata/test-app5.yaml
vendored
Normal file
16
pkg/apiserver/event/sync/testdata/test-app5.yaml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: example-sync-project
|
||||
spec:
|
||||
components:
|
||||
- name: example-exist-env
|
||||
type: webservice
|
||||
properties:
|
||||
image: wordpress
|
||||
traits:
|
||||
- type: gateway
|
||||
properties:
|
||||
domain: testsvc.example.com
|
||||
http:
|
||||
"/": 8000
|
||||
@@ -101,7 +101,7 @@ func (a *ApplicationSync) Start(ctx context.Context, errorChan chan error) {
|
||||
app := getApp(obj)
|
||||
if app.DeletionTimestamp == nil {
|
||||
a.Queue.Add(app)
|
||||
klog.Infof("watched update/add app event, namespace: %s, name: %s", app.Namespace, app.Name)
|
||||
klog.V(4).Infof("watched update/add app event, namespace: %s, name: %s", app.Namespace, app.Name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ func (a *ApplicationSync) Start(ctx context.Context, errorChan chan error) {
|
||||
},
|
||||
DeleteFunc: func(obj interface{}) {
|
||||
app := getApp(obj)
|
||||
klog.Infof("watched delete app event, namespace: %s, name: %s", app.Namespace, app.Name)
|
||||
klog.V(4).Infof("watched delete app event, namespace: %s, name: %s", app.Namespace, app.Name)
|
||||
a.Queue.Forget(app)
|
||||
a.Queue.Done(app)
|
||||
err = cu.DeleteApp(ctx, app)
|
||||
|
||||
@@ -26,6 +26,7 @@ import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
|
||||
"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/pkg/apiserver/domain/model"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/domain/repository"
|
||||
@@ -133,6 +134,9 @@ var _ = Describe("Test Worker CR sync to datastore", func() {
|
||||
app2.Spec = newapp2.Spec
|
||||
Expect(k8sClient.Update(context.TODO(), app2)).Should(BeNil())
|
||||
|
||||
app2.Status.LatestRevision = &common.Revision{Name: "v3"}
|
||||
Expect(k8sClient.Status().Update(context.TODO(), app2)).Should(BeNil())
|
||||
|
||||
Eventually(func() error {
|
||||
appm := model.ApplicationComponent{AppPrimaryKey: formatAppComposedName(app2.Name, app2.Namespace), Name: "nginx2"}
|
||||
return ds.Get(ctx, &appm)
|
||||
|
||||
@@ -74,7 +74,7 @@ type Entity interface {
|
||||
PrimaryKey() string
|
||||
TableName() string
|
||||
ShortTableName() string
|
||||
Index() map[string]string
|
||||
Index() map[string]interface{}
|
||||
}
|
||||
|
||||
// NewEntity Create a new object based on the input type
|
||||
|
||||
@@ -35,8 +35,8 @@ import (
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/clients"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/datastore"
|
||||
pkgUtils "github.com/oam-dev/kubevela/pkg/utils"
|
||||
)
|
||||
|
||||
type kubeapi struct {
|
||||
@@ -46,17 +46,13 @@ type kubeapi struct {
|
||||
|
||||
// New new kubeapi datastore instance
|
||||
// Data is stored using ConfigMap.
|
||||
func New(ctx context.Context, cfg datastore.Config) (datastore.DataStore, error) {
|
||||
kubeClient, err := clients.GetKubeClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
func New(ctx context.Context, cfg datastore.Config, client client.Client) (datastore.DataStore, error) {
|
||||
if cfg.Database == "" {
|
||||
cfg.Database = "kubevela_store"
|
||||
}
|
||||
var namespace corev1.Namespace
|
||||
if err := kubeClient.Get(ctx, types.NamespacedName{Name: cfg.Database}, &namespace); apierrors.IsNotFound(err) {
|
||||
if err := kubeClient.Create(ctx, &corev1.Namespace{
|
||||
if err := client.Get(ctx, types.NamespacedName{Name: cfg.Database}, &namespace); apierrors.IsNotFound(err) {
|
||||
if err := client.Create(ctx, &corev1.Namespace{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: cfg.Database,
|
||||
Annotations: map[string]string{"description": "For KubeVela API Server metadata storage."},
|
||||
@@ -64,9 +60,9 @@ func New(ctx context.Context, cfg datastore.Config) (datastore.DataStore, error)
|
||||
return nil, fmt.Errorf("create namespace failure %w", err)
|
||||
}
|
||||
}
|
||||
migrate(cfg.Database)
|
||||
migrate(cfg.Database, client)
|
||||
return &kubeapi{
|
||||
kubeClient: kubeClient,
|
||||
kubeClient: client,
|
||||
namespace: cfg.Database,
|
||||
}, nil
|
||||
}
|
||||
@@ -81,7 +77,7 @@ func generateName(entity datastore.Entity) string {
|
||||
|
||||
func (m *kubeapi) generateConfigMap(entity datastore.Entity) *corev1.ConfigMap {
|
||||
data, _ := json.Marshal(entity)
|
||||
labels := entity.Index()
|
||||
labels := convertIndex2Labels(entity.Index())
|
||||
if labels == nil {
|
||||
labels = make(map[string]string)
|
||||
}
|
||||
@@ -176,7 +172,7 @@ func (m *kubeapi) Put(ctx context.Context, entity datastore.Entity) error {
|
||||
return datastore.ErrTableNameEmpty
|
||||
}
|
||||
// update labels
|
||||
labels := entity.Index()
|
||||
labels := convertIndex2Labels(entity.Index())
|
||||
if labels == nil {
|
||||
labels = make(map[string]string)
|
||||
}
|
||||
@@ -350,8 +346,8 @@ func (m *kubeapi) List(ctx context.Context, entity datastore.Entity, op *datasto
|
||||
|
||||
rq, _ := labels.NewRequirement(MigrateKey, selection.DoesNotExist, []string{"ok"})
|
||||
selector = selector.Add(*rq)
|
||||
|
||||
for k, v := range entity.Index() {
|
||||
metedataLabels := convertIndex2Labels(entity.Index())
|
||||
for k, v := range metedataLabels {
|
||||
rq, err := labels.NewRequirement(k, selection.Equals, []string{verifyValue(v)})
|
||||
if err != nil {
|
||||
return nil, datastore.ErrIndexInvalid
|
||||
@@ -441,7 +437,8 @@ func (m *kubeapi) Count(ctx context.Context, entity datastore.Entity, filterOpti
|
||||
if err != nil {
|
||||
return 0, datastore.NewDBError(err)
|
||||
}
|
||||
for k, v := range entity.Index() {
|
||||
metedataLabels := convertIndex2Labels(entity.Index())
|
||||
for k, v := range metedataLabels {
|
||||
rq, err := labels.NewRequirement(k, selection.Equals, []string{verifyValue(v)})
|
||||
if err != nil {
|
||||
return 0, datastore.ErrIndexInvalid
|
||||
@@ -494,3 +491,19 @@ func verifyValue(v string) string {
|
||||
s = strings.ReplaceAll(s, " ", "-")
|
||||
return strings.ToLower(s)
|
||||
}
|
||||
|
||||
func convertIndex2Labels(index map[string]interface{}) map[string]string {
|
||||
if index == nil {
|
||||
return nil
|
||||
}
|
||||
ret := make(map[string]string, len(index))
|
||||
for k, v := range index {
|
||||
value := pkgUtils.ToString(v)
|
||||
if value == "" {
|
||||
klog.Warningf("unable to cast %#v of type %T to string", v, v)
|
||||
continue
|
||||
}
|
||||
ret[k] = pkgUtils.ToString(v)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ var _ = BeforeSuite(func(done Done) {
|
||||
By("new kube client success")
|
||||
|
||||
clients.SetKubeClient(k8sClient)
|
||||
kubeStore, err = New(context.TODO(), datastore.Config{Database: "test"})
|
||||
kubeStore, err = New(context.TODO(), datastore.Config{Database: "test"}, k8sClient)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(kubeStore).ToNot(BeNil())
|
||||
close(done)
|
||||
|
||||
@@ -72,20 +72,38 @@ var _ = Describe("Test kubeapi datastore driver", func() {
|
||||
err := kubeStore.Put(context.TODO(), &model.Application{Name: "kubevela-app", Description: "this is demo"})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
})
|
||||
It("Test index", func() {
|
||||
It("Test application index", func() {
|
||||
var app = model.Application{
|
||||
Name: "test",
|
||||
}
|
||||
selector, err := labels.Parse(fmt.Sprintf("table=%s", app.TableName()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(cmp.Diff(app.Index()["name"], "test")).Should(BeEmpty())
|
||||
for k, v := range app.Index() {
|
||||
index := convertIndex2Labels(app.Index())
|
||||
for k, v := range index {
|
||||
rq, err := labels.NewRequirement(k, selection.Equals, []string{v})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
selector = selector.Add(*rq)
|
||||
}
|
||||
Expect(cmp.Diff(selector.String(), "name=test,table=vela_application")).Should(BeEmpty())
|
||||
})
|
||||
It("Test workflow index", func() {
|
||||
defaultPtr := false
|
||||
var workflow = model.Workflow{
|
||||
Name: "test",
|
||||
Default: &defaultPtr,
|
||||
}
|
||||
selector, err := labels.Parse(fmt.Sprintf("table=%s", workflow.TableName()))
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(cmp.Diff(workflow.Index()["name"], "test")).Should(BeEmpty())
|
||||
index := convertIndex2Labels(workflow.Index())
|
||||
for k, v := range index {
|
||||
rq, err := labels.NewRequirement(k, selection.Equals, []string{v})
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
selector = selector.Add(*rq)
|
||||
}
|
||||
Expect(cmp.Diff(selector.String(), "default=false,name=test,table=vela_workflow")).Should(BeEmpty())
|
||||
})
|
||||
It("Test list function", func() {
|
||||
var app model.Application
|
||||
list, err := kubeStore.List(context.TODO(), &app, &datastore.ListOptions{Page: -1})
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/domain/model"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/infrastructure/clients"
|
||||
)
|
||||
|
||||
// MigrateKey marks the label key of the migrated data
|
||||
@@ -36,17 +35,13 @@ const MigrateKey = "db.oam.dev/migrated"
|
||||
// migrate will migrate the configmap to new short table name, it won't delete the configmaps:
|
||||
// users can delete by the following commands:
|
||||
// kubectl -n kubevela delete cm -l db.oam.dev/migrated=ok
|
||||
func migrate(dbns string) {
|
||||
kubeClient, err := clients.GetKubeClient()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
func migrate(dbns string, c client.Client) {
|
||||
models := model.GetRegisterModels()
|
||||
for _, k := range models {
|
||||
var configMaps corev1.ConfigMapList
|
||||
table := k.TableName()
|
||||
selector, _ := labels.Parse(fmt.Sprintf("table=%s", table))
|
||||
if err = kubeClient.List(context.Background(), &configMaps, &client.ListOptions{Namespace: dbns, LabelSelector: selector}); err != nil {
|
||||
if err := c.List(context.Background(), &configMaps, &client.ListOptions{Namespace: dbns, LabelSelector: selector}); err != nil {
|
||||
err = client.IgnoreNotFound(err)
|
||||
if err != nil {
|
||||
klog.Errorf("migrate db for kubeapi storage err: %v", err)
|
||||
@@ -72,14 +67,14 @@ func migrate(dbns string) {
|
||||
}
|
||||
|
||||
cm.Labels[MigrateKey] = "ok"
|
||||
err = kubeClient.Update(context.Background(), &cm)
|
||||
err := c.Update(context.Background(), &cm)
|
||||
if err != nil {
|
||||
klog.Errorf("update migrated record %s for kubeapi storage err: %v", cm.Name, err)
|
||||
}
|
||||
cm.Name = strings.ReplaceAll(k.ShortTableName()+strings.TrimPrefix(cm.Name, checkprefix), "_", "-")
|
||||
cm.ResourceVersion = ""
|
||||
delete(cm.Labels, MigrateKey)
|
||||
err = kubeClient.Create(context.Background(), &cm)
|
||||
err = c.Create(context.Background(), &cm)
|
||||
if err != nil {
|
||||
klog.Errorf("migrate record %s for kubeapi storage err: %v", cm.Name, err)
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ var _ = Describe("Test Migrate", func() {
|
||||
cm.Namespace = nsName
|
||||
Expect(ds.kubeClient.Create(context.Background(), cm)).Should(BeNil())
|
||||
|
||||
migrate(nsName)
|
||||
migrate(nsName, k8sClient)
|
||||
cmList := v1.ConfigMapList{}
|
||||
Expect(k8sClient.List(context.Background(), &cmList, client.InNamespace(nsName))).Should(BeNil())
|
||||
Expect(len(cmList.Items)).Should(BeEquivalentTo(2))
|
||||
|
||||
@@ -90,7 +90,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)
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ func (c *application) GetWebServiceRoute() *restful.WebService {
|
||||
Writes(apis.ApplicationStatisticsResponse{}))
|
||||
|
||||
ws.Route(ws.POST("/{appName}/triggers").To(c.createApplicationTrigger).
|
||||
Doc("create one application trigger").
|
||||
Doc("Create an application trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Filter(c.RbacService.CheckPerm("trigger", "create")).
|
||||
Filter(c.appCheckFilter).
|
||||
@@ -129,7 +129,7 @@ func (c *application) GetWebServiceRoute() *restful.WebService {
|
||||
Writes(apis.ApplicationTriggerBase{}))
|
||||
|
||||
ws.Route(ws.DELETE("/{appName}/triggers/{token}").To(c.deleteApplicationTrigger).
|
||||
Doc("delete one application trigger").
|
||||
Doc("Delete an application trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Filter(c.RbacService.CheckPerm("trigger", "delete")).
|
||||
Filter(c.appCheckFilter).
|
||||
@@ -139,8 +139,19 @@ func (c *application) GetWebServiceRoute() *restful.WebService {
|
||||
Returns(400, "Bad Request", bcode.Bcode{}).
|
||||
Writes([]*apis.EmptyResponse{}))
|
||||
|
||||
ws.Route(ws.PUT("/{appName}/triggers/{token}").To(c.updateApplicationTrigger).
|
||||
Doc("Update an application trigger").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Filter(c.RbacService.CheckPerm("trigger", "update")).
|
||||
Filter(c.appCheckFilter).
|
||||
Param(ws.PathParameter("appName", "identifier of the application ").DataType("string")).
|
||||
Param(ws.PathParameter("token", "identifier of the trigger").DataType("string")).
|
||||
Returns(200, "OK", apis.ApplicationTriggerBase{}).
|
||||
Returns(400, "Bad Request", bcode.Bcode{}).
|
||||
Writes([]*apis.ApplicationTriggerBase{}))
|
||||
|
||||
ws.Route(ws.GET("/{appName}/triggers").To(c.listApplicationTriggers).
|
||||
Doc("list application triggers").
|
||||
Doc("List the application triggers").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Filter(c.RbacService.CheckPerm("trigger", "list")).
|
||||
Filter(c.appCheckFilter).
|
||||
@@ -747,6 +758,24 @@ func (c *application) deleteApplicationTrigger(req *restful.Request, res *restfu
|
||||
}
|
||||
}
|
||||
|
||||
func (c *application) updateApplicationTrigger(req *restful.Request, res *restful.Response) {
|
||||
var updateReq apis.UpdateApplicationTriggerRequest
|
||||
if err := req.ReadEntity(&updateReq); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
app := req.Request.Context().Value(&apis.CtxKeyApplication).(*model.Application)
|
||||
trigger, err := c.ApplicationService.UpdateApplicationTrigger(req.Request.Context(), app, req.PathParameter("token"), updateReq)
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
if err := res.WriteEntity(trigger); err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (c *application) publishApplicationTemplate(req *restful.Request, res *restful.Response) {
|
||||
app := req.Request.Context().Value(&apis.CtxKeyApplication).(*model.Application)
|
||||
base, err := c.ApplicationService.PublishApplicationTemplate(req.Request.Context(), app)
|
||||
|
||||
@@ -274,6 +274,23 @@ func ConvertPermission2DTO(permission *model.Permission) *apisv1.PermissionBase
|
||||
}
|
||||
}
|
||||
|
||||
// ConvertTrigger2DTO convert trigger model to the DTO
|
||||
func ConvertTrigger2DTO(trigger model.ApplicationTrigger) *apisv1.ApplicationTriggerBase {
|
||||
return &apisv1.ApplicationTriggerBase{
|
||||
WorkflowName: trigger.WorkflowName,
|
||||
Name: trigger.Name,
|
||||
Alias: trigger.Alias,
|
||||
Description: trigger.Description,
|
||||
Type: trigger.Type,
|
||||
PayloadType: trigger.PayloadType,
|
||||
Token: trigger.Token,
|
||||
Registry: trigger.Registry,
|
||||
ComponentName: trigger.ComponentName,
|
||||
CreateTime: trigger.CreateTime,
|
||||
UpdateTime: trigger.UpdateTime,
|
||||
}
|
||||
}
|
||||
|
||||
func convertBool(b *bool) bool {
|
||||
if b == nil {
|
||||
return false
|
||||
|
||||
@@ -512,6 +512,16 @@ type CreateApplicationTriggerRequest struct {
|
||||
Registry string `json:"registry,omitempty" optional:"true"`
|
||||
}
|
||||
|
||||
// UpdateApplicationTriggerRequest update application trigger
|
||||
type UpdateApplicationTriggerRequest struct {
|
||||
Alias string `json:"alias" validate:"checkalias" optional:"true"`
|
||||
Description string `json:"description" optional:"true"`
|
||||
WorkflowName string `json:"workflowName"`
|
||||
PayloadType string `json:"payloadType" validate:"checkpayloadtype"`
|
||||
ComponentName string `json:"componentName,omitempty" optional:"true"`
|
||||
Registry string `json:"registry,omitempty" optional:"true"`
|
||||
}
|
||||
|
||||
// ApplicationTriggerBase application trigger base model
|
||||
type ApplicationTriggerBase struct {
|
||||
Name string `json:"name"`
|
||||
@@ -522,6 +532,7 @@ type ApplicationTriggerBase struct {
|
||||
PayloadType string `json:"payloadType"`
|
||||
Token string `json:"token"`
|
||||
ComponentName string `json:"componentName,omitempty"`
|
||||
Registry string `json:"registry"`
|
||||
CreateTime time.Time `json:"createTime"`
|
||||
UpdateTime time.Time `json:"updateTime"`
|
||||
}
|
||||
|
||||
@@ -69,9 +69,19 @@ func (h repository) GetWebServiceRoute() *restful.WebService {
|
||||
Writes([]string{}))
|
||||
|
||||
// List available chart versions
|
||||
ws.Route(ws.GET("/charts/{chart}/versions").To(h.listVersions).
|
||||
ws.Route(ws.GET("/chart/versions").To(h.listVersionsFromQuery).
|
||||
Doc("list versions").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Param(ws.QueryParameter("chart", "helm chart").DataType("string").Required(true)).
|
||||
Param(ws.QueryParameter("repoUrl", "helm repository url").DataType("string").Required(true)).
|
||||
Param(ws.QueryParameter("secretName", "secret of the repo").DataType("string")).
|
||||
Returns(200, "OK", v1.ChartVersionListResponse{}).
|
||||
Returns(400, "Bad Request", bcode.Bcode{}).
|
||||
Writes([]string{}))
|
||||
|
||||
ws.Route(ws.GET("/charts/{chart}/versions").To(h.listChartVersions).
|
||||
Doc("list versions").Deprecate().
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Param(ws.QueryParameter("repoUrl", "helm repository url").DataType("string")).
|
||||
Param(ws.QueryParameter("secretName", "secret of the repo").DataType("string")).
|
||||
Returns(200, "OK", v1.ChartVersionListResponse{}).
|
||||
@@ -79,14 +89,26 @@ func (h repository) GetWebServiceRoute() *restful.WebService {
|
||||
Writes([]string{}))
|
||||
|
||||
// List available chart versions
|
||||
ws.Route(ws.GET("/charts/{chart}/versions/{version}/values").To(h.chartValues).
|
||||
ws.Route(ws.GET("/chart/values").To(h.chartValues).
|
||||
Doc("get chart value").
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Param(ws.QueryParameter("chart", "helm chart").DataType("string").Required(true)).
|
||||
Param(ws.QueryParameter("version", "helm chart version").DataType("string").Required(true)).
|
||||
Param(ws.QueryParameter("repoUrl", "helm repository url").DataType("string").Required(true)).
|
||||
Param(ws.QueryParameter("repoType", "helm repository type").DataType("string").Required(true)).
|
||||
Param(ws.QueryParameter("secretName", "secret of the repo").DataType("string")).
|
||||
Returns(200, "OK", "").
|
||||
Returns(400, "Bad Request", bcode.Bcode{}).
|
||||
Writes(map[string]string{}))
|
||||
|
||||
ws.Route(ws.GET("/charts/{chart}/versions/{version}/values").To(h.getChartValues).
|
||||
Doc("get chart value").Deprecate().
|
||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||
Param(ws.QueryParameter("repoUrl", "helm repository url").DataType("string")).
|
||||
Param(ws.QueryParameter("secretName", "secret of the repo").DataType("string")).
|
||||
Returns(200, "OK", map[string]interface{}{}).
|
||||
Returns(400, "Bad Request", bcode.Bcode{}).
|
||||
Writes([]string{}))
|
||||
Writes(map[string]interface{}{}))
|
||||
|
||||
ws.Route(ws.GET("/image/repos").To(h.getImageRepos).
|
||||
Doc("get the oci repos").
|
||||
@@ -132,9 +154,9 @@ func (h repository) listCharts(req *restful.Request, res *restful.Response) {
|
||||
}
|
||||
}
|
||||
|
||||
func (h repository) listVersions(req *restful.Request, res *restful.Response) {
|
||||
func (h repository) listVersionsFromQuery(req *restful.Request, res *restful.Response) {
|
||||
url := req.QueryParameter("repoUrl")
|
||||
chartName := req.PathParameter("chart")
|
||||
chartName := req.QueryParameter("chart")
|
||||
secName := req.QueryParameter("secretName")
|
||||
skipCache, err := isSkipCache(req)
|
||||
if err != nil {
|
||||
@@ -154,7 +176,7 @@ func (h repository) listVersions(req *restful.Request, res *restful.Response) {
|
||||
}
|
||||
}
|
||||
|
||||
func (h repository) chartValues(req *restful.Request, res *restful.Response) {
|
||||
func (h repository) getChartValues(req *restful.Request, res *restful.Response) {
|
||||
url := req.QueryParameter("repoUrl")
|
||||
secName := req.QueryParameter("secretName")
|
||||
chartName := req.PathParameter("chart")
|
||||
@@ -165,12 +187,57 @@ func (h repository) chartValues(req *restful.Request, res *restful.Response) {
|
||||
return
|
||||
}
|
||||
|
||||
versions, err := h.HelmService.GetChartValues(req.Request.Context(), url, chartName, version, secName, skipCache)
|
||||
values, err := h.HelmService.GetChartValues(req.Request.Context(), url, chartName, version, secName, "helm", skipCache)
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
err = res.WriteEntity(versions)
|
||||
err = res.WriteEntity(values)
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h repository) listChartVersions(req *restful.Request, res *restful.Response) {
|
||||
url := req.QueryParameter("repoUrl")
|
||||
chartName := req.PathParameter("chart")
|
||||
secName := req.QueryParameter("secretName")
|
||||
skipCache, err := isSkipCache(req)
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, bcode.ErrSkipCacheParameter)
|
||||
return
|
||||
}
|
||||
versions, err := h.HelmService.ListChartVersions(req.Request.Context(), url, chartName, secName, skipCache)
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
err = res.WriteEntity(v1.ChartVersionListResponse{Versions: versions})
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (h repository) chartValues(req *restful.Request, res *restful.Response) {
|
||||
url := req.QueryParameter("repoUrl")
|
||||
secName := req.QueryParameter("secretName")
|
||||
chartName := req.QueryParameter("chart")
|
||||
version := req.QueryParameter("version")
|
||||
repoType := req.QueryParameter("repoType")
|
||||
skipCache, err := isSkipCache(req)
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, bcode.ErrSkipCacheParameter)
|
||||
return
|
||||
}
|
||||
|
||||
values, err := h.HelmService.ListChartValuesFiles(req.Request.Context(), url, chartName, version, secName, repoType, skipCache)
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
err = res.WriteEntity(values)
|
||||
if err != nil {
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
|
||||
@@ -121,7 +121,7 @@ func (dt *Target) createTarget(req *restful.Request, res *restful.Response) {
|
||||
// Call the domain layer code
|
||||
TargetDetail, err := dt.TargetService.CreateTarget(req.Request.Context(), createReq)
|
||||
if err != nil {
|
||||
klog.Errorf("create -target failure %s", err.Error())
|
||||
klog.Errorf("create target failure %s", err.Error())
|
||||
bcode.ReturnError(req, res, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/apiserver/utils/container"
|
||||
pkgconfig "github.com/oam-dev/kubevela/pkg/config"
|
||||
"github.com/oam-dev/kubevela/pkg/features"
|
||||
pkgUtils "github.com/oam-dev/kubevela/pkg/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/apply"
|
||||
)
|
||||
@@ -86,6 +87,8 @@ func (s *restServer) buildIoCContainer() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
authClient := utils.NewAuthClient(kubeClient)
|
||||
|
||||
var ds datastore.DataStore
|
||||
switch s.cfg.Datastore.Type {
|
||||
case "mongodb":
|
||||
@@ -94,7 +97,7 @@ func (s *restServer) buildIoCContainer() error {
|
||||
return fmt.Errorf("create mongodb datastore instance failure %w", err)
|
||||
}
|
||||
case "kubeapi":
|
||||
ds, err = kubeapi.New(context.Background(), s.cfg.Datastore)
|
||||
ds, err = kubeapi.New(context.Background(), s.cfg.Datastore, kubeClient)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create kubeapi datastore instance failure %w", err)
|
||||
}
|
||||
@@ -106,23 +109,22 @@ func (s *restServer) buildIoCContainer() error {
|
||||
return fmt.Errorf("fail to provides the datastore bean to the container: %w", err)
|
||||
}
|
||||
|
||||
kubeClient = utils.NewAuthClient(kubeClient)
|
||||
if err := s.beanContainer.ProvideWithName("kubeClient", kubeClient); err != nil {
|
||||
if err := s.beanContainer.ProvideWithName("kubeClient", authClient); err != nil {
|
||||
return fmt.Errorf("fail to provides the kubeClient bean to the container: %w", err)
|
||||
}
|
||||
if err := s.beanContainer.ProvideWithName("kubeConfig", kubeConfig); err != nil {
|
||||
return fmt.Errorf("fail to provides the kubeConfig bean to the container: %w", err)
|
||||
}
|
||||
if err := s.beanContainer.ProvideWithName("apply", apply.NewAPIApplicator(kubeClient)); err != nil {
|
||||
if err := s.beanContainer.ProvideWithName("apply", apply.NewAPIApplicator(authClient)); err != nil {
|
||||
return fmt.Errorf("fail to provides the apply bean to the container: %w", err)
|
||||
}
|
||||
|
||||
factory := pkgconfig.NewConfigFactory(kubeClient)
|
||||
factory := pkgconfig.NewConfigFactory(authClient)
|
||||
if err := s.beanContainer.ProvideWithName("configFactory", factory); err != nil {
|
||||
return fmt.Errorf("fail to provides the config factory bean to the container: %w", err)
|
||||
}
|
||||
|
||||
addonStore := pkgaddon.NewRegistryDataStore(kubeClient)
|
||||
addonStore := pkgaddon.NewRegistryDataStore(authClient)
|
||||
if err := s.beanContainer.ProvideWithName("registryDatastore", addonStore); err != nil {
|
||||
return fmt.Errorf("fail to provides the registry datastore bean to the container: %w", err)
|
||||
}
|
||||
@@ -149,6 +151,12 @@ func (s *restServer) buildIoCContainer() error {
|
||||
|
||||
func (s *restServer) Run(ctx context.Context, errChan chan error) error {
|
||||
|
||||
for feature := range features.APIServerMutableFeatureGate.GetAll() {
|
||||
if features.APIServerFeatureGate.Enabled(feature) {
|
||||
klog.Infof("The %s feature enabled", feature)
|
||||
}
|
||||
}
|
||||
|
||||
// build the Ioc Container
|
||||
if err := s.buildIoCContainer(); err != nil {
|
||||
return err
|
||||
|
||||
@@ -86,6 +86,12 @@ func (c *authClient) Status() client.StatusWriter {
|
||||
return &authAppStatusClient{StatusWriter: c.Client.Status()}
|
||||
}
|
||||
|
||||
// Get .
|
||||
func (c *authClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object) error {
|
||||
ctx = ContextWithUserInfo(ctx)
|
||||
return c.Client.Get(ctx, key, obj)
|
||||
}
|
||||
|
||||
// List .
|
||||
func (c *authClient) List(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error {
|
||||
ctx = ContextWithUserInfo(ctx)
|
||||
|
||||
@@ -37,4 +37,7 @@ var (
|
||||
|
||||
// ErrNotFoundDistribution means the distribution is not exist
|
||||
ErrNotFoundDistribution = NewBcode(404, 16007, "the distribution is not exist")
|
||||
|
||||
// ErrChangeSecretType the secret type of the config can not be change
|
||||
ErrChangeSecretType = NewBcode(400, 16008, "the secret type of the config can not be change")
|
||||
)
|
||||
|
||||
@@ -23,8 +23,6 @@ import (
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/yaml"
|
||||
@@ -167,7 +165,6 @@ var _ = Describe("Test Live-Diff", func() {
|
||||
Expect(k8sClient.Create(context.Background(), un)).Should(Succeed())
|
||||
}
|
||||
ctx := context.Background()
|
||||
Expect(k8sClient.Create(ctx, &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: "vela-system"}})).Should(Succeed())
|
||||
applyFile("diff-input-app-with-externals.yaml", "default")
|
||||
applyFile("diff-apprevision.yaml", "default")
|
||||
app := &v1beta1.Application{}
|
||||
@@ -190,7 +187,6 @@ var _ = Describe("Test Live-Diff", func() {
|
||||
Expect(runDiff()).Should(ContainSubstring("\"myworker\" not found"))
|
||||
applyFile("td-myingress.yaml", "vela-system")
|
||||
applyFile("cd-myworker.yaml", "vela-system")
|
||||
applyFile("wd-deploy.yaml", "vela-system")
|
||||
applyFile("wd-ref-objects.yaml", "vela-system")
|
||||
Expect(runDiff()).Should(ContainSubstring("\"deploy-livediff-demo\" not found"))
|
||||
applyFile("external-workflow.yaml", "default")
|
||||
|
||||
@@ -37,14 +37,19 @@ import (
|
||||
|
||||
"github.com/kubevela/workflow/pkg/cue/packages"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
|
||||
"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/appfile"
|
||||
"github.com/oam-dev/kubevela/pkg/cue/definition"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/discoverymapper"
|
||||
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
"github.com/oam-dev/kubevela/pkg/policy/envbinding"
|
||||
"github.com/oam-dev/kubevela/pkg/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/apply"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/step"
|
||||
)
|
||||
|
||||
// DryRun executes dry-run on an application
|
||||
@@ -136,13 +141,15 @@ func (d *Option) ExecuteDryRun(ctx context.Context, application *v1beta1.Applica
|
||||
if app.Namespace != "" {
|
||||
ctx = oamutil.SetNamespaceInCtx(ctx, app.Namespace)
|
||||
}
|
||||
appFile, err := parser.GenerateAppFileFromApp(ctx, app)
|
||||
generateCtx := apiutils.WithProject(ctx, "")
|
||||
appFile, err := parser.GenerateAppFileFromApp(generateCtx, app)
|
||||
if err != nil {
|
||||
return nil, nil, errors.WithMessage(err, "cannot generate appFile from application")
|
||||
}
|
||||
if appFile.Namespace == "" {
|
||||
appFile.Namespace = corev1.NamespaceDefault
|
||||
}
|
||||
|
||||
comps, err := appFile.GenerateComponentManifests()
|
||||
if err != nil {
|
||||
return nil, nil, errors.WithMessage(err, "cannot generate manifests from components and traits")
|
||||
@@ -206,3 +213,120 @@ func (d *Option) PrintDryRun(buff *bytes.Buffer, appName string, comps []*types.
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExecuteDryRunWithPolicies is similar to ExecuteDryRun func, but considers deploy workflow step and topology+override policies
|
||||
func (d *Option) ExecuteDryRunWithPolicies(ctx context.Context, application *v1beta1.Application, buff *bytes.Buffer) error {
|
||||
|
||||
app := application.DeepCopy()
|
||||
if app.Namespace == "" {
|
||||
app.Namespace = corev1.NamespaceDefault
|
||||
} else {
|
||||
ctx = oamutil.SetNamespaceInCtx(ctx, app.Namespace)
|
||||
}
|
||||
parser := appfile.NewDryRunApplicationParser(d.Client, d.DiscoveryMapper, d.PackageDiscover, d.Auxiliaries)
|
||||
af, err := parser.GenerateAppFileFromApp(ctx, app)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deployWorkflowCount := 0
|
||||
for _, wfs := range af.WorkflowSteps {
|
||||
if wfs.Type == step.DeployWorkflowStep {
|
||||
deployWorkflowCount++
|
||||
deployWorkflowStepSpec := &step.DeployWorkflowStepSpec{}
|
||||
if err := utils.StrictUnmarshal(wfs.Properties.Raw, deployWorkflowStepSpec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
topologyPolicies, overridePolicies, err := filterPolicies(af.Policies, deployWorkflowStepSpec.Policies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(topologyPolicies) > 0 {
|
||||
for _, tp := range topologyPolicies {
|
||||
patchedApp, err := patchApp(app, overridePolicies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
comps, pms, err := d.ExecuteDryRun(ctx, patchedApp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = d.PrintDryRun(buff, fmt.Sprintf("%s with topology %s", patchedApp.Name, tp.Name), comps, pms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
patchedApp, err := patchApp(app, overridePolicies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
comps, pms, err := d.ExecuteDryRun(ctx, patchedApp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = d.PrintDryRun(buff, fmt.Sprintf("%s only with override policies", patchedApp.Name), comps, pms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if deployWorkflowCount == 0 {
|
||||
comps, pms, err := d.ExecuteDryRun(ctx, app)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = d.PrintDryRun(buff, app.Name, comps, pms)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func filterPolicies(policies []v1beta1.AppPolicy, policyNames []string) ([]v1beta1.AppPolicy, []v1beta1.AppPolicy, error) {
|
||||
policyMap := make(map[string]v1beta1.AppPolicy)
|
||||
for _, policy := range policies {
|
||||
policyMap[policy.Name] = policy
|
||||
}
|
||||
var topologyPolicies []v1beta1.AppPolicy
|
||||
var overridePolicies []v1beta1.AppPolicy
|
||||
for _, policyName := range policyNames {
|
||||
if policy, found := policyMap[policyName]; found {
|
||||
switch policy.Type {
|
||||
case v1alpha1.TopologyPolicyType:
|
||||
topologyPolicies = append(topologyPolicies, policy)
|
||||
case v1alpha1.OverridePolicyType:
|
||||
overridePolicies = append(overridePolicies, policy)
|
||||
}
|
||||
} else {
|
||||
return nil, nil, errors.Errorf("policy %s not found", policyName)
|
||||
}
|
||||
}
|
||||
return topologyPolicies, overridePolicies, nil
|
||||
}
|
||||
|
||||
func patchApp(application *v1beta1.Application, overridePolicies []v1beta1.AppPolicy) (*v1beta1.Application, error) {
|
||||
app := application.DeepCopy()
|
||||
for _, policy := range overridePolicies {
|
||||
|
||||
if policy.Properties == nil {
|
||||
return nil, fmt.Errorf("override policy %s must not have empty properties", policy.Name)
|
||||
}
|
||||
overrideSpec := &v1alpha1.OverridePolicySpec{}
|
||||
if err := utils.StrictUnmarshal(policy.Properties.Raw, overrideSpec); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parse override policy %s", policy.Name)
|
||||
}
|
||||
overrideComps, err := envbinding.PatchComponents(app.Spec.Components, overrideSpec.Components, overrideSpec.Selector)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to apply override policy %s", policy.Name)
|
||||
}
|
||||
app.Spec.Components = overrideComps
|
||||
}
|
||||
|
||||
return app, nil
|
||||
}
|
||||
|
||||
@@ -17,8 +17,11 @@ limitations under the License.
|
||||
package dryrun
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
|
||||
@@ -59,3 +62,108 @@ var _ = Describe("Test DryRun", func() {
|
||||
Expect(diff).Should(BeEmpty())
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("Test dry run with policies", func() {
|
||||
It("Test dry run with override policy", func() {
|
||||
|
||||
webservice, err := os.ReadFile("../../../charts/vela-core/templates/defwithtemplate/webservice.yaml")
|
||||
Expect(err).Should(BeNil())
|
||||
webserviceYAML := strings.Replace(string(webservice), "{{ include \"systemDefinitionNamespace\" . }}", types.DefaultKubeVelaNS, 1)
|
||||
wwd := v1beta1.ComponentDefinition{}
|
||||
Expect(yaml.Unmarshal([]byte(webserviceYAML), &wwd)).Should(BeNil())
|
||||
Expect(k8sClient.Create(context.TODO(), &wwd)).Should(BeNil())
|
||||
|
||||
scaler, err := os.ReadFile("../../../charts/vela-core/templates/defwithtemplate/scaler.yaml")
|
||||
Expect(err).Should(BeNil())
|
||||
scalerYAML := strings.Replace(string(scaler), "{{ include \"systemDefinitionNamespace\" . }}", types.DefaultKubeVelaNS, 1)
|
||||
var td v1beta1.TraitDefinition
|
||||
Expect(yaml.Unmarshal([]byte(scalerYAML), &td)).Should(BeNil())
|
||||
Expect(k8sClient.Create(context.TODO(), &td)).Should(BeNil())
|
||||
|
||||
appYAML := readDataFromFile("./testdata/testing-dry-run-1.yaml")
|
||||
app := &v1beta1.Application{}
|
||||
Expect(yaml.Unmarshal([]byte(appYAML), &app)).Should(BeNil())
|
||||
|
||||
var buff = bytes.Buffer{}
|
||||
err = dryrunOpt.ExecuteDryRunWithPolicies(context.TODO(), app, &buff)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app with topology target-default)"))
|
||||
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app with topology target-prod)"))
|
||||
Expect(buff.String()).Should(ContainSubstring("name: testing-dryrun"))
|
||||
Expect(buff.String()).Should(ContainSubstring("kind: Deployment"))
|
||||
Expect(buff.String()).Should(ContainSubstring("replicas: 1"))
|
||||
Expect(buff.String()).Should(ContainSubstring("replicas: 3"))
|
||||
Expect(buff.String()).Should(ContainSubstring("kind: Service"))
|
||||
})
|
||||
|
||||
It("Test dry run only with override policy", func() {
|
||||
|
||||
appYAML := readDataFromFile("./testdata/testing-dry-run-2.yaml")
|
||||
app := &v1beta1.Application{}
|
||||
Expect(yaml.Unmarshal([]byte(appYAML), &app)).Should(BeNil())
|
||||
|
||||
var buff = bytes.Buffer{}
|
||||
err := dryrunOpt.ExecuteDryRunWithPolicies(context.TODO(), app, &buff)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app only with override policies)"))
|
||||
Expect(buff.String()).Should(ContainSubstring("name: testing-dryrun"))
|
||||
Expect(buff.String()).Should(ContainSubstring("kind: Deployment"))
|
||||
Expect(buff.String()).Should(ContainSubstring("replicas: 3"))
|
||||
Expect(buff.String()).Should(ContainSubstring("kind: Service"))
|
||||
})
|
||||
|
||||
It("Test dry run without deploy workflow", func() {
|
||||
|
||||
appYAML := readDataFromFile("./testdata/testing-dry-run-3.yaml")
|
||||
app := &v1beta1.Application{}
|
||||
Expect(yaml.Unmarshal([]byte(appYAML), &app)).Should(BeNil())
|
||||
|
||||
var buff = bytes.Buffer{}
|
||||
err := dryrunOpt.ExecuteDryRunWithPolicies(context.TODO(), app, &buff)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app)"))
|
||||
Expect(buff.String()).Should(ContainSubstring("name: testing-dryrun"))
|
||||
Expect(buff.String()).Should(ContainSubstring("kind: Deployment"))
|
||||
})
|
||||
|
||||
It("Test dry run without custom policy", func() {
|
||||
|
||||
topo, err := os.ReadFile("./testdata/pd-mypolicy.yaml")
|
||||
Expect(err).Should(BeNil())
|
||||
var pd v1beta1.PolicyDefinition
|
||||
Expect(yaml.Unmarshal([]byte(topo), &pd)).Should(BeNil())
|
||||
Expect(k8sClient.Create(context.TODO(), &pd)).Should(BeNil())
|
||||
|
||||
appYAML := readDataFromFile("./testdata/testing-dry-run-4.yaml")
|
||||
app := &v1beta1.Application{}
|
||||
Expect(yaml.Unmarshal([]byte(appYAML), &app)).Should(BeNil())
|
||||
|
||||
var buff = bytes.Buffer{}
|
||||
err = dryrunOpt.ExecuteDryRunWithPolicies(context.TODO(), app, &buff)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app) -- Component(testing-dryrun)"))
|
||||
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app) -- Policy(mypolicy)"))
|
||||
Expect(buff.String()).Should(ContainSubstring("name: my-policy"))
|
||||
})
|
||||
|
||||
It("Test dry run with trait", func() {
|
||||
|
||||
nocalhost, err := os.ReadFile("../../../charts/vela-core/templates/defwithtemplate/nocalhost.yaml")
|
||||
Expect(err).Should(BeNil())
|
||||
nocalhostYAML := strings.Replace(string(nocalhost), "{{ include \"systemDefinitionNamespace\" . }}", types.DefaultKubeVelaNS, 1)
|
||||
var td v1beta1.TraitDefinition
|
||||
Expect(yaml.Unmarshal([]byte(nocalhostYAML), &td)).Should(BeNil())
|
||||
Expect(k8sClient.Create(context.TODO(), &td)).Should(BeNil())
|
||||
|
||||
appYAML := readDataFromFile("./testdata/testing-dry-run-5.yaml")
|
||||
app := &v1beta1.Application{}
|
||||
Expect(yaml.Unmarshal([]byte(appYAML), &app)).Should(BeNil())
|
||||
|
||||
var buff = bytes.Buffer{}
|
||||
err = dryrunOpt.ExecuteDryRunWithPolicies(context.TODO(), app, &buff)
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app) -- Component(testing-dryrun)"))
|
||||
Expect(buff.String()).Should(ContainSubstring("## From the trait nocalhost"))
|
||||
Expect(buff.String()).Should(ContainSubstring("trait.oam.dev/type: nocalhost"))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -17,11 +17,19 @@ limitations under the License.
|
||||
package dryrun
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
@@ -103,6 +111,16 @@ var _ = BeforeSuite(func(done Done) {
|
||||
tdMyIngress, err := oamutil.Object2Unstructured(myingressDef)
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
// create vela-system ns
|
||||
Expect(k8sClient.Create(context.TODO(), &corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: types.DefaultKubeVelaNS}})).Should(Succeed())
|
||||
// create deploy workflow step definition
|
||||
deploy, err := os.ReadFile("./testdata/wd-deploy.yaml")
|
||||
Expect(err).Should(BeNil())
|
||||
var wfsd v1beta1.WorkflowStepDefinition
|
||||
Expect(yaml.Unmarshal([]byte(deploy), &wfsd)).Should(BeNil())
|
||||
wfsd.SetNamespace(types.DefaultKubeVelaNS)
|
||||
Expect(k8sClient.Create(context.TODO(), &wfsd)).Should(BeNil())
|
||||
|
||||
dryrunOpt = NewDryRunOption(k8sClient, cfg, dm, pd, []oam.Object{cdMyWorker, tdMyIngress}, false)
|
||||
diffOpt = &LiveDiffOption{DryRun: dryrunOpt, Parser: appfile.NewApplicationParser(k8sClient, dm, pd)}
|
||||
|
||||
|
||||
22
pkg/appfile/dryrun/testdata/pd-mypolicy.yaml
vendored
Normal file
22
pkg/appfile/dryrun/testdata/pd-mypolicy.yaml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
|
||||
# Definition source cue file: vela-templates/definitions/internal/topology.cue
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: PolicyDefinition
|
||||
metadata:
|
||||
name: mypolicy
|
||||
namespace: vela-system
|
||||
spec:
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
output: {
|
||||
apiVersion: "testing/v1"
|
||||
kind: "Policy"
|
||||
policy: {
|
||||
name: parameter.name
|
||||
}
|
||||
}
|
||||
|
||||
parameter: {
|
||||
name: string
|
||||
}
|
||||
48
pkg/appfile/dryrun/testdata/testing-dry-run-1.yaml
vendored
Normal file
48
pkg/appfile/dryrun/testdata/testing-dry-run-1.yaml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: testing-app
|
||||
namespace: default
|
||||
spec:
|
||||
components:
|
||||
- name: testing-dryrun
|
||||
type: webservice
|
||||
properties:
|
||||
image: oamdev/hello-world:v1
|
||||
ports:
|
||||
- port: 8000
|
||||
expose: true
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 1
|
||||
policies:
|
||||
- name: target-default
|
||||
type: topology
|
||||
properties:
|
||||
clusters: [ "local" ]
|
||||
namespace: "default"
|
||||
- name: target-prod
|
||||
type: topology
|
||||
properties:
|
||||
clusters: [ "local" ]
|
||||
namespace: "prod"
|
||||
- name: deploy-ha
|
||||
type: override
|
||||
properties:
|
||||
components:
|
||||
- type: webservice
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 3
|
||||
workflow:
|
||||
steps:
|
||||
- name: deploy2default
|
||||
type: deploy
|
||||
properties:
|
||||
policies: [ "target-default" ]
|
||||
- name: deploy2prod
|
||||
type: deploy
|
||||
properties:
|
||||
policies: [ "target-prod", "deploy-ha" ]
|
||||
27
pkg/appfile/dryrun/testdata/testing-dry-run-2.yaml
vendored
Normal file
27
pkg/appfile/dryrun/testdata/testing-dry-run-2.yaml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: testing-app
|
||||
spec:
|
||||
components:
|
||||
- name: testing-dryrun
|
||||
type: webservice
|
||||
properties:
|
||||
image: oamdev/hello-world:v1
|
||||
ports:
|
||||
- port: 8000
|
||||
expose: true
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 1
|
||||
policies:
|
||||
- name: deploy-ha
|
||||
type: override
|
||||
properties:
|
||||
components:
|
||||
- type: webservice
|
||||
traits:
|
||||
- type: scaler
|
||||
properties:
|
||||
replicas: 3
|
||||
15
pkg/appfile/dryrun/testdata/testing-dry-run-3.yaml
vendored
Normal file
15
pkg/appfile/dryrun/testdata/testing-dry-run-3.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: testing-app
|
||||
spec:
|
||||
components:
|
||||
- name: testing-dryrun
|
||||
type: webservice
|
||||
properties:
|
||||
image: oamdev/hello-world:v1
|
||||
workflow:
|
||||
steps:
|
||||
- name: suspend
|
||||
type: suspend
|
||||
|
||||
16
pkg/appfile/dryrun/testdata/testing-dry-run-4.yaml
vendored
Normal file
16
pkg/appfile/dryrun/testdata/testing-dry-run-4.yaml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: testing-app
|
||||
spec:
|
||||
components:
|
||||
- name: testing-dryrun
|
||||
type: webservice
|
||||
properties:
|
||||
image: oamdev/hello-world:v1
|
||||
policies:
|
||||
- name: mypolicy
|
||||
type: mypolicy
|
||||
properties:
|
||||
name: "my-policy"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user