mirror of
https://github.com/kubevela/kubevela.git
synced 2026-02-26 07:44:05 +00:00
Compare commits
88 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62efa9c787 | ||
|
|
0c449d52b1 | ||
|
|
7a69a3b52b | ||
|
|
7973864c22 | ||
|
|
f88b167b04 | ||
|
|
8b8c00fbba | ||
|
|
5f04812d06 | ||
|
|
9c037c8233 | ||
|
|
dc14baf1d8 | ||
|
|
003f329b31 | ||
|
|
b036624efc | ||
|
|
73c9c75c6f | ||
|
|
cdcda5c9f9 | ||
|
|
5861988909 | ||
|
|
d3581b9189 | ||
|
|
30fb7a56a0 | ||
|
|
786e0f7755 | ||
|
|
544cc4afb6 | ||
|
|
a07acc02c9 | ||
|
|
26faaaf4f9 | ||
|
|
ac9aa16579 | ||
|
|
a8cc84587c | ||
|
|
263081a105 | ||
|
|
308819db33 | ||
|
|
0defc5d312 | ||
|
|
c8d53c103c | ||
|
|
3655a90dfe | ||
|
|
e94426963d | ||
|
|
5d8543fd8b | ||
|
|
48d1ba0538 | ||
|
|
eb1bb69a3e | ||
|
|
a39a8356bd | ||
|
|
e3dc76d0cd | ||
|
|
5be6f38e54 | ||
|
|
6961587c7f | ||
|
|
6cbc12f9bb | ||
|
|
08548968f0 | ||
|
|
d787e95a08 | ||
|
|
c4f9c8f63f | ||
|
|
6ee7eb345b | ||
|
|
b5d42d3d4e | ||
|
|
662597bbca | ||
|
|
9459aae74f | ||
|
|
94cbcad471 | ||
|
|
68a2223353 | ||
|
|
15c0b1e218 | ||
|
|
faf5502fae | ||
|
|
bdf9bf16b8 | ||
|
|
6afe75efa6 | ||
|
|
88a85eacb6 | ||
|
|
c315e81757 | ||
|
|
5b6b66a5cc | ||
|
|
103bd9b42e | ||
|
|
b494185481 | ||
|
|
9d479b7f7c | ||
|
|
629592c7e7 | ||
|
|
b06dec994a | ||
|
|
4218faac4b | ||
|
|
555e94a10c | ||
|
|
5349f1663f | ||
|
|
4778aacaaf | ||
|
|
dab2059bf8 | ||
|
|
9c57c09878 | ||
|
|
cc1ac251ce | ||
|
|
18fb098fce | ||
|
|
5a5721048c | ||
|
|
bab5bb2caf | ||
|
|
cce1859294 | ||
|
|
72bb0798ef | ||
|
|
29aa2b9644 | ||
|
|
307d1db36d | ||
|
|
00ae0c9494 | ||
|
|
f0357fdc8f | ||
|
|
ef8b0ac00f | ||
|
|
aaaf2bddac | ||
|
|
eeb6f08edf | ||
|
|
b9f1cc97a9 | ||
|
|
2117554d53 | ||
|
|
9edd6ebc30 | ||
|
|
ccdfc409a8 | ||
|
|
449b3e0b49 | ||
|
|
8be1fb29b4 | ||
|
|
b42e6cf1e6 | ||
|
|
096afa227b | ||
|
|
57b74c3687 | ||
|
|
9203bbcdb8 | ||
|
|
f3e920ab60 | ||
|
|
6893a2b776 |
4
.github/workflows/back-port.yml
vendored
4
.github/workflows/back-port.yml
vendored
@@ -17,12 +17,12 @@ jobs:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Open Backport PR
|
||||
uses: zeebe-io/backport-action@bf5fdd624b35f95d5b85991a728bd5744e8c6cf2
|
||||
uses: zeebe-io/backport-action@08bafb375e6e9a9a2b53a744b987e5d81a133191
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github_workspace: ${{ github.workspace }}
|
||||
|
||||
4
.github/workflows/chart.yml
vendored
4
.github/workflows/chart.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
HELM_CHART_NAME: vela-core
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
- name: Get git revision
|
||||
id: vars
|
||||
shell: bash
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
with:
|
||||
version: v3.4.0
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Generate helm doc
|
||||
|
||||
2
.github/workflows/codeql-analysis.yml
vendored
2
.github/workflows/codeql-analysis.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
|
||||
|
||||
2
.github/workflows/commit-lint.yml
vendored
2
.github/workflows/commit-lint.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
check:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: thehanimo/pr-title-checker@v1.4.0
|
||||
- uses: thehanimo/pr-title-checker@v1.4.1
|
||||
with:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
pass_on_octokit_error: true
|
||||
|
||||
4
.github/workflows/core-api-test.yml
vendored
4
.github/workflows/core-api-test.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Go 1.19
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
env:
|
||||
GO_VERSION: '1.19'
|
||||
with:
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
|
||||
4
.github/workflows/definition-lint.yml
vendored
4
.github/workflows/definition-lint.yml
vendored
@@ -23,12 +23,12 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
|
||||
6
.github/workflows/e2e-multicluster-test.yml
vendored
6
.github/workflows/e2e-multicluster-test.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
steps:
|
||||
- name: Detect No-op Changes
|
||||
id: noop
|
||||
uses: fkirc/skip-duplicate-actions@12aca0a884f6137d619d6a8a09fcc3406ced5281
|
||||
uses: fkirc/skip-duplicate-actions@f75f66ce1886f00957d99748a42c724f4330bdcf
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]'
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
sudo snap install helm --classic
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
|
||||
6
.github/workflows/e2e-test.yml
vendored
6
.github/workflows/e2e-test.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
steps:
|
||||
- name: Detect No-op Changes
|
||||
id: noop
|
||||
uses: fkirc/skip-duplicate-actions@12aca0a884f6137d619d6a8a09fcc3406ced5281
|
||||
uses: fkirc/skip-duplicate-actions@f75f66ce1886f00957d99748a42c724f4330bdcf
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]'
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Install tools
|
||||
run: |
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
sudo snap install helm --classic
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
|
||||
42
.github/workflows/go.yml
vendored
42
.github/workflows/go.yml
vendored
@@ -30,7 +30,7 @@ jobs:
|
||||
steps:
|
||||
- name: Detect No-op Changes
|
||||
id: noop
|
||||
uses: fkirc/skip-duplicate-actions@12aca0a884f6137d619d6a8a09fcc3406ced5281
|
||||
uses: fkirc/skip-duplicate-actions@f75f66ce1886f00957d99748a42c724f4330bdcf
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]'
|
||||
@@ -44,12 +44,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
@@ -69,12 +69,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
# version, but we prefer this action because it leaves 'annotations' (i.e.
|
||||
# it comments on PRs to point out linter violations).
|
||||
- name: Lint
|
||||
uses: golangci/golangci-lint-action@639cd343e1d3b897ff35927a75193d57cfcba299 # v3.6.0
|
||||
uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc # v3.7.0
|
||||
with:
|
||||
version: ${{ env.GOLANGCI_VERSION }}
|
||||
|
||||
@@ -94,22 +94,22 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65
|
||||
with:
|
||||
node-version: '14'
|
||||
|
||||
- name: Cache Go Dependencies
|
||||
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
|
||||
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
|
||||
with:
|
||||
path: .work/pkg
|
||||
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
|
||||
@@ -139,17 +139,17 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Cache Go Dependencies
|
||||
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
|
||||
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
|
||||
with:
|
||||
path: .work/pkg
|
||||
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
|
||||
@@ -170,15 +170,15 @@ jobs:
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@16c0bc4a6e6ada2cfd8afd41d22d95379cf7c32a # v2.8.0
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
|
||||
- name: Build Test for vela core
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v4.1.1
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile
|
||||
@@ -190,15 +190,15 @@ jobs:
|
||||
if: needs.detect-noop.outputs.noop != 'true'
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
submodules: true
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@16c0bc4a6e6ada2cfd8afd41d22d95379cf7c32a # v2.8.0
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
|
||||
- name: Build Test for CLI
|
||||
uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v4.1.1
|
||||
uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
|
||||
with:
|
||||
context: .
|
||||
file: Dockerfile.cli
|
||||
|
||||
9
.github/workflows/issue-commands.yml
vendored
9
.github/workflows/issue-commands.yml
vendored
@@ -7,6 +7,7 @@ on:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
bot:
|
||||
@@ -16,13 +17,13 @@ jobs:
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout Actions
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
repository: "oam-dev/kubevela-github-actions"
|
||||
path: ./actions
|
||||
ref: v0.4.2
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c
|
||||
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65
|
||||
with:
|
||||
node-version: '14'
|
||||
cache: 'npm'
|
||||
@@ -75,11 +76,11 @@ jobs:
|
||||
})
|
||||
console.log("Added '" + label + "' label.")
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Open Backport PR
|
||||
uses: zeebe-io/backport-action@bf5fdd624b35f95d5b85991a728bd5744e8c6cf2
|
||||
uses: zeebe-io/backport-action@08bafb375e6e9a9a2b53a744b987e5d81a133191
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github_workspace: ${{ github.workspace }}
|
||||
|
||||
2
.github/workflows/license.yml
vendored
2
.github/workflows/license.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
name: Check for unapproved licenses
|
||||
steps:
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
- name: Set up Ruby
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
|
||||
14
.github/workflows/registry.yml
vendored
14
.github/workflows/registry.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
packages: write
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: |
|
||||
@@ -31,23 +31,23 @@ jobs:
|
||||
run: |
|
||||
echo "git_revision=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
|
||||
- name: Login ghcr.io
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Login docker.io
|
||||
uses: docker/login-action@465a07811f14bebb1938fbed4728c6a1ff8901fc # v2.2.0
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
registry: docker.io
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7 # v2.2.0
|
||||
- uses: docker/setup-buildx-action@16c0bc4a6e6ada2cfd8afd41d22d95379cf7c32a # v2.8.0
|
||||
- uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
|
||||
- uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
|
||||
with:
|
||||
driver-opts: image=moby/buildkit:master
|
||||
|
||||
- uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v4.1.1
|
||||
- uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
|
||||
name: Build & Pushing vela-core for Dockerhub, GHCR
|
||||
with:
|
||||
context: .
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
docker.io/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
|
||||
ghcr.io/${{ github.repository_owner }}/oamdev/vela-core:${{ steps.get_version.outputs.VERSION }}
|
||||
|
||||
- uses: docker/build-push-action@2eb1c1961a95fc15694676618e422e8ba1d63825 # v4.1.1
|
||||
- uses: docker/build-push-action@0565240e2d4ab88bba5387d719585280857ece09 # v5.0.0
|
||||
name: Build & Pushing CLI for Dockerhub, GHCR
|
||||
with:
|
||||
context: .
|
||||
|
||||
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -24,16 +24,16 @@ jobs:
|
||||
name: goreleaser
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- run: git fetch --force --tags
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: 1.19
|
||||
cache: true
|
||||
- uses: goreleaser/goreleaser-action@336e29918d653399e599bfca99fadc1d7ffbc9f7 # v4.3.0
|
||||
- uses: goreleaser/goreleaser-action@7ec5c2b0c6cdda6e8bbb49444bc797dd33d74dd8 # v5.0.0
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: 1.14.1
|
||||
@@ -56,7 +56,7 @@ jobs:
|
||||
name: upload-sha256sums
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
- name: Update kubectl plugin version in krew-index
|
||||
uses: rajatjindal/krew-release-bot@df3eb197549e3568be8b4767eec31c5e8e8e6ad8 # v0.0.46
|
||||
- name: Update Homebrew formula
|
||||
|
||||
6
.github/workflows/scorecards.yml
vendored
6
.github/workflows/scorecards.yml
vendored
@@ -23,12 +23,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@08b4669551908b1024bb425080c797723083c031 # tag=v2.2.0
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # tag=v2.3.1
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
|
||||
4
.github/workflows/sdk-test.yml
vendored
4
.github/workflows/sdk-test.yml
vendored
@@ -26,10 +26,10 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
|
||||
4
.github/workflows/sync-api.yml
vendored
4
.github/workflows/sync-api.yml
vendored
@@ -18,12 +18,12 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
|
||||
4
.github/workflows/sync-sdk.yaml
vendored
4
.github/workflows/sync-sdk.yaml
vendored
@@ -22,12 +22,12 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
|
||||
2
.github/workflows/trivy-scan.yml
vendored
2
.github/workflows/trivy-scan.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
|
||||
- name: Build Vela Core image from Dockerfile
|
||||
run: |
|
||||
|
||||
10
.github/workflows/unit-test.yml
vendored
10
.github/workflows/unit-test.yml
vendored
@@ -29,7 +29,7 @@ jobs:
|
||||
steps:
|
||||
- name: Detect No-op Changes
|
||||
id: noop
|
||||
uses: fkirc/skip-duplicate-actions@12aca0a884f6137d619d6a8a09fcc3406ced5281
|
||||
uses: fkirc/skip-duplicate-actions@f75f66ce1886f00957d99748a42c724f4330bdcf
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
paths_ignore: '["**.md", "**.mdx", "**.png", "**.jpg"]'
|
||||
@@ -43,17 +43,17 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@fac708d6674e30b6ba41289acaab6d4b75aa0753
|
||||
uses: actions/setup-go@0c52d547c9bc32b1aa3301fd7a9cb496313a4491
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9
|
||||
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Cache Go Dependencies
|
||||
uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8
|
||||
uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84
|
||||
with:
|
||||
path: .work/pkg
|
||||
key: ${{ runner.os }}-pkg-${{ hashFiles('**/go.sum') }}
|
||||
@@ -71,7 +71,7 @@ jobs:
|
||||
kind create cluster
|
||||
|
||||
- name: install Kubebuilder
|
||||
uses: RyanSiu1995/kubebuilder-action@ed0e300b13152c2c2bfb104475665c7bf609332f
|
||||
uses: RyanSiu1995/kubebuilder-action@7170cb0476187070ae04cbb6cee305e809de2693
|
||||
with:
|
||||
version: 3.9.1
|
||||
kubebuilderOnly: false
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
ARG BASE_IMAGE
|
||||
# Build the manager binary
|
||||
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.19-alpine@sha256:2381c1e5f8350a901597d633b2e517775eeac7a6682be39225a93b22cfd0f8bb as builder
|
||||
FROM golang:1.19-alpine3.18 as builder
|
||||
|
||||
WORKDIR /workspace
|
||||
# Copy the Go Modules manifests
|
||||
@@ -34,7 +34,7 @@ RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=${TARGETARCH} \
|
||||
# You can replace distroless as minimal base image to package the manager binary
|
||||
# Refer to https://github.com/GoogleContainerTools/distroless for more details
|
||||
# Overwrite `BASE_IMAGE` by passing `--build-arg=BASE_IMAGE=gcr.io/distroless/static:nonroot`
|
||||
FROM ${BASE_IMAGE:-alpine@sha256:e2e16842c9b54d985bf1ef9242a313f36b856181f188de21313820e177002501}
|
||||
FROM ${BASE_IMAGE:-alpine:3.18}
|
||||
# This is required by daemon connecting with cri
|
||||
RUN apk add --no-cache ca-certificates bash expat
|
||||
|
||||
|
||||
2
Makefile
2
Makefile
@@ -62,7 +62,7 @@ staticcheck: staticchecktool
|
||||
## lint: Run the golangci-lint
|
||||
lint: golangci
|
||||
@$(INFO) lint
|
||||
@$(GOLANGCILINT) run --skip-dirs 'scaffold'
|
||||
@$(GOLANGCILINT) run --fix --verbose --skip-dirs 'scaffold'
|
||||
|
||||
## reviewable: Run the reviewable
|
||||
reviewable: manifests fmt vet lint staticcheck helm-doc-gen sdk_fmt
|
||||
|
||||
@@ -32,22 +32,6 @@ type CRDInfo struct {
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
// Chart defines all necessary information to install a whole chart
|
||||
type Chart struct {
|
||||
Repo string `json:"repo"`
|
||||
URL string `json:"url"`
|
||||
Name string `json:"name"`
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
Version string `json:"version"`
|
||||
Values map[string]interface{} `json:"values"`
|
||||
}
|
||||
|
||||
// Installation defines the installation method for this Capability, currently only helm is supported
|
||||
type Installation struct {
|
||||
Helm Chart `json:"helm"`
|
||||
// TODO(wonderflow) add raw yaml file support for install capability
|
||||
}
|
||||
|
||||
// CapType defines the type of capability
|
||||
type CapType string
|
||||
|
||||
@@ -107,7 +91,6 @@ type Capability struct {
|
||||
CueTemplateURI string `json:"templateURI,omitempty"`
|
||||
Parameters []Parameter `json:"parameters,omitempty"`
|
||||
CrdName string `json:"crdName,omitempty"`
|
||||
Center string `json:"center,omitempty"`
|
||||
Status string `json:"status,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Example string `json:"example,omitempty"`
|
||||
@@ -121,8 +104,7 @@ type Capability struct {
|
||||
Namespace string `json:"namespace,omitempty"`
|
||||
|
||||
// Plugin Source
|
||||
Source *Source `json:"source,omitempty"`
|
||||
CrdInfo *CRDInfo `json:"crdInfo,omitempty"`
|
||||
Source *Source `json:"source,omitempty"`
|
||||
|
||||
// Terraform
|
||||
TerraformConfiguration string `json:"terraformConfiguration,omitempty"`
|
||||
|
||||
@@ -26,13 +26,8 @@ type ComponentManifest struct {
|
||||
Namespace string
|
||||
RevisionName string
|
||||
RevisionHash string
|
||||
// StandardWorkload contains K8s resource generated from "output" block of ComponentDefinition
|
||||
StandardWorkload *unstructured.Unstructured
|
||||
// Traits contains both resources generated from "outputs" block of ComponentDefinition and resources generated from TraitDefinition
|
||||
Traits []*unstructured.Unstructured
|
||||
|
||||
// PackagedWorkloadResources contain all the workload related resources. It could be a Helm
|
||||
// Release, Git Repo or anything that can package and run a workload.
|
||||
PackagedWorkloadResources []*unstructured.Unstructured
|
||||
PackagedTraitResources map[string][]*unstructured.Unstructured
|
||||
// ComponentOutput contains K8s resource generated from "output" block of ComponentDefinition
|
||||
ComponentOutput *unstructured.Unstructured
|
||||
// ComponentOutputsAndTraits contains both resources generated from "outputs" block of ComponentDefinition and resources generated from TraitDefinition
|
||||
ComponentOutputsAndTraits []*unstructured.Unstructured
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ webhooks:
|
||||
- apiGroups:
|
||||
- core.oam.dev
|
||||
apiVersions:
|
||||
- v1alpha2
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
@@ -89,4 +89,30 @@ webhooks:
|
||||
- UPDATE
|
||||
resources:
|
||||
- componentdefinitions
|
||||
- clientConfig:
|
||||
caBundle: Cg==
|
||||
service:
|
||||
name: {{ template "kubevela.name" . }}-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /validating-core-oam-dev-v1beta1-policydefinitions
|
||||
{{- if .Values.admissionWebhooks.patch.enabled }}
|
||||
failurePolicy: Ignore
|
||||
{{- else }}
|
||||
failurePolicy: Fail
|
||||
{{- end }}
|
||||
name: validating.core.oam-dev.v1beta1.policydefinitions
|
||||
sideEffects: None
|
||||
admissionReviewVersions:
|
||||
- v1beta1
|
||||
- v1
|
||||
rules:
|
||||
- apiGroups:
|
||||
- core.oam.dev
|
||||
apiVersions:
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
resources:
|
||||
- policydefinitions
|
||||
{{- end -}}
|
||||
|
||||
@@ -19,5 +19,7 @@ spec:
|
||||
component: string
|
||||
// +usage=Specify the cluster
|
||||
cluster: *"" | string
|
||||
// +usage=Specify the namespace
|
||||
namespace: *"" | string
|
||||
}
|
||||
|
||||
|
||||
135
charts/vela-core/templates/defwithtemplate/container-ports.yaml
Normal file
135
charts/vela-core/templates/defwithtemplate/container-ports.yaml
Normal file
@@ -0,0 +1,135 @@
|
||||
# Code generated by KubeVela templates. DO NOT EDIT. Please edit the original cue file.
|
||||
# Definition source cue file: vela-templates/definitions/internal/container-ports.cue
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: TraitDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
definition.oam.dev/description: Expose on the host and bind the external port to host to enable web traffic for your component.
|
||||
name: container-ports
|
||||
namespace: {{ include "systemDefinitionNamespace" . }}
|
||||
spec:
|
||||
appliesToWorkloads:
|
||||
- deployments.apps
|
||||
- statefulsets.apps
|
||||
- daemonsets.apps
|
||||
- jobs.batch
|
||||
podDisruptive: true
|
||||
schematic:
|
||||
cue:
|
||||
template: |
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
#PatchParams: {
|
||||
// +usage=Specify the name of the target container, if not set, use the component name
|
||||
containerName: *"" | string
|
||||
// +usage=Specify ports you want customer traffic sent to
|
||||
ports: *[] | [...{
|
||||
// +usage=Number of port to expose on the pod's IP address
|
||||
containerPort: int
|
||||
// +usage=Protocol for port. Must be UDP, TCP, or SCTP
|
||||
protocol: *"TCP" | "UDP" | "SCTP"
|
||||
// +usage=Number of port to expose on the host
|
||||
hostPort?: int
|
||||
// +usage=What host IP to bind the external port to.
|
||||
hostIP?: string
|
||||
}]
|
||||
}
|
||||
|
||||
PatchContainer: {
|
||||
_params: #PatchParams
|
||||
name: _params.containerName
|
||||
_baseContainers: context.output.spec.template.spec.containers
|
||||
_matchContainers_: [ for _container_ in _baseContainers if _container_.name == name {_container_}]
|
||||
_baseContainer: *_|_ | {...}
|
||||
if len(_matchContainers_) == 0 {
|
||||
err: "container \(name) not found"
|
||||
}
|
||||
if len(_matchContainers_) > 0 {
|
||||
_baseContainer: _matchContainers_[0]
|
||||
_basePorts: _baseContainer.ports
|
||||
if _basePorts == _|_ {
|
||||
// +patchStrategy=replace
|
||||
ports: [ for port in _params.ports {
|
||||
containerPort: port.containerPort
|
||||
protocol: port.protocol
|
||||
if port.hostPort != _|_ {
|
||||
hostPort: port.hostPort
|
||||
}
|
||||
if port.hostIP != _|_ {
|
||||
hostIP: port.hostIP
|
||||
}
|
||||
}]
|
||||
}
|
||||
if _basePorts != _|_ {
|
||||
_basePortsMap: {for _basePort in _basePorts {(strings.ToLower(_basePort.protocol) + strconv.FormatInt(_basePort.containerPort, 10)): _basePort}}
|
||||
_portsMap: {for port in _params.ports {(strings.ToLower(port.protocol) + strconv.FormatInt(port.containerPort, 10)): port}}
|
||||
// +patchStrategy=replace
|
||||
ports: [ for portVar in _basePorts {
|
||||
containerPort: portVar.containerPort
|
||||
protocol: portVar.protocol
|
||||
name: portVar.name
|
||||
_uniqueKey: strings.ToLower(portVar.protocol) + strconv.FormatInt(portVar.containerPort, 10)
|
||||
if _portsMap[_uniqueKey] != _|_ {
|
||||
if _portsMap[_uniqueKey].hostPort != _|_ {
|
||||
hostPort: _portsMap[_uniqueKey].hostPort
|
||||
}
|
||||
if _portsMap[_uniqueKey].hostIP != _|_ {
|
||||
hostIP: _portsMap[_uniqueKey].hostIP
|
||||
}
|
||||
}
|
||||
}] + [ for port in _params.ports if _basePortsMap[strings.ToLower(port.protocol)+strconv.FormatInt(port.containerPort, 10)] == _|_ {
|
||||
if port.containerPort != _|_ {
|
||||
containerPort: port.containerPort
|
||||
}
|
||||
if port.protocol != _|_ {
|
||||
protocol: port.protocol
|
||||
}
|
||||
if port.hostPort != _|_ {
|
||||
hostPort: port.hostPort
|
||||
}
|
||||
if port.hostIP != _|_ {
|
||||
hostIP: port.hostIP
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
patch: spec: template: spec: {
|
||||
if parameter.containers == _|_ {
|
||||
// +patchKey=name
|
||||
containers: [{
|
||||
PatchContainer & {_params: {
|
||||
if parameter.containerName == "" {
|
||||
containerName: context.name
|
||||
}
|
||||
if parameter.containerName != "" {
|
||||
containerName: parameter.containerName
|
||||
}
|
||||
ports: parameter.ports
|
||||
}}
|
||||
}]
|
||||
}
|
||||
if parameter.containers != _|_ {
|
||||
// +patchKey=name
|
||||
containers: [ for c in parameter.containers {
|
||||
if c.containerName == "" {
|
||||
err: "container name must be set for containers"
|
||||
}
|
||||
if c.containerName != "" {
|
||||
PatchContainer & {_params: c}
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
parameter: *#PatchParams | close({
|
||||
// +usage=Specify the container ports for multiple containers
|
||||
containers: [...#PatchParams]
|
||||
})
|
||||
|
||||
errs: [ for c in patch.spec.template.spec.containers if c.err != _|_ {c.err}]
|
||||
|
||||
@@ -14,7 +14,9 @@ spec:
|
||||
podDisruptive: false
|
||||
schematic:
|
||||
cue:
|
||||
template: |2
|
||||
template: |
|
||||
import "strconv"
|
||||
|
||||
let nameSuffix = {
|
||||
if parameter.name != _|_ {"-" + parameter.name}
|
||||
if parameter.name == _|_ {""}
|
||||
@@ -30,6 +32,7 @@ spec:
|
||||
selector: "app.oam.dev/component": context.name
|
||||
ports: [
|
||||
for k, v in parameter.http {
|
||||
name: "port-" + strconv.FormatInt(v, 10)
|
||||
port: v
|
||||
targetPort: v
|
||||
},
|
||||
@@ -58,6 +61,18 @@ spec:
|
||||
if parameter.gatewayHost != _|_ {
|
||||
"ingress.controller/host": parameter.gatewayHost
|
||||
}
|
||||
if parameter.annotations != _|_ {
|
||||
for key, value in parameter.annotations {
|
||||
"\(key)": "\(value)"
|
||||
}
|
||||
}
|
||||
}
|
||||
labels: {
|
||||
if parameter.labels != _|_ {
|
||||
for key, value in parameter.labels {
|
||||
"\(key)": "\(value)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
spec: {
|
||||
@@ -122,6 +137,12 @@ spec:
|
||||
|
||||
// +usage=Specify a pathType for the ingress rules, defaults to "ImplementationSpecific"
|
||||
pathType: *"ImplementationSpecific" | "Prefix" | "Exact"
|
||||
|
||||
// +usage=Specify the annotations to be added to the ingress
|
||||
annotations?: [string]: string
|
||||
|
||||
// +usage=Specify the labels to be added to the ingress
|
||||
labels?: [string]: string
|
||||
}
|
||||
status:
|
||||
customStatus: |-
|
||||
|
||||
@@ -3,6 +3,7 @@ apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "kubevela.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "kubevela.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
@@ -121,6 +122,7 @@ apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:leader-election-role
|
||||
namespace: {{ .Release.Namespace }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -154,6 +156,7 @@ apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:leader-election-rolebinding
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
@@ -168,6 +171,7 @@ apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:template-reader-role
|
||||
namespace: {{ .Release.Namespace }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
@@ -188,6 +192,7 @@ apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "kubevela.fullname" . }}:template-reader-binding
|
||||
namespace: {{ .Release.Namespace }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
|
||||
@@ -81,7 +81,6 @@ func NewCoreOptions() *CoreOptions {
|
||||
DefRevisionLimit: 20,
|
||||
AutoGenWorkloadDefinition: true,
|
||||
ConcurrentReconciles: 4,
|
||||
EnableCompatibility: false,
|
||||
IgnoreAppWithoutControllerRequirement: false,
|
||||
IgnoreDefinitionWithoutControllerRequirement: false,
|
||||
},
|
||||
|
||||
@@ -47,7 +47,7 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/auth"
|
||||
"github.com/oam-dev/kubevela/pkg/cache"
|
||||
commonconfig "github.com/oam-dev/kubevela/pkg/controller/common"
|
||||
oamv1alpha2 "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1"
|
||||
oamv1beta1 "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1/application"
|
||||
"github.com/oam-dev/kubevela/pkg/features"
|
||||
"github.com/oam-dev/kubevela/pkg/monitor/watcher"
|
||||
@@ -75,6 +75,10 @@ func NewCoreCommand() *cobra.Command {
|
||||
return run(signals.SetupSignalHandler(), s)
|
||||
},
|
||||
SilenceUsage: true,
|
||||
FParseErrWhitelist: cobra.FParseErrWhitelist{
|
||||
// Allow unknown flags for backward-compatibility.
|
||||
UnknownFlags: true,
|
||||
},
|
||||
}
|
||||
|
||||
fs := cmd.Flags()
|
||||
@@ -227,7 +231,7 @@ func prepareRun(ctx context.Context, mgr manager.Manager, s *options.CoreOptions
|
||||
}
|
||||
}
|
||||
|
||||
if err := oamv1alpha2.Setup(mgr, *s.ControllerArgs); err != nil {
|
||||
if err := oamv1beta1.Setup(mgr, *s.ControllerArgs); err != nil {
|
||||
klog.ErrorS(err, "Unable to setup the oam controller")
|
||||
return err
|
||||
}
|
||||
|
||||
66
go.mod
66
go.mod
@@ -12,7 +12,7 @@ require (
|
||||
github.com/bluele/gcache v0.0.2
|
||||
github.com/briandowns/spinner v1.23.0
|
||||
github.com/chartmuseum/helm-push v0.10.4
|
||||
github.com/containerd/containerd v1.7.2
|
||||
github.com/containerd/containerd v1.7.5
|
||||
github.com/crossplane/crossplane-runtime v0.19.2
|
||||
github.com/cue-exp/kubevelafix v0.0.0-20220922150317-aead819d979d
|
||||
github.com/dave/jennifer v1.6.1
|
||||
@@ -24,37 +24,37 @@ require (
|
||||
github.com/form3tech-oss/jwt-go v3.2.5+incompatible
|
||||
github.com/gdamore/tcell/v2 v2.6.0
|
||||
github.com/getkin/kin-openapi v0.118.0
|
||||
github.com/go-git/go-git/v5 v5.7.0
|
||||
github.com/go-logr/logr v1.2.4
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/go-git/go-git/v5 v5.8.1
|
||||
github.com/go-logr/logr v1.3.0
|
||||
github.com/go-resty/resty/v2 v2.8.0
|
||||
github.com/golang/mock v1.6.0
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/google/go-containerregistry v0.15.2
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/google/go-containerregistry v0.16.1
|
||||
github.com/google/go-github/v32 v32.1.0
|
||||
github.com/gosuri/uitable v0.0.4
|
||||
github.com/hashicorp/go-version v1.6.0
|
||||
github.com/hashicorp/hcl/v2 v2.17.0
|
||||
github.com/hashicorp/hcl/v2 v2.18.0
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174
|
||||
github.com/imdario/mergo v0.3.16
|
||||
github.com/kubevela/pkg v1.8.1-0.20230522085329-7d5e1241a86d
|
||||
github.com/kubevela/workflow v0.5.1-0.20230412142834-be9e5a10baf0
|
||||
github.com/kubevela/workflow v0.6.0
|
||||
github.com/kyokomi/emoji v2.2.4+incompatible
|
||||
github.com/magiconair/properties v1.8.7
|
||||
github.com/mattn/go-runewidth v0.0.14
|
||||
github.com/mattn/go-runewidth v0.0.15
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2
|
||||
github.com/nacos-group/nacos-sdk-go/v2 v2.2.2
|
||||
github.com/oam-dev/cluster-gateway v1.9.0-alpha.2
|
||||
github.com/oam-dev/cluster-register v1.0.4-0.20230424040021-147f7c1fefe5
|
||||
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28
|
||||
github.com/oam-dev/terraform-controller v0.7.11
|
||||
github.com/oam-dev/terraform-controller v0.8.0
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/onsi/ginkgo/v2 v2.11.0
|
||||
github.com/onsi/gomega v1.27.8
|
||||
github.com/onsi/ginkgo/v2 v2.13.1
|
||||
github.com/onsi/gomega v1.29.0
|
||||
github.com/openkruise/kruise-api v1.4.0
|
||||
github.com/openkruise/rollouts v0.3.0
|
||||
github.com/pelletier/go-toml v1.9.5
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.15.1
|
||||
github.com/prometheus/client_golang v1.16.0
|
||||
github.com/prometheus/client_model v0.4.0
|
||||
github.com/rivo/tview v0.0.0-20221128165837-db36428c92d9
|
||||
github.com/rogpeppe/go-internal v1.10.0
|
||||
@@ -64,16 +64,16 @@ require (
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/tidwall/gjson v1.14.4
|
||||
github.com/wercker/stern v0.0.0-20190705090245-4fa46dd6987f
|
||||
github.com/xanzy/go-gitlab v0.86.0
|
||||
github.com/xanzy/go-gitlab v0.91.1
|
||||
github.com/xlab/treeprint v1.2.0
|
||||
go.uber.org/multierr v1.11.0
|
||||
golang.org/x/crypto v0.10.0
|
||||
golang.org/x/oauth2 v0.9.0
|
||||
golang.org/x/sync v0.3.0
|
||||
golang.org/x/term v0.9.0
|
||||
golang.org/x/text v0.10.0
|
||||
golang.org/x/tools v0.10.0
|
||||
gomodules.xyz/jsonpatch/v2 v2.3.0
|
||||
golang.org/x/crypto v0.14.0
|
||||
golang.org/x/oauth2 v0.12.0
|
||||
golang.org/x/sync v0.4.0
|
||||
golang.org/x/term v0.13.0
|
||||
golang.org/x/text v0.13.0
|
||||
golang.org/x/tools v0.14.0
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
helm.sh/helm/v3 v3.11.2
|
||||
k8s.io/api v0.26.3
|
||||
@@ -98,7 +98,8 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 // indirect
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||
@@ -109,13 +110,14 @@ require (
|
||||
github.com/Masterminds/squirrel v1.5.3 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
github.com/NYTimes/gziphandler v1.1.1 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect
|
||||
github.com/acomagu/bufpipe v1.0.4 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/alessio/shellescape v1.4.1 // indirect
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.1704 // indirect
|
||||
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
@@ -130,10 +132,10 @@ require (
|
||||
github.com/coreos/go-systemd/v22 v22.5.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
|
||||
github.com/creack/pty v1.1.18 // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.3 // indirect
|
||||
github.com/docker/cli v23.0.5+incompatible // indirect
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
|
||||
github.com/docker/cli v24.0.0+incompatible // indirect
|
||||
github.com/docker/distribution v2.8.2+incompatible // indirect
|
||||
github.com/docker/docker v23.0.5+incompatible // indirect
|
||||
github.com/docker/docker v24.0.0+incompatible // indirect
|
||||
github.com/docker/docker-credential-helpers v0.7.0 // indirect
|
||||
github.com/docker/go-connections v0.4.0 // indirect
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
@@ -233,7 +235,7 @@ require (
|
||||
github.com/pjbgf/sha1cd v0.3.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/common v0.42.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/prometheus/procfs v0.10.1 // indirect
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b // indirect
|
||||
github.com/rivo/uniseg v0.4.3 // indirect
|
||||
github.com/robfig/cron/v3 v3.0.1 // indirect
|
||||
@@ -241,7 +243,7 @@ require (
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/shopspring/decimal v1.3.1 // indirect
|
||||
github.com/skeema/knownhosts v1.1.1 // indirect
|
||||
github.com/skeema/knownhosts v1.2.0 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
@@ -268,14 +270,14 @@ require (
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/mod v0.11.0 // indirect
|
||||
golang.org/x/net v0.11.0 // indirect
|
||||
golang.org/x/sys v0.9.0 // indirect
|
||||
golang.org/x/mod v0.13.0 // indirect
|
||||
golang.org/x/net v0.17.0 // indirect
|
||||
golang.org/x/sys v0.14.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4 // indirect
|
||||
google.golang.org/grpc v1.53.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
|
||||
142
go.sum
142
go.sum
@@ -1,15 +1,17 @@
|
||||
cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y=
|
||||
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
|
||||
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
|
||||
cloud.google.com/go/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
|
||||
cloud.google.com/go/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cuelang.org/go v0.5.0 h1:D6N0UgTGJCOxFKU8RU+qYvavKNsVc/+ZobmifStVJzU=
|
||||
cuelang.org/go v0.5.0/go.mod h1:okjJBHFQFer+a41sAe2SaGm1glWS8oEb6CmJvn5Zdws=
|
||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||
github.com/AlecAivazis/survey/v2 v2.1.1 h1:LEMbHE0pLj75faaVEKClEX1TM4AJmmnOh9eimREzLWI=
|
||||
github.com/AlecAivazis/survey/v2 v2.1.1/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
@@ -57,8 +59,8 @@ github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMo
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw=
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs=
|
||||
@@ -69,7 +71,7 @@ github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki
|
||||
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/agiledragon/gomonkey/v2 v2.4.0 h1:YDQJYiSQ8o78dCMXehU1E4F/Kh4jPX+MV+/iK/yfL7s=
|
||||
github.com/agiledragon/gomonkey/v2 v2.9.0 h1:PDiKKybR596O6FHW+RVSG0Z7uGCBNbmbUXh3uCNQ7Hc=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@@ -89,6 +91,8 @@ github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:o
|
||||
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
|
||||
@@ -124,7 +128,7 @@ github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx2
|
||||
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng=
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
|
||||
github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
|
||||
github.com/cenkalti/backoff/v4 v4.2.0 h1:HN5dHm3WBOgndBH6E8V0q2jIYIR3s9yglV8k/+MN3u4=
|
||||
@@ -145,7 +149,6 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
|
||||
github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
|
||||
github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
@@ -162,9 +165,9 @@ github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h
|
||||
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA=
|
||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
|
||||
github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM=
|
||||
github.com/containerd/containerd v1.7.2 h1:UF2gdONnxO8I6byZXDi5sXWiWvlW3D/sci7dTQimEJo=
|
||||
github.com/containerd/containerd v1.7.2/go.mod h1:afcz74+K10M/+cjGHIVQrCt3RAQhUSCAjJ9iMYhhkuI=
|
||||
github.com/containerd/continuity v0.4.1 h1:wQnVrjIyQ8vhU2sgOiL5T07jo+ouqc2bnKsv5/EqGhU=
|
||||
github.com/containerd/containerd v1.7.5 h1:i9T9XpAWMe11BHMN7pu1BZqOGjXaKTPyz2v+KYOZgkY=
|
||||
github.com/containerd/containerd v1.7.5/go.mod h1:ieJNCSzASw2shSGYLHx8NAE7WsZ/gEigo5fQ78W5Zvw=
|
||||
github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
|
||||
github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o=
|
||||
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
|
||||
@@ -192,8 +195,8 @@ github.com/crossplane/crossplane-runtime v0.19.2 h1:9qBnhpqKN4x6apF2siaQ6PvgxqBX
|
||||
github.com/crossplane/crossplane-runtime v0.19.2/go.mod h1:OJQ1NxtQK2ZTRmvtnQPoy8LsXsARTnVydRVDQEgIuz4=
|
||||
github.com/cue-exp/kubevelafix v0.0.0-20220922150317-aead819d979d h1:VNJA1nSKA8Xna5wjUIMItHlWmEej8Bb9fZ3vCNtIAX0=
|
||||
github.com/cue-exp/kubevelafix v0.0.0-20220922150317-aead819d979d/go.mod h1:SyTryzw/zYJIogw3H2IRcYdV5gsSoVMJiKGElcQK09I=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI=
|
||||
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/dave/jennifer v1.6.1 h1:T4T/67t6RAA5AIV6+NP8Uk/BIsXgDoqEowgycdQQLuk=
|
||||
github.com/dave/jennifer v1.6.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -304,8 +307,8 @@ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmS
|
||||
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
|
||||
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
|
||||
github.com/go-git/go-git/v5 v5.7.0 h1:t9AudWVLmqzlo+4bqdf7GY+46SUuRsx59SboFxkq2aE=
|
||||
github.com/go-git/go-git/v5 v5.7.0/go.mod h1:coJHKEOk5kUClpsNlXrUvPrDxY3w3gjHvhcZd8Fodw8=
|
||||
github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A=
|
||||
github.com/go-git/go-git/v5 v5.8.1/go.mod h1:FHFuoD6yGz5OSKEBK+aWN9Oah0q54Jxl0abmj6GnqAo=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gorp/gorp/v3 v3.0.5/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw=
|
||||
github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs=
|
||||
@@ -324,8 +327,8 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
|
||||
github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQf7Ro=
|
||||
@@ -342,8 +345,8 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
||||
github.com/go-resty/resty/v2 v2.8.0 h1:J29d0JFWwSWrDCysnOK/YjsPMLQTx0TvgJEHVGvf2L8=
|
||||
github.com/go-resty/resty/v2 v2.8.0/go.mod h1:UCui0cMHekLrSntoMyofdSTaPpinlRHFtPpizuyDW2w=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
@@ -427,10 +430,11 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE=
|
||||
github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-containerregistry v0.16.1 h1:rUEt426sR6nyrL3gt+18ibRcvYpKYdpsa5ZW7MA08dQ=
|
||||
github.com/google/go-containerregistry v0.16.1/go.mod h1:u0qB2l7mvtWVR5kNcbFIhFY1hLbf8eeGapA+vbFDCtQ=
|
||||
github.com/google/go-github/v32 v32.1.0 h1:GWkQOdXqviCPx7Q7Fj+KyPoGm4SwHRh8rheoPhd27II=
|
||||
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
@@ -510,8 +514,8 @@ github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f/go.mod h1:oZtUIOe8dh
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/hcl/v2 v2.0.0/go.mod h1:oVVDG71tEinNGYCxinCYadcmKU9bglqW9pV3txagJ90=
|
||||
github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY=
|
||||
github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4=
|
||||
github.com/hashicorp/hcl/v2 v2.18.0 h1:wYnG7Lt31t2zYkcquwgKo6MWXzRUDIeIVU5naZwHLl8=
|
||||
github.com/hashicorp/hcl/v2 v2.18.0/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
@@ -599,8 +603,8 @@ 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/pkg v1.8.1-0.20230522085329-7d5e1241a86d h1:QMmTg33lUZEfTz94eYJKa6Nb7GDcEOmuXsXRt/dA5vk=
|
||||
github.com/kubevela/pkg v1.8.1-0.20230522085329-7d5e1241a86d/go.mod h1:3ZWrl2+zb5ROdC2NJPPrL/4sun4M10wYfRP/9gF9WJE=
|
||||
github.com/kubevela/workflow v0.5.1-0.20230412142834-be9e5a10baf0 h1:/ZPmjKpd/+fpCjJfNfUnE7jdESuCcZeP+fyTUAU9an0=
|
||||
github.com/kubevela/workflow v0.5.1-0.20230412142834-be9e5a10baf0/go.mod h1:0GhIWFIPP+Zt31m4Aslx9mihoyNz3HrOvCV69ljMIBo=
|
||||
github.com/kubevela/workflow v0.6.0 h1:fYXviOYD5zqHs3J61tNbM4HZ85EcZlPm7Fyz8Q5o9Fk=
|
||||
github.com/kubevela/workflow v0.6.0/go.mod h1:sjLcYqKHKeCQ+w77gijoNILwIShJKnCU+e3q7ETtZGI=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
@@ -652,8 +656,9 @@ github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPn
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-oci8 v0.1.1/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
|
||||
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
@@ -740,8 +745,8 @@ github.com/oam-dev/stern v1.13.2 h1:jlGgtJbKmIVhzkH44ft5plkgs8XEfvxbFrQdX60CQR4=
|
||||
github.com/oam-dev/stern v1.13.2/go.mod h1:0pLjZt0amXE/ErF16Rdrgd98H2owN8Hmn3/7CX5+AeA=
|
||||
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28 h1:tD8HiFKnt0jnwdTWjeqUnfnUYLD/+Nsmj8ZGIxqDWiU=
|
||||
github.com/oam-dev/terraform-config-inspect v0.0.0-20210418082552-fc72d929aa28/go.mod h1:Mu8i0/DdplvnjwRbAYPsc8+LRR27n/mp8VWdkN10GzE=
|
||||
github.com/oam-dev/terraform-controller v0.7.11 h1:uucdSBLL0PUz60hOZfjsAe/ivrd/K/2u0Iko8nVQIE0=
|
||||
github.com/oam-dev/terraform-controller v0.7.11/go.mod h1:xvgChKG0pij0WEKRrX7w30SdVBPVOlRl/+Mv7+2C1cI=
|
||||
github.com/oam-dev/terraform-controller v0.8.0 h1:/881bAELCsceSj+Zh3Nsu8Ym5N7D5Ho0HsWzO+TDc1w=
|
||||
github.com/oam-dev/terraform-controller v0.8.0/go.mod h1:ydc9iHjgLzwuWB+MlE2vRA8gOZsif0T4E2FL34K8CZ4=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
@@ -759,8 +764,8 @@ github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8Ay
|
||||
github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
|
||||
github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
|
||||
github.com/onsi/ginkgo/v2 v2.6.0/go.mod h1:63DOGlLAH8+REH8jUGdL3YpCpu7JODesutUjdENfUAc=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU=
|
||||
github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM=
|
||||
github.com/onsi/ginkgo/v2 v2.13.1 h1:LNGfMbR2OVGBfXjvRZIZ2YCTQdGKtPLvuI1rMCCj3OU=
|
||||
github.com/onsi/ginkgo/v2 v2.13.1/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
@@ -772,8 +777,8 @@ github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ
|
||||
github.com/onsi/gomega v1.23.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
|
||||
github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
|
||||
github.com/onsi/gomega v1.24.1/go.mod h1:3AOiACssS3/MajrniINInwbfOOtfZvplPzuRSmvt1jM=
|
||||
github.com/onsi/gomega v1.27.8 h1:gegWiwZjBsf2DgiSbf5hpokZ98JVDMcWkUiigk6/KXc=
|
||||
github.com/onsi/gomega v1.27.8/go.mod h1:2J8vzI/s+2shY9XHRApDkdgPo1TKT7P2u6fXeJKFnNQ=
|
||||
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
|
||||
github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
|
||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8=
|
||||
@@ -824,8 +829,8 @@ github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||
github.com/prometheus/client_golang v1.15.1 h1:8tXpTmJbyH5lydzFPoxSIJ0J46jdh3tylbvM1xCv0LI=
|
||||
github.com/prometheus/client_golang v1.15.1/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk=
|
||||
github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8=
|
||||
github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
@@ -852,8 +857,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
|
||||
github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=
|
||||
github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=
|
||||
github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg=
|
||||
github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b h1:zd/2RNzIRkoGGMjE+YIsZ85CnDIz672JK2F3Zl4vux4=
|
||||
github.com/protocolbuffers/txtpbfmt v0.0.0-20220428173112-74888fd59c2b/go.mod h1:KjY0wibdYKc4DYkerHSbguaf3JeIPGhNJBp2BNiFH78=
|
||||
@@ -893,8 +898,8 @@ github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/skeema/knownhosts v1.1.1 h1:MTk78x9FPgDFVFkDLTrsnnfCJl7g1C/nnKvePgrIngE=
|
||||
github.com/skeema/knownhosts v1.1.1/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
|
||||
github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
|
||||
github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||
@@ -964,8 +969,8 @@ github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN
|
||||
github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck=
|
||||
github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
|
||||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/xanzy/go-gitlab v0.86.0 h1:jR8V9cK9jXRQDb46KOB20NCF3ksY09luaG0IfXE6p7w=
|
||||
github.com/xanzy/go-gitlab v0.86.0/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
|
||||
github.com/xanzy/go-gitlab v0.91.1 h1:gnV57IPGYywWer32oXKBcdmc8dVxeKl3AauV8Bu17rw=
|
||||
github.com/xanzy/go-gitlab v0.91.1/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
@@ -1116,10 +1121,12 @@ golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
|
||||
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
@@ -1142,8 +1149,8 @@ golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
|
||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -1182,7 +1189,6 @@ golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
@@ -1195,8 +1201,10 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
|
||||
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1208,8 +1216,8 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.9.0 h1:BPpt2kU7oMRq3kCHAA1tbSEshXRw1LpG2ztgDwrzuAs=
|
||||
golang.org/x/oauth2 v0.9.0/go.mod h1:qYgFZaFiu6Wg24azG8bdV52QJXJGbZzIIsRCdVKzbLw=
|
||||
golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
|
||||
golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -1222,8 +1230,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -1276,7 +1284,6 @@ golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211029165221-6e7872819dc8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -1298,8 +1305,10 @@ golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
|
||||
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
|
||||
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
@@ -1311,8 +1320,10 @@ golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
|
||||
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
|
||||
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@@ -1324,8 +1335,9 @@ golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
|
||||
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -1364,15 +1376,15 @@ golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
|
||||
golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
|
||||
golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
|
||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
|
||||
gomodules.xyz/jsonpatch/v2 v2.3.0 h1:8NFhfS6gzxNqjLIYnZxg319wZ5Qjnx4m/CcX+Klzazc=
|
||||
gomodules.xyz/jsonpatch/v2 v2.3.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
||||
@@ -1454,8 +1466,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||
|
||||
@@ -42,7 +42,7 @@ var ComponentDefDirs = []string{"./vela-templates/definitions/internal/component
|
||||
|
||||
// CustomComponentHeaderEN .
|
||||
var CustomComponentHeaderEN = `---
|
||||
title: Built-in Component Type
|
||||
title: Built-in ParsedComponents Type
|
||||
---
|
||||
|
||||
This documentation will walk through all the built-in component types sorted alphabetically.
|
||||
|
||||
@@ -9,7 +9,7 @@ kubectl-vela:
|
||||
|
||||
# Build the docker image
|
||||
.PHONY: docker-build
|
||||
docker-build: docker-build-core docker-build-apiserver docker-build-cli
|
||||
docker-build: docker-build-core docker-build-cli
|
||||
@$(OK)
|
||||
|
||||
.PHONY: docker-build-core
|
||||
|
||||
@@ -46,12 +46,13 @@ else
|
||||
GOIMPORTS=$(shell which goimports)
|
||||
endif
|
||||
|
||||
CUE_VERSION ?= v0.6.0
|
||||
.PHONY: installcue
|
||||
installcue:
|
||||
ifeq (, $(shell which cue))
|
||||
@{ \
|
||||
set -e ;\
|
||||
go install cuelang.org/go/cmd/cue@latest ;\
|
||||
go install cuelang.org/go/cmd/cue@$(CUE_VERSION) ;\
|
||||
}
|
||||
CUE=$(GOBIN)/cue
|
||||
else
|
||||
|
||||
@@ -1135,13 +1135,16 @@ func TestPackageAddon(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGenerateAnnotation(t *testing.T) {
|
||||
meta := Meta{SystemRequirements: &SystemRequirements{
|
||||
VelaVersion: ">1.4.0",
|
||||
KubernetesVersion: ">1.20.0",
|
||||
}}
|
||||
meta := Meta{
|
||||
Name: "test-addon",
|
||||
SystemRequirements: &SystemRequirements{
|
||||
VelaVersion: ">1.4.0",
|
||||
KubernetesVersion: ">1.20.0",
|
||||
}}
|
||||
res := generateAnnotation(&meta)
|
||||
assert.Equal(t, res[velaSystemRequirement], ">1.4.0")
|
||||
assert.Equal(t, res[kubernetesSystemRequirement], ">1.20.0")
|
||||
assert.Equal(t, res[addonSystemRequirement], meta.Name)
|
||||
|
||||
meta = Meta{}
|
||||
meta.SystemRequirements = &SystemRequirements{KubernetesVersion: ">=1.20.1"}
|
||||
|
||||
@@ -337,6 +337,11 @@ func (u *Cache) listVersionRegistryUIDataAndCache(r Registry) ([]*UIData, error)
|
||||
klog.Errorf("fail to get addon from versioned registry %s, addon %s version %s for cache updating, %v", r.Name, addon.Name, addon.Version, err)
|
||||
continue
|
||||
}
|
||||
// identity an addon from helm chart structure
|
||||
if uiData.Name == "" {
|
||||
addon.Name = ""
|
||||
continue
|
||||
}
|
||||
u.putVersionedUIData2Cache(r.Name, addon.Name, addon.Version, uiData)
|
||||
// we also no version key, if use get addonUIData without version will return this vale as latest data.
|
||||
u.putVersionedUIData2Cache(r.Name, addon.Name, "latest", uiData)
|
||||
|
||||
@@ -448,6 +448,7 @@ func generateAnnotation(meta *Meta) map[string]string {
|
||||
res[kubernetesSystemRequirement] = meta.SystemRequirements.KubernetesVersion
|
||||
}
|
||||
}
|
||||
res[addonSystemRequirement] = meta.Name
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,8 @@ const (
|
||||
velaSystemRequirement = `system.vela`
|
||||
// kubernetesSystemRequirement is the kubernetes requirement annotation key
|
||||
kubernetesSystemRequirement = `system.kubernetes`
|
||||
// addonSystemRequirement is the annotation key to identity an addon from helm chart structure
|
||||
addonSystemRequirement = `addon.name`
|
||||
)
|
||||
|
||||
// VersionedRegistry is the interface of support version registry
|
||||
@@ -159,9 +161,8 @@ func (i versionedRegistry) loadAddon(ctx context.Context, name, version string)
|
||||
sort.Sort(sort.Reverse(versions))
|
||||
addonVersion, availableVersions := chooseVersion(version, versions)
|
||||
if addonVersion == nil {
|
||||
return nil, errors.Errorf("specified version %s not exist", utils.Sanitize(version))
|
||||
return nil, errors.Errorf("specified version %s for addon %s not exist", utils.Sanitize(version), name)
|
||||
}
|
||||
klog.V(5).Infof("Addon '%s' with version '%s' found from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
|
||||
for _, chartURL := range addonVersion.URLs {
|
||||
if !utils.IsValidURL(chartURL) {
|
||||
chartURL, err = utils.JoinURL(i.url, chartURL)
|
||||
@@ -186,7 +187,9 @@ func (i versionedRegistry) loadAddon(ctx context.Context, name, version string)
|
||||
addonPkg.AvailableVersions = availableVersions
|
||||
addonPkg.RegistryName = i.name
|
||||
addonPkg.Meta.SystemRequirements = LoadSystemRequirements(addonVersion.Annotations)
|
||||
klog.V(5).Infof("Addon '%s' with version '%s' loaded successfully from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
|
||||
if addonPkg.Name != "" {
|
||||
klog.V(5).Infof("Addon '%s' with version '%s' loaded successfully from registry '%s'", addonVersion.Name, addonVersion.Version, i.name)
|
||||
}
|
||||
return addonPkg, nil
|
||||
}
|
||||
return nil, ErrFetch
|
||||
@@ -228,6 +231,7 @@ func loadAddonPackage(addonName string, files []*loader.BufferedFile) (*WholeAdd
|
||||
}
|
||||
|
||||
// chooseVersion will return the target version and all available versions
|
||||
// This function is not sensitive to v-prefix, which means if specifiedVersion=0.3.0, v0.3.0 can be chosen.
|
||||
func chooseVersion(specifiedVersion string, versions []*repo.ChartVersion) (*repo.ChartVersion, []string) {
|
||||
var addonVersion *repo.ChartVersion
|
||||
var availableVersions []string
|
||||
@@ -238,7 +242,7 @@ func chooseVersion(specifiedVersion string, versions []*repo.ChartVersion) (*rep
|
||||
continue
|
||||
}
|
||||
if len(specifiedVersion) != 0 {
|
||||
if v.Version == specifiedVersion {
|
||||
if utils.IgnoreVPrefix(v.Version) == utils.IgnoreVPrefix(specifiedVersion) {
|
||||
addonVersion = versions[i]
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -51,13 +51,36 @@ func TestChooseAddonVersion(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
targetVersion, availableVersion := chooseVersion("v1.2.0", versions)
|
||||
assert.Equal(t, availableVersion, []string{"v1.4.0-beta1", "v1.3.6", "v1.2.0"})
|
||||
assert.Equal(t, targetVersion.Version, "v1.2.0")
|
||||
|
||||
targetVersion, availableVersion = chooseVersion("", versions)
|
||||
assert.Equal(t, availableVersion, []string{"v1.4.0-beta1", "v1.3.6", "v1.2.0"})
|
||||
assert.Equal(t, targetVersion.Version, "v1.3.6")
|
||||
avs := []string{"v1.4.0-beta1", "v1.3.6", "v1.2.0"}
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
specifiedVersion string
|
||||
wantVersion string
|
||||
wantAVersions []string
|
||||
}{
|
||||
{
|
||||
name: "choose specified",
|
||||
specifiedVersion: "v1.2.0",
|
||||
wantVersion: "v1.2.0",
|
||||
wantAVersions: avs,
|
||||
},
|
||||
{
|
||||
name: "choose specified, ignore v prefix",
|
||||
specifiedVersion: "1.2.0",
|
||||
wantVersion: "v1.2.0",
|
||||
wantAVersions: avs,
|
||||
},
|
||||
{
|
||||
name: "not specifying version, choose non-prerelease && highest version",
|
||||
specifiedVersion: "",
|
||||
wantVersion: "v1.3.6",
|
||||
wantAVersions: avs,
|
||||
},
|
||||
} {
|
||||
targetVersion, availableVersion := chooseVersion(tc.specifiedVersion, versions)
|
||||
assert.Equal(t, availableVersion, tc.wantAVersions)
|
||||
assert.Equal(t, targetVersion.Version, tc.wantVersion)
|
||||
}
|
||||
}
|
||||
|
||||
var versionedHandler http.HandlerFunc = func(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
@@ -74,8 +74,10 @@ const (
|
||||
GitCredentialsSecretReferenceKey = "gitCredentialsSecretReference"
|
||||
)
|
||||
|
||||
// Workload is component
|
||||
type Workload struct {
|
||||
// Component is an internal struct for component in application
|
||||
// User-defined policies are parsed as a Component without any Traits because their purpose is dispatching some resources
|
||||
// Internal policies are NOT parsed as a Component
|
||||
type Component struct {
|
||||
Name string
|
||||
Type string
|
||||
CapabilityCategory types.CapabilityCategory
|
||||
@@ -89,39 +91,39 @@ type Workload struct {
|
||||
}
|
||||
|
||||
// EvalContext eval workload template and set the result to context
|
||||
func (wl *Workload) EvalContext(ctx process.Context) error {
|
||||
return wl.engine.Complete(ctx, wl.FullTemplate.TemplateStr, wl.Params)
|
||||
func (comp *Component) EvalContext(ctx process.Context) error {
|
||||
return comp.engine.Complete(ctx, comp.FullTemplate.TemplateStr, comp.Params)
|
||||
}
|
||||
|
||||
// GetTemplateContext get workload template context, it will be used to eval status and health
|
||||
func (wl *Workload) GetTemplateContext(ctx process.Context, client client.Client, accessor util.NamespaceAccessor) (map[string]interface{}, error) {
|
||||
func (comp *Component) GetTemplateContext(ctx process.Context, client client.Client, accessor util.NamespaceAccessor) (map[string]interface{}, error) {
|
||||
// if the standard workload is managed by trait, just return empty context
|
||||
if wl.SkipApplyWorkload {
|
||||
if comp.SkipApplyWorkload {
|
||||
return nil, nil
|
||||
}
|
||||
templateContext, err := wl.engine.GetTemplateContext(ctx, client, accessor)
|
||||
templateContext, err := comp.engine.GetTemplateContext(ctx, client, accessor)
|
||||
if templateContext != nil {
|
||||
templateContext[velaprocess.ParameterFieldName] = wl.Params
|
||||
templateContext[velaprocess.ParameterFieldName] = comp.Params
|
||||
}
|
||||
return templateContext, err
|
||||
}
|
||||
|
||||
// EvalStatus eval workload status
|
||||
func (wl *Workload) EvalStatus(templateContext map[string]interface{}) (string, error) {
|
||||
func (comp *Component) EvalStatus(templateContext map[string]interface{}) (string, error) {
|
||||
// if the standard workload is managed by trait always return empty message
|
||||
if wl.SkipApplyWorkload {
|
||||
if comp.SkipApplyWorkload {
|
||||
return "", nil
|
||||
}
|
||||
return wl.engine.Status(templateContext, wl.FullTemplate.CustomStatus, wl.Params)
|
||||
return comp.engine.Status(templateContext, comp.FullTemplate.CustomStatus, comp.Params)
|
||||
}
|
||||
|
||||
// EvalHealth eval workload health check
|
||||
func (wl *Workload) EvalHealth(templateContext map[string]interface{}) (bool, error) {
|
||||
func (comp *Component) EvalHealth(templateContext map[string]interface{}) (bool, error) {
|
||||
// if the health of template is not set or standard workload is managed by trait always return true
|
||||
if wl.SkipApplyWorkload {
|
||||
if comp.SkipApplyWorkload {
|
||||
return true, nil
|
||||
}
|
||||
return wl.engine.HealthCheck(templateContext, wl.FullTemplate.Health, wl.Params)
|
||||
return comp.engine.HealthCheck(templateContext, comp.FullTemplate.Health, comp.Params)
|
||||
}
|
||||
|
||||
// Trait is ComponentTrait
|
||||
@@ -168,9 +170,10 @@ func (trait *Trait) EvalHealth(templateContext map[string]interface{}) (bool, er
|
||||
|
||||
// Appfile describes application
|
||||
type Appfile struct {
|
||||
Name string
|
||||
Namespace string
|
||||
Workloads []*Workload
|
||||
Name string
|
||||
Namespace string
|
||||
ParsedComponents []*Component
|
||||
ParsedPolicies []*Component
|
||||
|
||||
AppRevision *v1beta1.ApplicationRevision
|
||||
AppRevisionName string
|
||||
@@ -183,19 +186,17 @@ type Appfile struct {
|
||||
RelatedComponentDefinitions map[string]*v1beta1.ComponentDefinition
|
||||
RelatedWorkflowStepDefinitions map[string]*v1beta1.WorkflowStepDefinition
|
||||
|
||||
Policies []v1beta1.AppPolicy
|
||||
PolicyWorkloads []*Workload
|
||||
Components []common.ApplicationComponent
|
||||
Artifacts []*types.ComponentManifest
|
||||
WorkflowSteps []workflowv1alpha1.WorkflowStep
|
||||
WorkflowMode *workflowv1alpha1.WorkflowExecuteMode
|
||||
Policies []v1beta1.AppPolicy
|
||||
Components []common.ApplicationComponent
|
||||
Artifacts []*types.ComponentManifest
|
||||
WorkflowSteps []workflowv1alpha1.WorkflowStep
|
||||
WorkflowMode *workflowv1alpha1.WorkflowExecuteMode
|
||||
|
||||
ExternalPolicies map[string]*v1alpha1.Policy
|
||||
ExternalWorkflow *workflowv1alpha1.Workflow
|
||||
ReferredObjects []*unstructured.Unstructured
|
||||
|
||||
parser *Parser
|
||||
app *v1beta1.Application
|
||||
app *v1beta1.Application
|
||||
|
||||
Debug bool
|
||||
}
|
||||
@@ -204,7 +205,7 @@ type Appfile struct {
|
||||
// internal policies like apply-once, topology, will not render manifests
|
||||
func (af *Appfile) GeneratePolicyManifests(ctx context.Context) ([]*unstructured.Unstructured, error) {
|
||||
var manifests []*unstructured.Unstructured
|
||||
for _, policy := range af.PolicyWorkloads {
|
||||
for _, policy := range af.ParsedPolicies {
|
||||
un, err := af.generatePolicyUnstructured(policy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -214,7 +215,7 @@ func (af *Appfile) GeneratePolicyManifests(ctx context.Context) ([]*unstructured
|
||||
return manifests, nil
|
||||
}
|
||||
|
||||
func (af *Appfile) generatePolicyUnstructured(workload *Workload) ([]*unstructured.Unstructured, error) {
|
||||
func (af *Appfile) generatePolicyUnstructured(workload *Component) ([]*unstructured.Unstructured, error) {
|
||||
ctxData := GenerateContextDataFromAppFile(af, workload.Name)
|
||||
uns, err := generatePolicyUnstructuredFromCUEModule(workload, af.Artifacts, ctxData)
|
||||
if err != nil {
|
||||
@@ -231,16 +232,16 @@ func (af *Appfile) generatePolicyUnstructured(workload *Workload) ([]*unstructur
|
||||
return uns, nil
|
||||
}
|
||||
|
||||
func generatePolicyUnstructuredFromCUEModule(wl *Workload, artifacts []*types.ComponentManifest, ctxData velaprocess.ContextData) ([]*unstructured.Unstructured, error) {
|
||||
func generatePolicyUnstructuredFromCUEModule(comp *Component, artifacts []*types.ComponentManifest, ctxData velaprocess.ContextData) ([]*unstructured.Unstructured, error) {
|
||||
pCtx := velaprocess.NewContext(ctxData)
|
||||
pCtx.PushData(velaprocess.ContextDataArtifacts, prepareArtifactsData(artifacts))
|
||||
if err := wl.EvalContext(pCtx); err != nil {
|
||||
if err := comp.EvalContext(pCtx); err != nil {
|
||||
return nil, errors.Wrapf(err, "evaluate base template app=%s in namespace=%s", ctxData.AppName, ctxData.Namespace)
|
||||
}
|
||||
base, auxs := pCtx.Output()
|
||||
workload, err := base.Unstructured()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "evaluate base template policy=%s app=%s", wl.Name, ctxData.AppName)
|
||||
return nil, errors.Wrapf(err, "evaluate base template policy=%s app=%s", comp.Name, ctxData.AppName)
|
||||
}
|
||||
commonLabels := definition.GetCommonLabels(definition.GetBaseContextLabels(pCtx))
|
||||
util.AddLabels(workload, commonLabels)
|
||||
@@ -249,7 +250,7 @@ func generatePolicyUnstructuredFromCUEModule(wl *Workload, artifacts []*types.Co
|
||||
for _, assist := range auxs {
|
||||
tr, err := assist.Ins.Unstructured()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "evaluate auxiliary=%s template for policy=%s app=%s", assist.Name, wl.Name, ctxData.AppName)
|
||||
return nil, errors.Wrapf(err, "evaluate auxiliary=%s template for policy=%s app=%s", assist.Name, comp.Name, ctxData.AppName)
|
||||
}
|
||||
util.AddLabels(tr, commonLabels)
|
||||
res = append(res, tr)
|
||||
@@ -265,10 +266,10 @@ func generatePolicyUnstructuredFromCUEModule(wl *Workload, artifacts []*types.Co
|
||||
func prepareArtifactsData(comps []*types.ComponentManifest) map[string]interface{} {
|
||||
artifacts := unstructured.Unstructured{Object: make(map[string]interface{})}
|
||||
for _, pComp := range comps {
|
||||
if pComp.StandardWorkload != nil {
|
||||
_ = unstructured.SetNestedField(artifacts.Object, pComp.StandardWorkload.Object, pComp.Name, "workload")
|
||||
if pComp.ComponentOutput != nil {
|
||||
_ = unstructured.SetNestedField(artifacts.Object, pComp.ComponentOutput.Object, pComp.Name, "workload")
|
||||
}
|
||||
for _, t := range pComp.Traits {
|
||||
for _, t := range pComp.ComponentOutputsAndTraits {
|
||||
if t == nil {
|
||||
continue
|
||||
}
|
||||
@@ -283,10 +284,10 @@ func prepareArtifactsData(comps []*types.ComponentManifest) map[string]interface
|
||||
|
||||
// GenerateComponentManifests converts an appFile to a slice of ComponentManifest
|
||||
func (af *Appfile) GenerateComponentManifests() ([]*types.ComponentManifest, error) {
|
||||
compManifests := make([]*types.ComponentManifest, len(af.Workloads))
|
||||
af.Artifacts = make([]*types.ComponentManifest, len(af.Workloads))
|
||||
for i, wl := range af.Workloads {
|
||||
cm, err := af.GenerateComponentManifest(wl, nil)
|
||||
compManifests := make([]*types.ComponentManifest, len(af.ParsedComponents))
|
||||
af.Artifacts = make([]*types.ComponentManifest, len(af.ParsedComponents))
|
||||
for i, comp := range af.ParsedComponents {
|
||||
cm, err := af.GenerateComponentManifest(comp, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -301,21 +302,21 @@ func (af *Appfile) GenerateComponentManifests() ([]*types.ComponentManifest, err
|
||||
}
|
||||
|
||||
// GenerateComponentManifest generate only one ComponentManifest
|
||||
func (af *Appfile) GenerateComponentManifest(wl *Workload, mutate func(*velaprocess.ContextData)) (*types.ComponentManifest, error) {
|
||||
func (af *Appfile) GenerateComponentManifest(comp *Component, mutate func(*velaprocess.ContextData)) (*types.ComponentManifest, error) {
|
||||
if af.Namespace == "" {
|
||||
af.Namespace = corev1.NamespaceDefault
|
||||
}
|
||||
ctxData := GenerateContextDataFromAppFile(af, wl.Name)
|
||||
ctxData := GenerateContextDataFromAppFile(af, comp.Name)
|
||||
if mutate != nil {
|
||||
mutate(&ctxData)
|
||||
}
|
||||
// generate context here to avoid nil pointer panic
|
||||
wl.Ctx = NewBasicContext(ctxData, wl.Params)
|
||||
switch wl.CapabilityCategory {
|
||||
comp.Ctx = NewBasicContext(ctxData, comp.Params)
|
||||
switch comp.CapabilityCategory {
|
||||
case types.TerraformCategory:
|
||||
return generateComponentFromTerraformModule(wl, af.Name, af.Namespace)
|
||||
return generateComponentFromTerraformModule(comp, af.Name, af.Namespace)
|
||||
default:
|
||||
return generateComponentFromCUEModule(wl, ctxData)
|
||||
return generateComponentFromCUEModule(comp, ctxData)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,14 +325,14 @@ func (af *Appfile) SetOAMContract(comp *types.ComponentManifest) error {
|
||||
|
||||
compName := comp.Name
|
||||
commonLabels := af.generateAndFilterCommonLabels(compName)
|
||||
af.assembleWorkload(comp.StandardWorkload, compName, commonLabels)
|
||||
af.assembleWorkload(comp.ComponentOutput, compName, commonLabels)
|
||||
|
||||
workloadRef := corev1.ObjectReference{
|
||||
APIVersion: comp.StandardWorkload.GetAPIVersion(),
|
||||
Kind: comp.StandardWorkload.GetKind(),
|
||||
Name: comp.StandardWorkload.GetName(),
|
||||
APIVersion: comp.ComponentOutput.GetAPIVersion(),
|
||||
Kind: comp.ComponentOutput.GetKind(),
|
||||
Name: comp.ComponentOutput.GetName(),
|
||||
}
|
||||
for _, trait := range comp.Traits {
|
||||
for _, trait := range comp.ComponentOutputsAndTraits {
|
||||
af.assembleTrait(trait, comp.Name, commonLabels)
|
||||
if err := af.setWorkloadRefToTrait(workloadRef, trait); err != nil && !IsNotFoundInAppFile(err) {
|
||||
return errors.WithMessagef(err, "cannot set workload reference to trait %q", trait.GetName())
|
||||
@@ -393,15 +394,15 @@ func (af *Appfile) setNamespace(obj *unstructured.Unstructured) {
|
||||
}
|
||||
}
|
||||
|
||||
func (af *Appfile) assembleWorkload(wl *unstructured.Unstructured, compName string, labels map[string]string) {
|
||||
func (af *Appfile) assembleWorkload(comp *unstructured.Unstructured, compName string, labels map[string]string) {
|
||||
// use component name as workload name if workload name is not specified
|
||||
// don't override the name set in render phase if exist
|
||||
if len(wl.GetName()) == 0 {
|
||||
wl.SetName(compName)
|
||||
if len(comp.GetName()) == 0 {
|
||||
comp.SetName(compName)
|
||||
}
|
||||
af.setNamespace(wl)
|
||||
af.setWorkloadLabels(wl, labels)
|
||||
af.filterAndSetAnnotations(wl)
|
||||
af.setNamespace(comp)
|
||||
af.setWorkloadLabels(comp, labels)
|
||||
af.filterAndSetAnnotations(comp)
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -416,10 +417,10 @@ func (af *Appfile) assembleWorkload(wl *unstructured.Unstructured, compName stri
|
||||
|
||||
// Component Revision name was not added here (app.oam.dev/revision: mycomp-v2)
|
||||
*/
|
||||
func (af *Appfile) setWorkloadLabels(wl *unstructured.Unstructured, commonLabels map[string]string) {
|
||||
func (af *Appfile) setWorkloadLabels(comp *unstructured.Unstructured, commonLabels map[string]string) {
|
||||
// add more workload-specific labels here
|
||||
util.AddLabels(wl, map[string]string{oam.LabelOAMResourceType: oam.ResourceTypeWorkload})
|
||||
util.AddLabels(wl, commonLabels)
|
||||
util.AddLabels(comp, map[string]string{oam.LabelOAMResourceType: oam.ResourceTypeWorkload})
|
||||
util.AddLabels(comp, commonLabels)
|
||||
}
|
||||
|
||||
func (af *Appfile) assembleTrait(trait *unstructured.Unstructured, compName string, labels map[string]string) {
|
||||
@@ -491,14 +492,14 @@ func IsNotFoundInAppFile(err error) bool {
|
||||
}
|
||||
|
||||
// PrepareProcessContext prepares a DSL process Context
|
||||
func PrepareProcessContext(wl *Workload, ctxData velaprocess.ContextData) (process.Context, error) {
|
||||
if wl.Ctx == nil {
|
||||
wl.Ctx = NewBasicContext(ctxData, wl.Params)
|
||||
func PrepareProcessContext(comp *Component, ctxData velaprocess.ContextData) (process.Context, error) {
|
||||
if comp.Ctx == nil {
|
||||
comp.Ctx = NewBasicContext(ctxData, comp.Params)
|
||||
}
|
||||
if err := wl.EvalContext(wl.Ctx); err != nil {
|
||||
if err := comp.EvalContext(comp.Ctx); err != nil {
|
||||
return nil, errors.Wrapf(err, "evaluate base template app=%s in namespace=%s", ctxData.AppName, ctxData.Namespace)
|
||||
}
|
||||
return wl.Ctx, nil
|
||||
return comp.Ctx, nil
|
||||
}
|
||||
|
||||
// NewBasicContext prepares a basic DSL process Context
|
||||
@@ -510,27 +511,27 @@ func NewBasicContext(contextData velaprocess.ContextData, params map[string]inte
|
||||
return pCtx
|
||||
}
|
||||
|
||||
func generateComponentFromCUEModule(wl *Workload, ctxData velaprocess.ContextData) (*types.ComponentManifest, error) {
|
||||
pCtx, err := PrepareProcessContext(wl, ctxData)
|
||||
func generateComponentFromCUEModule(comp *Component, ctxData velaprocess.ContextData) (*types.ComponentManifest, error) {
|
||||
pCtx, err := PrepareProcessContext(comp, ctxData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return baseGenerateComponent(pCtx, wl, ctxData.AppName, ctxData.Namespace)
|
||||
return baseGenerateComponent(pCtx, comp, ctxData.AppName, ctxData.Namespace)
|
||||
}
|
||||
|
||||
func generateComponentFromTerraformModule(wl *Workload, appName, ns string) (*types.ComponentManifest, error) {
|
||||
return baseGenerateComponent(wl.Ctx, wl, appName, ns)
|
||||
func generateComponentFromTerraformModule(comp *Component, appName, ns string) (*types.ComponentManifest, error) {
|
||||
return baseGenerateComponent(comp.Ctx, comp, appName, ns)
|
||||
}
|
||||
|
||||
func baseGenerateComponent(pCtx process.Context, wl *Workload, appName, ns string) (*types.ComponentManifest, error) {
|
||||
func baseGenerateComponent(pCtx process.Context, comp *Component, appName, ns string) (*types.ComponentManifest, error) {
|
||||
var err error
|
||||
pCtx.PushData(velaprocess.ContextComponentType, wl.Type)
|
||||
for _, tr := range wl.Traits {
|
||||
pCtx.PushData(velaprocess.ContextComponentType, comp.Type)
|
||||
for _, tr := range comp.Traits {
|
||||
if err := tr.EvalContext(pCtx); err != nil {
|
||||
return nil, errors.Wrapf(err, "evaluate template trait=%s app=%s", tr.Name, wl.Name)
|
||||
return nil, errors.Wrapf(err, "evaluate template trait=%s app=%s", tr.Name, comp.Name)
|
||||
}
|
||||
}
|
||||
if patcher := wl.Patch; patcher != nil {
|
||||
if patcher := comp.Patch; patcher != nil {
|
||||
workload, auxiliaries := pCtx.Output()
|
||||
if p, err := patcher.LookupValue("workload"); err == nil {
|
||||
if err := workload.Unify(p.CueValue()); err != nil {
|
||||
@@ -545,86 +546,86 @@ func baseGenerateComponent(pCtx process.Context, wl *Workload, appName, ns strin
|
||||
}
|
||||
}
|
||||
}
|
||||
compManifest, err := evalWorkloadWithContext(pCtx, wl, ns, appName)
|
||||
compManifest, err := evalWorkloadWithContext(pCtx, comp, ns, appName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
compManifest.Name = wl.Name
|
||||
compManifest.Name = comp.Name
|
||||
compManifest.Namespace = ns
|
||||
return compManifest, nil
|
||||
}
|
||||
|
||||
// makeWorkloadWithContext evaluate the workload's template to unstructured resource.
|
||||
func makeWorkloadWithContext(pCtx process.Context, wl *Workload, ns, appName string) (*unstructured.Unstructured, error) {
|
||||
func makeWorkloadWithContext(pCtx process.Context, comp *Component, ns, appName string) (*unstructured.Unstructured, error) {
|
||||
var (
|
||||
workload *unstructured.Unstructured
|
||||
err error
|
||||
)
|
||||
base, _ := pCtx.Output()
|
||||
switch wl.CapabilityCategory {
|
||||
switch comp.CapabilityCategory {
|
||||
case types.TerraformCategory:
|
||||
workload, err = generateTerraformConfigurationWorkload(wl, ns)
|
||||
workload, err = generateTerraformConfigurationWorkload(comp, ns)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to generate Terraform Configuration workload for workload %s", wl.Name)
|
||||
return nil, errors.Wrapf(err, "failed to generate Terraform Configuration workload for workload %s", comp.Name)
|
||||
}
|
||||
default:
|
||||
workload, err = base.Unstructured()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "evaluate base template component=%s app=%s", wl.Name, appName)
|
||||
return nil, errors.Wrapf(err, "evaluate base template component=%s app=%s", comp.Name, appName)
|
||||
}
|
||||
}
|
||||
commonLabels := definition.GetCommonLabels(definition.GetBaseContextLabels(pCtx))
|
||||
util.AddLabels(workload, util.MergeMapOverrideWithDst(commonLabels, map[string]string{oam.WorkloadTypeLabel: wl.Type}))
|
||||
util.AddLabels(workload, util.MergeMapOverrideWithDst(commonLabels, map[string]string{oam.WorkloadTypeLabel: comp.Type}))
|
||||
return workload, nil
|
||||
}
|
||||
|
||||
// evalWorkloadWithContext evaluate the workload's template to generate component manifest
|
||||
func evalWorkloadWithContext(pCtx process.Context, wl *Workload, ns, appName string) (*types.ComponentManifest, error) {
|
||||
func evalWorkloadWithContext(pCtx process.Context, comp *Component, ns, appName string) (*types.ComponentManifest, error) {
|
||||
compManifest := &types.ComponentManifest{}
|
||||
workload, err := makeWorkloadWithContext(pCtx, wl, ns, appName)
|
||||
workload, err := makeWorkloadWithContext(pCtx, comp, ns, appName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
compManifest.StandardWorkload = workload
|
||||
compManifest.ComponentOutput = workload
|
||||
|
||||
_, assists := pCtx.Output()
|
||||
compManifest.Traits = make([]*unstructured.Unstructured, len(assists))
|
||||
compManifest.ComponentOutputsAndTraits = make([]*unstructured.Unstructured, len(assists))
|
||||
commonLabels := definition.GetCommonLabels(definition.GetBaseContextLabels(pCtx))
|
||||
for i, assist := range assists {
|
||||
tr, err := assist.Ins.Unstructured()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "evaluate trait=%s template for component=%s app=%s", assist.Name, wl.Name, appName)
|
||||
return nil, errors.Wrapf(err, "evaluate trait=%s template for component=%s app=%s", assist.Name, comp.Name, appName)
|
||||
}
|
||||
labels := util.MergeMapOverrideWithDst(commonLabels, map[string]string{oam.TraitTypeLabel: assist.Type})
|
||||
if assist.Name != "" {
|
||||
labels[oam.TraitResource] = assist.Name
|
||||
}
|
||||
util.AddLabels(tr, labels)
|
||||
compManifest.Traits[i] = tr
|
||||
compManifest.ComponentOutputsAndTraits[i] = tr
|
||||
}
|
||||
return compManifest, nil
|
||||
}
|
||||
|
||||
func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructured.Unstructured, error) {
|
||||
if wl.FullTemplate == nil || wl.FullTemplate.Terraform == nil || wl.FullTemplate.Terraform.Configuration == "" {
|
||||
func generateTerraformConfigurationWorkload(comp *Component, ns string) (*unstructured.Unstructured, error) {
|
||||
if comp.FullTemplate == nil || comp.FullTemplate.Terraform == nil || comp.FullTemplate.Terraform.Configuration == "" {
|
||||
return nil, errors.New(errTerraformConfigurationIsNotSet)
|
||||
}
|
||||
params, err := json.Marshal(wl.Params)
|
||||
params, err := json.Marshal(comp.Params)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, errFailToConvertTerraformComponentProperties)
|
||||
}
|
||||
|
||||
if wl.FullTemplate.ComponentDefinition == nil || wl.FullTemplate.ComponentDefinition.Spec.Schematic == nil ||
|
||||
wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform == nil {
|
||||
if comp.FullTemplate.ComponentDefinition == nil || comp.FullTemplate.ComponentDefinition.Spec.Schematic == nil ||
|
||||
comp.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform == nil {
|
||||
return nil, errors.New(errTerraformComponentDefinition)
|
||||
}
|
||||
|
||||
configuration := terraformapi.Configuration{
|
||||
TypeMeta: metav1.TypeMeta{APIVersion: "terraform.core.oam.dev/v1beta2", Kind: "Configuration"},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: wl.Name,
|
||||
Name: comp.Name,
|
||||
Namespace: ns,
|
||||
Annotations: wl.FullTemplate.ComponentDefinition.Annotations,
|
||||
Annotations: comp.FullTemplate.ComponentDefinition.Annotations,
|
||||
},
|
||||
}
|
||||
// 1. parse the spec of configuration
|
||||
@@ -635,26 +636,26 @@ func generateTerraformConfigurationWorkload(wl *Workload, ns string) (*unstructu
|
||||
configuration.Spec = spec
|
||||
|
||||
if configuration.Spec.WriteConnectionSecretToReference == nil {
|
||||
configuration.Spec.WriteConnectionSecretToReference = wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.WriteConnectionSecretToReference
|
||||
configuration.Spec.WriteConnectionSecretToReference = comp.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.WriteConnectionSecretToReference
|
||||
}
|
||||
if configuration.Spec.WriteConnectionSecretToReference != nil && configuration.Spec.WriteConnectionSecretToReference.Namespace == "" {
|
||||
configuration.Spec.WriteConnectionSecretToReference.Namespace = ns
|
||||
}
|
||||
|
||||
if configuration.Spec.ProviderReference == nil {
|
||||
configuration.Spec.ProviderReference = wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.ProviderReference
|
||||
configuration.Spec.ProviderReference = comp.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.ProviderReference
|
||||
}
|
||||
|
||||
if configuration.Spec.GitCredentialsSecretReference == nil {
|
||||
configuration.Spec.GitCredentialsSecretReference = wl.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.GitCredentialsSecretReference
|
||||
configuration.Spec.GitCredentialsSecretReference = comp.FullTemplate.ComponentDefinition.Spec.Schematic.Terraform.GitCredentialsSecretReference
|
||||
}
|
||||
|
||||
switch wl.FullTemplate.Terraform.Type {
|
||||
switch comp.FullTemplate.Terraform.Type {
|
||||
case "hcl":
|
||||
configuration.Spec.HCL = wl.FullTemplate.Terraform.Configuration
|
||||
configuration.Spec.HCL = comp.FullTemplate.Terraform.Configuration
|
||||
case "remote":
|
||||
configuration.Spec.Remote = wl.FullTemplate.Terraform.Configuration
|
||||
configuration.Spec.Path = wl.FullTemplate.Terraform.Path
|
||||
configuration.Spec.Remote = comp.FullTemplate.Terraform.Configuration
|
||||
configuration.Spec.Path = comp.FullTemplate.Terraform.Path
|
||||
}
|
||||
|
||||
// 2. parse variable
|
||||
|
||||
@@ -135,7 +135,7 @@ variable "password" {
|
||||
`
|
||||
)
|
||||
|
||||
wl := &Workload{
|
||||
wl := &Component{
|
||||
Name: "sample-db",
|
||||
FullTemplate: &Template{
|
||||
Terraform: &common.Terraform{
|
||||
@@ -161,10 +161,10 @@ variable "password" {
|
||||
}
|
||||
|
||||
af := &Appfile{
|
||||
Workloads: []*Workload{wl},
|
||||
Name: appName,
|
||||
AppRevisionName: revision,
|
||||
Namespace: ns,
|
||||
ParsedComponents: []*Component{wl},
|
||||
Name: appName,
|
||||
AppRevisionName: revision,
|
||||
Namespace: ns,
|
||||
}
|
||||
|
||||
variable := map[string]interface{}{"account_name": "oamtest"}
|
||||
@@ -194,7 +194,7 @@ variable "password" {
|
||||
|
||||
expectCompManifest := &oamtypes.ComponentManifest{
|
||||
Name: compName,
|
||||
StandardWorkload: func() *unstructured.Unstructured {
|
||||
ComponentOutput: func() *unstructured.Unstructured {
|
||||
r, _ := util.Object2Unstructured(workload)
|
||||
return r
|
||||
}(),
|
||||
@@ -319,13 +319,13 @@ var _ = Describe("Test evalWorkloadWithContext", func() {
|
||||
err error
|
||||
)
|
||||
type appArgs struct {
|
||||
wl *Workload
|
||||
wl *Component
|
||||
appName string
|
||||
revision string
|
||||
}
|
||||
|
||||
args := appArgs{
|
||||
wl: &Workload{
|
||||
wl: &Component{
|
||||
Name: compName,
|
||||
FullTemplate: &Template{
|
||||
Terraform: &common.Terraform{
|
||||
@@ -404,7 +404,7 @@ variable "password" {
|
||||
}, args.wl.Name)
|
||||
pCtx := NewBasicContext(ctxData, args.wl.Params)
|
||||
comp, err := evalWorkloadWithContext(pCtx, args.wl, ns, args.appName)
|
||||
Expect(comp.StandardWorkload).ShouldNot(BeNil())
|
||||
Expect(comp.ComponentOutput).ShouldNot(BeNil())
|
||||
Expect(comp.Name).Should(Equal(""))
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
@@ -595,7 +595,7 @@ func TestGenerateTerraformConfigurationWorkload(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
wl := &Workload{
|
||||
wl := &Component{
|
||||
FullTemplate: template,
|
||||
Name: name,
|
||||
Params: tc.args.params,
|
||||
@@ -629,10 +629,10 @@ func TestPrepareArtifactsData(t *testing.T) {
|
||||
Name: "readyComp",
|
||||
Namespace: "ns",
|
||||
RevisionName: "readyComp-v1",
|
||||
StandardWorkload: &unstructured.Unstructured{Object: map[string]interface{}{
|
||||
ComponentOutput: &unstructured.Unstructured{Object: map[string]interface{}{
|
||||
"fake": "workload",
|
||||
}},
|
||||
Traits: func() []*unstructured.Unstructured {
|
||||
ComponentOutputsAndTraits: func() []*unstructured.Unstructured {
|
||||
ingressYAML := `apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
@@ -730,12 +730,12 @@ if context.componentType == "stateless" {
|
||||
publishVersion: context.publishVersion
|
||||
}`,
|
||||
}
|
||||
wl := &Workload{Type: "stateful", Traits: []*Trait{tr}}
|
||||
wl := &Component{Type: "stateful", Traits: []*Trait{tr}}
|
||||
cm, err := baseGenerateComponent(pContext, wl, appName, ns)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, cm.Traits[0].Object["kind"], "StatefulSet")
|
||||
assert.Equal(t, cm.Traits[0].Object["workflowName"], workflowName)
|
||||
assert.Equal(t, cm.Traits[0].Object["publishVersion"], publishVersion)
|
||||
assert.Equal(t, cm.ComponentOutputsAndTraits[0].Object["kind"], "StatefulSet")
|
||||
assert.Equal(t, cm.ComponentOutputsAndTraits[0].Object["workflowName"], workflowName)
|
||||
assert.Equal(t, cm.ComponentOutputsAndTraits[0].Object["publishVersion"], publishVersion)
|
||||
}
|
||||
|
||||
var _ = Describe("Test use context.appLabels& context.appAnnotations in componentDefinition ", func() {
|
||||
@@ -751,7 +751,7 @@ var _ = Describe("Test use context.appLabels& context.appAnnotations in componen
|
||||
"ak1": "av1",
|
||||
"ak2": "av2",
|
||||
},
|
||||
Workloads: []*Workload{
|
||||
ParsedComponents: []*Component{
|
||||
{
|
||||
Name: "comp1",
|
||||
Type: "deployment",
|
||||
@@ -817,7 +817,7 @@ var _ = Describe("Test use context.appLabels& context.appAnnotations in componen
|
||||
Expect(err).To(BeNil())
|
||||
By("Verify expected ComponentManifest")
|
||||
deployment := &appsv1.Deployment{}
|
||||
runtime.DefaultUnstructuredConverter.FromUnstructured(componentManifests[0].StandardWorkload.Object, deployment)
|
||||
runtime.DefaultUnstructuredConverter.FromUnstructured(componentManifests[0].ComponentOutput.Object, deployment)
|
||||
labels := deployment.Spec.Template.Labels
|
||||
annotations := deployment.Spec.Template.Annotations
|
||||
Expect(cmp.Diff(len(labels), 2)).Should(BeEmpty())
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
|
||||
"github.com/aryann/difflib"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/client-go/rest"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
@@ -40,7 +41,7 @@ import (
|
||||
)
|
||||
|
||||
// NewLiveDiffOption creates a live-diff option
|
||||
func NewLiveDiffOption(c client.Client, cfg *rest.Config, pd *packages.PackageDiscover, as []oam.Object) *LiveDiffOption {
|
||||
func NewLiveDiffOption(c client.Client, cfg *rest.Config, pd *packages.PackageDiscover, as []*unstructured.Unstructured) *LiveDiffOption {
|
||||
parser := appfile.NewApplicationParser(c, pd)
|
||||
return &LiveDiffOption{DryRun: NewDryRunOption(c, cfg, pd, as, false), Parser: parser}
|
||||
}
|
||||
@@ -136,7 +137,7 @@ func (l *LiveDiffOption) RenderlessDiff(ctx context.Context, base, comparor Live
|
||||
m := &manifest{Name: app.Name, Kind: AppKind, Data: string(bs)}
|
||||
if appfileError != nil {
|
||||
m.Data += "Error: " + appfileError.Error() + "\n"
|
||||
return m, nil //nolint
|
||||
return m, nil // nolint
|
||||
}
|
||||
for _, policy := range af.ExternalPolicies {
|
||||
if bs, err = marshalObject(policy); err == nil {
|
||||
@@ -440,8 +441,8 @@ func generateManifest(app *v1beta1.Application, comps []*types.ComponentManifest
|
||||
Name: comp.Name,
|
||||
Kind: RawCompKind,
|
||||
}
|
||||
removeRevisionRelatedLabelAndAnnotation(comp.StandardWorkload)
|
||||
b, err := yaml.Marshal(comp.StandardWorkload)
|
||||
removeRevisionRelatedLabelAndAnnotation(comp.ComponentOutput)
|
||||
b, err := yaml.Marshal(comp.ComponentOutput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "cannot marshal component %q", comp.Name)
|
||||
}
|
||||
@@ -459,7 +460,7 @@ func generateManifest(app *v1beta1.Application, comps []*types.ComponentManifest
|
||||
comp.RevisionName = ""
|
||||
// get matched raw component and add it into appConfigComponent's subs
|
||||
subs := []*manifest{rawCompManifests[comp.Name]}
|
||||
for _, t := range comp.Traits {
|
||||
for _, t := range comp.ComponentOutputsAndTraits {
|
||||
removeRevisionRelatedLabelAndAnnotation(t)
|
||||
|
||||
tType := t.GetLabels()[oam.TraitTypeLabel]
|
||||
|
||||
@@ -56,7 +56,7 @@ type DryRun interface {
|
||||
}
|
||||
|
||||
// NewDryRunOption creates a dry-run option
|
||||
func NewDryRunOption(c client.Client, cfg *rest.Config, pd *packages.PackageDiscover, as []oam.Object, serverSideDryRun bool) *Option {
|
||||
func NewDryRunOption(c client.Client, cfg *rest.Config, pd *packages.PackageDiscover, as []*unstructured.Unstructured, serverSideDryRun bool) *Option {
|
||||
parser := appfile.NewDryRunApplicationParser(c, pd, as)
|
||||
return &Option{c, pd, parser, parser.GenerateAppFileFromApp, cfg, as, serverSideDryRun}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ type Option struct {
|
||||
// Auxiliaries are capability definitions used to parse application.
|
||||
// DryRun will use capabilities in Auxiliaries as higher priority than
|
||||
// getting one from cluster.
|
||||
Auxiliaries []oam.Object
|
||||
Auxiliaries []*unstructured.Unstructured
|
||||
|
||||
// serverSideDryRun If set to true, means will dry run via the apiserver.
|
||||
serverSideDryRun bool
|
||||
@@ -171,7 +171,7 @@ func (d *Option) ExecuteDryRun(ctx context.Context, application *v1beta1.Applica
|
||||
func (d *Option) PrintDryRun(buff *bytes.Buffer, appName string, comps []*types.ComponentManifest, policies []*unstructured.Unstructured) error {
|
||||
var components = make(map[string]*unstructured.Unstructured)
|
||||
for _, comp := range comps {
|
||||
components[comp.Name] = comp.StandardWorkload
|
||||
components[comp.Name] = comp.ComponentOutput
|
||||
}
|
||||
for _, c := range comps {
|
||||
if _, err := fmt.Fprintf(buff, "---\n# Application(%s) -- Component(%s) \n---\n\n", appName, c.Name); err != nil {
|
||||
@@ -183,7 +183,7 @@ func (d *Option) PrintDryRun(buff *bytes.Buffer, appName string, comps []*types.
|
||||
}
|
||||
buff.Write(result)
|
||||
buff.WriteString("\n---\n")
|
||||
for _, t := range c.Traits {
|
||||
for _, t := range c.ComponentOutputsAndTraits {
|
||||
traitType := t.GetLabels()[oam.TraitTypeLabel]
|
||||
switch {
|
||||
case traitType == definition.AuxiliaryWorkload:
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
@@ -46,7 +47,6 @@ import (
|
||||
|
||||
coreoam "github.com/oam-dev/kubevela/apis/core.oam.dev"
|
||||
"github.com/oam-dev/kubevela/pkg/appfile"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
@@ -113,7 +113,7 @@ var _ = BeforeSuite(func() {
|
||||
wfsd.SetNamespace(types.DefaultKubeVelaNS)
|
||||
Expect(k8sClient.Create(context.TODO(), &wfsd)).Should(BeNil())
|
||||
|
||||
dryrunOpt = NewDryRunOption(k8sClient, cfg, pd, []oam.Object{cdMyWorker, tdMyIngress}, false)
|
||||
dryrunOpt = NewDryRunOption(k8sClient, cfg, pd, []*unstructured.Unstructured{cdMyWorker, tdMyIngress}, false)
|
||||
diffOpt = &LiveDiffOption{DryRun: dryrunOpt, Parser: appfile.NewApplicationParser(k8sClient, pd)}
|
||||
})
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ PackagedWorkloadResources: null
|
||||
RevisionHash: ""
|
||||
RevisionName: ""
|
||||
Scopes: []
|
||||
StandardWorkload:
|
||||
ComponentOutput:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -35,7 +35,7 @@ StandardWorkload:
|
||||
- "1000"
|
||||
image: busybox
|
||||
name: myweb
|
||||
Traits:
|
||||
ComponentOutputsAndTraits:
|
||||
- apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
|
||||
@@ -77,7 +77,7 @@ func NewApplicationParser(cli client.Client, pd *packages.PackageDiscover) *Pars
|
||||
}
|
||||
|
||||
// NewDryRunApplicationParser create an appfile parser for DryRun
|
||||
func NewDryRunApplicationParser(cli client.Client, pd *packages.PackageDiscover, defs []oam.Object) *Parser {
|
||||
func NewDryRunApplicationParser(cli client.Client, pd *packages.PackageDiscover, defs []*unstructured.Unstructured) *Parser {
|
||||
return &Parser{
|
||||
client: cli,
|
||||
pd: pd,
|
||||
@@ -105,8 +105,6 @@ func (p *Parser) GenerateAppFile(ctx context.Context, app *v1beta1.Application)
|
||||
|
||||
// GenerateAppFileFromApp converts an application to an Appfile
|
||||
func (p *Parser) GenerateAppFileFromApp(ctx context.Context, app *v1beta1.Application) (*Appfile, error) {
|
||||
ns := app.Namespace
|
||||
appName := app.Name
|
||||
|
||||
for idx := range app.Spec.Policies {
|
||||
if app.Spec.Policies[idx].Name == "" {
|
||||
@@ -114,62 +112,32 @@ func (p *Parser) GenerateAppFileFromApp(ctx context.Context, app *v1beta1.Applic
|
||||
}
|
||||
}
|
||||
|
||||
appfile := p.newAppFile(appName, ns, app)
|
||||
appFile := newAppFile(app)
|
||||
if app.Status.LatestRevision != nil {
|
||||
appfile.AppRevisionName = app.Status.LatestRevision.Name
|
||||
appFile.AppRevisionName = app.Status.LatestRevision.Name
|
||||
}
|
||||
|
||||
var wds []*Workload
|
||||
for _, comp := range app.Spec.Components {
|
||||
wd, err := p.parseWorkload(ctx, comp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
wds = append(wds, wd)
|
||||
}
|
||||
appfile.Workloads = wds
|
||||
appfile.Components = app.Spec.Components
|
||||
|
||||
var err error
|
||||
if err = p.parseWorkflowSteps(ctx, appfile); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parseWorkflowSteps")
|
||||
if err = p.parseComponents(ctx, appFile); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parseComponents")
|
||||
}
|
||||
if err = p.parsePolicies(ctx, appfile); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parsePolicies")
|
||||
if err = p.parseWorkflowSteps(ctx, appFile); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parseWorkflowSteps")
|
||||
}
|
||||
if err = p.parseReferredObjects(ctx, appfile); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parseReferredObjects")
|
||||
if err = p.parsePolicies(ctx, appFile); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parsePolicies")
|
||||
}
|
||||
if err = p.parseReferredObjects(ctx, appFile); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parseReferredObjects")
|
||||
}
|
||||
|
||||
for _, w := range wds {
|
||||
if w == nil {
|
||||
continue
|
||||
}
|
||||
if w.FullTemplate.ComponentDefinition != nil {
|
||||
cd := w.FullTemplate.ComponentDefinition.DeepCopy()
|
||||
cd.Status = v1beta1.ComponentDefinitionStatus{}
|
||||
appfile.RelatedComponentDefinitions[w.FullTemplate.ComponentDefinition.Name] = cd
|
||||
}
|
||||
for _, t := range w.Traits {
|
||||
if t == nil {
|
||||
continue
|
||||
}
|
||||
if t.FullTemplate.TraitDefinition != nil {
|
||||
td := t.FullTemplate.TraitDefinition.DeepCopy()
|
||||
td.Status = v1beta1.TraitDefinitionStatus{}
|
||||
appfile.RelatedTraitDefinitions[t.FullTemplate.TraitDefinition.Name] = td
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return appfile, nil
|
||||
return appFile, nil
|
||||
}
|
||||
|
||||
func (p *Parser) newAppFile(appName, ns string, app *v1beta1.Application) *Appfile {
|
||||
func newAppFile(app *v1beta1.Application) *Appfile {
|
||||
file := &Appfile{
|
||||
Name: appName,
|
||||
Namespace: ns,
|
||||
Name: app.Name,
|
||||
Namespace: app.Namespace,
|
||||
|
||||
AppLabels: make(map[string]string),
|
||||
AppAnnotations: make(map[string]string),
|
||||
@@ -179,8 +147,7 @@ func (p *Parser) newAppFile(appName, ns string, app *v1beta1.Application) *Appfi
|
||||
|
||||
ExternalPolicies: make(map[string]*v1alpha1.Policy),
|
||||
|
||||
parser: p,
|
||||
app: app,
|
||||
app: app,
|
||||
}
|
||||
for k, v := range app.Annotations {
|
||||
file.AppAnnotations[k] = v
|
||||
@@ -246,10 +213,8 @@ func (p *Parser) GenerateAppFileFromRevision(appRev *v1beta1.ApplicationRevision
|
||||
|
||||
inheritLabelAndAnnotationFromAppRev(appRev)
|
||||
|
||||
app := appRev.Spec.Application.DeepCopy()
|
||||
ns := app.Namespace
|
||||
appName := app.Name
|
||||
appfile := p.newAppFile(appName, ns, app)
|
||||
ctx := context.Background()
|
||||
appfile := newAppFile(appRev.Spec.Application.DeepCopy())
|
||||
appfile.AppRevision = appRev
|
||||
appfile.AppRevisionName = appRev.Name
|
||||
appfile.AppRevisionHash = appRev.Labels[oam.LabelAppRevisionHash]
|
||||
@@ -259,62 +224,52 @@ func (p *Parser) GenerateAppFileFromRevision(appRev *v1beta1.ApplicationRevision
|
||||
}
|
||||
appfile.ExternalWorkflow = appRev.Spec.Workflow
|
||||
|
||||
var wds []*Workload
|
||||
for _, comp := range app.Spec.Components {
|
||||
wd, err := p.ParseWorkloadFromRevision(comp, appRev)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
wds = append(wds, wd)
|
||||
if err := p.parseComponentsFromRevision(appfile); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parseComponentsFromRevision")
|
||||
}
|
||||
appfile.Workloads = wds
|
||||
appfile.Components = app.Spec.Components
|
||||
if err := p.parseWorkflowStepsFromRevision(context.Background(), appfile); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parseWorkflowStepsFromRevision")
|
||||
if err := p.parseWorkflowStepsFromRevision(ctx, appfile); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parseWorkflowStepsFromRevision")
|
||||
}
|
||||
if err := p.parsePoliciesFromRevision(context.Background(), appfile); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parsePolicies")
|
||||
if err := p.parsePoliciesFromRevision(ctx, appfile); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parsePolicies")
|
||||
}
|
||||
if err := p.parseReferredObjectsFromRevision(appfile); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to parseReferredObjects")
|
||||
}
|
||||
|
||||
for k, v := range appRev.Spec.ComponentDefinitions {
|
||||
appfile.RelatedComponentDefinitions[k] = v.DeepCopy()
|
||||
}
|
||||
for k, v := range appRev.Spec.TraitDefinitions {
|
||||
appfile.RelatedTraitDefinitions[k] = v.DeepCopy()
|
||||
}
|
||||
for k, v := range appRev.Spec.WorkflowStepDefinitions {
|
||||
appfile.RelatedWorkflowStepDefinitions[k] = v.DeepCopy()
|
||||
return nil, errors.Wrap(err, "failed to parseReferredObjects")
|
||||
}
|
||||
|
||||
// add compatible code for upgrading to v1.3 as the workflow steps were not recorded before v1.2
|
||||
if len(appfile.RelatedWorkflowStepDefinitions) == 0 && len(appfile.WorkflowSteps) > 0 {
|
||||
ctx := context.Background()
|
||||
for _, workflowStep := range appfile.WorkflowSteps {
|
||||
if step.IsBuiltinWorkflowStepType(workflowStep.Type) {
|
||||
continue
|
||||
}
|
||||
if _, found := appfile.RelatedWorkflowStepDefinitions[workflowStep.Type]; found {
|
||||
continue
|
||||
}
|
||||
def := &v1beta1.WorkflowStepDefinition{}
|
||||
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStep.Type); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get workflow step definition %s", workflowStep.Type)
|
||||
}
|
||||
appfile.RelatedWorkflowStepDefinitions[workflowStep.Type] = def
|
||||
}
|
||||
|
||||
appRev.Spec.WorkflowStepDefinitions = make(map[string]*v1beta1.WorkflowStepDefinition)
|
||||
for name, def := range appfile.RelatedWorkflowStepDefinitions {
|
||||
appRev.Spec.WorkflowStepDefinitions[name] = def
|
||||
if err := p.parseWorkflowStepsForLegacyRevision(ctx, appfile); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to parseWorkflowStepsForLegacyRevision")
|
||||
}
|
||||
}
|
||||
|
||||
return appfile, nil
|
||||
}
|
||||
|
||||
// parseWorkflowStepsForLegacyRevision compatible for upgrading to v1.3 as the workflow steps were not recorded before v1.2
|
||||
func (p *Parser) parseWorkflowStepsForLegacyRevision(ctx context.Context, af *Appfile) error {
|
||||
for _, workflowStep := range af.WorkflowSteps {
|
||||
if step.IsBuiltinWorkflowStepType(workflowStep.Type) {
|
||||
continue
|
||||
}
|
||||
if _, found := af.RelatedWorkflowStepDefinitions[workflowStep.Type]; found {
|
||||
continue
|
||||
}
|
||||
def := &v1beta1.WorkflowStepDefinition{}
|
||||
if err := util.GetCapabilityDefinition(ctx, p.client, def, workflowStep.Type); err != nil {
|
||||
return errors.Wrapf(err, "failed to get workflow step definition %s", workflowStep.Type)
|
||||
}
|
||||
af.RelatedWorkflowStepDefinitions[workflowStep.Type] = def
|
||||
}
|
||||
|
||||
af.AppRevision.Spec.WorkflowStepDefinitions = make(map[string]*v1beta1.WorkflowStepDefinition)
|
||||
for name, def := range af.RelatedWorkflowStepDefinitions {
|
||||
af.AppRevision.Spec.WorkflowStepDefinitions[name] = def
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseReferredObjectsFromRevision(af *Appfile) error {
|
||||
af.ReferredObjects = []*unstructured.Unstructured{}
|
||||
for _, obj := range af.AppRevision.Spec.ReferredObjects {
|
||||
@@ -389,11 +344,11 @@ func (p *Parser) parsePoliciesFromRevision(ctx context.Context, af *Appfile) (er
|
||||
case v1alpha1.DebugPolicyType:
|
||||
af.Debug = true
|
||||
default:
|
||||
w, err := p.makeWorkloadFromRevision(policy.Name, policy.Type, types.TypePolicy, policy.Properties, af.AppRevision)
|
||||
w, err := p.makeComponentFromRevision(policy.Name, policy.Type, types.TypePolicy, policy.Properties, af.AppRevision)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
af.PolicyWorkloads = append(af.PolicyWorkloads, w)
|
||||
af.ParsedPolicies = append(af.ParsedPolicies, w)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -432,11 +387,11 @@ func (p *Parser) parsePolicies(ctx context.Context, af *Appfile) (err error) {
|
||||
af.RelatedTraitDefinitions[def.Name] = def
|
||||
}
|
||||
default:
|
||||
w, err := p.makeWorkload(ctx, policy.Name, policy.Type, types.TypePolicy, policy.Properties)
|
||||
w, err := p.makeComponent(ctx, policy.Name, policy.Type, types.TypePolicy, policy.Properties)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
af.PolicyWorkloads = append(af.PolicyWorkloads, w)
|
||||
af.ParsedPolicies = append(af.ParsedPolicies, w)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -480,7 +435,14 @@ func (p *Parser) loadWorkflowToAppfile(ctx context.Context, af *Appfile) error {
|
||||
}
|
||||
|
||||
func (p *Parser) parseWorkflowStepsFromRevision(ctx context.Context, af *Appfile) error {
|
||||
return p.loadWorkflowToAppfile(ctx, af)
|
||||
if err := p.loadWorkflowToAppfile(ctx, af); err != nil {
|
||||
return err
|
||||
}
|
||||
// Definitions are already in AppRevision
|
||||
for k, v := range af.AppRevision.Spec.WorkflowStepDefinitions {
|
||||
af.RelatedWorkflowStepDefinitions[k] = v.DeepCopy()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseWorkflowSteps(ctx context.Context, af *Appfile) error {
|
||||
@@ -488,14 +450,14 @@ func (p *Parser) parseWorkflowSteps(ctx context.Context, af *Appfile) error {
|
||||
return err
|
||||
}
|
||||
for _, workflowStep := range af.WorkflowSteps {
|
||||
err := p.parseWorkflowStep(ctx, af, workflowStep.Type)
|
||||
err := p.fetchAndSetWorkflowStepDefinition(ctx, af, workflowStep.Type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if workflowStep.SubSteps != nil {
|
||||
for _, workflowSubStep := range workflowStep.SubSteps {
|
||||
err := p.parseWorkflowStep(ctx, af, workflowSubStep.Type)
|
||||
err := p.fetchAndSetWorkflowStepDefinition(ctx, af, workflowSubStep.Type)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -505,7 +467,7 @@ func (p *Parser) parseWorkflowSteps(ctx context.Context, af *Appfile) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseWorkflowStep(ctx context.Context, af *Appfile, workflowStepType string) error {
|
||||
func (p *Parser) fetchAndSetWorkflowStepDefinition(ctx context.Context, af *Appfile, workflowStepType string) error {
|
||||
if step.IsBuiltinWorkflowStepType(workflowStepType) {
|
||||
return nil
|
||||
}
|
||||
@@ -520,36 +482,36 @@ func (p *Parser) parseWorkflowStep(ctx context.Context, af *Appfile, workflowSte
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Parser) makeWorkload(ctx context.Context, name, typ string, capType types.CapType, props *runtime.RawExtension) (*Workload, error) {
|
||||
func (p *Parser) makeComponent(ctx context.Context, name, typ string, capType types.CapType, props *runtime.RawExtension) (*Component, error) {
|
||||
templ, err := p.tmplLoader.LoadTemplate(ctx, p.client, typ, capType)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "fetch component/policy type of %s", name)
|
||||
}
|
||||
return p.convertTemplate2Workload(name, typ, props, templ)
|
||||
return p.convertTemplate2Component(name, typ, props, templ)
|
||||
}
|
||||
|
||||
func (p *Parser) makeWorkloadFromRevision(name, typ string, capType types.CapType, props *runtime.RawExtension, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
|
||||
func (p *Parser) makeComponentFromRevision(name, typ string, capType types.CapType, props *runtime.RawExtension, appRev *v1beta1.ApplicationRevision) (*Component, error) {
|
||||
templ, err := LoadTemplateFromRevision(typ, capType, appRev, p.client.RESTMapper())
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "fetch component/policy type of %s from revision", name)
|
||||
}
|
||||
|
||||
return p.convertTemplate2Workload(name, typ, props, templ)
|
||||
return p.convertTemplate2Component(name, typ, props, templ)
|
||||
}
|
||||
|
||||
func (p *Parser) convertTemplate2Workload(name, typ string, props *runtime.RawExtension, templ *Template) (*Workload, error) {
|
||||
func (p *Parser) convertTemplate2Component(name, typ string, props *runtime.RawExtension, templ *Template) (*Component, error) {
|
||||
settings, err := util.RawExtension2Map(props)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "fail to parse settings for %s", name)
|
||||
}
|
||||
wlType, err := util.ConvertDefinitionRevName(typ)
|
||||
cpType, err := util.ConvertDefinitionRevName(typ)
|
||||
if err != nil {
|
||||
wlType = typ
|
||||
cpType = typ
|
||||
}
|
||||
return &Workload{
|
||||
return &Component{
|
||||
Traits: []*Trait{},
|
||||
Name: name,
|
||||
Type: wlType,
|
||||
Type: cpType,
|
||||
CapabilityCategory: templ.CapabilityCategory,
|
||||
FullTemplate: templ,
|
||||
Params: settings,
|
||||
@@ -557,10 +519,61 @@ func (p *Parser) convertTemplate2Workload(name, typ string, props *runtime.RawEx
|
||||
}, nil
|
||||
}
|
||||
|
||||
// parseWorkload resolve an ApplicationComponent and generate a Workload
|
||||
// parseComponents resolve an Application Components and Traits to generate Component
|
||||
func (p *Parser) parseComponents(ctx context.Context, af *Appfile) error {
|
||||
var comps []*Component
|
||||
for _, c := range af.app.Spec.Components {
|
||||
comp, err := p.parseComponent(ctx, c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
comps = append(comps, comp)
|
||||
}
|
||||
|
||||
af.ParsedComponents = comps
|
||||
af.Components = af.app.Spec.Components
|
||||
setComponentDefinitions(af, comps)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setComponentDefinitions(af *Appfile, comps []*Component) {
|
||||
for _, comp := range comps {
|
||||
if comp == nil {
|
||||
continue
|
||||
}
|
||||
if comp.FullTemplate.ComponentDefinition != nil {
|
||||
cd := comp.FullTemplate.ComponentDefinition.DeepCopy()
|
||||
cd.Status = v1beta1.ComponentDefinitionStatus{}
|
||||
af.RelatedComponentDefinitions[comp.FullTemplate.ComponentDefinition.Name] = cd
|
||||
}
|
||||
for _, t := range comp.Traits {
|
||||
if t == nil {
|
||||
continue
|
||||
}
|
||||
if t.FullTemplate.TraitDefinition != nil {
|
||||
td := t.FullTemplate.TraitDefinition.DeepCopy()
|
||||
td.Status = v1beta1.TraitDefinitionStatus{}
|
||||
af.RelatedTraitDefinitions[t.FullTemplate.TraitDefinition.Name] = td
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// setComponentDefinitionsFromRevision can set related definitions directly from app revision
|
||||
func setComponentDefinitionsFromRevision(af *Appfile) {
|
||||
for k, v := range af.AppRevision.Spec.ComponentDefinitions {
|
||||
af.RelatedComponentDefinitions[k] = v.DeepCopy()
|
||||
}
|
||||
for k, v := range af.AppRevision.Spec.TraitDefinitions {
|
||||
af.RelatedTraitDefinitions[k] = v.DeepCopy()
|
||||
}
|
||||
}
|
||||
|
||||
// parseComponent resolve an ApplicationComponent and generate a Component
|
||||
// containing ALL information required by an Appfile.
|
||||
func (p *Parser) parseWorkload(ctx context.Context, comp common.ApplicationComponent) (*Workload, error) {
|
||||
workload, err := p.makeWorkload(ctx, comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties)
|
||||
func (p *Parser) parseComponent(ctx context.Context, comp common.ApplicationComponent) (*Component, error) {
|
||||
workload, err := p.makeComponent(ctx, comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -571,7 +584,7 @@ func (p *Parser) parseWorkload(ctx context.Context, comp common.ApplicationCompo
|
||||
return workload, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseTraits(ctx context.Context, workload *Workload, comp common.ApplicationComponent) error {
|
||||
func (p *Parser) parseTraits(ctx context.Context, workload *Component, comp common.ApplicationComponent) error {
|
||||
for _, traitValue := range comp.Traits {
|
||||
properties, err := util.RawExtension2Map(traitValue.Properties)
|
||||
if err != nil {
|
||||
@@ -587,10 +600,26 @@ func (p *Parser) parseTraits(ctx context.Context, workload *Workload, comp commo
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseWorkloadFromRevision resolve an ApplicationComponent and generate a Workload
|
||||
func (p *Parser) parseComponentsFromRevision(af *Appfile) error {
|
||||
var comps []*Component
|
||||
for _, c := range af.app.Spec.Components {
|
||||
comp, err := p.ParseComponentFromRevision(c, af.AppRevision)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
comps = append(comps, comp)
|
||||
}
|
||||
af.ParsedComponents = comps
|
||||
af.Components = af.app.Spec.Components
|
||||
// Definitions are already in AppRevision
|
||||
setComponentDefinitionsFromRevision(af)
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseComponentFromRevision resolve an ApplicationComponent and generate a Component
|
||||
// containing ALL information required by an Appfile from app revision.
|
||||
func (p *Parser) ParseWorkloadFromRevision(comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
|
||||
workload, err := p.makeWorkloadFromRevision(comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties, appRev)
|
||||
func (p *Parser) ParseComponentFromRevision(comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Component, error) {
|
||||
workload, err := p.makeComponentFromRevision(comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties, appRev)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -602,7 +631,7 @@ func (p *Parser) ParseWorkloadFromRevision(comp common.ApplicationComponent, app
|
||||
return workload, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseTraitsFromRevision(comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision, workload *Workload) error {
|
||||
func (p *Parser) parseTraitsFromRevision(comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision, workload *Component) error {
|
||||
for _, traitValue := range comp.Traits {
|
||||
properties, err := util.RawExtension2Map(traitValue.Properties)
|
||||
if err != nil {
|
||||
@@ -618,35 +647,35 @@ func (p *Parser) parseTraitsFromRevision(comp common.ApplicationComponent, appRe
|
||||
return nil
|
||||
}
|
||||
|
||||
// ParseWorkloadFromRevisionAndClient resolve an ApplicationComponent and generate a Workload
|
||||
// ParseComponentFromRevisionAndClient resolve an ApplicationComponent and generate a Component
|
||||
// containing ALL information required by an Appfile from app revision, and will fall back to
|
||||
// load external definitions if not found
|
||||
func (p *Parser) ParseWorkloadFromRevisionAndClient(ctx context.Context, comp common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Workload, error) {
|
||||
workload, err := p.makeWorkloadFromRevision(comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties, appRev)
|
||||
func (p *Parser) ParseComponentFromRevisionAndClient(ctx context.Context, c common.ApplicationComponent, appRev *v1beta1.ApplicationRevision) (*Component, error) {
|
||||
comp, err := p.makeComponentFromRevision(c.Name, c.Type, types.TypeComponentDefinition, c.Properties, appRev)
|
||||
if IsNotFoundInAppRevision(err) {
|
||||
workload, err = p.makeWorkload(ctx, comp.Name, comp.Type, types.TypeComponentDefinition, comp.Properties)
|
||||
comp, err = p.makeComponent(ctx, c.Name, c.Type, types.TypeComponentDefinition, c.Properties)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, traitValue := range comp.Traits {
|
||||
for _, traitValue := range c.Traits {
|
||||
properties, err := util.RawExtension2Map(traitValue.Properties)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("fail to parse properties of %s for %s", traitValue.Type, comp.Name)
|
||||
return nil, errors.Errorf("fail to parse properties of %s for %s", traitValue.Type, c.Name)
|
||||
}
|
||||
trait, err := p.parseTraitFromRevision(traitValue.Type, properties, appRev)
|
||||
if IsNotFoundInAppRevision(err) {
|
||||
trait, err = p.parseTrait(ctx, traitValue.Type, properties)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "component(%s) parse trait(%s)", comp.Name, traitValue.Type)
|
||||
return nil, errors.WithMessagef(err, "component(%s) parse trait(%s)", c.Name, traitValue.Type)
|
||||
}
|
||||
|
||||
workload.Traits = append(workload.Traits, trait)
|
||||
comp.Traits = append(comp.Traits, trait)
|
||||
}
|
||||
|
||||
return workload, nil
|
||||
return comp, nil
|
||||
}
|
||||
|
||||
func (p *Parser) parseTrait(ctx context.Context, name string, properties map[string]interface{}) (*Trait, error) {
|
||||
@@ -685,7 +714,7 @@ func (p *Parser) convertTemplate2Trait(name string, properties map[string]interf
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ValidateComponentNames validate all component names whether repeat in cluster and template
|
||||
// ValidateComponentNames validate all component names whether repeat in app
|
||||
func (p *Parser) ValidateComponentNames(app *v1beta1.Application) (int, error) {
|
||||
compNames := map[string]struct{}{}
|
||||
for idx, comp := range app.Spec.Components {
|
||||
|
||||
@@ -46,7 +46,7 @@ import (
|
||||
|
||||
var expectedExceptApp = &Appfile{
|
||||
Name: "application-sample",
|
||||
Workloads: []*Workload{
|
||||
ParsedComponents: []*Component{
|
||||
{
|
||||
Name: "myweb",
|
||||
Type: "worker",
|
||||
@@ -286,11 +286,11 @@ var _ = Describe("Test application parser", func() {
|
||||
})
|
||||
|
||||
func equal(af, dest *Appfile) bool {
|
||||
if af.Name != dest.Name || len(af.Workloads) != len(dest.Workloads) {
|
||||
if af.Name != dest.Name || len(af.ParsedComponents) != len(dest.ParsedComponents) {
|
||||
return false
|
||||
}
|
||||
for i, wd := range af.Workloads {
|
||||
destWd := dest.Workloads[i]
|
||||
for i, wd := range af.ParsedComponents {
|
||||
destWd := dest.ParsedComponents[i]
|
||||
if wd.Name != destWd.Name || len(wd.Traits) != len(destWd.Traits) {
|
||||
return false
|
||||
}
|
||||
@@ -327,7 +327,7 @@ var _ = Describe("Test application parser", func() {
|
||||
// prepare verify data
|
||||
expectedExceptAppfile = &Appfile{
|
||||
Name: "backport-1-2-test-demo",
|
||||
Workloads: []*Workload{
|
||||
ParsedComponents: []*Component{
|
||||
{
|
||||
Name: "backport-1-2-test-demo",
|
||||
Type: "webservice",
|
||||
@@ -502,14 +502,17 @@ patch: spec: replicas: parameter.replicas
|
||||
|
||||
_, err := NewApplicationParser(&mockClient, pd).GenerateAppFile(context.TODO(), &app)
|
||||
Expect(err).Should(HaveOccurred())
|
||||
Expect(err.Error() == "failed to get workflow step definition apply-application-unknown: not found").Should(BeTrue())
|
||||
Expect(err.Error()).Should(SatisfyAll(
|
||||
ContainSubstring("failed to get workflow step definition apply-application-unknown: not found"),
|
||||
ContainSubstring("failed to parseWorkflowStepsForLegacyRevision")),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
func TestParser_parseTraits(t *testing.T) {
|
||||
type args struct {
|
||||
workload *Workload
|
||||
workload *Component
|
||||
comp common.ApplicationComponent
|
||||
}
|
||||
tests := []struct {
|
||||
@@ -517,7 +520,7 @@ func TestParser_parseTraits(t *testing.T) {
|
||||
args args
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
mockTemplateLoaderFn TemplateLoaderFn
|
||||
validateFunc func(w *Workload) bool
|
||||
validateFunc func(w *Component) bool
|
||||
}{
|
||||
{
|
||||
name: "test empty traits",
|
||||
@@ -574,7 +577,7 @@ func TestParser_parseTraits(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
workload: &Workload{},
|
||||
workload: &Component{},
|
||||
},
|
||||
wantErr: assert.NoError,
|
||||
mockTemplateLoaderFn: func(ctx context.Context, reader client.Client, s string, capType types.CapType) (*Template, error) {
|
||||
@@ -585,7 +588,7 @@ func TestParser_parseTraits(t *testing.T) {
|
||||
CustomStatus: "healthy",
|
||||
}, nil
|
||||
},
|
||||
validateFunc: func(w *Workload) bool {
|
||||
validateFunc: func(w *Component) bool {
|
||||
return w != nil && len(w.Traits) != 0 && w.Traits[0].Name == "expose" && w.Traits[0].Template == "template"
|
||||
},
|
||||
},
|
||||
@@ -608,12 +611,12 @@ func TestParser_parseTraitsFromRevision(t *testing.T) {
|
||||
type args struct {
|
||||
comp common.ApplicationComponent
|
||||
appRev *v1beta1.ApplicationRevision
|
||||
workload *Workload
|
||||
workload *Component
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
validateFunc func(w *Workload) bool
|
||||
validateFunc func(w *Component) bool
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
@@ -634,7 +637,7 @@ func TestParser_parseTraitsFromRevision(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
workload: &Workload{},
|
||||
workload: &Component{},
|
||||
},
|
||||
wantErr: assert.Error,
|
||||
},
|
||||
@@ -656,7 +659,7 @@ func TestParser_parseTraitsFromRevision(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
workload: &Workload{},
|
||||
workload: &Component{},
|
||||
},
|
||||
wantErr: assert.Error,
|
||||
},
|
||||
@@ -685,10 +688,10 @@ func TestParser_parseTraitsFromRevision(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
workload: &Workload{},
|
||||
workload: &Component{},
|
||||
},
|
||||
wantErr: assert.NoError,
|
||||
validateFunc: func(w *Workload) bool {
|
||||
validateFunc: func(w *Component) bool {
|
||||
return w != nil && len(w.Traits) == 1 && w.Traits[0].Name == "expose"
|
||||
},
|
||||
},
|
||||
|
||||
@@ -34,7 +34,6 @@ import (
|
||||
"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"
|
||||
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
@@ -252,35 +251,33 @@ func verifyRevisionName(capName string, capType types.CapType, apprev *v1beta1.A
|
||||
// DryRunTemplateLoader return a function that do the same work as
|
||||
// LoadTemplate, but load template from provided ones before loading from
|
||||
// cluster through LoadTemplate
|
||||
func DryRunTemplateLoader(defs []oam.Object) TemplateLoaderFn {
|
||||
func DryRunTemplateLoader(defs []*unstructured.Unstructured) TemplateLoaderFn {
|
||||
return func(ctx context.Context, r client.Client, capName string, capType types.CapType) (*Template, error) {
|
||||
// retrieve provided cap definitions
|
||||
for _, def := range defs {
|
||||
if unstructDef, ok := def.(*unstructured.Unstructured); ok {
|
||||
if unstructDef.GetKind() == v1beta1.ComponentDefinitionKind &&
|
||||
capType == types.TypeComponentDefinition && unstructDef.GetName() == capName {
|
||||
compDef := &v1beta1.ComponentDefinition{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructDef.Object, compDef); err != nil {
|
||||
return nil, errors.Wrap(err, "invalid component definition")
|
||||
}
|
||||
tmpl, err := newTemplateOfCompDefinition(compDef)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "cannot load template of component definition %q", capName)
|
||||
}
|
||||
return tmpl, nil
|
||||
if def.GetKind() == v1beta1.ComponentDefinitionKind &&
|
||||
capType == types.TypeComponentDefinition && def.GetName() == capName {
|
||||
compDef := &v1beta1.ComponentDefinition{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(def.Object, compDef); err != nil {
|
||||
return nil, errors.Wrap(err, "invalid component definition")
|
||||
}
|
||||
if unstructDef.GetKind() == v1beta1.TraitDefinitionKind &&
|
||||
capType == types.TypeTrait && unstructDef.GetName() == capName {
|
||||
traitDef := &v1beta1.TraitDefinition{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructDef.Object, traitDef); err != nil {
|
||||
return nil, errors.Wrap(err, "invalid trait definition")
|
||||
}
|
||||
tmpl, err := newTemplateOfTraitDefinition(traitDef)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "cannot load template of trait definition %q", capName)
|
||||
}
|
||||
return tmpl, nil
|
||||
tmpl, err := newTemplateOfCompDefinition(compDef)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "cannot load template of component definition %q", capName)
|
||||
}
|
||||
return tmpl, nil
|
||||
}
|
||||
if def.GetKind() == v1beta1.TraitDefinitionKind &&
|
||||
capType == types.TypeTrait && def.GetName() == capName {
|
||||
traitDef := &v1beta1.TraitDefinition{}
|
||||
if err := runtime.DefaultUnstructuredConverter.FromUnstructured(def.Object, traitDef); err != nil {
|
||||
return nil, errors.Wrap(err, "invalid trait definition")
|
||||
}
|
||||
tmpl, err := newTemplateOfTraitDefinition(traitDef)
|
||||
if err != nil {
|
||||
return nil, errors.WithMessagef(err, "cannot load template of trait definition %q", capName)
|
||||
}
|
||||
return tmpl, nil
|
||||
}
|
||||
}
|
||||
// not found in provided cap definitions
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/crossplane/crossplane-runtime/pkg/test"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
ktypes "k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -31,7 +32,6 @@ import (
|
||||
"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"
|
||||
oamutil "github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
@@ -362,7 +362,7 @@ spec:
|
||||
TraitDefinition: traitDef,
|
||||
}
|
||||
|
||||
dryRunLoadTemplate := DryRunTemplateLoader([]oam.Object{unstrctCompDef, unstrctTraitDef})
|
||||
dryRunLoadTemplate := DryRunTemplateLoader([]*unstructured.Unstructured{unstrctCompDef, unstrctTraitDef})
|
||||
compTmpl, err := dryRunLoadTemplate(nil, nil, "myworker", types.TypeComponentDefinition)
|
||||
if err != nil {
|
||||
t.Error("failed load template of component defintion", err)
|
||||
|
||||
@@ -38,7 +38,7 @@ func TestIsNotFoundInAppRevision(t *testing.T) {
|
||||
require.True(t, IsNotFoundInAppRevision(fmt.Errorf("ComponentDefinition XXX not found in app revision")))
|
||||
}
|
||||
|
||||
func TestParseWorkloadFromRevisionAndClient(t *testing.T) {
|
||||
func TestParseComponentFromRevisionAndClient(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
cli := fake.NewClientBuilder().WithScheme(scheme).Build()
|
||||
p := &Parser{
|
||||
@@ -63,21 +63,21 @@ func TestParseWorkloadFromRevisionAndClient(t *testing.T) {
|
||||
require.NoError(t, cli.Create(ctx, cd))
|
||||
require.NoError(t, cli.Create(ctx, td))
|
||||
appRev.Spec.TraitDefinitions = map[string]*v1beta1.TraitDefinition{"internal": {}}
|
||||
_, err := p.ParseWorkloadFromRevisionAndClient(ctx, comp, appRev)
|
||||
_, err := p.ParseComponentFromRevisionAndClient(ctx, comp, appRev)
|
||||
require.NoError(t, err)
|
||||
|
||||
_comp1 := comp.DeepCopy()
|
||||
_comp1.Type = "bad"
|
||||
_, err = p.ParseWorkloadFromRevisionAndClient(ctx, *_comp1, appRev)
|
||||
_, err = p.ParseComponentFromRevisionAndClient(ctx, *_comp1, appRev)
|
||||
require.Error(t, err)
|
||||
|
||||
_comp2 := comp.DeepCopy()
|
||||
_comp2.Traits[0].Type = "bad"
|
||||
_, err = p.ParseWorkloadFromRevisionAndClient(ctx, *_comp2, appRev)
|
||||
_, err = p.ParseComponentFromRevisionAndClient(ctx, *_comp2, appRev)
|
||||
require.Error(t, err)
|
||||
|
||||
_comp3 := comp.DeepCopy()
|
||||
_comp3.Traits[0].Properties = &runtime.RawExtension{Raw: []byte(`bad`)}
|
||||
_, err = p.ParseWorkloadFromRevisionAndClient(ctx, *_comp3, appRev)
|
||||
_, err = p.ParseComponentFromRevisionAndClient(ctx, *_comp3, appRev)
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
|
||||
// ValidateCUESchematicAppfile validates CUE schematic workloads in an Appfile
|
||||
func (p *Parser) ValidateCUESchematicAppfile(a *Appfile) error {
|
||||
for _, wl := range a.Workloads {
|
||||
for _, wl := range a.ParsedComponents {
|
||||
// because helm & kube schematic has no CUE template
|
||||
// it only validates CUE schematic workload
|
||||
if wl.CapabilityCategory != types.CUECategory || wl.Type == v1alpha1.RefObjectsComponentType {
|
||||
@@ -53,7 +53,7 @@ func (p *Parser) ValidateCUESchematicAppfile(a *Appfile) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func newValidationProcessContext(wl *Workload, ctxData velaprocess.ContextData) (process.Context, error) {
|
||||
func newValidationProcessContext(c *Component, ctxData velaprocess.ContextData) (process.Context, error) {
|
||||
baseHooks := []process.BaseHook{
|
||||
// add more hook funcs here to validate CUE base
|
||||
}
|
||||
@@ -65,7 +65,7 @@ func newValidationProcessContext(wl *Workload, ctxData velaprocess.ContextData)
|
||||
ctxData.BaseHooks = baseHooks
|
||||
ctxData.AuxiliaryHooks = auxiliaryHooks
|
||||
pCtx := velaprocess.NewContext(ctxData)
|
||||
if err := wl.EvalContext(pCtx); err != nil {
|
||||
if err := c.EvalContext(pCtx); err != nil {
|
||||
return nil, errors.Wrapf(err, "evaluate base template app=%s in namespace=%s", ctxData.AppName, ctxData.Namespace)
|
||||
}
|
||||
return pCtx, nil
|
||||
|
||||
@@ -34,7 +34,7 @@ var _ = Describe("Test validate CUE schematic Appfile", func() {
|
||||
|
||||
DescribeTable("Test validate outputs name unique", func(tc SubTestCase) {
|
||||
Expect("").Should(BeEmpty())
|
||||
wl := &Workload{
|
||||
wl := &Component{
|
||||
Name: "myweb",
|
||||
Type: "worker",
|
||||
CapabilityCategory: types.CUECategory,
|
||||
|
||||
@@ -111,7 +111,7 @@ url: "https://127.0.0.1:8443/api/v1/token?val=test-token"`)
|
||||
runner, _ := newHTTPCmd(cue.Value{})
|
||||
got, err := runner.Run(®istry.Meta{Obj: reqInst.Value()})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
body := (got.(map[string]interface{}))["body"].(string)
|
||||
|
||||
@@ -162,7 +162,10 @@ func newMockHttpsServer() *httptest.Server {
|
||||
|
||||
pool := x509.NewCertPool()
|
||||
pool.AppendCertsFromPEM([]byte(decodeCert(testdata.MockCerts.Ca)))
|
||||
cert, _ := tls.X509KeyPair([]byte(decodeCert(testdata.MockCerts.ServerCrt)), []byte(decodeCert(testdata.MockCerts.ServerKey)))
|
||||
cert, err := tls.X509KeyPair([]byte(decodeCert(testdata.MockCerts.ServerCrt)), []byte(decodeCert(testdata.MockCerts.ServerKey)))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
ts.TLS = &tls.Config{
|
||||
ClientCAs: pool,
|
||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
||||
|
||||
12
pkg/builtin/http/testdata/certs.go
vendored
12
pkg/builtin/http/testdata/certs.go
vendored
@@ -17,12 +17,12 @@ limitations under the License.
|
||||
package testdata
|
||||
|
||||
var (
|
||||
_ = `LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBcHRMN21JQmdaaDVEd1FYYkJXaHRSeURGK01qaytQeStNU1Vyck5pc1EyeXF4cnphCjhEeWw5a0pRWW5oMnVYVFV1RnBzbDRhM1J5dEJaVkdrMDNQT0RXOWJIblR2QUNPZHJjMnR2WmR5ZXRXU1ZtQ2cKOHhuc3Y3WHVQS0VGb0VwakVaMDdCWjY2blFIRDg2MHFMeGFGRWtMNHk2MzU5SThWVlRBYk5RejVPQ3dmM29mUQpMN0JPL2RVNUJtRTNXTDhhVHF3SXRSa0hJeE5pWCs4OWU2Z3dCY3RHdUZLR3ZacFhGaW1VeXA1Y0crVWI2RzkyCi9KUTZJWm45dGFIZ3NFYWIvWUNwZ2U1Rkp5WVR1dzVlakhRajRYNVh3ZVRKU0tsN0UwUmZhMjl5VnM5aXdhNDQKcmVNSzVXR2hVUFl6T1o0MURGZnU1MmJnMjVPODF6QWJFSFpLUndJREFRQUJBb0lCQUNUVUJ2OFB1RGhURGhvYQp0Tk5vemxjWmdSci9IcTFvL29QUzlPVmZvQWZ5Z1hFR1dEOFk1SHFOQVRuNzVobmpGT0x0ODNNd0psM3J5ckFYCmFnL1VUUFRpVkhkUTBVSnltbWk0TTFiYmpFWlp4OGlSNUhaR2p1Rnp4SGhXQSt2ekFCUHZaZ3hEa21iKzhNZG0KdngxT0YycUVwbkF3cERHOU5MUnR2bFBqM1ZEczhVODU2c2hWeDdBdFE3RGJUWkQwdEpsQ0pzTzR5TitjL1oxOApiRzJKNDB2RWFLalVGTE9HNitScE43NEZLeGtvOFJJejZxeERQMk5VMUg1ajVVVi9tZXdRdDBsRTNqbEc5MmcvCnVwTngyK0xnYUkrMWhCR3AzV2prQlRWcWloZWxrUk5XZkNLczdXOHJtYk83V3MvK2cwcVNidnAvUjBWQWpQd0MKdGt4SENFRUNnWUVBM2s3K0hOVkNZY0YxN2k2ZTJnNTJDVHV0cDJBYzkvSUNMdVJzNGFRZlB4MkxFc2VDalJnNgovaHNsOGpLbmRDS1JQdTBJbkoxckF4NzVrZXBKZWpWcTBIbkFEN2VtcVhuMDN0UjJmb3hvbkxBOEtQMzdSSnJqClhlZ0k5NiswWUU3QUY5dWZqQVhPeXpFU3RQVkNSVDlJOFRMSlEwRFhraW56bDhVUm5aZ1RjdmtDZ1lFQXdCdFYKLzNnbFR5Z0syNTFpMS9FakdrK3I3THF5NzdCY29LVzZHTm91K0FiQ3gxalhZVE1URDNTRXVyMzBueHB6VWNkdgpIbEI1NkI2Q1JmRkdXN0o1U0tkeXI5WmhQUUtITUQ1TkZhbm00S1F4NmZmVFhubExRdnhhT2c2TFRnTDRSdjFyCjVaeUdEbDhBKzRRckpNVk1OOTZOVEY1VDB0TXRUaHlIVnpLbHR6OENnWUJ3Q3BQYjZFZUtpVHhzakthVzg4N2QKbkd4Sy9RL2NqdVkyeC8xd1E0MVQvQW5KcnkvRytMMVNzRkFSbnlIeVVER3Y2enI1NUFTNUQvVnNhdzRaUDY3VAozMmpEQXlaR0tDY1gzekRSV3VhbWdkUHdQUUZVZEZPL1VtQ2lwTFZlREpLWDg2S1hxWjJ0bnMvMHo5OVVreTZxCkVaU0tCclllL25HOHZoL0FzNUtwMFFLQmdRQzFxT1BncWFkMk8rSlFuSHE4d3UwejAwVTduYXpabFlkeDdtV1YKWExUdm04MFNuME5FU2Z6ckwzN1g3QXJuYlNiQm5YckpTc2FNcGxVQWVORFVvMmVuT1pqdENDZDVmdXVCeGxnMApkUzY3SE9tS1d1ekl1S0JmM3F3Zm5HTkV5UEFvaVRvL3JZempDQm13dmVIaWFxUFJiU1Ztb3doWEk1VUMrVjFPCktybWtGd0tCZ1FEVERDWlg1WWQ5ZUdXZG1OM3pUU2Z6YkRrRkxqZkYyYTVBK2lDL281TmoyVmpHRG4xTjRvVUwKajF0dVZLb0xoVjhVZzd0Lzc4V0V0UkRnK1p3QVZhSW84bE1zU244dDVQNFFrY2pkSDI4bHpFaTQwWHpxQkF0Lwpoalppb1pNN2ZHUmJWK29yakZSQ2tZWnNaMUdua2FrbG5Mdk4vYVRuM25HV2tEZjFaZGM0YVE9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQ==` //ca.key
|
||||
caCrt = `LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURDVENDQWZHZ0F3SUJBZ0lVR0JyQzVnODhaamxOSVlmbzVHdnFSbUhFNFY4d0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZERVNNQkFHQTFVRUF3d0pNVEkzTGpBdU1DNHhNQjRYRFRJeU1Ea3lOekE0TkRBd05sb1hEVEl6TURreApPREE0TkRBd05sb3dGREVTTUJBR0ExVUVBd3dKTVRJM0xqQXVNQzR4TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGCkFBT0NBUThBTUlJQkNnS0NBUUVBdWJyNFNXQVJneDM4dzcxanVVNFdJZ0NLZVpYKzRDR1A1WHBSVVQ0SFg2VmsKaENadGlrZmJPc0ErZUpmdWlHZVNhUDlPL0lFRUlRZXhya2lrY3F2SzNseVJ0YzNuWnhPK1NzakY3WTVsM1ROZwpGSWh3L25GMWkxdVJuMUxwc0Y2b1hWdUtGb0QvTVNCdU1rWU82Z2VRaEZnTmZNNXdEU3NsVHFRR2pIRUlPZWkyCmRYeTh6UHFNMVowREFQOUxRZHdXN1BKeG9NRWVkNTN6Y2hhYlJWNlZXTE45WkxjWURJLzhpVG5CTWlPNDdnRVQKeXo5Q1B0N0htWjM4N0JsWUQwN3REMWlkLzFieUhCSGt5Mng2YU9OOUo3dEpOU1Zna0VKRmozUVBFQzFlVUp0NgpWbFRUS1c3cGRUVTBybWFDNDBhbmgyVExnYlYwR0pKdnI4ZDVkeUhvMlFJREFRQUJvMU13VVRBZEJnTlZIUTRFCkZnUVVhKzJHeWswdE9oaFpTanNjaGQ0bnV1K1IrUEl3SHdZRFZSMGpCQmd3Rm9BVWErMkd5azB0T2hoWlNqc2MKaGQ0bnV1K1IrUEl3RHdZRFZSMFRBUUgvQkFVd0F3RUIvekFOQmdrcWhraUc5dzBCQVFzRkFBT0NBUUVBWlpHeApsSlhGUDJZVDlCaDdaYnFkWTllcEViRTNJWENzZEsvS3E2Rmx4T0RKTUJqTUIrUVM0R2QzeUMwVEU3NFZGY3lpCk5tSUxPQ2g4amJUR01QNVRuYUR0Z0pQaXpGaEZySzQwYjhnVXVqVXVZUDdJWTFlUkE1Sno5V3lSSjNFeG5RYmcKaGFkekJWQUJVdkl5RS9BUHZIeGNEKzgzcEhWd1VlS3JIcVZHU1Qxc2hmdWVDeHVnQ1pvMUg3OFVET1NNM0tsdAplQkFTbUhZc1Rtb3VTa2RVR2JwbXpvUEc0YlJyYzk3M3JycDZLcSsxZmMwQmF5NVZna2YzUXJGdFFQSE5WSVlNCnVWaTBKaHAraVpSN0MyTXVHbUFKc2U4dHRWNHBpUTY2RlBrNjdPNmZwa0NGbnp2VlYyNko2MTMwNjAwMURtOUkKTHFPajFFUVhOK29RMWJpRFFnPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=`
|
||||
serverKey = `LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBdTNOaUF5Um91aVQ3ZkpaTmhIZWt1TjgwSnh2ZVpDMStwYVVYZk00UVBoNUE1R0MyCkdLN2psMXlpUC9wQ0U4NHoyWmdSQldnalh3UWVqa0UweU1QdDdHUkxEZzVmYmhsSGNVUUZ3UDRyd3BFRjRBSDkKYVRYeVNONUxqUDFzbyswMU80bHJ1L0FPRXlibUxKYjdYSkJOc1dlZ2lqM1dYWlR3NWpYeWFjWWxwT2ZKVE1ObQpQQ0thOHpRNlVMNk1QUmZFaERGNHB4SXhnUTVuaFMxcUcxWUtqUkUycTdkRU95R0o3cFUrT3Vjdm83dzRTSlNpCkdRUDFteVRiVGV0YkxXZ3h0N2tqVUlxRVZFNERHU0h1TUszeks3V2t2bzVrcDRBVytCYjZkRk96Ulg5OVFWN08KM0pZV1U3eGVWSm5zZHFpVXh6d0Z2WjA2ZEtWeCtlOEswK0RGUFFJREFRQUJBb0lCQURvMVgwYzRoQ2pobVJLYwpIZUEzd3ZnQm45RlJMeU1PbVpoWWhzMmpzNW1HallJZG9nNVNLS3gxQUpFN1prOStKYzI1RWZnSzJZa0UzM1F2ClBYUG1tN2hmZ0lzUjNZSno2U0o4REFsZEpEdWNDeVgvbURDV3B2RUh6cEF1bGhEbGRUVlN2QmkxTjdtc3g2Y3IKRDAwMEpsd2pvTStzMmlkZk85dFEvMERuWGdNeHlvYUJSVjd0OGF6enJVaFYxM01xenF5eHcvbjI5dDFXcld0ZQpjaTNkN3g4RWx3Yk5YNFJpOUk2dk9lZktOSDN4bEUrNWpjdlJSWmR4ajhXaHUzMlhhcTA1SG0za0h4SGw2ODM4Cm12aDlyeU9Ec3NTTm5RS0R3VVRYRjdsYXZFMDJyaW9scmoyRUJNcUErVE1jQ2ZvTnJ4elNGajVtVUxDamxGNWsKQnZxRVVpVUNnWUVBNndyYTVGR3U2MUZsTjlqY0p2dVNiNmlTUHN3RTczWE5pOWx1anhxSmFTeHVkSDFnMk9GTgp4WUNIZFR2WFhsdTc3TThadHVmMGFUMUM3UWQxcU8vVngyVFJTSVpOTG95RzJpRHBEL0RXdlBwKzBCTWN3K0orCitKTEpsWFlnbnZYQjlXRmk5eFljWnZDblR2eDJwS0ZFV1M4bTkvbDBQQUU4eUhDdVUxd1VPM2NDZ1lFQXpDb3YKdFIrVkp0dis2STRQV3o0bGQ1VTE0UWwrdk1hV3pXNDhHWnNsSm8zdjducnFPS2piU2xjakgrc3NNVldjYVprVQp0TFRRbFljcWFOdUJONkJydEtXQTVlSi9mV0VyVlF4azRpa0o4c3BLL2VCSTBGcnRPSnAxSm41amc0TTIvYmdvCjdBYUFHTDUvbjFNOTBscmNpZHNRYkg2TlhNN29JOTZjU2ZKQkNlc0NnWUVBdkNrdmZOS0xkcVR0bzl5K3VaSngKODJOKzJEalp4cDJIRkdyWFlFWjlOSzQyS3Bsb201Y2FmSDdkY2hPYTRWWU14cEl3NHNVa1c4K0lNVnJrYlg2NgpwR3BvUkdnSGg3bEdCMytMTkpDNFNBYzgxL1JFOWVmdmY2MTdKV1N3enJDdE9uUmhGcThqdzZEcVA0aEtycGJQCnNablcxM05qQXRwMnYzdTlnc3hYQWhjQ2dZQXRnR0Z0am9KaFRMcDgvZHd5UzZGeUMxRWN2RThBcDRuSWN2NzEKL2Z2RG9mS05SZHVaa1JoK2N2a2pEZmlsYmgwVDg4Z0hsaHkrbG9jL0kxeWpGeCtwL1JEREt6MmFwZU5RYXhpNAp4c2l1MGFMdy9lRjhmaWRNYkRBYnlpTkhsaURWWHd2UHZvc2grS0xjMFdKLzFUdzloUk1kK3Y1cVpycVo4KzBGCkZmYWt6UUtCZ1FDWk5DT3huWHlYQ2JYZ2RCY0txbE84L3BoWXBFOVVDMS81WktBMm1icng3ejBFdVdyR2pLNjUKU09QNDVQcithUDBTa3hTMll2QyttM3dCU0dJZU93QWEvb1dMY0dmbmdUbUpoMHNiYVJ1OXR5Y1QrR2hZemlGawp3ajV4TENBTzdFLzFKT3VkaGgramtwdGVMMVJiSUh2eXRwU3ZiN0VtUUVIbytOQWxBMHFPQkE9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=`
|
||||
serverCrt = `LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKakNDQWc2Z0F3SUJBZ0lVRHd3UklLMnRLVlVVMHJlZXF3U3htZVhEQWVNd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZERVNNQkFHQTFVRUF3d0pNVEkzTGpBdU1DNHhNQjRYRFRJeU1Ea3lOekE0TkRJeU5Wb1hEVEl6TURreQpOekE0TkRJeU5Wb3dLekVSTUE4R0ExVUVDZ3dJUzNWaVpWWmxiR0V4RmpBVUJnTlZCQU1NRFNvdWEzVmlaWFpsCmJHRXVhVzh3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQzdjMklESkdpNkpQdDgKbGsyRWQ2UzQzelFuRzk1a0xYNmxwUmQ4emhBK0hrRGtZTFlZcnVPWFhLSS8ra0lUempQWm1CRUZhQ05mQkI2TwpRVFRJdyszc1pFc09EbDl1R1VkeFJBWEEvaXZDa1FYZ0FmMXBOZkpJM2t1TS9XeWo3VFU3aVd1NzhBNFRKdVlzCmx2dGNrRTJ4WjZDS1BkWmRsUERtTmZKcHhpV2s1OGxNdzJZOElwcnpORHBRdm93OUY4U0VNWGluRWpHQkRtZUYKTFdvYlZncU5FVGFydDBRN0lZbnVsVDQ2NXkranZEaElsS0laQS9XYkpOdE42MXN0YURHM3VTTlFpb1JVVGdNWgpJZTR3cmZNcnRhUytqbVNuZ0JiNEZ2cDBVN05GZjMxQlhzN2NsaFpUdkY1VW1leDJxSlRIUEFXOW5UcDBwWEg1Cjd3clQ0TVU5QWdNQkFBR2pXVEJYTUI4R0ExVWRJd1FZTUJhQUZHdnRoc3BOTFRvWVdVbzdISVhlSjdydmtmankKTUFrR0ExVWRFd1FDTUFBd0N3WURWUjBQQkFRREFnVHdNQndHQTFVZEVRUVZNQk9DQzJ0MVltVjJaV3hoTG1sdgpod1IvQUFBQk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ1Y2S3VjTmNKdGVMelpNQW1acE9CR0Y0NWZJVGVrCnRDeUZPMGRXWVRabDgzRXlSbWtCd1hSQzJoekZSQ3RaMU5jY2hGNE5SaVhMbWIwM0FnTGhRRGxUR09PN3hlNFcKVUF4MjRtdlNteW05a3ljZGIyUUhqZ2xzRHJVS040QWJuRWpoYzladWxTeVNnVG15YTl2bEh5SHBoZ3V0YUhSQgpKNkVTWHJlYzUwZUxtSC9sSjkyTEwwV01JNW4rd05lajdyTkltbktQeWZ5dUhhaXdmUlZzeVJ1ZXZETWJhSXdpCmhVNmhFOXZGTEkwa0hKaEdYa05ZOEFWbTFoYXhyWGp5Q2xwaWlsQ04xcnV1U3QzYUplN2NpUkVCL08xR2JEeGwKaFQxMUtnMTZzMEJWZHZjL2lzaVZ5SVZTQmozdVRDRCtQWStaMjUzWUc1cnd3U2xxWUlWa2QzdFkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=`
|
||||
clientKey = `LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBdTNOaUF5Um91aVQ3ZkpaTmhIZWt1TjgwSnh2ZVpDMStwYVVYZk00UVBoNUE1R0MyCkdLN2psMXlpUC9wQ0U4NHoyWmdSQldnalh3UWVqa0UweU1QdDdHUkxEZzVmYmhsSGNVUUZ3UDRyd3BFRjRBSDkKYVRYeVNONUxqUDFzbyswMU80bHJ1L0FPRXlibUxKYjdYSkJOc1dlZ2lqM1dYWlR3NWpYeWFjWWxwT2ZKVE1ObQpQQ0thOHpRNlVMNk1QUmZFaERGNHB4SXhnUTVuaFMxcUcxWUtqUkUycTdkRU95R0o3cFUrT3Vjdm83dzRTSlNpCkdRUDFteVRiVGV0YkxXZ3h0N2tqVUlxRVZFNERHU0h1TUszeks3V2t2bzVrcDRBVytCYjZkRk96Ulg5OVFWN08KM0pZV1U3eGVWSm5zZHFpVXh6d0Z2WjA2ZEtWeCtlOEswK0RGUFFJREFRQUJBb0lCQURvMVgwYzRoQ2pobVJLYwpIZUEzd3ZnQm45RlJMeU1PbVpoWWhzMmpzNW1HallJZG9nNVNLS3gxQUpFN1prOStKYzI1RWZnSzJZa0UzM1F2ClBYUG1tN2hmZ0lzUjNZSno2U0o4REFsZEpEdWNDeVgvbURDV3B2RUh6cEF1bGhEbGRUVlN2QmkxTjdtc3g2Y3IKRDAwMEpsd2pvTStzMmlkZk85dFEvMERuWGdNeHlvYUJSVjd0OGF6enJVaFYxM01xenF5eHcvbjI5dDFXcld0ZQpjaTNkN3g4RWx3Yk5YNFJpOUk2dk9lZktOSDN4bEUrNWpjdlJSWmR4ajhXaHUzMlhhcTA1SG0za0h4SGw2ODM4Cm12aDlyeU9Ec3NTTm5RS0R3VVRYRjdsYXZFMDJyaW9scmoyRUJNcUErVE1jQ2ZvTnJ4elNGajVtVUxDamxGNWsKQnZxRVVpVUNnWUVBNndyYTVGR3U2MUZsTjlqY0p2dVNiNmlTUHN3RTczWE5pOWx1anhxSmFTeHVkSDFnMk9GTgp4WUNIZFR2WFhsdTc3TThadHVmMGFUMUM3UWQxcU8vVngyVFJTSVpOTG95RzJpRHBEL0RXdlBwKzBCTWN3K0orCitKTEpsWFlnbnZYQjlXRmk5eFljWnZDblR2eDJwS0ZFV1M4bTkvbDBQQUU4eUhDdVUxd1VPM2NDZ1lFQXpDb3YKdFIrVkp0dis2STRQV3o0bGQ1VTE0UWwrdk1hV3pXNDhHWnNsSm8zdjducnFPS2piU2xjakgrc3NNVldjYVprVQp0TFRRbFljcWFOdUJONkJydEtXQTVlSi9mV0VyVlF4azRpa0o4c3BLL2VCSTBGcnRPSnAxSm41amc0TTIvYmdvCjdBYUFHTDUvbjFNOTBscmNpZHNRYkg2TlhNN29JOTZjU2ZKQkNlc0NnWUVBdkNrdmZOS0xkcVR0bzl5K3VaSngKODJOKzJEalp4cDJIRkdyWFlFWjlOSzQyS3Bsb201Y2FmSDdkY2hPYTRWWU14cEl3NHNVa1c4K0lNVnJrYlg2NgpwR3BvUkdnSGg3bEdCMytMTkpDNFNBYzgxL1JFOWVmdmY2MTdKV1N3enJDdE9uUmhGcThqdzZEcVA0aEtycGJQCnNablcxM05qQXRwMnYzdTlnc3hYQWhjQ2dZQXRnR0Z0am9KaFRMcDgvZHd5UzZGeUMxRWN2RThBcDRuSWN2NzEKL2Z2RG9mS05SZHVaa1JoK2N2a2pEZmlsYmgwVDg4Z0hsaHkrbG9jL0kxeWpGeCtwL1JEREt6MmFwZU5RYXhpNAp4c2l1MGFMdy9lRjhmaWRNYkRBYnlpTkhsaURWWHd2UHZvc2grS0xjMFdKLzFUdzloUk1kK3Y1cVpycVo4KzBGCkZmYWt6UUtCZ1FDWk5DT3huWHlYQ2JYZ2RCY0txbE84L3BoWXBFOVVDMS81WktBMm1icng3ejBFdVdyR2pLNjUKU09QNDVQcithUDBTa3hTMll2QyttM3dCU0dJZU93QWEvb1dMY0dmbmdUbUpoMHNiYVJ1OXR5Y1QrR2hZemlGawp3ajV4TENBTzdFLzFKT3VkaGgramtwdGVMMVJiSUh2eXRwU3ZiN0VtUUVIbytOQWxBMHFPQkE9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=`
|
||||
clientCrt = `LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURKakNDQWc2Z0F3SUJBZ0lVRHd3UklLMnRLVlVVMHJlZXF3U3htZVhEQWVNd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZERVNNQkFHQTFVRUF3d0pNVEkzTGpBdU1DNHhNQjRYRFRJeU1Ea3lOekE0TkRJeU5Wb1hEVEl6TURreQpOekE0TkRJeU5Wb3dLekVSTUE4R0ExVUVDZ3dJUzNWaVpWWmxiR0V4RmpBVUJnTlZCQU1NRFNvdWEzVmlaWFpsCmJHRXVhVzh3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQzdjMklESkdpNkpQdDgKbGsyRWQ2UzQzelFuRzk1a0xYNmxwUmQ4emhBK0hrRGtZTFlZcnVPWFhLSS8ra0lUempQWm1CRUZhQ05mQkI2TwpRVFRJdyszc1pFc09EbDl1R1VkeFJBWEEvaXZDa1FYZ0FmMXBOZkpJM2t1TS9XeWo3VFU3aVd1NzhBNFRKdVlzCmx2dGNrRTJ4WjZDS1BkWmRsUERtTmZKcHhpV2s1OGxNdzJZOElwcnpORHBRdm93OUY4U0VNWGluRWpHQkRtZUYKTFdvYlZncU5FVGFydDBRN0lZbnVsVDQ2NXkranZEaElsS0laQS9XYkpOdE42MXN0YURHM3VTTlFpb1JVVGdNWgpJZTR3cmZNcnRhUytqbVNuZ0JiNEZ2cDBVN05GZjMxQlhzN2NsaFpUdkY1VW1leDJxSlRIUEFXOW5UcDBwWEg1Cjd3clQ0TVU5QWdNQkFBR2pXVEJYTUI4R0ExVWRJd1FZTUJhQUZHdnRoc3BOTFRvWVdVbzdISVhlSjdydmtmankKTUFrR0ExVWRFd1FDTUFBd0N3WURWUjBQQkFRREFnVHdNQndHQTFVZEVRUVZNQk9DQzJ0MVltVjJaV3hoTG1sdgpod1IvQUFBQk1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ1Y2S3VjTmNKdGVMelpNQW1acE9CR0Y0NWZJVGVrCnRDeUZPMGRXWVRabDgzRXlSbWtCd1hSQzJoekZSQ3RaMU5jY2hGNE5SaVhMbWIwM0FnTGhRRGxUR09PN3hlNFcKVUF4MjRtdlNteW05a3ljZGIyUUhqZ2xzRHJVS040QWJuRWpoYzladWxTeVNnVG15YTl2bEh5SHBoZ3V0YUhSQgpKNkVTWHJlYzUwZUxtSC9sSjkyTEwwV01JNW4rd05lajdyTkltbktQeWZ5dUhhaXdmUlZzeVJ1ZXZETWJhSXdpCmhVNmhFOXZGTEkwa0hKaEdYa05ZOEFWbTFoYXhyWGp5Q2xwaWlsQ04xcnV1U3QzYUplN2NpUkVCL08xR2JEeGwKaFQxMUtnMTZzMEJWZHZjL2lzaVZ5SVZTQmozdVRDRCtQWStaMjUzWUc1cnd3U2xxWUlWa2QzdFkKLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=`
|
||||
_ = "LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQktnd2dnU2tBZ0VBQW9JQkFRQytxS2xxbUZXZVhLMmYKU1EwN1BYbmorbVZUTzVndXlhRFhiNU1UZUo2SFhQZTUxKzFrU01ZY3hSM3NCMFlKdkdFSFY0Q1R1Y0s1M0FrdgppU1lRbHMxTnJBL0E4OUlRZDIrWDVXRG81V0h1d3h2VWEvbkFWQVM3cFZZRVZDTlVydHRCKzJsc0J3YysxR2J6Cm4wMmxONFEvc2hES0JUSm1ja2xRTTFvZlI3Q2oyREFGOGl4TlVGRjYvMUZJYkJPVDliU3JBL1M1aFhVeDlTYzEKenJrVjdkbmp4a1hKR2pOdThBcTcwZWQ2cGFPWFRmOW9CM2I0UXh3bEdocXRyMTkvYzFTNVhSakJnN3I4MFFKOQpCcXBqMTFzdG94Qy9lNG03YkdMMWZ6UGtBdlZwdWNibnNxYmQza0hZSWR6QVlaN2M1RllsR2NicTFCaGlHbVJrCjduVDdLWWM5QWdNQkFBRUNnZ0VBSzlnZmRacm9mWTEwZzkvSndpakdBZzVRQk03OGxTM2E1aEFMYzN2V2dPeDUKTDJ5ZmMrTmtZN05VeVRWMi9zQXFWQVRrVlpSdldreG1kRjhHdU9Qay9JcW42TWhwTTA0MEJHdEVXT3AvRmVnYQpXMFFsWC93eVJuQ2tFa1REQnpOYXlwYWxUS2xsR2liQU1pQWRPL1JEWGw1MWkrK2NBb0VmcU9qV1BjRS90cjJXCjllbkFhWlgyS0pyVGNoajB2TEE0TitJVGI0YzNkMDhEemhEcCtzWGpDVlJhb1U5cE1WN1cyRmtaeW5IUEVHa0gKcWNkT0lwVmRITkVPajNhNDN5cStUb29jSWFoRlI2VkVmVGxvcEwrb1ZsZ1dNUW9tWEdDaG1pbFBTK0V0dWxHbwo2U2dSU1lKODhSTXMrZjdCUm1mMG1pNmlVdDFScENXWGlpTnRDTk1VNVFLQmdRRDhIL2RkMDZuWHY5V04xbWdaCkozNHg0K2hxTTNsTGVDZmNCVlF0NGFWRnoyVFRVUXB4cFFQRWpRUldxaDk0djJzemlyUTBnWWdGS2pmQUw2MVAKUlBmaTBmQU5YMEl3OExYc053SGM2NTdkRGJvQmZjUnRlYTNzQ2NuRlRIcC9SMU9RTVI2Q0x3WkRhR0pBM1E4NwpZMW1OUHhtaGFIY1A1bk5mVUlWT3d2ajRHd0tCZ1FEQmx0aDR4aFVHeG9LZUpSUHl0ODA1b2hicVdaRCs1UDFsCm1nVGxhQmdJOFFJMHNoWC8xK0tXbkE4L3pEdTk3SFJtdjZJL1NneG9mbmxTTFZYaWlZcjJXNnhCaGVMbzZzQ2kKQXR0WFpUbVVEY3U3Y2I4aldSNERPeFpIcC93VG4yQ3NHNy9PdEtnbkpKM0JJczNYRko5d25sVGRqQVNHcnR5dgpUYjF1cFFramh3S0JnRXJGZ0NzSFZ0dHhQUGd2bWZlN3lxVXBIZ2hBODd2NkNuZ3A3R2tlL2xEUnpPa09vN1pJClpmR29rSnpUSHpwRUtwckNpK2IyYzB4MDFNdmVWOXVtYkkyTURWRXA2d3R3bDhOU0hPOVR3VzExWUxDSWgvU2YKbllEZTlrUFpCb3N3c0F1WFJhRCtLVEZjaDZjTTZET0lwMHBJYUdXQ0FhMXBmdFhKbjM5WU8xWDVBb0dCQUpvTgo2WnhLdlliVHlEUURlNWxtalNsMUJObGZoMVJnZEFvN2cvUHZYMWtXT2RRbmQveE9GMklWTk1sblJJK0NNS3RuCmlyemt0M1VjV0gxOTJGL2JacnRmL25keURUMmZPc1p5a1l3OTRKRWlYV09BUkVQajhrOU40UkFLN1QzTVVna0UKV0NJdGY3Y09tMytMcTlTaDg3T1NQQ1RGL1FBVS9VZUFET1NVN3UzWEFvR0JBTXduaDJHcDRyMTFpLzA0OUZKVwpVVjBTZ3NTSng2U1NkU3pDNklZeS8ySlN4aVpxZUdtODR0aGRDYzFiWnpHNDhiSUZhNHQwNUEwU2E2QTRlM2VLCmpFK1ZRNVRuUFlOOS9MMXNFdThNN0Zub1EyRFJZT3ZPQTk2K3R3aURBT0FwT2dxdmNWekhLU0RYUDRJNFVHeGYKUmRtNUNyTFlsOXI3Tmo5dkZJQ050UGRYCi0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K" // ca.key
|
||||
caCrt = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURDRENDQWZBQ0NRREQ2WFQ1T0hOaWR6QU5CZ2txaGtpRzl3MEJBUXNGQURCRk1Rc3dDUVlEVlFRR0V3SkQKVGpFUU1BNEdBMVVFQ0F3SFFtVnBhbWx1WnpFUU1BNEdBMVVFQnd3SFFtVnBhbWx1WnpFU01CQUdBMVVFQXd3SgpNVEkzTGpBdU1DNHhNQ0FYRFRJek1Ea3hPVEF6TWpneU4xb1lEekl4TWpNd09ESTJNRE15T0RJM1dqQkZNUXN3CkNRWURWUVFHRXdKRFRqRVFNQTRHQTFVRUNBd0hRbVZwYW1sdVp6RVFNQTRHQTFVRUJ3d0hRbVZwYW1sdVp6RVMKTUJBR0ExVUVBd3dKTVRJM0xqQXVNQzR4TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQwpBUUVBdnFpcGFwaFZubHl0bjBrTk96MTU0L3BsVXp1WUxzbWcxMitURTNpZWgxejN1ZGZ0WkVqR0hNVWQ3QWRHCkNieGhCMWVBazduQ3Vkd0pMNGttRUpiTlRhd1B3UFBTRUhkdmwrVmc2T1ZoN3NNYjFHdjV3RlFFdTZWV0JGUWoKVks3YlFmdHBiQWNIUHRSbTg1OU5wVGVFUDdJUXlnVXlabkpKVUROYUgwZXdvOWd3QmZJc1RWQlJldjlSU0d3VAprL1cwcXdQMHVZVjFNZlVuTmM2NUZlM1o0OFpGeVJvemJ2QUt1OUhuZXFXamwwMy9hQWQyK0VNY0pSb2FyYTlmCmYzTlV1VjBZd1lPNi9ORUNmUWFxWTlkYkxhTVF2M3VKdTJ4aTlYOHo1QUwxYWJuRzU3S20zZDVCMkNIY3dHR2UKM09SV0pSbkc2dFFZWWhwa1pPNTAreW1IUFFJREFRQUJNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUI2Vm1xbApBVEFuWFBpZXdvUS9SOGNaU2wzSHRHVEk5OWJwYjF1NVlxWnllRTFjZjBOY3pRR29EOGFUUW9odWRzUnd2by96ClVkc2R1a3JyT2crTGlRMW1NZTNBYkN6WGVxOStOT1pScFdJcVVtRW1GeFNDcjYwbGRIekpvdmc1ZkM1eWVYbUUKQkJaRmpvQm45SXBzOUtpRUgvajk3Z25JR3FlQnkxVm1rZzFKTkR4eUZaVlVaYTZEVm02RzQwMVVZWjNra3FsVQp4RGRrVFpVeUxSZzNOcGE2SkliQmdwK3JoZ05nLzkwdmZFTlE2dHR1R3pOVWxQYnFaM3ViM1M3eGRDQXhnWXFkCnJtK1pxb29sblRUYzhIbnI0UUV6ZTBBdVBsd3RUV0VhdENrS0VqOEg3WHBnelpid3JoMjFDZEdCYjlMZlVMQTAKcjN1SHhCdi9oZC9yc0xJQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg=="
|
||||
serverKey = "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBb0o1Tzl0bHVzTW5OaTVNQVNwYklDRWVyYnpUc1JDNmNKZ1R3czBkK3l2bTVnT1ZBCnVkU1RkaHJ3NG1URjNZaVJ2SHF2NWhiRWtBKzAvNTRaVGtXQ1hXSi9NOXpGMTIvZlJPQU9wWDBZTmlsNi9kSEQKeUhTbXB4R3FtUkpwRzVzc1ltc0dFQndMRzN5MVJmN2ZmQ3EwWkpiUzRldzJNRmxDejZuM095c3I5V1ExT0VFNApJNXJMYUhvOHdoekhJbVdXS3R6N2tHcWpscWtJU0ZSdThyUVROaVhlMTY3WUZhdUNiUU02eEZiUTdyV29VM3JOCmswVkgwQUs3QVp3Y0xBYTQ0QkpEcmdZSGJHM3U1Q0I1YnVKdnF0SUtBa09nUWhBb3RWY0g2WjBFNGhHb0hhZHkKdEdaYVRPN2pQdnUrT29CVGZ3dUd4UERVZ3hqdkZuaUVqNWk2aVFJREFRQUJBb0lCQUN6OVN0Yi8vbTVNaUdPQgpFSUxVQzBHdWVZbVR4RjR3eEJJdUxoRzVnLzFzeDVZZ0lPb3NiZ1dWOUVVbHZ2cVhoMkxJNXI1SFFGV3Q0Si84Cjg4K2x6cWREc0tlaFBsVmpBNkh5TklnTUt4ejRyM2VyS3ZEYUk5Z0dMY2ZralVaclI1cGxxZlFYTnRGRE5DOWYKL2M5MDBzU2VMb0dUdlhYN2VxaGFUbUxuYTgrM0NVUEd1RVNPWDk4NHRCS1FKTWlBeFhhSXFIemszZ2w0OEZBNApSdjlidnJoeU5nR2FRTHFUZ2lDMzM3a1l0TU1LaEk3M3FYbmtwdmgxeVZZOUhiOU5ibk5NL25KbmxRMzE3eGhrCm04VDFORGVUblBXZzg2Y20xYWRKa3E1MG9ORVYxbVZWOVdHS293RmNRSlBHdWhXNTJreEVzSm9JM1RWMkl4NkwKZkMyVFR4RUNnWUVBejdiSFhUVGpVa3RnVzd0YmZXbEsyMWMydVQvdWNteTBGZ01rTll3WnRKS0c4bmdyUlRTdApTV0pnV1BLbThwVGpjV1FTeFg4Q1dWMVYyUEdZdTVSa1Y0S3p3RmY3K0tNNWZuMzArSkc2Z0t1Q0FqNFlReVpCCk1EaWtQTDJtZzB0SEtIVDRNaWRYdy8xcW1nbExxZE9HWEpQbkhnT0FiajM0Um1vRGVLQU9WOVVDZ1lFQXhmVFYKb1h5UURvaG5tNTJCR3ZmaFFxT1hVcTNLV0NheG9qOTloWmREVGxXREl5ZDJmUFZ2SGVvRWRCdjBtRGpIc1BQawp6NWR5UEtkTHE3NXo2elRCMit3MVI0RDJxcnQvRnRtQkpDak1KNmxYRkZCaFNaeDJ6eDltSW9wdEkwNTgyMHNUCm1FM01vWEJ6NXBYMjEzN1BkVGp4OFJlTC9wZjVTRUlMS1VwWkJlVUNnWUFLeTRjRTh4QzFZREY3MHZyb1E2YWUKUzZRT2NLSWwxRHh2d0c0TFVtS3JuY25ocEJrcm1aYy83eHJ1eEgya3NkUTRPbWszVm1oNjJIenpyMnF1cFFHcQpBcUx3NWlHMFJGZGltWTAzdGVzcGNNQnErV3N0WWptVkZmeURJNkFaeHJuR0FuNDdyUXZFcGRENmZHMHdRRXdGClY3SjFQdDFYM1dTZjFEYWwrRHVHbVFLQmdRQ1E0R3NwVU55dGhpOHR1TXd3VEpKVUR4NUVxR1NhdDFieUE3MTkKOUFLU1pnc2Z3MVg0aGpmWWtOakprVndsdkFpSi9UWE1xRzQyN2NsMzNGOUNHTTU0Z2h0TVJacEJ3ZzkxVGFJeQpNSm1adlZtNXlFb3JjWk9TYXN4NUl3NVU5TEIwWGpIdEdhTlYwOU0vUXludzlTSW9ESkVsZmJJN2xrWWZHQmJMCkZWcXA4UUtCZ0NCVEdpd1ZsOXJkU0tLdXFUeXVSVmt0ZXFVOUtERTJ2K1BSVStyT3RQQ3pyVEwzKzdmaURzZDQKUE1iZUVQTWRlYk9oMzRaUFgxYlg4UTIwUlA3dmRVS3d1Y25QaE9kQ2NabG00UlRxa0o2L1RVZ2N6VmFHWDV6dwpITml1cFBXZlZGcnEzVnBkc3c4RjBpN1M2WllqNzBiSUFNMFF5V1FtWk9PaVhhanJlMllSCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg=="
|
||||
serverCrt = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURzRENDQXBpZ0F3SUJBZ0lKQUlkVDl3UHIrTlJJTUEwR0NTcUdTSWIzRFFFQkN3VUFNRVV4Q3pBSkJnTlYKQkFZVEFrTk9NUkF3RGdZRFZRUUlEQWRDWldscWFXNW5NUkF3RGdZRFZRUUhEQWRDWldscWFXNW5NUkl3RUFZRApWUVFEREFreE1qY3VNQzR3TGpFd0lCY05Nak13T1RFNU1EWXlPVE15V2hnUE1qRXlNekE0TWpZd05qSTVNekphCk1GZ3hDekFKQmdOVkJBWVRBa05PTVJBd0RnWURWUVFJREFkQ1pXbHFhVzVuTVJBd0RnWURWUVFIREFkQ1pXbHEKYVc1bk1SRXdEd1lEVlFRS0RBaExkV0psVm1Wc1lURVNNQkFHQTFVRUF3d0pNVEkzTGpBdU1DNHhNSUlCSWpBTgpCZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUFvSjVPOXRsdXNNbk5pNU1BU3BiSUNFZXJielRzClJDNmNKZ1R3czBkK3l2bTVnT1ZBdWRTVGRocnc0bVRGM1lpUnZIcXY1aGJFa0ErMC81NFpUa1dDWFdKL005ekYKMTIvZlJPQU9wWDBZTmlsNi9kSER5SFNtcHhHcW1SSnBHNXNzWW1zR0VCd0xHM3kxUmY3ZmZDcTBaSmJTNGV3MgpNRmxDejZuM095c3I5V1ExT0VFNEk1ckxhSG84d2h6SEltV1dLdHo3a0dxamxxa0lTRlJ1OHJRVE5pWGUxNjdZCkZhdUNiUU02eEZiUTdyV29VM3JOazBWSDBBSzdBWndjTEFhNDRCSkRyZ1lIYkczdTVDQjVidUp2cXRJS0FrT2cKUWhBb3RWY0g2WjBFNGhHb0hhZHl0R1phVE83alB2dStPb0JUZnd1R3hQRFVneGp2Rm5pRWo1aTZpUUlEQVFBQgpvNEdOTUlHS01GOEdBMVVkSXdSWU1GYWhTYVJITUVVeEN6QUpCZ05WQkFZVEFrTk9NUkF3RGdZRFZRUUlEQWRDClpXbHFhVzVuTVJBd0RnWURWUVFIREFkQ1pXbHFhVzVuTVJJd0VBWURWUVFEREFreE1qY3VNQzR3TGpHQ0NRREQKNlhUNU9ITmlkekFKQmdOVkhSTUVBakFBTUJ3R0ExVWRFUVFWTUJPQ0MydDFZbVYyWld4aExtbHZod1IvQUFBQgpNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUFyc0owQ01aWUtkRWZKRHFFYlhicVlLRkJOMHdNTnhUSVZBMmdWCldTVkYxOEh3UC9UaEFOUUZQbHlKdVhKc2xETnBLdkpMTCtybHVpZnUxSHNhaWRMUk9uZDhQUG0yWUpHZWJIWk0KYi8rRW4zT3ZaQks5UmFNemJxWDBaY0NOeGNIVkMrLzNvbjVhb0VDekNwMUpsYUU0amNtRkJ0US93ZjJPMkkwTgpBdUJPYTBxMnQyNXAwdDFUQldwVkNnaGxocXpuME5rc2VERTdIUzI1WGNpU0YzZkNSUnNNS2QrclNuOHcxc3NYCnE4RkI2R09MQ1lTS3hXaElzV3IxNmVhZTBXYWFNUldYSTMvQ0JVR0hUZ05sektnb2VVUTVKdVNqL2VNdDZhTUMKclpoTWVhRVpobXhkMGVqZHRJOFcvT1YvUXhxbTdDSTdjcGowU0hrNC9MbS94K0RsCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
|
||||
clientKey = "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBdTd1c1ozazNrRERYaStlTEo5L3dRTURxZHFDbVhyUlQycDgvSXh1WlNESTdZUVJGCjk1T0RDSllGVnY0M3hoRTRldWZtR0VqQk9CcGV5N2t4SDNjU2JKbjhNTUFpK09XaGViZ2o3Z0EyNjdGSVhJVnIKemRpNFVtaStRRDJISE05YytQREdBWHpoVFRBc0l3M0NSdjlzL01pM0FMVCswZnUwekR1ZmlWYUJnSWs2c1ZoSgphb0pIOG5hTUlTMUpwZjlWcDFyTVNnRWo2c1ZGWXlPdGk4T1JGYkExbHFNOE8vTS9FZHhzUDI1dXlianI1My9JClA5SHZjQWE4Snh3SS80ZlRVTWhiMGNsRnRWUm5Mak1hL1BwNXAvd1MvNDdEbkIzT3BuWlVzckJsQXZOemtXMTEKWUVyeVJUTlp1RWdSeEdsTEY5WmZtbmREcUpETjlFbVdDcEJnSHdJREFRQUJBb0lCQUZncm9LRkljU3dyaEZDVgpBdXBMWnM5Q3k5dkRQK0FpMlc5SWM2TE5oNFE4ODE1eFgxc1QwT3JyYXI2Y3p4MGJZV2Q0R3IwMURtcUhHQmFlCmQ4L0xZTC9ZNG5VVENGblZuNjFIS3JqUktQb3hYVWIyOHRiTy9tTFdCdVN0QVJRcTRBT2JNYVBwUHZlOXREMFMKYlRoakpwRGl3L0IxRVdrVnlxaFJLSENjVEY1TlJ3VHpZZEZCdHcwQVBmdzRZSFhMbmdGTU5IYjBMUTZmdXhFTQp1MWJPazh3Zk9mVzl3eVVCdU1URVhQNlZRdnpJSktiY2tPVzFJU2VlK2ozVHI4OUYwU2lVWGFuekcyV2R3R1Y3ClNlbWUydExWV05YV285U3A0QStRWjVyV2YydWJUeGMxNW0wakV0R24xNkt2WFhGK0hXR0E5a2tUSm1RaDN4WW0KU3BiVG1zRUNnWUVBNmRlZEpZZ0twaVowRDlyZHM0eXFlbEtMaHF6U3hsM2pHQ1puMXpmMFFWdXBMbFpiKzJtSwpGakt1UGR4OVpIWHQ2cTgwaTFYUlhMaDhhUENiUCtxSEJ1c0FBNzAvYlhOSTdubWw5TEc4Yy81V3NBMEovQTZWCnByd2QveWphaEhBcWN4SC9UdmhOSnptS3ZiUDFMSXFOQm9nblRFY294aS9hckcwQVh4VW5NWGtDZ1lFQXpZV1QKUzRCKzh0RG44aHQ1a0xtRW1UZ3VOSVZqajdxZTllZk5JaTdkc2VtVGVGSjZlcWNPRGw2V3VwOFNiYi9iR0QvNApBS1ZyVnpvVmtpWmltUE9PRFdKUFhKWGhJVFdnVENIT3FQYm1qbENtMm1NejlPL0sybHJhMGMxUnlIZzIzV2wzCkJPRTFjNU8wUGh6UlVHald5YlJUZlUwc1hIbXNqbUhoZ3RXZkVGY0NnWUJoNTZ0YzNtT1BBd1NPNnRUdDZ0UXAKbU12Z0hCVzNoZkdoMTlxY0trb3kzeHlyVU83OENVa09XRFBKcExvL1NIelBTSUhZWUpyaWxqOUlkSXlicXliVApoNnFlNWlwYk9leHNKRFNPaWFmY2JMMkF3a1RPNnBCUG1lMTVPbktiQnBkUFRGYTNpcEJLL3ZXT3pYeTJKR0E5ClB0NHRPcEhnd0lKdXRNaDJCdFk5Q1FLQmdRQ0hNMjAvaVF0Nlh6V0d6czQ5Qjk0VUVhSkx5TWhEWUNoOGFuNUgKRTMraUw1OWsweFZocEk0Wm85NFNiTnpwdUFIQXhTdzMrSnBScXBOUUx0SkQvazBmdnVHb2JhekpkUWE3cnEzTgo5NGFhYnJJbERvZTZoUmowWmpwM05GT3R4bStKWG56K2g4enErR3JsUlgzcElON1RtRDRvT3VHSkFENGsrSDBxCjNhOGpSd0tCZ1FDMnB4OTc4Zm1PZ0tjRGJpMCtnajdYSUlqNFRjNHIvL0t5MnIzd2xuOFlPWEt1L3lNbXFXR3kKNUVyOFJNTWhINDlYWHdnWk1od0g5cEdocGo2M2Y3WnBEWllJUGRIU2s3TDhjZXJoaHRIWWdtN3o2L3NWVnREcgpmazM3S2NjQ1RrZitWZXl4eVRvaDNKL3VMelNyRVlScVhxbldlckE2YjQ3MUhublppQTBwR2c9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo="
|
||||
clientCrt = "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURuVENDQW9XZ0F3SUJBZ0lKQUlkVDl3UHIrTlJGTUEwR0NTcUdTSWIzRFFFQkN3VUFNRVV4Q3pBSkJnTlYKQkFZVEFrTk9NUkF3RGdZRFZRUUlEQWRDWldscWFXNW5NUkF3RGdZRFZRUUhEQWRDWldscWFXNW5NUkl3RUFZRApWUVFEREFreE1qY3VNQzR3TGpFd0lCY05Nak13T1RFNU1ETTFOVEUxV2hnUE1qRXlNekE0TWpZd016VTFNVFZhCk1FUXhDekFKQmdOVkJBWVRBa05PTVJBd0RnWURWUVFJREFkQ1pXbHFhVzVuTVJBd0RnWURWUVFIREFkQ1pXbHEKYVc1bk1SRXdEd1lEVlFRS0RBaExkV0psVm1Wc1lUQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQwpBUW9DZ2dFQkFMdTdyR2Q1TjVBdzE0dm5peWZmOEVEQTZuYWdwbDYwVTlxZlB5TWJtVWd5TzJFRVJmZVRnd2lXCkJWYitOOFlST0hybjVoaEl3VGdhWHN1NU1SOTNFbXlaL0REQUl2amxvWG00SSs0QU51dXhTRnlGYTgzWXVGSm8KdmtBOWh4elBYUGp3eGdGODRVMHdMQ01Od2tiL2JQekl0d0MwL3RIN3RNdzduNGxXZ1lDSk9yRllTV3FDUi9KMgpqQ0V0U2FYL1ZhZGF6RW9CSStyRlJXTWpyWXZEa1JXd05aYWpQRHZ6UHhIY2JEOXVic200NitkL3lEL1I3M0FHCnZDY2NDUCtIMDFESVc5SEpSYlZVWnk0ekd2ejZlYWY4RXYrT3c1d2R6cVoyVkxLd1pRTHpjNUZ0ZFdCSzhrVXoKV2JoSUVjUnBTeGZXWDVwM1E2aVF6ZlJKbGdxUVlCOENBd0VBQWFPQmpqQ0JpekJmQmdOVkhTTUVXREJXb1VtawpSekJGTVFzd0NRWURWUVFHRXdKRFRqRVFNQTRHQTFVRUNBd0hRbVZwYW1sdVp6RVFNQTRHQTFVRUJ3d0hRbVZwCmFtbHVaekVTTUJBR0ExVUVBd3dKTVRJM0xqQXVNQzR4Z2drQXcrbDArVGh6WW5jd0NRWURWUjBUQkFJd0FEQWQKQmdOVkhSRUVGakFVZ2hKamJHbGxiblF1YTNWaVpYWmxiR0V1YVc4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQgpBS2VZTVJHR25kaXJJeS9OMjd0eU81VExxSDh3Q1pocXI3VFU2bW1BUjUrS09PTDVqU0U0SkNOTkFiNXpXSDVLCmsrSVVpR1prNHprOWtCSmNtaG02dDNIdWVMVmMwUkZyWjZHQUhwV2hjclBGN0ZkTWpmTzRYNHFiT1IwL2k4OVkKVi9VRkxpYTMyOTUvZ3RiWkJmTWhpZGxzWXZ5aS9kMXhUR25Ba1FDRTR0cHEyK0l3RzNwZ05LRmErRlpvWmU0Ygo3YllyUDcvTXBKYWd5bVJXUGZ1anlRZXVCMzlabFNYZlNTQzZoUU41RHlpTmQxTGZhNXFNd1JtTmxlMGtUdE12Ci9QRkVIWDR2T1R4SFMvYmc1T2lPVEpBenBNZnZ1bHA2YmxrbHR3SmFJMmw2b0N6RU9VVlpNKzJPKzBHZzEzS3UKNFpTZjg0Z3FQYmF4UzgwQkphTVlhNDg9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K"
|
||||
MockCerts = struct {
|
||||
Ca string
|
||||
ServerKey string
|
||||
|
||||
@@ -618,7 +618,7 @@ func (k *kubeConfigFactory) CreateOrUpdateConfig(ctx context.Context, i *Config,
|
||||
if secret.Labels[types.LabelConfigType] != i.Template.Name {
|
||||
return ErrChangeTemplate
|
||||
}
|
||||
if secret.Type != i.Secret.Type {
|
||||
if i.Secret.Type != "" && secret.Type != i.Secret.Type {
|
||||
return ErrChangeSecretType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,9 +46,6 @@ type Args struct {
|
||||
// AutoGenWorkloadDefinition indicates whether automatic generated workloadDefinition which componentDefinition refers to
|
||||
AutoGenWorkloadDefinition bool
|
||||
|
||||
// EnableCompatibility indicates that will change some functions of controller to adapt to multiple platforms, such as asi.
|
||||
EnableCompatibility bool
|
||||
|
||||
// IgnoreAppWithoutControllerRequirement indicates that application controller will not process the app without 'app.oam.dev/controller-version-require' annotation.
|
||||
IgnoreAppWithoutControllerRequirement bool
|
||||
|
||||
@@ -66,7 +63,6 @@ func (a *Args) AddFlags(fs *pflag.FlagSet, c *Args) {
|
||||
"definition-revision-limit is the maximum number of component/trait definition useless revisions that will be maintained, if the useless revisions exceed this number, older ones will be GCed first.The default value is 20.")
|
||||
fs.BoolVar(&a.AutoGenWorkloadDefinition, "autogen-workload-definition", c.AutoGenWorkloadDefinition, "Automatic generated workloadDefinition which componentDefinition refers to.")
|
||||
fs.IntVar(&a.ConcurrentReconciles, "concurrent-reconciles", c.ConcurrentReconciles, "concurrent-reconciles is the concurrent reconcile number of the controller. The default value is 4")
|
||||
fs.BoolVar(&a.EnableCompatibility, "enable-asi-compatibility", c.EnableCompatibility, "enable compatibility for asi")
|
||||
fs.BoolVar(&a.IgnoreAppWithoutControllerRequirement, "ignore-app-without-controller-version", c.IgnoreAppWithoutControllerRequirement, "If true, application controller will not process the app without 'app.oam.dev/controller-version-require' annotation")
|
||||
fs.BoolVar(&a.IgnoreDefinitionWithoutControllerRequirement, "ignore-definition-without-controller-version", c.IgnoreDefinitionWithoutControllerRequirement, "If true, trait/component/workflowstep definition controller will not process the definition without 'definition.oam.dev/controller-version-require' annotation")
|
||||
}
|
||||
|
||||
@@ -95,7 +95,6 @@ type Reconciler struct {
|
||||
type options struct {
|
||||
appRevisionLimit int
|
||||
concurrentReconciles int
|
||||
disableStatusUpdate bool
|
||||
ignoreAppNoCtrlReq bool
|
||||
controllerVersion string
|
||||
}
|
||||
@@ -141,7 +140,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
logCtx.AddTag("publish_version", app.GetAnnotations()[oam.AnnotationPublishVersion])
|
||||
|
||||
appParser := appfile.NewApplicationParser(r.Client, r.pd)
|
||||
handler, err := NewAppHandler(logCtx, r, app, appParser)
|
||||
handler, err := NewAppHandler(logCtx, r, app)
|
||||
if err != nil {
|
||||
return r.endWithNegativeCondition(logCtx, app, condition.ReconcileError(err), common.ApplicationStarting)
|
||||
}
|
||||
@@ -179,14 +178,14 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
app.Status.SetConditions(condition.ReadyCondition("Revision"))
|
||||
r.Recorder.Event(app, event.Normal(velatypes.ReasonRevisoned, velatypes.MessageRevisioned))
|
||||
|
||||
if err := handler.UpdateAppLatestRevisionStatus(logCtx); err != nil {
|
||||
if err := handler.UpdateAppLatestRevisionStatus(logCtx, r.patchStatus); err != nil {
|
||||
logCtx.Error(err, "Failed to update application status")
|
||||
return r.endWithNegativeCondition(logCtx, app, condition.ReconcileError(err), common.ApplicationRendering)
|
||||
}
|
||||
logCtx.Info("Successfully apply application revision")
|
||||
|
||||
if err := handler.ApplyPolicies(logCtx, appFile); err != nil {
|
||||
logCtx.Error(err, "[Handle ApplyPolicies]")
|
||||
logCtx.Error(err, "[handle ApplyPolicies]")
|
||||
r.Recorder.Event(app, event.Warning(velatypes.ReasonFailedApply, err))
|
||||
return r.endWithNegativeCondition(logCtx, app, condition.ErrorCondition(common.PolicyCondition.String(), errors.WithMessage(err, "ApplyPolices")), common.ApplicationPolicyGenerating)
|
||||
}
|
||||
@@ -258,7 +257,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Resu
|
||||
}
|
||||
|
||||
var phase = common.ApplicationRunning
|
||||
if !hasHealthCheckPolicy(appFile.PolicyWorkloads) {
|
||||
if !hasHealthCheckPolicy(appFile.ParsedPolicies) {
|
||||
app.Status.Services = handler.services
|
||||
if !isHealthy(handler.services) {
|
||||
phase = common.ApplicationUnhealthy
|
||||
@@ -440,23 +439,26 @@ func (r *Reconciler) endWithNegativeCondition(ctx context.Context, app *v1beta1.
|
||||
return r.result(fmt.Errorf("object level reconcile error, type: %q, msg: %q", string(condition.Type), condition.Message)).ret()
|
||||
}
|
||||
|
||||
// Application status can be updated by two methods: patch and update.
|
||||
type method int
|
||||
|
||||
const (
|
||||
patch = iota
|
||||
update
|
||||
)
|
||||
|
||||
type statusPatcher func(ctx context.Context, app *v1beta1.Application, phase common.ApplicationPhase) error
|
||||
|
||||
func (r *Reconciler) patchStatus(ctx context.Context, app *v1beta1.Application, phase common.ApplicationPhase) error {
|
||||
app.Status.Phase = phase
|
||||
updateObservedGeneration(app)
|
||||
if oldApp, ok := originalAppFrom(ctx); ok && oldApp != nil && equality.Semantic.DeepEqual(oldApp.Status, app.Status) {
|
||||
return nil
|
||||
}
|
||||
ctx, cancel := ctrlrec.NewReconcileTerminationContext(ctx)
|
||||
defer cancel()
|
||||
if err := r.Status().Patch(ctx, app, client.Merge); err != nil {
|
||||
// set to -1 to re-run workflow if status is failed to patch
|
||||
executor.StepStatusCache.Store(fmt.Sprintf("%s-%s", app.Name, app.Namespace), -1)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return r.writeStatusByMethod(ctx, patch, app, phase)
|
||||
}
|
||||
|
||||
func (r *Reconciler) updateStatus(ctx context.Context, app *v1beta1.Application, phase common.ApplicationPhase) error {
|
||||
return r.writeStatusByMethod(ctx, update, app, phase)
|
||||
}
|
||||
|
||||
func (r *Reconciler) writeStatusByMethod(ctx context.Context, method method, app *v1beta1.Application, phase common.ApplicationPhase) error {
|
||||
// pre-check if the status is changed
|
||||
app.Status.Phase = phase
|
||||
updateObservedGeneration(app)
|
||||
if oldApp, ok := originalAppFrom(ctx); ok && oldApp != nil && equality.Semantic.DeepEqual(oldApp.Status, app.Status) {
|
||||
@@ -464,15 +466,17 @@ func (r *Reconciler) updateStatus(ctx context.Context, app *v1beta1.Application,
|
||||
}
|
||||
ctx, cancel := ctrlrec.NewReconcileTerminationContext(ctx)
|
||||
defer cancel()
|
||||
if !r.disableStatusUpdate {
|
||||
return r.Status().Update(ctx, app)
|
||||
var f func() error
|
||||
switch method {
|
||||
case patch:
|
||||
f = func() error { return r.Status().Patch(ctx, app, client.Merge) }
|
||||
case update:
|
||||
f = func() error { return r.Status().Update(ctx, app) }
|
||||
default:
|
||||
// Should never happen
|
||||
panic("unknown method")
|
||||
}
|
||||
obj, err := app.Unstructured()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := r.Status().Update(ctx, obj); err != nil {
|
||||
// set to -1 to re-run workflow if status is failed to update
|
||||
if err := f(); err != nil {
|
||||
executor.StepStatusCache.Store(fmt.Sprintf("%s-%s", app.Name, app.Namespace), -1)
|
||||
return err
|
||||
}
|
||||
@@ -498,7 +502,7 @@ func (r *Reconciler) doWorkflowFinish(logCtx monitorContext.Context, app *v1beta
|
||||
logCtx.Info("Application manifests has applied by workflow successfully")
|
||||
}
|
||||
|
||||
func hasHealthCheckPolicy(policies []*appfile.Workload) bool {
|
||||
func hasHealthCheckPolicy(policies []*appfile.Component) bool {
|
||||
for _, p := range policies {
|
||||
if p.FullTemplate != nil && p.FullTemplate.PolicyDefinition != nil &&
|
||||
p.FullTemplate.PolicyDefinition.Spec.ManageHealthCheck {
|
||||
@@ -648,7 +652,6 @@ func timeReconcile(app *v1beta1.Application) func() {
|
||||
|
||||
func parseOptions(args core.Args) options {
|
||||
return options{
|
||||
disableStatusUpdate: args.EnableCompatibility,
|
||||
appRevisionLimit: args.AppRevisionLimit,
|
||||
concurrentReconciles: args.ConcurrentReconciles,
|
||||
ignoreAppNoCtrlReq: args.IgnoreAppWithoutControllerRequirement,
|
||||
|
||||
@@ -524,9 +524,9 @@ var _ = Describe("Test Application Controller", func() {
|
||||
Expect(len(comps) > 0).Should(BeTrue())
|
||||
comp := comps[0]
|
||||
|
||||
Expect(comp.StandardWorkload).ShouldNot(BeNil())
|
||||
Expect(comp.ComponentOutput).ShouldNot(BeNil())
|
||||
gotDeploy := &v1.Deployment{}
|
||||
Expect(runtime.DefaultUnstructuredConverter.FromUnstructured(comp.StandardWorkload.Object, gotDeploy)).Should(Succeed())
|
||||
Expect(runtime.DefaultUnstructuredConverter.FromUnstructured(comp.ComponentOutput.Object, gotDeploy)).Should(Succeed())
|
||||
gotDeploy.Annotations = nil
|
||||
Expect(cmp.Diff(gotDeploy, expDeployment)).Should(BeEmpty())
|
||||
|
||||
@@ -747,7 +747,7 @@ var _ = Describe("Test Application Controller", func() {
|
||||
comp := comps[0]
|
||||
|
||||
gotD := &v1.Deployment{}
|
||||
runtime.DefaultUnstructuredConverter.FromUnstructured(comp.StandardWorkload.Object, gotD)
|
||||
runtime.DefaultUnstructuredConverter.FromUnstructured(comp.ComponentOutput.Object, gotD)
|
||||
gotD.Annotations = nil
|
||||
Expect(cmp.Diff(gotD, expDeployment)).Should(BeEmpty())
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/kubevela/workflow/pkg/cue/packages"
|
||||
"github.com/pkg/errors"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -45,7 +46,9 @@ import (
|
||||
|
||||
// AppHandler handles application reconcile
|
||||
type AppHandler struct {
|
||||
r *Reconciler
|
||||
client.Client
|
||||
pd *packages.PackageDiscover
|
||||
|
||||
app *v1beta1.Application
|
||||
currentAppRev *v1beta1.ApplicationRevision
|
||||
latestAppRev *v1beta1.ApplicationRevision
|
||||
@@ -57,13 +60,12 @@ type AppHandler struct {
|
||||
services []common.ApplicationComponentStatus
|
||||
appliedResources []common.ClusterObjectReference
|
||||
deletedResources []common.ClusterObjectReference
|
||||
parser *appfile.Parser
|
||||
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// NewAppHandler create new app handler
|
||||
func NewAppHandler(ctx context.Context, r *Reconciler, app *v1beta1.Application, parser *appfile.Parser) (*AppHandler, error) {
|
||||
func NewAppHandler(ctx context.Context, r *Reconciler, app *v1beta1.Application) (*AppHandler, error) {
|
||||
if ctx, ok := ctx.(monitorContext.Context); ok {
|
||||
subCtx := ctx.Fork("create-app-handler", monitorContext.DurationMetric(func(v float64) {
|
||||
metrics.AppReconcileStageDurationHistogram.WithLabelValues("create-app-handler").Observe(v)
|
||||
@@ -75,10 +77,10 @@ func NewAppHandler(ctx context.Context, r *Reconciler, app *v1beta1.Application,
|
||||
return nil, errors.Wrapf(err, "failed to create resourceKeeper")
|
||||
}
|
||||
return &AppHandler{
|
||||
r: r,
|
||||
Client: r.Client,
|
||||
pd: r.pd,
|
||||
app: app,
|
||||
resourceKeeper: resourceHandler,
|
||||
parser: parser,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -221,19 +223,14 @@ func (h *AppHandler) addServiceStatus(cover bool, svcs ...common.ApplicationComp
|
||||
}
|
||||
}
|
||||
|
||||
// ProduceArtifacts will produce Application artifacts that will be saved in configMap.
|
||||
func (h *AppHandler) ProduceArtifacts(ctx context.Context, comps []*types.ComponentManifest, policies []*unstructured.Unstructured) error {
|
||||
return h.createResourcesConfigMap(ctx, h.currentAppRev, comps, policies)
|
||||
}
|
||||
|
||||
// collectTraitHealthStatus collect trait health status
|
||||
func (h *AppHandler) collectTraitHealthStatus(wl *appfile.Workload, tr *appfile.Trait, appRev *v1beta1.ApplicationRevision, overrideNamespace string) (common.ApplicationTraitStatus, []*unstructured.Unstructured, error) {
|
||||
func (h *AppHandler) collectTraitHealthStatus(comp *appfile.Component, tr *appfile.Trait, appRev *v1beta1.ApplicationRevision, overrideNamespace string) (common.ApplicationTraitStatus, []*unstructured.Unstructured, error) {
|
||||
defer func(clusterName string) {
|
||||
wl.Ctx.SetCtx(pkgmulticluster.WithCluster(wl.Ctx.GetCtx(), clusterName))
|
||||
}(multicluster.ClusterNameInContext(wl.Ctx.GetCtx()))
|
||||
comp.Ctx.SetCtx(pkgmulticluster.WithCluster(comp.Ctx.GetCtx(), clusterName))
|
||||
}(multicluster.ClusterNameInContext(comp.Ctx.GetCtx()))
|
||||
|
||||
var (
|
||||
pCtx = wl.Ctx
|
||||
pCtx = comp.Ctx
|
||||
appName = appRev.Spec.Application.Name
|
||||
traitStatus = common.ApplicationTraitStatus{
|
||||
Type: tr.Name,
|
||||
@@ -247,57 +244,57 @@ func (h *AppHandler) collectTraitHealthStatus(wl *appfile.Workload, tr *appfile.
|
||||
pCtx.SetCtx(pkgmulticluster.WithCluster(pCtx.GetCtx(), pkgmulticluster.Local))
|
||||
}
|
||||
_accessor := util.NewApplicationResourceNamespaceAccessor(h.app.Namespace, traitOverrideNamespace)
|
||||
templateContext, err := tr.GetTemplateContext(pCtx, h.r.Client, _accessor)
|
||||
templateContext, err := tr.GetTemplateContext(pCtx, h.Client, _accessor)
|
||||
if err != nil {
|
||||
return common.ApplicationTraitStatus{}, nil, errors.WithMessagef(err, "app=%s, comp=%s, trait=%s, get template context error", appName, wl.Name, tr.Name)
|
||||
return common.ApplicationTraitStatus{}, nil, errors.WithMessagef(err, "app=%s, comp=%s, trait=%s, get template context error", appName, comp.Name, tr.Name)
|
||||
}
|
||||
if ok, err := tr.EvalHealth(templateContext); !ok || err != nil {
|
||||
traitStatus.Healthy = false
|
||||
}
|
||||
traitStatus.Message, err = tr.EvalStatus(templateContext)
|
||||
if err != nil {
|
||||
return common.ApplicationTraitStatus{}, nil, errors.WithMessagef(err, "app=%s, comp=%s, trait=%s, evaluate status message error", appName, wl.Name, tr.Name)
|
||||
return common.ApplicationTraitStatus{}, nil, errors.WithMessagef(err, "app=%s, comp=%s, trait=%s, evaluate status message error", appName, comp.Name, tr.Name)
|
||||
}
|
||||
return traitStatus, extractOutputs(templateContext), nil
|
||||
}
|
||||
|
||||
// collectWorkloadHealthStatus collect workload health status
|
||||
func (h *AppHandler) collectWorkloadHealthStatus(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision, status *common.ApplicationComponentStatus, accessor util.NamespaceAccessor) (bool, *unstructured.Unstructured, []*unstructured.Unstructured, error) {
|
||||
func (h *AppHandler) collectWorkloadHealthStatus(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision, status *common.ApplicationComponentStatus, accessor util.NamespaceAccessor) (bool, *unstructured.Unstructured, []*unstructured.Unstructured, error) {
|
||||
var output *unstructured.Unstructured
|
||||
var outputs []*unstructured.Unstructured
|
||||
var (
|
||||
appName = appRev.Spec.Application.Name
|
||||
isHealth = true
|
||||
)
|
||||
if wl.CapabilityCategory == types.TerraformCategory {
|
||||
if comp.CapabilityCategory == types.TerraformCategory {
|
||||
var configuration terraforv1beta2.Configuration
|
||||
if err := h.r.Client.Get(ctx, client.ObjectKey{Name: wl.Name, Namespace: accessor.Namespace()}, &configuration); err != nil {
|
||||
if err := h.Client.Get(ctx, client.ObjectKey{Name: comp.Name, Namespace: accessor.Namespace()}, &configuration); err != nil {
|
||||
if kerrors.IsNotFound(err) {
|
||||
var legacyConfiguration terraforv1beta1.Configuration
|
||||
if err := h.r.Client.Get(ctx, client.ObjectKey{Name: wl.Name, Namespace: accessor.Namespace()}, &legacyConfiguration); err != nil {
|
||||
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, check health error", appName, wl.Name)
|
||||
if err := h.Client.Get(ctx, client.ObjectKey{Name: comp.Name, Namespace: accessor.Namespace()}, &legacyConfiguration); err != nil {
|
||||
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, check health error", appName, comp.Name)
|
||||
}
|
||||
isHealth = setStatus(status, legacyConfiguration.Status.ObservedGeneration, legacyConfiguration.Generation,
|
||||
legacyConfiguration.GetLabels(), appRev.Name, legacyConfiguration.Status.Apply.State, legacyConfiguration.Status.Apply.Message)
|
||||
} else {
|
||||
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, check health error", appName, wl.Name)
|
||||
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, check health error", appName, comp.Name)
|
||||
}
|
||||
} else {
|
||||
isHealth = setStatus(status, configuration.Status.ObservedGeneration, configuration.Generation, configuration.GetLabels(),
|
||||
appRev.Name, configuration.Status.Apply.State, configuration.Status.Apply.Message)
|
||||
}
|
||||
} else {
|
||||
templateContext, err := wl.GetTemplateContext(wl.Ctx, h.r.Client, accessor)
|
||||
templateContext, err := comp.GetTemplateContext(comp.Ctx, h.Client, accessor)
|
||||
if err != nil {
|
||||
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, get template context error", appName, wl.Name)
|
||||
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, get template context error", appName, comp.Name)
|
||||
}
|
||||
if ok, err := wl.EvalHealth(templateContext); !ok || err != nil {
|
||||
if ok, err := comp.EvalHealth(templateContext); !ok || err != nil {
|
||||
isHealth = false
|
||||
}
|
||||
status.Healthy = isHealth
|
||||
status.Message, err = wl.EvalStatus(templateContext)
|
||||
status.Message, err = comp.EvalStatus(templateContext)
|
||||
if err != nil {
|
||||
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, evaluate workload status message error", appName, wl.Name)
|
||||
return false, nil, nil, errors.WithMessagef(err, "app=%s, comp=%s, evaluate workload status message error", appName, comp.Name)
|
||||
}
|
||||
output, outputs = extractOutputAndOutputs(templateContext)
|
||||
}
|
||||
@@ -306,14 +303,14 @@ func (h *AppHandler) collectWorkloadHealthStatus(ctx context.Context, wl *appfil
|
||||
|
||||
// nolint
|
||||
// collectHealthStatus will collect health status of component, including component itself and traits.
|
||||
func (h *AppHandler) collectHealthStatus(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision, overrideNamespace string, skipWorkload bool, traitFilters ...TraitFilter) (*common.ApplicationComponentStatus, *unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
|
||||
func (h *AppHandler) collectHealthStatus(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision, overrideNamespace string, skipWorkload bool, traitFilters ...TraitFilter) (*common.ApplicationComponentStatus, *unstructured.Unstructured, []*unstructured.Unstructured, bool, error) {
|
||||
output := new(unstructured.Unstructured)
|
||||
outputs := make([]*unstructured.Unstructured, 0)
|
||||
accessor := util.NewApplicationResourceNamespaceAccessor(h.app.Namespace, overrideNamespace)
|
||||
var (
|
||||
status = common.ApplicationComponentStatus{
|
||||
Name: wl.Name,
|
||||
WorkloadDefinition: wl.FullTemplate.Reference.Definition,
|
||||
Name: comp.Name,
|
||||
WorkloadDefinition: comp.FullTemplate.Reference.Definition,
|
||||
Healthy: true,
|
||||
Namespace: accessor.Namespace(),
|
||||
Cluster: multicluster.ClusterNameInContext(ctx),
|
||||
@@ -324,7 +321,7 @@ func (h *AppHandler) collectHealthStatus(ctx context.Context, wl *appfile.Worklo
|
||||
|
||||
status = h.getServiceStatus(status)
|
||||
if !skipWorkload {
|
||||
isHealth, output, outputs, err = h.collectWorkloadHealthStatus(ctx, wl, appRev, &status, accessor)
|
||||
isHealth, output, outputs, err = h.collectWorkloadHealthStatus(ctx, comp, appRev, &status, accessor)
|
||||
if err != nil {
|
||||
return nil, nil, nil, false, err
|
||||
}
|
||||
@@ -332,7 +329,7 @@ func (h *AppHandler) collectHealthStatus(ctx context.Context, wl *appfile.Worklo
|
||||
|
||||
var traitStatusList []common.ApplicationTraitStatus
|
||||
collectNext:
|
||||
for _, tr := range wl.Traits {
|
||||
for _, tr := range comp.Traits {
|
||||
for _, filter := range traitFilters {
|
||||
// If filtered out by one of the filters
|
||||
if filter(*tr) {
|
||||
@@ -340,7 +337,7 @@ collectNext:
|
||||
}
|
||||
}
|
||||
|
||||
traitStatus, _outputs, err := h.collectTraitHealthStatus(wl, tr, appRev, overrideNamespace)
|
||||
traitStatus, _outputs, err := h.collectTraitHealthStatus(comp, tr, appRev, overrideNamespace)
|
||||
if err != nil {
|
||||
return nil, nil, nil, false, err
|
||||
}
|
||||
@@ -389,6 +386,7 @@ func setStatus(status *common.ApplicationComponentStatus, observedGeneration, ge
|
||||
}
|
||||
|
||||
// ApplyPolicies will render policies into manifests from appfile and dispatch them
|
||||
// Note the builtin policy like apply-once, shared-resource, etc. is not handled here.
|
||||
func (h *AppHandler) ApplyPolicies(ctx context.Context, af *appfile.Appfile) error {
|
||||
if ctx, ok := ctx.(monitorContext.Context); ok {
|
||||
subCtx := ctx.Fork("apply-policies", monitorContext.DurationMetric(func(v float64) {
|
||||
|
||||
@@ -224,7 +224,7 @@ var _ = Describe("Test deleter resource", func() {
|
||||
},
|
||||
},
|
||||
}
|
||||
h, err := NewAppHandler(ctx, reconciler, &v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Name: "example", Namespace: "default"}}, nil)
|
||||
h, err := NewAppHandler(ctx, reconciler, &v1beta1.Application{ObjectMeta: metav1.ObjectMeta{Name: "example", Namespace: "default"}})
|
||||
Expect(err).Should(Succeed())
|
||||
h.appliedResources = appliedRsc
|
||||
Expect(h.Delete(ctx, "", common.WorkflowResourceCreator, &u))
|
||||
|
||||
@@ -17,136 +17,15 @@ limitations under the License.
|
||||
package assemble
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/appfile"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
)
|
||||
|
||||
// NewAppManifests create a AppManifests
|
||||
func NewAppManifests(appRevision *v1beta1.ApplicationRevision, parser *appfile.Parser) *AppManifests {
|
||||
return &AppManifests{AppRevision: appRevision, parser: parser}
|
||||
}
|
||||
|
||||
// AppManifests contains configuration to assemble resources recorded in the ApplicationRevision.
|
||||
// 'Assemble' means expand Application(Component and Trait) into K8s resource and get them ready to go, to be emitted
|
||||
// into K8s
|
||||
type AppManifests struct {
|
||||
AppRevision *v1beta1.ApplicationRevision
|
||||
WorkloadOptions []WorkloadOption
|
||||
|
||||
componentManifests []*types.ComponentManifest
|
||||
appName string
|
||||
appNamespace string
|
||||
appLabels map[string]string
|
||||
appAnnotations map[string]string
|
||||
appOwnerRef *metav1.OwnerReference
|
||||
|
||||
assembledWorkloads map[string]*unstructured.Unstructured
|
||||
assembledTraits map[string][]*unstructured.Unstructured
|
||||
// key is workload reference, values are the references of scopes the workload belongs to
|
||||
skipWorkloadApplyComp map[string]bool
|
||||
|
||||
finalized bool
|
||||
err error
|
||||
|
||||
parser *appfile.Parser
|
||||
}
|
||||
|
||||
// WorkloadOption will be applied to each workloads AFTER it has been assembled by generic rules shown below:
|
||||
// 1) use component name as workload name
|
||||
// 2) use application namespace as workload namespace if unspecified
|
||||
// 3) set application as workload's owner
|
||||
// 4) pass all application's labels and annotations to workload's
|
||||
// Component and ComponentDefinition are enough for caller to manipulate workloads.
|
||||
// Caller can use below labels of workload to get more information:
|
||||
// - oam.LabelAppName
|
||||
// - oam.LabelAppRevision
|
||||
// - oam.LabelAppRevisionHash
|
||||
// - oam.LabelAppComponent
|
||||
// - oam.LabelAppComponentRevision
|
||||
type WorkloadOption interface {
|
||||
ApplyToWorkload(*unstructured.Unstructured, *v1beta1.ComponentDefinition, []*unstructured.Unstructured) error
|
||||
}
|
||||
|
||||
// WithWorkloadOption add a WorkloadOption to plug in custom logic applied to each workload
|
||||
func (am *AppManifests) WithWorkloadOption(wo WorkloadOption) *AppManifests {
|
||||
if am.WorkloadOptions == nil {
|
||||
am.WorkloadOptions = make([]WorkloadOption, 0)
|
||||
}
|
||||
am.WorkloadOptions = append(am.WorkloadOptions, wo)
|
||||
return am
|
||||
}
|
||||
|
||||
// WithComponentManifests set component manifests with the given one
|
||||
func (am *AppManifests) WithComponentManifests(componentManifests []*types.ComponentManifest) *AppManifests {
|
||||
am.componentManifests = componentManifests
|
||||
return am
|
||||
}
|
||||
|
||||
// AssembledManifests do assemble and merge all assembled resources(except referenced scopes) into one array
|
||||
// The result guarantee the order of resources as defined in application originally.
|
||||
// If it contains more than one component, the resources are well-orderred and also grouped.
|
||||
// For example, if app = comp1 (wl1 + trait1 + trait2) + comp2 (wl2 + trait3 +trait4),
|
||||
// the result is [wl1, trait1, trait2, wl2, trait3, trait4]
|
||||
func (am *AppManifests) AssembledManifests() ([]*unstructured.Unstructured, error) {
|
||||
if !am.finalized {
|
||||
am.assemble()
|
||||
}
|
||||
if am.err != nil {
|
||||
return nil, am.err
|
||||
}
|
||||
r := make([]*unstructured.Unstructured, 0)
|
||||
for compName, wl := range am.assembledWorkloads {
|
||||
skipApplyWorkload := false
|
||||
ts := am.assembledTraits[compName]
|
||||
for _, t := range ts {
|
||||
r = append(r, t.DeepCopy())
|
||||
if v := t.GetLabels()[oam.LabelManageWorkloadTrait]; v == "true" {
|
||||
skipApplyWorkload = true
|
||||
}
|
||||
}
|
||||
if !skipApplyWorkload {
|
||||
r = append(r, wl.DeepCopy())
|
||||
} else {
|
||||
klog.InfoS("assemble meet a managedByTrait workload, so skip apply it",
|
||||
"namespace", am.AppRevision.Namespace, "appRev", am.AppRevision.Name)
|
||||
}
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// GroupAssembledManifests do assemble and return all resources grouped by components
|
||||
func (am *AppManifests) GroupAssembledManifests() (
|
||||
map[string]*unstructured.Unstructured,
|
||||
map[string][]*unstructured.Unstructured,
|
||||
error) {
|
||||
if !am.finalized {
|
||||
am.assemble()
|
||||
}
|
||||
if am.err != nil {
|
||||
return nil, nil, am.err
|
||||
}
|
||||
workloads := make(map[string]*unstructured.Unstructured)
|
||||
for k, wl := range am.assembledWorkloads {
|
||||
workloads[k] = wl.DeepCopy()
|
||||
}
|
||||
traits := make(map[string][]*unstructured.Unstructured)
|
||||
for k, ts := range am.assembledTraits {
|
||||
traits[k] = make([]*unstructured.Unstructured, len(ts))
|
||||
for i, t := range ts {
|
||||
traits[k][i] = t.DeepCopy()
|
||||
}
|
||||
}
|
||||
return workloads, traits, nil
|
||||
}
|
||||
|
||||
// checkAutoDetectComponent will check if the standardWorkload is empty,
|
||||
// currently only Helm-based component is possible to be auto-detected
|
||||
// TODO implement auto-detect mechanism
|
||||
@@ -154,38 +33,9 @@ func checkAutoDetectComponent(wl *unstructured.Unstructured) bool {
|
||||
return wl == nil || (len(wl.GetAPIVersion()) == 0 && len(wl.GetKind()) == 0)
|
||||
}
|
||||
|
||||
func (am *AppManifests) assemble() {
|
||||
if err := am.complete(); err != nil {
|
||||
am.finalizeAssemble(err)
|
||||
return
|
||||
}
|
||||
|
||||
klog.InfoS("Assemble manifests for application", "name", am.appName, "revision", am.AppRevision.GetName())
|
||||
if err := am.validate(); err != nil {
|
||||
am.finalizeAssemble(err)
|
||||
return
|
||||
}
|
||||
for _, comp := range am.componentManifests {
|
||||
klog.InfoS("Assemble manifests for component", "name", comp.Name)
|
||||
wl, traits, err := PrepareBeforeApply(comp, am.AppRevision, am.WorkloadOptions)
|
||||
if err != nil {
|
||||
am.finalizeAssemble(err)
|
||||
return
|
||||
}
|
||||
if wl == nil {
|
||||
klog.Warningf("component without specify workloadDef can not attach traits currently")
|
||||
continue
|
||||
}
|
||||
|
||||
am.assembledWorkloads[comp.Name] = wl
|
||||
am.assembledTraits[comp.Name] = traits
|
||||
}
|
||||
am.finalizeAssemble(nil)
|
||||
}
|
||||
|
||||
// PrepareBeforeApply will prepare for some necessary info before apply
|
||||
func PrepareBeforeApply(comp *types.ComponentManifest, appRev *v1beta1.ApplicationRevision, workloadOpt []WorkloadOption) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
|
||||
if checkAutoDetectComponent(comp.StandardWorkload) {
|
||||
func PrepareBeforeApply(comp *types.ComponentManifest, appRev *v1beta1.ApplicationRevision) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
|
||||
if checkAutoDetectComponent(comp.ComponentOutput) {
|
||||
return nil, nil, nil
|
||||
}
|
||||
compRevisionName := comp.RevisionName
|
||||
@@ -194,16 +44,13 @@ func PrepareBeforeApply(comp *types.ComponentManifest, appRev *v1beta1.Applicati
|
||||
oam.LabelAppComponentRevision: compRevisionName,
|
||||
oam.LabelAppRevisionHash: appRev.Labels[oam.LabelAppRevisionHash],
|
||||
}
|
||||
wl, err := assembleWorkload(compName, comp.StandardWorkload, additionalLabel, comp.PackagedWorkloadResources, appRev, workloadOpt)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
wl := assembleWorkload(compName, comp.ComponentOutput, additionalLabel)
|
||||
|
||||
assembledTraits := make([]*unstructured.Unstructured, len(comp.Traits))
|
||||
assembledTraits := make([]*unstructured.Unstructured, len(comp.ComponentOutputsAndTraits))
|
||||
|
||||
HandleCheckManageWorkloadTrait(*appRev, []*types.ComponentManifest{comp})
|
||||
|
||||
for i, trait := range comp.Traits {
|
||||
for i, trait := range comp.ComponentOutputsAndTraits {
|
||||
setTraitLabels(trait, additionalLabel)
|
||||
assembledTraits[i] = trait
|
||||
}
|
||||
@@ -211,57 +58,7 @@ func PrepareBeforeApply(comp *types.ComponentManifest, appRev *v1beta1.Applicati
|
||||
return wl, assembledTraits, nil
|
||||
}
|
||||
|
||||
func (am *AppManifests) complete() error {
|
||||
if len(am.componentManifests) == 0 {
|
||||
var err error
|
||||
af, err := am.parser.GenerateAppFileFromRevision(am.AppRevision)
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "fail to generate appfile from revision for app manifests complete")
|
||||
}
|
||||
am.componentManifests, err = af.GenerateComponentManifests()
|
||||
if err != nil {
|
||||
return errors.WithMessage(err, "fail to complete manifests as generate from app revision failed")
|
||||
}
|
||||
}
|
||||
am.appNamespace = am.AppRevision.GetNamespace()
|
||||
am.appLabels = am.AppRevision.GetLabels()
|
||||
am.appName = am.AppRevision.GetLabels()[oam.LabelAppName]
|
||||
am.appAnnotations = am.AppRevision.GetAnnotations()
|
||||
am.appOwnerRef = metav1.GetControllerOf(am.AppRevision)
|
||||
|
||||
am.assembledWorkloads = make(map[string]*unstructured.Unstructured)
|
||||
am.assembledTraits = make(map[string][]*unstructured.Unstructured)
|
||||
am.skipWorkloadApplyComp = make(map[string]bool)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (am *AppManifests) finalizeAssemble(err error) {
|
||||
am.finalized = true
|
||||
if err == nil {
|
||||
klog.InfoS("Successfully assemble manifests for application", "name", am.appName, "revision", am.AppRevision.GetName(), "namespace", am.appNamespace)
|
||||
return
|
||||
}
|
||||
klog.ErrorS(err, "Failed assembling manifests for application", "name", am.appName, "revision", am.AppRevision.GetName())
|
||||
am.err = errors.WithMessagef(err, "cannot assemble resources' manifests for application %q", am.appName)
|
||||
}
|
||||
|
||||
// AssembleOptions is highly coulped with AppRevision, should check the AppRevision provides all info
|
||||
// required by AssembleOptions
|
||||
func (am *AppManifests) validate() error {
|
||||
if am.appOwnerRef == nil {
|
||||
return errors.New("AppRevision must have an Application as owner")
|
||||
}
|
||||
if len(am.AppRevision.Labels[oam.LabelAppName]) == 0 {
|
||||
return errors.New("AppRevision must have app name in the label")
|
||||
}
|
||||
if len(am.AppRevision.Labels[oam.LabelAppRevisionHash]) == 0 {
|
||||
return errors.New("AppRevision must have revision hash in the label")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func assembleWorkload(compName string, wl *unstructured.Unstructured,
|
||||
labels map[string]string, resources []*unstructured.Unstructured, appRev *v1beta1.ApplicationRevision, wop []WorkloadOption) (*unstructured.Unstructured, error) {
|
||||
func assembleWorkload(compName string, wl *unstructured.Unstructured, labels map[string]string) *unstructured.Unstructured {
|
||||
// use component name as workload name if workload name is not specified
|
||||
// don't override the name set in render phase if exist
|
||||
if len(wl.GetName()) == 0 {
|
||||
@@ -269,21 +66,8 @@ func assembleWorkload(compName string, wl *unstructured.Unstructured,
|
||||
}
|
||||
setWorkloadLabels(wl, labels)
|
||||
|
||||
workloadType := wl.GetLabels()[oam.WorkloadTypeLabel]
|
||||
compDefinition := appRev.Spec.ComponentDefinitions[workloadType]
|
||||
copyPackagedResources := make([]*unstructured.Unstructured, len(resources))
|
||||
for i, v := range resources {
|
||||
copyPackagedResources[i] = v.DeepCopy()
|
||||
}
|
||||
for _, wo := range wop {
|
||||
if err := wo.ApplyToWorkload(wl, compDefinition.DeepCopy(), copyPackagedResources); err != nil {
|
||||
klog.ErrorS(err, "Failed applying a workload option", "workload", klog.KObj(wl), "name", wl.GetName())
|
||||
return nil, errors.Wrapf(err, "cannot apply workload option for component %q", compName)
|
||||
}
|
||||
klog.InfoS("Successfully apply a workload option", "workload", klog.KObj(wl), "name", wl.GetName())
|
||||
}
|
||||
klog.InfoS("Successfully assemble a workload", "workload", klog.KObj(wl), "APIVersion", wl.GetAPIVersion(), "Kind", wl.GetKind())
|
||||
return wl, nil
|
||||
return wl
|
||||
}
|
||||
|
||||
// component revision label added here
|
||||
@@ -313,7 +97,7 @@ func HandleCheckManageWorkloadTrait(appRev v1beta1.ApplicationRevision, comps []
|
||||
return
|
||||
}
|
||||
for _, comp := range comps {
|
||||
for _, trait := range comp.Traits {
|
||||
for _, trait := range comp.ComponentOutputsAndTraits {
|
||||
traitType := trait.GetLabels()[oam.TraitTypeLabel]
|
||||
if manageWorkloadTrait[traitType] {
|
||||
trait.SetLabels(util.MergeMapOverrideWithDst(trait.GetLabels(), map[string]string{oam.LabelManageWorkloadTrait: "true"}))
|
||||
|
||||
@@ -15,99 +15,3 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
package assemble
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
var _ = Describe("Test Assemble Options", func() {
|
||||
It("test assemble", func() {
|
||||
var (
|
||||
compName = "test-comp"
|
||||
namespace = "default"
|
||||
)
|
||||
|
||||
appRev := &v1beta1.ApplicationRevision{}
|
||||
b, err := os.ReadFile("./testdata/apprevision.yaml")
|
||||
/* appRevision test data is generated based on below application
|
||||
apiVersion: core.oam.dev/v1beta1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: test-assemble
|
||||
spec:
|
||||
components:
|
||||
- name: test-comp
|
||||
type: webservice
|
||||
properties:
|
||||
image: crccheck/hello-world
|
||||
port: 8000
|
||||
traits:
|
||||
- type: ingress
|
||||
properties:
|
||||
domain: localhost
|
||||
http:
|
||||
"/": 8000
|
||||
*/
|
||||
Expect(err).Should(BeNil())
|
||||
err = yaml.Unmarshal(b, appRev)
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
ao := NewAppManifests(appRev, appParser)
|
||||
workloads, traits, err := ao.GroupAssembledManifests()
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
By("Verify amount of result resources")
|
||||
allResources, err := ao.AssembledManifests()
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(len(allResources)).Should(Equal(3))
|
||||
|
||||
By("Verify amount of result grouped resources")
|
||||
Expect(len(workloads)).Should(Equal(1))
|
||||
Expect(len(traits[compName])).Should(Equal(2))
|
||||
|
||||
By("Verify workload metadata (name, namespace, labels, annotations, ownerRef)")
|
||||
wl := workloads[compName]
|
||||
Expect(wl.GetName()).Should(Equal(compName))
|
||||
Expect(wl.GetNamespace()).Should(Equal(namespace))
|
||||
labels := wl.GetLabels()
|
||||
labelKeys := make([]string, 0, len(labels))
|
||||
for k := range labels {
|
||||
labelKeys = append(labelKeys, k)
|
||||
}
|
||||
Expect(labelKeys).Should(ContainElements(
|
||||
oam.LabelAppName,
|
||||
oam.LabelAppRevision,
|
||||
oam.LabelAppRevisionHash,
|
||||
oam.LabelAppComponent,
|
||||
oam.LabelAppComponentRevision,
|
||||
oam.WorkloadTypeLabel,
|
||||
oam.LabelOAMResourceType))
|
||||
Expect(len(wl.GetAnnotations())).Should(Equal(1))
|
||||
|
||||
By("Verify trait metadata (name, namespace, labels, annotations, ownerRef)")
|
||||
trait := traits[compName][0]
|
||||
Expect(trait.GetName()).Should(ContainSubstring(compName))
|
||||
Expect(trait.GetNamespace()).Should(Equal(namespace))
|
||||
labels = trait.GetLabels()
|
||||
labelKeys = make([]string, 0, len(labels))
|
||||
for k := range labels {
|
||||
labelKeys = append(labelKeys, k)
|
||||
}
|
||||
Expect(labelKeys).Should(ContainElements(
|
||||
oam.LabelAppName,
|
||||
oam.LabelAppRevision,
|
||||
oam.LabelAppRevisionHash,
|
||||
oam.LabelAppComponent,
|
||||
oam.LabelAppComponentRevision,
|
||||
oam.TraitTypeLabel,
|
||||
oam.LabelOAMResourceType))
|
||||
Expect(len(wl.GetAnnotations())).Should(Equal(1))
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package assemble
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/klog/v2"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
helmapi "github.com/oam-dev/kubevela/pkg/appfile/helm/flux2apis"
|
||||
)
|
||||
|
||||
// WorkloadOptionFn implement interface WorkloadOption
|
||||
type WorkloadOptionFn func(*unstructured.Unstructured, *v1beta1.ComponentDefinition, []*unstructured.Unstructured) error
|
||||
|
||||
// ApplyToWorkload will apply the manipulation defined in the function to assembled workload
|
||||
func (fn WorkloadOptionFn) ApplyToWorkload(wl *unstructured.Unstructured,
|
||||
compDefinition *v1beta1.ComponentDefinition, packagedWorkloadResources []*unstructured.Unstructured) error {
|
||||
return fn(wl, compDefinition, packagedWorkloadResources)
|
||||
}
|
||||
|
||||
// DiscoveryHelmBasedWorkload only works for Helm-based component. It computes a qualifiedFullName for the workload and
|
||||
// try to get it from K8s cluster.
|
||||
// If not found, block down-streaming process until Helm creates the workload successfully.
|
||||
func DiscoveryHelmBasedWorkload(ctx context.Context, c client.Reader) WorkloadOption {
|
||||
return WorkloadOptionFn(func(assembledWorkload *unstructured.Unstructured, compDef *v1beta1.ComponentDefinition, resources []*unstructured.Unstructured) error {
|
||||
return discoverHelmModuleWorkload(ctx, c, assembledWorkload, compDef, resources)
|
||||
})
|
||||
}
|
||||
|
||||
func discoverHelmModuleWorkload(ctx context.Context, c client.Reader, assembledWorkload *unstructured.Unstructured,
|
||||
_ *v1beta1.ComponentDefinition, helmResources []*unstructured.Unstructured) error {
|
||||
if len(helmResources) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(assembledWorkload.GetAPIVersion()) == 0 &&
|
||||
len(assembledWorkload.GetKind()) == 0 {
|
||||
// workload GVK remains to auto-detect
|
||||
// we cannot discover workload without GVK, and caller should skip dispatching the assembled workload
|
||||
return nil
|
||||
}
|
||||
ns := assembledWorkload.GetNamespace()
|
||||
var rls *unstructured.Unstructured
|
||||
for _, v := range helmResources {
|
||||
if v.GetKind() == helmapi.HelmReleaseGVK.Kind {
|
||||
rls = v.DeepCopy()
|
||||
break
|
||||
}
|
||||
}
|
||||
if rls == nil {
|
||||
return errors.New("cannot get helm release")
|
||||
}
|
||||
rlsName := rls.GetName()
|
||||
chartName, ok, err := unstructured.NestedString(rls.Object, helmapi.HelmChartNamePath...)
|
||||
if err != nil || !ok {
|
||||
return errors.New("cannot get helm chart name")
|
||||
}
|
||||
|
||||
// qualifiedFullName is used as the name of target workload.
|
||||
// It strictly follows the convention that Helm generate default full name as below:
|
||||
// > We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
// > If release name contains chart name it will be used as a full name.
|
||||
qualifiedWorkloadName := rlsName
|
||||
if !strings.Contains(rlsName, chartName) {
|
||||
qualifiedWorkloadName = fmt.Sprintf("%s-%s", rlsName, chartName)
|
||||
if len(qualifiedWorkloadName) > 63 {
|
||||
qualifiedWorkloadName = strings.TrimSuffix(qualifiedWorkloadName[:63], "-")
|
||||
}
|
||||
}
|
||||
|
||||
workloadByHelm := assembledWorkload.DeepCopy()
|
||||
if err := c.Get(ctx, client.ObjectKey{Namespace: ns, Name: qualifiedWorkloadName}, workloadByHelm); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// check it's created by helm and match the release info
|
||||
annots := workloadByHelm.GetAnnotations()
|
||||
labels := workloadByHelm.GetLabels()
|
||||
if annots == nil || labels == nil ||
|
||||
annots["meta.helm.sh/release-name"] != rlsName ||
|
||||
annots["meta.helm.sh/release-namespace"] != ns ||
|
||||
labels["app.kubernetes.io/managed-by"] != "Helm" {
|
||||
err := fmt.Errorf("the workload is found but not match with helm info(meta.helm.sh/release-name: %s, meta.helm.sh/namespace: %s, app.kubernetes.io/managed-by: Helm)", rlsName, ns)
|
||||
klog.ErrorS(err, "Found a name-matched workload but not managed by Helm", "name", qualifiedWorkloadName,
|
||||
"annotations", annots, "labels", labels)
|
||||
return err
|
||||
}
|
||||
assembledWorkload.SetName(qualifiedWorkloadName)
|
||||
return nil
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package assemble
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/pkg/errors"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
"github.com/crossplane/crossplane-runtime/pkg/test"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
helmapi "github.com/oam-dev/kubevela/pkg/appfile/helm/flux2apis"
|
||||
)
|
||||
|
||||
var _ = Describe("Test WorkloadOption", func() {
|
||||
var (
|
||||
appRev *v1beta1.ApplicationRevision
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
appRev = &v1beta1.ApplicationRevision{}
|
||||
b, err := os.ReadFile("./testdata/apprevision.yaml")
|
||||
Expect(err).Should(BeNil())
|
||||
err = yaml.Unmarshal(b, appRev)
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
|
||||
Describe("test DiscoveryHelmBasedWorkload", func() {
|
||||
ns := "test-ns"
|
||||
releaseName := "test-rls"
|
||||
chartName := "test-chart"
|
||||
release := &unstructured.Unstructured{}
|
||||
release.SetGroupVersionKind(helmapi.HelmReleaseGVK)
|
||||
release.SetName(releaseName)
|
||||
unstructured.SetNestedMap(release.Object, map[string]interface{}{
|
||||
"chart": map[string]interface{}{
|
||||
"spec": map[string]interface{}{
|
||||
"chart": chartName,
|
||||
"version": "1.0.0",
|
||||
},
|
||||
},
|
||||
}, "spec")
|
||||
|
||||
rlsWithoutChart := release.DeepCopy()
|
||||
unstructured.SetNestedMap(rlsWithoutChart.Object, nil, "spec", "chart")
|
||||
|
||||
wl := &unstructured.Unstructured{}
|
||||
wl.SetAPIVersion("apps/v1")
|
||||
wl.SetKind("Deployment")
|
||||
wl.SetLabels(map[string]string{
|
||||
"app.kubernetes.io/managed-by": "Helm",
|
||||
})
|
||||
wl.SetAnnotations(map[string]string{
|
||||
"meta.helm.sh/release-name": releaseName,
|
||||
"meta.helm.sh/release-namespace": ns,
|
||||
})
|
||||
type SubCase struct {
|
||||
reason string
|
||||
c client.Reader
|
||||
helm *unstructured.Unstructured
|
||||
workloadInComp *unstructured.Unstructured
|
||||
wantWorkload *unstructured.Unstructured
|
||||
wantErr error
|
||||
}
|
||||
|
||||
DescribeTable("Test cases for DiscoveryHelmBasedWorkload", func(tc SubCase) {
|
||||
By(tc.reason)
|
||||
assembledWorkload := &unstructured.Unstructured{}
|
||||
assembledWorkload.SetAPIVersion("apps/v1")
|
||||
assembledWorkload.SetKind("Deployment")
|
||||
assembledWorkload.SetNamespace(ns)
|
||||
err := discoverHelmModuleWorkload(context.Background(), tc.c, assembledWorkload, nil, []*unstructured.Unstructured{tc.helm})
|
||||
|
||||
By("Verify error")
|
||||
diff := cmp.Diff(tc.wantErr, err, test.EquateErrors())
|
||||
Expect(diff).Should(BeEmpty())
|
||||
|
||||
if tc.wantErr == nil {
|
||||
By("Verify found workload")
|
||||
diff = cmp.Diff(tc.wantWorkload, assembledWorkload)
|
||||
Expect(diff).Should(BeEmpty())
|
||||
}
|
||||
},
|
||||
Entry("CannotGetReleaseFromComp", SubCase{
|
||||
reason: "An error should occur because cannot get release",
|
||||
helm: &unstructured.Unstructured{},
|
||||
wantErr: errors.New("cannot get helm release"),
|
||||
}),
|
||||
Entry("CannotGetChartFromRelease", SubCase{
|
||||
reason: "An error should occur because cannot get chart info",
|
||||
helm: rlsWithoutChart.DeepCopy(),
|
||||
wantErr: errors.New("cannot get helm chart name"),
|
||||
}),
|
||||
Entry("CannotGetWorkload", SubCase{
|
||||
reason: "An error should occur because cannot get workload from k8s cluster",
|
||||
helm: release.DeepCopy(),
|
||||
workloadInComp: &unstructured.Unstructured{},
|
||||
c: &test.MockClient{MockGet: test.NewMockGetFn(errors.New("boom"))},
|
||||
wantErr: errors.New("boom"),
|
||||
}),
|
||||
Entry("GetNotMatchedWorkload", SubCase{
|
||||
reason: "An error should occur because the found workload is not managed by Helm",
|
||||
helm: release.DeepCopy(),
|
||||
workloadInComp: &unstructured.Unstructured{},
|
||||
c: &test.MockClient{MockGet: test.NewMockGetFn(nil, func(obj client.Object) error {
|
||||
o, _ := obj.(*unstructured.Unstructured)
|
||||
*o = unstructured.Unstructured{}
|
||||
o.SetLabels(map[string]string{
|
||||
"app.kubernetes.io/managed-by": "non-helm",
|
||||
})
|
||||
return nil
|
||||
})},
|
||||
wantErr: fmt.Errorf("the workload is found but not match with helm info(meta.helm.sh/release-name: %s,"+
|
||||
" meta.helm.sh/namespace: %s, app.kubernetes.io/managed-by: Helm)", "test-rls", "test-ns"),
|
||||
}),
|
||||
Entry("DiscoverSuccessfully", SubCase{
|
||||
reason: "No error should occur and the workload should be found",
|
||||
c: &test.MockClient{MockGet: test.NewMockGetFn(nil, func(obj client.Object) error {
|
||||
o, _ := obj.(*unstructured.Unstructured)
|
||||
*o = *wl.DeepCopy()
|
||||
return nil
|
||||
})},
|
||||
workloadInComp: wl.DeepCopy(),
|
||||
helm: release.DeepCopy(),
|
||||
wantWorkload: func() *unstructured.Unstructured {
|
||||
r := &unstructured.Unstructured{}
|
||||
r.SetAPIVersion("apps/v1")
|
||||
r.SetKind("Deployment")
|
||||
r.SetNamespace(ns)
|
||||
r.SetName("test-rls-test-chart")
|
||||
return r
|
||||
}(),
|
||||
wantErr: nil,
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -108,8 +108,8 @@ func ByTraitType(readyTraits, checkTraits []*unstructured.Unstructured) TraitFil
|
||||
|
||||
// manifestDispatcher is a manifest dispatcher
|
||||
type manifestDispatcher struct {
|
||||
run func(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision, clusterName string) (bool, error)
|
||||
healthCheck func(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision) (bool, error)
|
||||
run func(ctx context.Context, c *appfile.Component, appRev *v1beta1.ApplicationRevision, clusterName string) (bool, error)
|
||||
healthCheck func(ctx context.Context, c *appfile.Component, appRev *v1beta1.ApplicationRevision) (bool, error)
|
||||
}
|
||||
|
||||
func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, readyWorkload *unstructured.Unstructured, readyTraits []*unstructured.Unstructured, overrideNamespace string) ([]*manifestDispatcher, error) {
|
||||
@@ -124,25 +124,25 @@ func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, rea
|
||||
}
|
||||
|
||||
dispatcher := new(manifestDispatcher)
|
||||
dispatcher.healthCheck = func(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision) (bool, error) {
|
||||
skipWorkload, manifests := assembleManifestFn(wl.SkipApplyWorkload)
|
||||
dispatcher.healthCheck = func(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision) (bool, error) {
|
||||
skipWorkload, manifests := assembleManifestFn(comp.SkipApplyWorkload)
|
||||
if !h.resourceKeeper.ContainsResources(manifests) {
|
||||
return false, nil
|
||||
}
|
||||
_, _, _, isHealth, err := h.collectHealthStatus(ctx, wl, appRev, options.OverrideNamespace, skipWorkload,
|
||||
_, _, _, isHealth, err := h.collectHealthStatus(ctx, comp, appRev, options.OverrideNamespace, skipWorkload,
|
||||
ByTraitType(readyTraits, options.Traits))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return isHealth, nil
|
||||
}
|
||||
dispatcher.run = func(ctx context.Context, wl *appfile.Workload, appRev *v1beta1.ApplicationRevision, clusterName string) (bool, error) {
|
||||
skipWorkload, dispatchManifests := assembleManifestFn(wl.SkipApplyWorkload)
|
||||
if isHealth, err := dispatcher.healthCheck(ctx, wl, appRev); !isHealth || err != nil {
|
||||
dispatcher.run = func(ctx context.Context, comp *appfile.Component, appRev *v1beta1.ApplicationRevision, clusterName string) (bool, error) {
|
||||
skipWorkload, dispatchManifests := assembleManifestFn(comp.SkipApplyWorkload)
|
||||
if isHealth, err := dispatcher.healthCheck(ctx, comp, appRev); !isHealth || err != nil {
|
||||
if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, dispatchManifests...); err != nil {
|
||||
return false, errors.WithMessage(err, "Dispatch")
|
||||
}
|
||||
status, _, _, isHealth, err := h.collectHealthStatus(ctx, wl, appRev, options.OverrideNamespace, skipWorkload,
|
||||
status, _, _, isHealth, err := h.collectHealthStatus(ctx, comp, appRev, options.OverrideNamespace, skipWorkload,
|
||||
ByTraitType(readyTraits, options.Traits))
|
||||
if err != nil {
|
||||
return false, errors.WithMessage(err, "CollectHealthStatus")
|
||||
@@ -179,7 +179,7 @@ func (h *AppHandler) generateDispatcher(appRev *v1beta1.ApplicationRevision, rea
|
||||
traitType = splitName
|
||||
}
|
||||
}
|
||||
stageType, err = getTraitDispatchStage(h.r.Client, traitType, appRev)
|
||||
stageType, err = getTraitDispatchStage(h.Client, traitType, appRev)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -95,37 +95,39 @@ func (h *AppHandler) GenerateApplicationSteps(ctx monitorContext.Context,
|
||||
oam.LabelAppNamespace: app.Namespace,
|
||||
}
|
||||
handlerProviders := providers.NewProviders()
|
||||
kube.Install(handlerProviders, h.r.Client, appLabels, &kube.Handlers{
|
||||
kube.Install(handlerProviders, h.Client, appLabels, &kube.Handlers{
|
||||
Apply: h.Dispatch,
|
||||
Delete: h.Delete,
|
||||
})
|
||||
configprovider.Install(handlerProviders, h.r.Client, func(ctx context.Context, resources []*unstructured.Unstructured, applyOptions []apply.ApplyOption) error {
|
||||
configprovider.Install(handlerProviders, h.Client, func(ctx context.Context, resources []*unstructured.Unstructured, applyOptions []apply.ApplyOption) error {
|
||||
for _, res := range resources {
|
||||
res.SetLabels(util.MergeMapOverrideWithDst(res.GetLabels(), appLabels))
|
||||
}
|
||||
return h.resourceKeeper.Dispatch(ctx, resources, applyOptions)
|
||||
})
|
||||
oamProvider.Install(handlerProviders, app, af, h.r.Client, h.applyComponentFunc(
|
||||
appParser, appRev, af), h.renderComponentFunc(appParser, appRev, af))
|
||||
oamProvider.Install(handlerProviders, app, af, h.Client,
|
||||
h.applyComponentFunc(appParser, appRev, af),
|
||||
h.renderComponentFunc(appParser, appRev, af),
|
||||
)
|
||||
pCtx := velaprocess.NewContext(generateContextDataFromApp(app, appRev.Name))
|
||||
renderer := func(ctx context.Context, comp common.ApplicationComponent) (*appfile.Workload, error) {
|
||||
return appParser.ParseWorkloadFromRevisionAndClient(ctx, comp, appRev)
|
||||
renderer := func(ctx context.Context, comp common.ApplicationComponent) (*appfile.Component, error) {
|
||||
return appParser.ParseComponentFromRevisionAndClient(ctx, comp, appRev)
|
||||
}
|
||||
multiclusterProvider.Install(handlerProviders, h.r.Client, app, af,
|
||||
multiclusterProvider.Install(handlerProviders, h.Client, app, af,
|
||||
h.applyComponentFunc(appParser, appRev, af),
|
||||
h.checkComponentHealth(appParser, appRev, af),
|
||||
renderer)
|
||||
terraformProvider.Install(handlerProviders, app, renderer)
|
||||
query.Install(handlerProviders, h.r.Client, nil)
|
||||
query.Install(handlerProviders, h.Client, nil)
|
||||
|
||||
instance := generateWorkflowInstance(af, app)
|
||||
executor.InitializeWorkflowInstance(instance)
|
||||
runners, err := generator.GenerateRunners(ctx, instance, wfTypes.StepGeneratorOptions{
|
||||
Providers: handlerProviders,
|
||||
PackageDiscover: h.r.pd,
|
||||
PackageDiscover: h.pd,
|
||||
ProcessCtx: pCtx,
|
||||
TemplateLoader: template.NewWorkflowStepTemplateRevisionLoader(appRev, h.r.Client.RESTMapper()),
|
||||
Client: h.r.Client,
|
||||
TemplateLoader: template.NewWorkflowStepTemplateRevisionLoader(appRev, h.Client.RESTMapper()),
|
||||
Client: h.Client,
|
||||
StepConvertor: map[string]func(step workflowv1alpha1.WorkflowStep) (workflowv1alpha1.WorkflowStep, error){
|
||||
wfTypes.WorkflowStepTypeApplyComponent: func(lstep workflowv1alpha1.WorkflowStep) (workflowv1alpha1.WorkflowStep, error) {
|
||||
copierStep := lstep.DeepCopy()
|
||||
@@ -252,6 +254,7 @@ func convertStepProperties(step *workflowv1alpha1.WorkflowStep, app *v1beta1.App
|
||||
o := struct {
|
||||
Component string `json:"component"`
|
||||
Cluster string `json:"cluster"`
|
||||
Namespace string `json:"namespace"`
|
||||
}{}
|
||||
js, err := common.RawExtensionPointer{RawExtension: step.Properties}.MarshalJSON()
|
||||
if err != nil {
|
||||
@@ -291,6 +294,9 @@ func convertStepProperties(step *workflowv1alpha1.WorkflowStep, app *v1beta1.App
|
||||
"value": c,
|
||||
"cluster": o.Cluster,
|
||||
}
|
||||
if o.Namespace != "" {
|
||||
stepProperties["namespace"] = o.Namespace
|
||||
}
|
||||
step.Properties = util.Object2RawExtension(stepProperties)
|
||||
return nil
|
||||
}
|
||||
@@ -319,7 +325,7 @@ func (h *AppHandler) renderComponentFunc(appParser *appfile.Parser, appRev *v1be
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return renderComponentsAndTraits(h.r.Client, manifest, appRev, clusterName, overrideNamespace)
|
||||
return renderComponentsAndTraits(manifest, appRev, clusterName, overrideNamespace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,7 +341,7 @@ func (h *AppHandler) checkComponentHealth(appParser *appfile.Parser, appRev *v1b
|
||||
}
|
||||
wl.Ctx.SetCtx(auth.ContextWithUserInfo(ctx, h.app))
|
||||
|
||||
readyWorkload, readyTraits, err := renderComponentsAndTraits(h.r.Client, manifest, appRev, clusterName, overrideNamespace)
|
||||
readyWorkload, readyTraits, err := renderComponentsAndTraits(manifest, appRev, clusterName, overrideNamespace)
|
||||
if err != nil {
|
||||
return false, nil, nil, err
|
||||
}
|
||||
@@ -371,14 +377,9 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
if len(manifest.PackagedWorkloadResources) != 0 {
|
||||
if err := h.Dispatch(ctx, clusterName, common.WorkflowResourceCreator, manifest.PackagedWorkloadResources...); err != nil {
|
||||
return nil, nil, false, errors.WithMessage(err, "cannot dispatch packaged workload resources")
|
||||
}
|
||||
}
|
||||
wl.Ctx.SetCtx(auth.ContextWithUserInfo(ctx, h.app))
|
||||
|
||||
readyWorkload, readyTraits, err := renderComponentsAndTraits(h.r.Client, manifest, appRev, clusterName, overrideNamespace)
|
||||
readyWorkload, readyTraits, err := renderComponentsAndTraits(manifest, appRev, clusterName, overrideNamespace)
|
||||
if err != nil {
|
||||
return nil, nil, false, err
|
||||
}
|
||||
@@ -414,13 +415,13 @@ func (h *AppHandler) applyComponentFunc(appParser *appfile.Parser, appRev *v1bet
|
||||
if DisableResourceApplyDoubleCheck {
|
||||
return readyWorkload, readyTraits, isHealth, nil
|
||||
}
|
||||
workload, traits, err := getComponentResources(auth.ContextWithUserInfo(ctx, h.app), manifest, wl.SkipApplyWorkload, h.r.Client)
|
||||
workload, traits, err := getComponentResources(auth.ContextWithUserInfo(ctx, h.app), manifest, wl.SkipApplyWorkload, h.Client)
|
||||
return workload, traits, isHealth, err
|
||||
}
|
||||
}
|
||||
|
||||
// overrideTraits will override cluster field to be local for traits which are control plane only
|
||||
func overrideTraits(appRev *v1beta1.ApplicationRevision, readyTraits []*unstructured.Unstructured) []*unstructured.Unstructured {
|
||||
// redirectTraitToLocalIfNeed will override cluster field to be local for traits which are control plane only
|
||||
func redirectTraitToLocalIfNeed(appRev *v1beta1.ApplicationRevision, readyTraits []*unstructured.Unstructured) []*unstructured.Unstructured {
|
||||
traits := readyTraits
|
||||
for index, readyTrait := range readyTraits {
|
||||
for _, trait := range appRev.Spec.TraitDefinitions {
|
||||
@@ -439,8 +440,8 @@ func (h *AppHandler) prepareWorkloadAndManifests(ctx context.Context,
|
||||
comp common.ApplicationComponent,
|
||||
appRev *v1beta1.ApplicationRevision,
|
||||
patcher *value.Value,
|
||||
af *appfile.Appfile) (*appfile.Workload, *types.ComponentManifest, error) {
|
||||
wl, err := appParser.ParseWorkloadFromRevisionAndClient(ctx, comp, appRev)
|
||||
af *appfile.Appfile) (*appfile.Component, *types.ComponentManifest, error) {
|
||||
wl, err := appParser.ParseComponentFromRevisionAndClient(ctx, comp, appRev)
|
||||
if err != nil {
|
||||
return nil, nil, errors.WithMessage(err, "ParseWorkload")
|
||||
}
|
||||
@@ -457,7 +458,7 @@ func (h *AppHandler) prepareWorkloadAndManifests(ctx context.Context,
|
||||
ctxData.Cluster = cluster
|
||||
}
|
||||
// cluster info are secrets stored in the control plane cluster
|
||||
ctxData.ClusterVersion = multicluster.GetVersionInfoFromObject(pkgmulticluster.WithCluster(ctx, types.ClusterLocalName), h.r.Client, ctxData.Cluster)
|
||||
ctxData.ClusterVersion = multicluster.GetVersionInfoFromObject(pkgmulticluster.WithCluster(ctx, types.ClusterLocalName), h.Client, ctxData.Cluster)
|
||||
ctxData.CompRevision, _ = ctrlutil.ComputeSpecHash(comp)
|
||||
})
|
||||
if err != nil {
|
||||
@@ -469,8 +470,8 @@ func (h *AppHandler) prepareWorkloadAndManifests(ctx context.Context,
|
||||
return wl, manifest, nil
|
||||
}
|
||||
|
||||
func renderComponentsAndTraits(client client.Client, manifest *types.ComponentManifest, appRev *v1beta1.ApplicationRevision, clusterName string, overrideNamespace string) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
|
||||
readyWorkload, readyTraits, err := assemble.PrepareBeforeApply(manifest, appRev, []assemble.WorkloadOption{assemble.DiscoveryHelmBasedWorkload(context.TODO(), client)})
|
||||
func renderComponentsAndTraits(manifest *types.ComponentManifest, appRev *v1beta1.ApplicationRevision, clusterName string, overrideNamespace string) (*unstructured.Unstructured, []*unstructured.Unstructured, error) {
|
||||
readyWorkload, readyTraits, err := assemble.PrepareBeforeApply(manifest, appRev)
|
||||
if err != nil {
|
||||
return nil, nil, errors.WithMessage(err, "assemble resources before apply fail")
|
||||
}
|
||||
@@ -486,14 +487,14 @@ func renderComponentsAndTraits(client client.Client, manifest *types.ComponentMa
|
||||
readyTrait.SetNamespace(overrideNamespace)
|
||||
}
|
||||
}
|
||||
readyTraits = overrideTraits(appRev, readyTraits)
|
||||
readyTraits = redirectTraitToLocalIfNeed(appRev, readyTraits)
|
||||
return readyWorkload, readyTraits, nil
|
||||
}
|
||||
|
||||
func checkSkipApplyWorkload(wl *appfile.Workload) {
|
||||
for _, trait := range wl.Traits {
|
||||
func checkSkipApplyWorkload(comp *appfile.Component) {
|
||||
for _, trait := range comp.Traits {
|
||||
if trait.FullTemplate.TraitDefinition.Spec.ManageWorkload {
|
||||
wl.SkipApplyWorkload = true
|
||||
comp.SkipApplyWorkload = true
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -505,14 +506,14 @@ func getComponentResources(ctx context.Context, manifest *types.ComponentManifes
|
||||
traits []*unstructured.Unstructured
|
||||
)
|
||||
if !skipStandardWorkload {
|
||||
v := manifest.StandardWorkload.DeepCopy()
|
||||
if err := cli.Get(ctx, client.ObjectKeyFromObject(manifest.StandardWorkload), v); err != nil {
|
||||
v := manifest.ComponentOutput.DeepCopy()
|
||||
if err := cli.Get(ctx, client.ObjectKeyFromObject(manifest.ComponentOutput), v); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
workload = v
|
||||
}
|
||||
|
||||
for _, trait := range manifest.Traits {
|
||||
for _, trait := range manifest.ComponentOutputsAndTraits {
|
||||
v := trait.DeepCopy()
|
||||
remoteCtx := multicluster.ContextWithClusterName(ctx, oam.GetCluster(v))
|
||||
if err := cli.Get(remoteCtx, client.ObjectKeyFromObject(trait), v); err != nil {
|
||||
|
||||
@@ -113,7 +113,7 @@ var _ = Describe("Test Application workflow generator", func() {
|
||||
_, err = af.GeneratePolicyManifests(context.Background())
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
handler, err := NewAppHandler(ctx, reconciler, app, appParser)
|
||||
handler, err := NewAppHandler(ctx, reconciler, app)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
logCtx := monitorContext.NewTraceContext(ctx, "")
|
||||
@@ -157,7 +157,7 @@ var _ = Describe("Test Application workflow generator", func() {
|
||||
_, err = af.GeneratePolicyManifests(context.Background())
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
handler, err := NewAppHandler(ctx, reconciler, app, appParser)
|
||||
handler, err := NewAppHandler(ctx, reconciler, app)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
logCtx := monitorContext.NewTraceContext(ctx, "")
|
||||
@@ -199,7 +199,7 @@ var _ = Describe("Test Application workflow generator", func() {
|
||||
af, err := appParser.GenerateAppFile(ctx, app)
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
handler, err := NewAppHandler(ctx, reconciler, app, appParser)
|
||||
handler, err := NewAppHandler(ctx, reconciler, app)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
logCtx := monitorContext.NewTraceContext(ctx, "")
|
||||
@@ -241,7 +241,7 @@ var _ = Describe("Test Application workflow generator", func() {
|
||||
af, err := appParser.GenerateAppFile(ctx, app)
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
handler, err := NewAppHandler(ctx, reconciler, app, appParser)
|
||||
handler, err := NewAppHandler(ctx, reconciler, app)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
logCtx := monitorContext.NewTraceContext(ctx, "")
|
||||
@@ -280,7 +280,7 @@ var _ = Describe("Test Application workflow generator", func() {
|
||||
af, err := appParser.GenerateAppFile(ctx, app)
|
||||
Expect(err).Should(BeNil())
|
||||
|
||||
handler, err := NewAppHandler(ctx, reconciler, app, appParser)
|
||||
handler, err := NewAppHandler(ctx, reconciler, app)
|
||||
Expect(err).Should(Succeed())
|
||||
|
||||
logCtx := monitorContext.NewTraceContext(ctx, "")
|
||||
|
||||
@@ -27,7 +27,6 @@ import (
|
||||
apiequality "k8s.io/apimachinery/pkg/api/equality"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
ktypes "k8s.io/apimachinery/pkg/types"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/klog/v2"
|
||||
@@ -43,7 +42,6 @@ import (
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"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"
|
||||
"github.com/oam-dev/kubevela/pkg/appfile"
|
||||
"github.com/oam-dev/kubevela/pkg/cache"
|
||||
"github.com/oam-dev/kubevela/pkg/component"
|
||||
@@ -56,17 +54,6 @@ import (
|
||||
|
||||
type contextKey int
|
||||
|
||||
const (
|
||||
// ConfigMapKeyComponents is the key in ConfigMap Data field for containing data of components
|
||||
ConfigMapKeyComponents = "components"
|
||||
// ConfigMapKeyPolicy is the key in ConfigMap Data field for containing data of policies
|
||||
ConfigMapKeyPolicy = "policies"
|
||||
// ManifestKeyWorkload is the key in Component Manifest for containing workload cr.
|
||||
ManifestKeyWorkload = "StandardWorkload"
|
||||
// ManifestKeyTraits is the key in Component Manifest for containing Trait cr.
|
||||
ManifestKeyTraits = "Traits"
|
||||
)
|
||||
|
||||
var (
|
||||
// DisableAllComponentRevision disable component revision creation
|
||||
DisableAllComponentRevision = false
|
||||
@@ -92,64 +79,6 @@ func replicaKeyFromContext(ctx context.Context) string {
|
||||
return key
|
||||
}
|
||||
|
||||
func (h *AppHandler) createResourcesConfigMap(ctx context.Context,
|
||||
appRev *v1beta1.ApplicationRevision,
|
||||
comps []*types.ComponentManifest,
|
||||
policies []*unstructured.Unstructured) error {
|
||||
|
||||
components := map[string]interface{}{}
|
||||
for _, c := range comps {
|
||||
components[c.Name] = SprintComponentManifest(c)
|
||||
}
|
||||
cm := &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: appRev.Name,
|
||||
Namespace: appRev.Namespace,
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
*metav1.NewControllerRef(appRev, v1beta1.ApplicationRevisionGroupVersionKind),
|
||||
},
|
||||
},
|
||||
Data: map[string]string{
|
||||
ConfigMapKeyComponents: string(util.MustJSONMarshal(components)),
|
||||
ConfigMapKeyPolicy: string(util.MustJSONMarshal(policies)),
|
||||
},
|
||||
}
|
||||
err := h.r.Client.Get(ctx, client.ObjectKey{Name: appRev.Name, Namespace: appRev.Namespace}, &corev1.ConfigMap{})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if err != nil && !apierrors.IsNotFound(err) {
|
||||
return err
|
||||
}
|
||||
return h.r.Client.Create(ctx, cm)
|
||||
}
|
||||
|
||||
// SprintComponentManifest formats and returns the resulting string.
|
||||
func SprintComponentManifest(cm *types.ComponentManifest) string {
|
||||
if cm.StandardWorkload.GetName() == "" {
|
||||
cm.StandardWorkload.SetName(cm.Name)
|
||||
}
|
||||
if cm.StandardWorkload.GetNamespace() == "" {
|
||||
cm.StandardWorkload.SetNamespace(cm.Namespace)
|
||||
}
|
||||
cl := map[string]interface{}{
|
||||
ManifestKeyWorkload: string(util.MustJSONMarshal(cm.StandardWorkload)),
|
||||
}
|
||||
|
||||
trs := []string{}
|
||||
for _, tr := range cm.Traits {
|
||||
if tr.GetName() == "" {
|
||||
tr.SetName(cm.Name)
|
||||
}
|
||||
if tr.GetNamespace() == "" {
|
||||
tr.SetNamespace(cm.Namespace)
|
||||
}
|
||||
trs = append(trs, string(util.MustJSONMarshal(tr)))
|
||||
}
|
||||
cl[ManifestKeyTraits] = trs
|
||||
return string(util.MustJSONMarshal(cl))
|
||||
}
|
||||
|
||||
// PrepareCurrentAppRevision will generate a pure revision without metadata and rendered result
|
||||
// the generated revision will be compare with the last revision to see if there's any difference.
|
||||
func (h *AppHandler) PrepareCurrentAppRevision(ctx context.Context, af *appfile.Appfile) error {
|
||||
@@ -213,7 +142,7 @@ func (h *AppHandler) gatherRevisionSpec(af *appfile.Appfile) (*v1beta1.Applicati
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, w := range af.Workloads {
|
||||
for _, w := range af.ParsedComponents {
|
||||
if w == nil {
|
||||
continue
|
||||
}
|
||||
@@ -238,7 +167,7 @@ func (h *AppHandler) gatherRevisionSpec(af *appfile.Appfile) (*v1beta1.Applicati
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, p := range af.PolicyWorkloads {
|
||||
for _, p := range af.ParsedPolicies {
|
||||
if p == nil || p.FullTemplate == nil {
|
||||
continue
|
||||
}
|
||||
@@ -283,7 +212,7 @@ func (h *AppHandler) getLatestAppRevision(ctx context.Context) error {
|
||||
}
|
||||
latestRevName := h.app.Status.LatestRevision.Name
|
||||
latestAppRev := &v1beta1.ApplicationRevision{}
|
||||
if err := h.r.Get(ctx, client.ObjectKey{Name: latestRevName, Namespace: h.app.Namespace}, latestAppRev); err != nil {
|
||||
if err := h.Get(ctx, client.ObjectKey{Name: latestRevName, Namespace: h.app.Namespace}, latestAppRev); err != nil {
|
||||
klog.ErrorS(err, "Failed to get latest app revision", "appRevisionName", latestRevName)
|
||||
return errors.Wrapf(err, "fail to get latest app revision %s", latestRevName)
|
||||
}
|
||||
@@ -403,7 +332,7 @@ func (h *AppHandler) currentAppRevIsNew(ctx context.Context) (bool, bool, error)
|
||||
return false, false, nil
|
||||
}
|
||||
|
||||
revs, err := GetAppRevisions(ctx, h.r.Client, h.app.Name, h.app.Namespace)
|
||||
revs, err := GetAppRevisions(ctx, h.Client, h.app.Name, h.app.Namespace)
|
||||
if err != nil {
|
||||
klog.ErrorS(err, "Failed to list app revision", "appName", h.app.Name)
|
||||
return false, false, errors.Wrap(err, "failed to list app revision")
|
||||
@@ -504,35 +433,6 @@ func deepEqualAppInRevision(old, new *v1beta1.ApplicationRevision) bool {
|
||||
return deepEqualAppSpec(&old.Spec.Application, &new.Spec.Application)
|
||||
}
|
||||
|
||||
// ComputeComponentRevisionHash to compute component hash
|
||||
func ComputeComponentRevisionHash(comp *types.ComponentManifest) (string, error) {
|
||||
compRevisionHash := struct {
|
||||
WorkloadHash string
|
||||
PackagedResourcesHash []string
|
||||
}{}
|
||||
wl := comp.StandardWorkload.DeepCopy()
|
||||
if wl != nil {
|
||||
// Only calculate spec for component revision
|
||||
spec := wl.Object["spec"]
|
||||
hash, err := utils.ComputeSpecHash(spec)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
compRevisionHash.WorkloadHash = hash
|
||||
}
|
||||
|
||||
// take packaged workload resources into account because they determine the workload
|
||||
compRevisionHash.PackagedResourcesHash = make([]string, len(comp.PackagedWorkloadResources))
|
||||
for i, v := range comp.PackagedWorkloadResources {
|
||||
hash, err := utils.ComputeSpecHash(v)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
compRevisionHash.PackagedResourcesHash[i] = hash
|
||||
}
|
||||
return utils.ComputeSpecHash(&compRevisionHash)
|
||||
}
|
||||
|
||||
// FinalizeAndApplyAppRevision finalise AppRevision object and apply it
|
||||
func (h *AppHandler) FinalizeAndApplyAppRevision(ctx context.Context) error {
|
||||
if DisableAllApplicationRevision {
|
||||
@@ -567,9 +467,9 @@ func (h *AppHandler) FinalizeAndApplyAppRevision(ctx context.Context) error {
|
||||
sharding.PropagateScheduledShardIDLabel(h.app, appRev)
|
||||
|
||||
gotAppRev := &v1beta1.ApplicationRevision{}
|
||||
if err := h.r.Get(ctx, client.ObjectKey{Name: appRev.Name, Namespace: appRev.Namespace}, gotAppRev); err != nil {
|
||||
if err := h.Get(ctx, client.ObjectKey{Name: appRev.Name, Namespace: appRev.Namespace}, gotAppRev); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
return h.r.Create(ctx, appRev)
|
||||
return h.Create(ctx, appRev)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -588,12 +488,12 @@ func (h *AppHandler) FinalizeAndApplyAppRevision(ctx context.Context) error {
|
||||
appRev.Spec.Compression.SetType(compression.Zstd)
|
||||
}
|
||||
|
||||
return h.r.Update(ctx, appRev)
|
||||
return h.Update(ctx, appRev)
|
||||
}
|
||||
|
||||
// UpdateAppLatestRevisionStatus only call to update app's latest revision status after applying manifests successfully
|
||||
// otherwise it will override previous revision which is used during applying to do GC jobs
|
||||
func (h *AppHandler) UpdateAppLatestRevisionStatus(ctx context.Context) error {
|
||||
func (h *AppHandler) UpdateAppLatestRevisionStatus(ctx context.Context, patchStatus statusPatcher) error {
|
||||
if DisableAllApplicationRevision {
|
||||
return nil
|
||||
}
|
||||
@@ -614,7 +514,7 @@ func (h *AppHandler) UpdateAppLatestRevisionStatus(ctx context.Context) error {
|
||||
Revision: int64(revNum),
|
||||
RevisionHash: h.currentRevHash,
|
||||
}
|
||||
if err := h.r.patchStatus(ctx, h.app, common.ApplicationRendering); err != nil {
|
||||
if err := patchStatus(ctx, h.app, common.ApplicationRendering); err != nil {
|
||||
klog.InfoS("Failed to update the latest appConfig revision to status", "application", klog.KObj(h.app),
|
||||
"latest revision", revName, "err", err)
|
||||
return err
|
||||
@@ -635,13 +535,13 @@ func (h *AppHandler) UpdateApplicationRevisionStatus(ctx context.Context, appRev
|
||||
// Versioned the context backend values.
|
||||
if wfStatus.ContextBackend != nil {
|
||||
var cm corev1.ConfigMap
|
||||
if err := h.r.Client.Get(ctx, ktypes.NamespacedName{Namespace: wfStatus.ContextBackend.Namespace, Name: wfStatus.ContextBackend.Name}, &cm); err != nil {
|
||||
if err := h.Client.Get(ctx, ktypes.NamespacedName{Namespace: wfStatus.ContextBackend.Namespace, Name: wfStatus.ContextBackend.Name}, &cm); err != nil {
|
||||
klog.Error(err, "[UpdateApplicationRevisionStatus] failed to load the context values", "ApplicationRevision", appRev.Name)
|
||||
}
|
||||
appRev.Status.WorkflowContext = cm.Data
|
||||
}
|
||||
|
||||
if err := h.r.Client.Status().Update(ctx, appRev); err != nil {
|
||||
if err := h.Client.Status().Update(ctx, appRev); err != nil {
|
||||
if logCtx, ok := ctx.(monitorContext.Context); ok {
|
||||
logCtx.Error(err, "[UpdateApplicationRevisionStatus] failed to update application revision status", "ApplicationRevision", appRev.Name)
|
||||
} else {
|
||||
|
||||
@@ -37,7 +37,6 @@ import (
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
oamtypes "github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/appfile"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/oam/util"
|
||||
@@ -49,7 +48,6 @@ var _ = Describe("test generate revision ", func() {
|
||||
cd := v1beta1.ComponentDefinition{}
|
||||
webCompDef := v1beta1.ComponentDefinition{}
|
||||
var handler *AppHandler
|
||||
var comps []*oamtypes.ComponentManifest
|
||||
var namespaceName string
|
||||
var ns corev1.Namespace
|
||||
ctx := context.Background()
|
||||
@@ -117,7 +115,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
appRevision2 = *appRevision1.DeepCopy()
|
||||
appRevision2.Name = "appRevision2"
|
||||
|
||||
_handler, err := NewAppHandler(ctx, reconciler, &app, nil)
|
||||
_handler, err := NewAppHandler(ctx, reconciler, &app)
|
||||
Expect(err).Should(Succeed())
|
||||
handler = _handler
|
||||
})
|
||||
@@ -171,13 +169,11 @@ var _ = Describe("test generate revision ", func() {
|
||||
ctx = util.SetNamespaceInCtx(ctx, app.Namespace)
|
||||
generatedAppfile, err := appParser.GenerateAppFile(ctx, &app)
|
||||
Expect(err).Should(Succeed())
|
||||
comps, err = generatedAppfile.GenerateComponentManifests()
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
|
||||
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
|
||||
prevHash := generatedAppfile.AppRevisionHash
|
||||
handler.app.Status.LatestRevision = &common.Revision{Name: generatedAppfile.AppRevisionName, Revision: 1, RevisionHash: generatedAppfile.AppRevisionHash}
|
||||
generatedAppfile.Workloads[0].FullTemplate.ComponentDefinition = nil
|
||||
generatedAppfile.ParsedComponents[0].FullTemplate.ComponentDefinition = nil
|
||||
generatedAppfile.RelatedComponentDefinitions = map[string]*v1beta1.ComponentDefinition{}
|
||||
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
|
||||
nonChangeHash := generatedAppfile.AppRevisionHash
|
||||
@@ -196,17 +192,14 @@ var _ = Describe("test generate revision ", func() {
|
||||
app.SetAnnotations(map[string]string{annoKey1: "true"})
|
||||
generatedAppfile, err := appParser.GenerateAppFile(ctx, &app)
|
||||
Expect(err).Should(Succeed())
|
||||
comps, err = generatedAppfile.GenerateComponentManifests()
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
|
||||
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
|
||||
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
|
||||
Expect(handler.UpdateAppLatestRevisionStatus(ctx)).Should(Succeed())
|
||||
Expect(handler.UpdateAppLatestRevisionStatus(ctx, reconciler.patchStatus)).Should(Succeed())
|
||||
|
||||
curApp := &v1beta1.Application{}
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx,
|
||||
return handler.Get(ctx,
|
||||
types.NamespacedName{Namespace: ns.Name, Name: app.Name},
|
||||
curApp)
|
||||
},
|
||||
@@ -216,7 +209,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
curAppRevision := &v1beta1.ApplicationRevision{}
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx,
|
||||
return handler.Get(ctx,
|
||||
types.NamespacedName{Namespace: ns.Name, Name: curApp.Status.LatestRevision.Name},
|
||||
curAppRevision)
|
||||
},
|
||||
@@ -234,14 +227,11 @@ var _ = Describe("test generate revision ", func() {
|
||||
annoKey2 := "testKey2"
|
||||
app.SetAnnotations(map[string]string{annoKey2: "true"})
|
||||
lastRevision := curApp.Status.LatestRevision.Name
|
||||
comps, err = generatedAppfile.GenerateComponentManifests()
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
|
||||
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
|
||||
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx,
|
||||
return handler.Get(ctx,
|
||||
types.NamespacedName{Namespace: ns.Name, Name: app.Name},
|
||||
curApp)
|
||||
},
|
||||
@@ -254,7 +244,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
curAppRevision = &v1beta1.ApplicationRevision{}
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx,
|
||||
return handler.Get(ctx,
|
||||
types.NamespacedName{Namespace: ns.Name, Name: lastRevision},
|
||||
curAppRevision)
|
||||
},
|
||||
@@ -272,16 +262,13 @@ var _ = Describe("test generate revision ", func() {
|
||||
Expect(k8sClient.Update(ctx, &app)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
generatedAppfile, err = appParser.GenerateAppFile(ctx, &app)
|
||||
Expect(err).Should(Succeed())
|
||||
comps, err = generatedAppfile.GenerateComponentManifests()
|
||||
Expect(err).Should(Succeed())
|
||||
handler.app = &app
|
||||
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
|
||||
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
|
||||
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
|
||||
Expect(handler.UpdateAppLatestRevisionStatus(ctx)).Should(Succeed())
|
||||
Expect(handler.UpdateAppLatestRevisionStatus(ctx, reconciler.patchStatus)).Should(Succeed())
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx,
|
||||
return handler.Get(ctx,
|
||||
types.NamespacedName{Namespace: ns.Name, Name: app.Name},
|
||||
curApp)
|
||||
},
|
||||
@@ -295,7 +282,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
curAppRevision = &v1beta1.ApplicationRevision{}
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx,
|
||||
return handler.Get(ctx,
|
||||
types.NamespacedName{Namespace: ns.Name, Name: curApp.Status.LatestRevision.Name},
|
||||
curAppRevision)
|
||||
},
|
||||
@@ -316,16 +303,13 @@ var _ = Describe("test generate revision ", func() {
|
||||
Expect(k8sClient.Update(ctx, &app)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
generatedAppfile, err = appParser.GenerateAppFile(ctx, &app)
|
||||
Expect(err).Should(Succeed())
|
||||
comps, err = generatedAppfile.GenerateComponentManifests()
|
||||
Expect(err).Should(Succeed())
|
||||
handler.app = &app
|
||||
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
|
||||
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
|
||||
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
|
||||
Expect(handler.UpdateAppLatestRevisionStatus(ctx)).Should(Succeed())
|
||||
Expect(handler.UpdateAppLatestRevisionStatus(ctx, reconciler.patchStatus)).Should(Succeed())
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx,
|
||||
return handler.Get(ctx,
|
||||
types.NamespacedName{Namespace: ns.Name, Name: app.Name},
|
||||
curApp)
|
||||
},
|
||||
@@ -339,7 +323,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
curAppRevision = &v1beta1.ApplicationRevision{}
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx,
|
||||
return handler.Get(ctx,
|
||||
types.NamespacedName{Namespace: ns.Name, Name: curApp.Status.LatestRevision.Name},
|
||||
curAppRevision)
|
||||
},
|
||||
@@ -361,24 +345,21 @@ var _ = Describe("test generate revision ", func() {
|
||||
app.SetAnnotations(map[string]string{annoKey1: "true"})
|
||||
generatedAppfile, err := appParser.GenerateAppFile(ctx, &app)
|
||||
Expect(err).Should(Succeed())
|
||||
comps, err = generatedAppfile.GenerateComponentManifests()
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
|
||||
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
|
||||
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
|
||||
Expect(handler.UpdateAppLatestRevisionStatus(ctx)).Should(Succeed())
|
||||
Expect(handler.UpdateAppLatestRevisionStatus(ctx, reconciler.patchStatus)).Should(Succeed())
|
||||
|
||||
curApp := &v1beta1.Application{}
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: app.Name}, curApp)
|
||||
return handler.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: app.Name}, curApp)
|
||||
}, time.Second*10, time.Millisecond*500).Should(BeNil())
|
||||
Expect(curApp.Status.LatestRevision.Revision).Should(BeEquivalentTo(1))
|
||||
By("Verify the created appRevision is exactly what it is")
|
||||
curAppRevision := &v1beta1.ApplicationRevision{}
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx,
|
||||
return handler.Get(ctx,
|
||||
types.NamespacedName{Namespace: ns.Name, Name: curApp.Status.LatestRevision.Name},
|
||||
curAppRevision)
|
||||
},
|
||||
@@ -396,10 +377,9 @@ var _ = Describe("test generate revision ", func() {
|
||||
lastRevision := curApp.Status.LatestRevision.Name
|
||||
Expect(handler.PrepareCurrentAppRevision(ctx, generatedAppfile)).Should(Succeed())
|
||||
Expect(handler.FinalizeAndApplyAppRevision(ctx)).Should(Succeed())
|
||||
Expect(handler.ProduceArtifacts(context.Background(), comps, nil)).Should(Succeed())
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: app.Name}, curApp)
|
||||
return handler.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: app.Name}, curApp)
|
||||
}, time.Second*10, time.Millisecond*500).Should(BeNil())
|
||||
// no new revision should be created
|
||||
Expect(curApp.Status.LatestRevision.Name).Should(Equal(lastRevision))
|
||||
@@ -409,7 +389,7 @@ var _ = Describe("test generate revision ", func() {
|
||||
curAppRevision = &v1beta1.ApplicationRevision{}
|
||||
Eventually(
|
||||
func() error {
|
||||
return handler.r.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: lastRevision}, curAppRevision)
|
||||
return handler.Get(ctx, types.NamespacedName{Namespace: ns.Name, Name: lastRevision}, curAppRevision)
|
||||
}, time.Second*5, time.Millisecond*500).Should(BeNil())
|
||||
Expect(err).Should(Succeed())
|
||||
Expect(curAppRevision.GetLabels()[oam.LabelAppRevisionHash]).Should(Equal(appHash1))
|
||||
@@ -734,7 +714,7 @@ status: {}
|
||||
Expect(k8sClient.Create(ctx, &apprev)).Should(SatisfyAny(BeNil(), &util.AlreadyExistMatcher{}))
|
||||
|
||||
// prepare handler
|
||||
_handler, err := NewAppHandler(ctx, reconciler, &app, nil)
|
||||
_handler, err := NewAppHandler(ctx, reconciler, &app)
|
||||
Expect(err).Should(Succeed())
|
||||
handler = _handler
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ const (
|
||||
OutputFieldName = "output"
|
||||
// OutputsFieldName is the reference of context Auxiliaries
|
||||
OutputsFieldName = "outputs"
|
||||
// ConfigFieldName is the reference of context config
|
||||
ConfigFieldName = "config"
|
||||
// ParameterFieldName is the keyword in CUE template to define users' input and the reference to the context parameter
|
||||
ParameterFieldName = "parameter"
|
||||
// ContextName is the name of context
|
||||
|
||||
@@ -35,6 +35,9 @@ import (
|
||||
pkgdef "github.com/oam-dev/kubevela/pkg/definition"
|
||||
)
|
||||
|
||||
// GoProxyEnvKey with the environment variable name that defines the GOPROXY preferences.
|
||||
const GoProxyEnvKey = "GOPROXY"
|
||||
|
||||
var (
|
||||
mainModuleVersionKey langArgKey = "MainModuleVersion"
|
||||
goProxyKey langArgKey = "GoProxy"
|
||||
@@ -48,11 +51,13 @@ var (
|
||||
goProxy = LangArg{
|
||||
Name: goProxyKey,
|
||||
Desc: "The proxy for go get/go mod tidy command",
|
||||
Default: "https://goproxy.cn,direct",
|
||||
Default: "",
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Propagate the environment GOPROXY variable to the tests that are executed through external containers.
|
||||
goProxy.Default = os.Getenv(GoProxyEnvKey)
|
||||
registerLangArg("go", mainModuleVersion, goProxy)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,6 @@ const (
|
||||
LabelAppName = "app.oam.dev/name"
|
||||
// LabelAppRevision records the name of Application, it's equal to name of AppConfig created by Application
|
||||
LabelAppRevision = "app.oam.dev/appRevision"
|
||||
// LabelAppDeployment records the name of AppDeployment.
|
||||
LabelAppDeployment = "app.oam.dev/appDeployment"
|
||||
// LabelAppComponent records the name of Component
|
||||
LabelAppComponent = "app.oam.dev/component"
|
||||
// LabelReplicaKey records the replica key of Component
|
||||
@@ -62,11 +60,6 @@ const (
|
||||
|
||||
// LabelControllerRevisionComponent indicate which component the revision belong to
|
||||
LabelControllerRevisionComponent = "controller.oam.dev/component"
|
||||
// LabelComponentRevisionHash records the hash value of a component
|
||||
LabelComponentRevisionHash = "app.oam.dev/component-revision-hash"
|
||||
|
||||
// LabelAddonsName records the name of initializer stored in configMap
|
||||
LabelAddonsName = "addons.oam.dev/type"
|
||||
|
||||
// LabelAddonName indicates the name of the corresponding Addon
|
||||
LabelAddonName = "addons.oam.dev/name"
|
||||
@@ -142,13 +135,6 @@ const (
|
||||
// its controller should not try to reconcile it
|
||||
AnnotationAppRevision = "app.oam.dev/app-revision"
|
||||
|
||||
// AnnotationAppRevisionOnly the Application update should only generate revision,
|
||||
// not any appContexts or components.
|
||||
AnnotationAppRevisionOnly = "app.oam.dev/revision-only"
|
||||
|
||||
// AnnotationWorkflowContext is used to pass in the workflow context marshalled in json format.
|
||||
AnnotationWorkflowContext = "app.oam.dev/workflow-context"
|
||||
|
||||
// AnnotationKubeVelaVersion is used to record current KubeVela version
|
||||
AnnotationKubeVelaVersion = "oam.dev/kubevela-version"
|
||||
|
||||
@@ -158,15 +144,9 @@ const (
|
||||
// AnnotationFilterLabelKeys is used to filter labels passed to workload and trait, split by comma
|
||||
AnnotationFilterLabelKeys = "filter.oam.dev/label-keys"
|
||||
|
||||
// AnnotationSkipGC is used to tell application to skip gc workload/trait
|
||||
AnnotationSkipGC = "app.oam.dev/skipGC"
|
||||
|
||||
// AnnotationDefinitionRevisionName is used to specify the name of DefinitionRevision in component/trait definition
|
||||
AnnotationDefinitionRevisionName = "definitionrevision.oam.dev/name"
|
||||
|
||||
// AnnotationAddonsName records the name of initializer stored in configMap
|
||||
AnnotationAddonsName = "addons.oam.dev/name"
|
||||
|
||||
// AnnotationLastAppliedConfiguration is kubectl annotations for 3-way merge
|
||||
AnnotationLastAppliedConfiguration = "kubectl.kubernetes.io/last-applied-configuration"
|
||||
|
||||
@@ -189,12 +169,6 @@ const (
|
||||
// AnnotationAppAlias specifies the alias for application in db.
|
||||
AnnotationAppAlias = "app.oam.dev/appAlias"
|
||||
|
||||
// AnnotationWorkloadGVK indicates the managed workload's GVK by trait
|
||||
AnnotationWorkloadGVK = "trait.oam.dev/workload-gvk"
|
||||
|
||||
// AnnotationWorkloadName indicates the managed workload's name by trait
|
||||
AnnotationWorkloadName = "trait.oam.dev/workload-name"
|
||||
|
||||
// AnnotationControllerRequirement indicates the controller version that can process the application/definition.
|
||||
AnnotationControllerRequirement = "app.oam.dev/controller-version-require"
|
||||
|
||||
|
||||
@@ -32,8 +32,6 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
"github.com/kubevela/workflow/pkg/cue/packages"
|
||||
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
)
|
||||
|
||||
// Args is args for controller-runtime client
|
||||
@@ -125,20 +123,18 @@ func (a *Args) GetClient() (client.Client, error) {
|
||||
}
|
||||
|
||||
// GetFakeClient returns a fake client with the definition objects preloaded
|
||||
func (a *Args) GetFakeClient(defs []oam.Object) (client.Client, error) {
|
||||
func (a *Args) GetFakeClient(defs []*unstructured.Unstructured) (client.Client, error) {
|
||||
if a.client != nil {
|
||||
return a.client, nil
|
||||
}
|
||||
if a.config == nil {
|
||||
if err := a.SetConfig(nil); err != nil {
|
||||
if err := a.SetConfig(&rest.Config{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
objs := make([]client.Object, 0, len(defs))
|
||||
for _, def := range defs {
|
||||
if unstructDef, ok := def.(*unstructured.Unstructured); ok {
|
||||
objs = append(objs, unstructDef)
|
||||
}
|
||||
objs = append(objs, def)
|
||||
}
|
||||
return fake.NewClientBuilder().WithObjects(objs...).WithScheme(a.Schema).Build(), nil
|
||||
}
|
||||
|
||||
@@ -63,6 +63,8 @@ import (
|
||||
terraformapiv1 "github.com/oam-dev/terraform-controller/api/v1beta1"
|
||||
terraformapi "github.com/oam-dev/terraform-controller/api/v1beta2"
|
||||
|
||||
workflowv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
|
||||
|
||||
oamcore "github.com/oam-dev/kubevela/apis/core.oam.dev"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
velacue "github.com/oam-dev/kubevela/pkg/cue"
|
||||
@@ -93,6 +95,7 @@ func init() {
|
||||
_ = metricsV1beta1api.AddToScheme(Scheme)
|
||||
_ = kruisev1alpha1.AddToScheme(Scheme)
|
||||
_ = gatewayv1beta1.AddToScheme(Scheme)
|
||||
_ = workflowv1alpha1.AddToScheme(Scheme)
|
||||
// +kubebuilder:scaffold:scheme
|
||||
}
|
||||
|
||||
|
||||
@@ -80,3 +80,8 @@ func Sanitize(s string) string {
|
||||
s = strings.ReplaceAll(s, "\r", "")
|
||||
return s
|
||||
}
|
||||
|
||||
// IgnoreVPrefix removes the leading "v" from a string
|
||||
func IgnoreVPrefix(s string) string {
|
||||
return strings.TrimPrefix(s, "v")
|
||||
}
|
||||
|
||||
@@ -26,3 +26,8 @@ func TestSanitize(t *testing.T) {
|
||||
s := "abc\ndef\rgh"
|
||||
require.Equal(t, "abcdefgh", Sanitize(s))
|
||||
}
|
||||
|
||||
func TestIgnoreVPrefix(t *testing.T) {
|
||||
require.Equal(t, "1.2.0", IgnoreVPrefix("v1.2.0"))
|
||||
require.Equal(t, "1.2.0", IgnoreVPrefix("1.2.0"))
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
controller "github.com/oam-dev/kubevela/pkg/controller/core.oam.dev"
|
||||
"github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev/v1beta1/application"
|
||||
"github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev/v1beta1/componentdefinition"
|
||||
"github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev/v1beta1/policydefinition"
|
||||
"github.com/oam-dev/kubevela/pkg/webhook/core.oam.dev/v1beta1/traitdefinition"
|
||||
)
|
||||
|
||||
@@ -33,6 +34,7 @@ func Register(mgr manager.Manager, args controller.Args) {
|
||||
componentdefinition.RegisterMutatingHandler(mgr, args)
|
||||
componentdefinition.RegisterValidatingHandler(mgr)
|
||||
traitdefinition.RegisterValidatingHandler(mgr, args)
|
||||
policydefinition.RegisterValidatingHandler(mgr)
|
||||
server := mgr.GetWebhookServer()
|
||||
server.Register("/convert", &conversion.Webhook{})
|
||||
}
|
||||
|
||||
@@ -75,6 +75,14 @@ func (h *ValidatingHandler) Handle(ctx context.Context, req admission.Request) a
|
||||
return admission.Denied(err.Error())
|
||||
}
|
||||
|
||||
// validate cueTemplate
|
||||
if obj.Spec.Schematic != nil && obj.Spec.Schematic.CUE != nil {
|
||||
err = webhookutils.ValidateCueTemplate(obj.Spec.Schematic.CUE.Template)
|
||||
if err != nil {
|
||||
return admission.Denied(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
revisionName := obj.GetAnnotations()[oam.AnnotationDefinitionRevisionName]
|
||||
if len(revisionName) != 0 {
|
||||
defRevName := fmt.Sprintf("%s-v%s", obj.Name, revisionName)
|
||||
|
||||
@@ -49,13 +49,19 @@ var cdRaw []byte
|
||||
var testScheme = runtime.NewScheme()
|
||||
var testEnv *envtest.Environment
|
||||
var cfg *rest.Config
|
||||
var validCueTemplate string
|
||||
var inValidCueTemplate string
|
||||
|
||||
func TestTraitdefinition(t *testing.T) {
|
||||
func TestComponentdefinition(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Traitdefinition Suite")
|
||||
RunSpecs(t, "Componentdefinition Suite")
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func() {
|
||||
|
||||
validCueTemplate = "{hello: 'world'}"
|
||||
inValidCueTemplate = "{hello: world}"
|
||||
|
||||
var yamlPath string
|
||||
if _, set := os.LookupEnv("COMPATIBILITY_TEST"); set {
|
||||
yamlPath = "../../../../../test/compatibility-test/testdata"
|
||||
@@ -81,7 +87,6 @@ var _ = BeforeSuite(func() {
|
||||
|
||||
cd = v1beta1.ComponentDefinition{}
|
||||
cd.SetGroupVersionKind(v1beta1.ComponentDefinitionGroupVersionKind)
|
||||
cdRaw, _ = json.Marshal(cd)
|
||||
})
|
||||
|
||||
var _ = AfterSuite(func() {
|
||||
@@ -169,5 +174,60 @@ var _ = Describe("Test ComponentDefinition validating handler", func() {
|
||||
Expect(resp.Allowed).Should(BeFalse())
|
||||
Expect(resp.Result.Reason).Should(Equal(metav1.StatusReason("the type and the definition of the workload field in ComponentDefinition wrongCd should represent the same workload")))
|
||||
})
|
||||
It("Test cue template validation passed", func() {
|
||||
cd.Spec = v1beta1.ComponentDefinitionSpec{
|
||||
Workload: common.WorkloadTypeDescriptor{
|
||||
Type: "deployments.apps",
|
||||
Definition: common.WorkloadGVK{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
},
|
||||
Schematic: &common.Schematic{
|
||||
CUE: &common.CUE{
|
||||
Template: validCueTemplate,
|
||||
},
|
||||
},
|
||||
}
|
||||
cdRaw, _ = json.Marshal(cd)
|
||||
|
||||
req = admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
Resource: reqResource,
|
||||
Object: runtime.RawExtension{Raw: cdRaw},
|
||||
},
|
||||
}
|
||||
resp := handler.Handle(context.TODO(), req)
|
||||
Expect(resp.Allowed).Should(BeTrue())
|
||||
})
|
||||
It("Test cue template validation failed", func() {
|
||||
cd.Spec = v1beta1.ComponentDefinitionSpec{
|
||||
Workload: common.WorkloadTypeDescriptor{
|
||||
Type: "deployments.apps",
|
||||
Definition: common.WorkloadGVK{
|
||||
APIVersion: "apps/v1",
|
||||
Kind: "Deployment",
|
||||
},
|
||||
},
|
||||
Schematic: &common.Schematic{
|
||||
CUE: &common.CUE{
|
||||
Template: inValidCueTemplate,
|
||||
},
|
||||
},
|
||||
}
|
||||
cdRaw, _ = json.Marshal(cd)
|
||||
|
||||
req = admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
Resource: reqResource,
|
||||
Object: runtime.RawExtension{Raw: cdRaw},
|
||||
},
|
||||
}
|
||||
resp := handler.Handle(context.TODO(), req)
|
||||
Expect(resp.Allowed).Should(BeFalse())
|
||||
Expect(string(resp.Result.Reason)).Should(ContainSubstring("hello: reference \"world\" not found"))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
Copyright 2021. The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package policydefinition
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/runtime/inject"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
webhookutils "github.com/oam-dev/kubevela/pkg/webhook/utils"
|
||||
)
|
||||
|
||||
var policyDefGVR = v1beta1.SchemeGroupVersion.WithResource("policydefinitions")
|
||||
|
||||
// ValidatingHandler handles validation of policy definition
|
||||
type ValidatingHandler struct {
|
||||
// Decoder decodes object
|
||||
Decoder *admission.Decoder
|
||||
Client client.Client
|
||||
}
|
||||
|
||||
var _ inject.Client = &ValidatingHandler{}
|
||||
|
||||
// InjectClient injects the client into the ApplicationValidateHandler
|
||||
func (h *ValidatingHandler) InjectClient(c client.Client) error {
|
||||
if h.Client != nil {
|
||||
return nil
|
||||
}
|
||||
h.Client = c
|
||||
return nil
|
||||
}
|
||||
|
||||
var _ admission.Handler = &ValidatingHandler{}
|
||||
|
||||
// Handle validate component definition
|
||||
func (h *ValidatingHandler) Handle(ctx context.Context, req admission.Request) admission.Response {
|
||||
obj := &v1beta1.PolicyDefinition{}
|
||||
if req.Resource.String() != policyDefGVR.String() {
|
||||
return admission.Errored(http.StatusBadRequest, fmt.Errorf("expect resource to be %s", policyDefGVR))
|
||||
}
|
||||
|
||||
if req.Operation == admissionv1.Create || req.Operation == admissionv1.Update {
|
||||
err := h.Decoder.Decode(req, obj)
|
||||
if err != nil {
|
||||
return admission.Errored(http.StatusBadRequest, err)
|
||||
}
|
||||
|
||||
// validate cueTemplate
|
||||
if obj.Spec.Schematic != nil && obj.Spec.Schematic.CUE != nil {
|
||||
err = webhookutils.ValidateCueTemplate(obj.Spec.Schematic.CUE.Template)
|
||||
if err != nil {
|
||||
return admission.Denied(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
revisionName := obj.GetAnnotations()[oam.AnnotationDefinitionRevisionName]
|
||||
if len(revisionName) != 0 {
|
||||
defRevName := fmt.Sprintf("%s-v%s", obj.Name, revisionName)
|
||||
err = webhookutils.ValidateDefinitionRevision(ctx, h.Client, obj, client.ObjectKey{Namespace: obj.Namespace, Name: defRevName})
|
||||
if err != nil {
|
||||
return admission.Denied(err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
return admission.ValidationResponse(true, "")
|
||||
}
|
||||
|
||||
var _ admission.DecoderInjector = &ValidatingHandler{}
|
||||
|
||||
// InjectDecoder injects the decoder into the ValidatingHandler
|
||||
func (h *ValidatingHandler) InjectDecoder(d *admission.Decoder) error {
|
||||
h.Decoder = d
|
||||
return nil
|
||||
}
|
||||
|
||||
// RegisterValidatingHandler will register ComponentDefinition validation to webhook
|
||||
func RegisterValidatingHandler(mgr manager.Manager) {
|
||||
server := mgr.GetWebhookServer()
|
||||
server.Register("/validating-core-oam-dev-v1beta1-policydefinitions", &webhook.Admission{Handler: &ValidatingHandler{}})
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright 2021. The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package policydefinition
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
)
|
||||
|
||||
var handler ValidatingHandler
|
||||
var req admission.Request
|
||||
var reqResource metav1.GroupVersionResource
|
||||
var decoder *admission.Decoder
|
||||
var pd v1beta1.PolicyDefinition
|
||||
var pdRaw []byte
|
||||
var scheme = runtime.NewScheme()
|
||||
var validCueTemplate string
|
||||
var inValidCueTemplate string
|
||||
|
||||
func TestPolicydefinition(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
RunSpecs(t, "Policydefinition Suite")
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func() {
|
||||
|
||||
validCueTemplate = "{hello: 'world'}"
|
||||
inValidCueTemplate = "{hello: world}"
|
||||
|
||||
pd = v1beta1.PolicyDefinition{}
|
||||
pd.SetGroupVersionKind(v1beta1.PolicyDefinitionGroupVersionKind)
|
||||
|
||||
var err error
|
||||
decoder, err = admission.NewDecoder(scheme)
|
||||
Expect(err).Should(BeNil())
|
||||
})
|
||||
|
||||
var _ = Describe("Test PolicyDefinition validating handler", func() {
|
||||
BeforeEach(func() {
|
||||
reqResource = metav1.GroupVersionResource{
|
||||
Group: v1beta1.Group,
|
||||
Version: v1beta1.Version,
|
||||
Resource: "policydefinitions"}
|
||||
handler = ValidatingHandler{}
|
||||
handler.InjectDecoder(decoder)
|
||||
})
|
||||
|
||||
It("Test wrong resource of admission request", func() {
|
||||
wrongReqResource := metav1.GroupVersionResource{
|
||||
Group: v1beta1.Group,
|
||||
Version: v1beta1.Version,
|
||||
Resource: "foos"}
|
||||
req = admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
Resource: wrongReqResource,
|
||||
Object: runtime.RawExtension{Raw: []byte("")},
|
||||
},
|
||||
}
|
||||
resp := handler.Handle(context.TODO(), req)
|
||||
Expect(resp.Allowed).Should(BeFalse())
|
||||
})
|
||||
|
||||
It("Test bad admission request", func() {
|
||||
req = admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
Resource: reqResource,
|
||||
Object: runtime.RawExtension{Raw: []byte("bad request")},
|
||||
},
|
||||
}
|
||||
resp := handler.Handle(context.TODO(), req)
|
||||
Expect(resp.Allowed).Should(BeFalse())
|
||||
})
|
||||
|
||||
Context("Test create/update operation admission request", func() {
|
||||
It("Test cue template validation passed", func() {
|
||||
pd.Spec = v1beta1.PolicyDefinitionSpec{
|
||||
Schematic: &common.Schematic{
|
||||
CUE: &common.CUE{
|
||||
Template: validCueTemplate,
|
||||
},
|
||||
},
|
||||
}
|
||||
pdRaw, _ = json.Marshal(pd)
|
||||
|
||||
req = admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
Resource: reqResource,
|
||||
Object: runtime.RawExtension{Raw: pdRaw},
|
||||
},
|
||||
}
|
||||
resp := handler.Handle(context.TODO(), req)
|
||||
Expect(resp.Allowed).Should(BeTrue())
|
||||
})
|
||||
It("Test cue template validation failed", func() {
|
||||
pd.Spec = v1beta1.PolicyDefinitionSpec{
|
||||
Schematic: &common.Schematic{
|
||||
CUE: &common.CUE{
|
||||
Template: inValidCueTemplate,
|
||||
},
|
||||
},
|
||||
}
|
||||
pdRaw, _ = json.Marshal(pd)
|
||||
|
||||
req = admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
Resource: reqResource,
|
||||
Object: runtime.RawExtension{Raw: pdRaw},
|
||||
},
|
||||
}
|
||||
resp := handler.Handle(context.TODO(), req)
|
||||
Expect(resp.Allowed).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -89,6 +89,15 @@ func (h *ValidatingHandler) Handle(ctx context.Context, req admission.Request) a
|
||||
return admission.Denied(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// validate cueTemplate
|
||||
if obj.Spec.Schematic != nil && obj.Spec.Schematic.CUE != nil {
|
||||
err = webhookutils.ValidateCueTemplate(obj.Spec.Schematic.CUE.Template)
|
||||
if err != nil {
|
||||
return admission.Denied(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
revisionName := obj.GetAnnotations()[oam.AnnotationDefinitionRevisionName]
|
||||
if len(revisionName) != 0 {
|
||||
defRevName := fmt.Sprintf("%s-v%s", obj.Name, revisionName)
|
||||
|
||||
@@ -21,16 +21,16 @@ import (
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
admissionv1 "k8s.io/api/admission/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
)
|
||||
|
||||
var handler ValidatingHandler
|
||||
@@ -40,6 +40,8 @@ var decoder *admission.Decoder
|
||||
var td v1beta1.TraitDefinition
|
||||
var tdRaw []byte
|
||||
var scheme = runtime.NewScheme()
|
||||
var validCueTemplate string
|
||||
var inValidCueTemplate string
|
||||
|
||||
func TestTraitdefinition(t *testing.T) {
|
||||
RegisterFailHandler(Fail)
|
||||
@@ -47,9 +49,12 @@ func TestTraitdefinition(t *testing.T) {
|
||||
}
|
||||
|
||||
var _ = BeforeSuite(func() {
|
||||
|
||||
validCueTemplate = "{hello: 'world'}"
|
||||
inValidCueTemplate = "{hello: world}"
|
||||
|
||||
td = v1beta1.TraitDefinition{}
|
||||
td.SetGroupVersionKind(v1beta1.TraitDefinitionGroupVersionKind)
|
||||
tdRaw, _ = json.Marshal(td)
|
||||
|
||||
var err error
|
||||
decoder, err = admission.NewDecoder(scheme)
|
||||
@@ -104,6 +109,7 @@ var _ = Describe("Test TraitDefinition validating handler", func() {
|
||||
handler.Validators = []TraitDefValidator{
|
||||
TraitDefValidatorFn(mockValidator),
|
||||
}
|
||||
tdRaw, _ = json.Marshal(td)
|
||||
req = admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
@@ -122,6 +128,7 @@ var _ = Describe("Test TraitDefinition validating handler", func() {
|
||||
handler.Validators = []TraitDefValidator{
|
||||
TraitDefValidatorFn(mockValidator),
|
||||
}
|
||||
tdRaw, _ = json.Marshal(td)
|
||||
req = admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
@@ -133,5 +140,45 @@ var _ = Describe("Test TraitDefinition validating handler", func() {
|
||||
Expect(resp.Allowed).Should(BeFalse())
|
||||
Expect(resp.Result.Reason).Should(Equal(metav1.StatusReason("mock validator error")))
|
||||
})
|
||||
It("Test cue template validation passed", func() {
|
||||
td.Spec = v1beta1.TraitDefinitionSpec{
|
||||
Schematic: &common.Schematic{
|
||||
CUE: &common.CUE{
|
||||
Template: validCueTemplate,
|
||||
},
|
||||
},
|
||||
}
|
||||
tdRaw, _ = json.Marshal(td)
|
||||
|
||||
req = admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
Resource: reqResource,
|
||||
Object: runtime.RawExtension{Raw: tdRaw},
|
||||
},
|
||||
}
|
||||
resp := handler.Handle(context.TODO(), req)
|
||||
Expect(resp.Allowed).Should(BeTrue())
|
||||
})
|
||||
It("Test cue template validation failed", func() {
|
||||
td.Spec = v1beta1.TraitDefinitionSpec{
|
||||
Schematic: &common.Schematic{
|
||||
CUE: &common.CUE{
|
||||
Template: inValidCueTemplate,
|
||||
},
|
||||
},
|
||||
}
|
||||
tdRaw, _ = json.Marshal(td)
|
||||
|
||||
req = admission.Request{
|
||||
AdmissionRequest: admissionv1.AdmissionRequest{
|
||||
Operation: admissionv1.Create,
|
||||
Resource: reqResource,
|
||||
Object: runtime.RawExtension{Raw: tdRaw},
|
||||
},
|
||||
}
|
||||
resp := handler.Handle(context.TODO(), req)
|
||||
Expect(resp.Allowed).Should(BeFalse())
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -18,8 +18,11 @@ package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"cuelang.org/go/cue/cuecontext"
|
||||
cueErrors "cuelang.org/go/cue/errors"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -30,6 +33,9 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/controller/core.oam.dev/v1beta1/core"
|
||||
)
|
||||
|
||||
// ContextRegex to match '**: reference "context" not found'
|
||||
var ContextRegex = `^.+:\sreference\s\"context\"\snot\sfound$`
|
||||
|
||||
// ValidateDefinitionRevision validate whether definition will modify the immutable object definitionRevision
|
||||
func ValidateDefinitionRevision(ctx context.Context, cli client.Client, def runtime.Object, defRevNamespacedName types.NamespacedName) error {
|
||||
if errs := validation.IsQualifiedName(defRevNamespacedName.Name); len(errs) != 0 {
|
||||
@@ -53,3 +59,31 @@ func ValidateDefinitionRevision(ctx context.Context, cli client.Client, def runt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidateCueTemplate validate cueTemplate
|
||||
func ValidateCueTemplate(cueTemplate string) error {
|
||||
|
||||
val := cuecontext.New().CompileString(cueTemplate)
|
||||
if e := checkError(val.Err()); e != nil {
|
||||
return e
|
||||
}
|
||||
|
||||
err := val.Validate()
|
||||
if e := checkError(err); e != nil {
|
||||
return e
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkError(err error) error {
|
||||
re := regexp.MustCompile(ContextRegex)
|
||||
if err != nil {
|
||||
// ignore context not found error
|
||||
for _, e := range cueErrors.Errors(err) {
|
||||
if !re.MatchString(e.Error()) {
|
||||
return cueErrors.New(e.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
69
pkg/webhook/utils/utils_test.go
Normal file
69
pkg/webhook/utils/utils_test.go
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
Copyright 2021 The KubeVela Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"cuelang.org/go/cue/errors"
|
||||
"github.com/crossplane/crossplane-runtime/pkg/test"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
func TestValidateCueTemplate(t *testing.T) {
|
||||
cases := map[string]struct {
|
||||
cueTemplate string
|
||||
want error
|
||||
}{
|
||||
"normalCueTemp": {
|
||||
cueTemplate: "name: 'name'",
|
||||
want: nil,
|
||||
},
|
||||
"contextNouFoundCueTemp": {
|
||||
cueTemplate: `
|
||||
output: {
|
||||
metadata: {
|
||||
name: context.name
|
||||
label: context.label
|
||||
annotation: "default"
|
||||
}
|
||||
}`,
|
||||
want: nil,
|
||||
},
|
||||
"inValidCueTemp": {
|
||||
cueTemplate: `
|
||||
output: {
|
||||
metadata: {
|
||||
name: context.name
|
||||
label: context.label
|
||||
annotation: "default"
|
||||
},
|
||||
hello: world
|
||||
}`,
|
||||
want: errors.New("output.hello: reference \"world\" not found"),
|
||||
},
|
||||
}
|
||||
|
||||
for caseName, cs := range cases {
|
||||
t.Run(caseName, func(t *testing.T) {
|
||||
err := ValidateCueTemplate(cs.cueTemplate)
|
||||
if diff := cmp.Diff(cs.want, err, test.EquateErrors()); diff != "" {
|
||||
t.Errorf("\n%s\nValidateCueTemplate: -want , +got \n%s\n", cs.want, diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ type ComponentRender func(ctx context.Context, comp common.ApplicationComponent,
|
||||
type ComponentHealthCheck func(ctx context.Context, comp common.ApplicationComponent, patcher *value.Value, clusterName string, overrideNamespace string) (bool, *unstructured.Unstructured, []*unstructured.Unstructured, error)
|
||||
|
||||
// WorkloadRenderer renderer to render application component into workload
|
||||
type WorkloadRenderer func(ctx context.Context, comp common.ApplicationComponent) (*appfile.Workload, error)
|
||||
type WorkloadRenderer func(ctx context.Context, comp common.ApplicationComponent) (*appfile.Component, error)
|
||||
|
||||
type provider struct {
|
||||
render ComponentRender
|
||||
|
||||
@@ -33,14 +33,14 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/appfile"
|
||||
)
|
||||
|
||||
func fakeWorkloadRenderer(_ context.Context, comp apicommon.ApplicationComponent) (*appfile.Workload, error) {
|
||||
func fakeWorkloadRenderer(_ context.Context, comp apicommon.ApplicationComponent) (*appfile.Component, error) {
|
||||
if strings.HasPrefix(comp.Name, "error") {
|
||||
return nil, errors.New(comp.Name)
|
||||
}
|
||||
if strings.HasPrefix(comp.Name, "terraform") {
|
||||
return &appfile.Workload{CapabilityCategory: types.TerraformCategory}, nil
|
||||
return &appfile.Component{CapabilityCategory: types.TerraformCategory}, nil
|
||||
}
|
||||
return &appfile.Workload{CapabilityCategory: types.CUECategory}, nil
|
||||
return &appfile.Component{CapabilityCategory: types.CUECategory}, nil
|
||||
}
|
||||
|
||||
func TestLoadTerraformComponents(t *testing.T) {
|
||||
|
||||
@@ -174,7 +174,7 @@ func (g *DeployWorkflowStepGenerator) Generate(app *v1beta1.Application, existin
|
||||
steps = append(steps, workflowv1alpha1.WorkflowStep{
|
||||
WorkflowStepBase: workflowv1alpha1.WorkflowStepBase{
|
||||
Name: "deploy",
|
||||
Type: "deploy",
|
||||
Type: DeployWorkflowStep,
|
||||
Properties: util.Object2RawExtension(map[string]interface{}{"policies": append([]string{}, overrides...)}),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -290,3 +291,10 @@ func TestWorkflowStepGenerator(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsBuiltinWorkflowStepType(t *testing.T) {
|
||||
assert.True(t, IsBuiltinWorkflowStepType("suspend"))
|
||||
assert.True(t, IsBuiltinWorkflowStepType("apply-component"))
|
||||
assert.True(t, IsBuiltinWorkflowStepType("step-group"))
|
||||
assert.True(t, IsBuiltinWorkflowStepType("builtin-apply-component"))
|
||||
}
|
||||
|
||||
@@ -5,8 +5,9 @@ import (
|
||||
oam: op.oam
|
||||
// apply component and traits
|
||||
apply: oam.#ApplyComponent & {
|
||||
value: parameter.value
|
||||
cluster: parameter.cluster
|
||||
value: parameter.value
|
||||
cluster: parameter.cluster
|
||||
namespace: parameter.namespace
|
||||
}
|
||||
|
||||
if apply.output != _|_ {
|
||||
@@ -18,5 +19,6 @@ if apply.outputs != _|_ {
|
||||
}
|
||||
parameter: {
|
||||
value: {...}
|
||||
cluster: *"" | string
|
||||
cluster: *"" | string
|
||||
namespace: *"" | string
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func ApplyTerraform(app *v1beta1.Application, k8sClient client.Client, ioStream
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, wl := range appFile.Workloads {
|
||||
for i, wl := range appFile.ParsedComponents {
|
||||
switch wl.CapabilityCategory {
|
||||
case types.TerraformCategory:
|
||||
name := wl.Name
|
||||
@@ -191,8 +191,8 @@ func generateSecretFromTerraformOutput(k8sClient client.Client, outputList []str
|
||||
}
|
||||
|
||||
// getTerraformJSONFiles gets Terraform JSON files or modules from workload
|
||||
func getTerraformJSONFiles(wl *appfile.Workload, ctxData process.ContextData) ([]byte, error) {
|
||||
pCtx, err := appfile.PrepareProcessContext(wl, ctxData)
|
||||
func getTerraformJSONFiles(comp *appfile.Component, ctxData process.ContextData) ([]byte, error) {
|
||||
pCtx, err := appfile.PrepareProcessContext(comp, ctxData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -1247,6 +1247,9 @@ func checkUninstallFromClusters(ctx context.Context, k8sClient client.Client, ad
|
||||
}
|
||||
installedClusters = append(installedClusters, c)
|
||||
}
|
||||
if len(disableClusters) == 0 {
|
||||
return nil
|
||||
}
|
||||
fmt.Println(color.New(color.FgRed).Sprintf("'%s' addon was currently installed on clusters %s, but this operation will uninstall from these clusters: %s \n", addonName, generateClustersInfo(installedClusters), generateClustersInfo(disableClusters)))
|
||||
input := NewUserInput()
|
||||
if !input.AskBool("Do you want to continue?", &UserInputOptions{AssumeYes: false}) {
|
||||
|
||||
@@ -60,6 +60,10 @@ func NewCommandWithIOStreams(ioStream util.IOStreams) *cobra.Command {
|
||||
ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
|
||||
return nil, cobra.ShellCompDirectiveNoFileComp
|
||||
},
|
||||
FParseErrWhitelist: cobra.FParseErrWhitelist{
|
||||
// Allow unknown flags for backward-compatibility.
|
||||
UnknownFlags: true,
|
||||
},
|
||||
}
|
||||
|
||||
scheme := common.Scheme
|
||||
|
||||
@@ -87,6 +87,7 @@ func ClusterCommandGroup(f velacmd.Factory, order string, c common.Args, ioStrea
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.SetOut(ioStreams.Out)
|
||||
cmd.AddCommand(
|
||||
NewClusterListCommand(&c),
|
||||
NewClusterJoinCommand(&c, ioStreams),
|
||||
|
||||
@@ -190,7 +190,7 @@ func PrintComponentListFromRegistry(registry Registry, ioStreams cmdutil.IOStrea
|
||||
|
||||
// InstallCompByNameFromRegistry will install given componentName comp to cluster from registry
|
||||
func InstallCompByNameFromRegistry(args common2.Args, ioStream cmdutil.IOStreams, compName string, registry Registry) error {
|
||||
capObj, data, err := registry.GetCap(compName)
|
||||
_, data, err := registry.GetCap(compName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -200,7 +200,7 @@ func InstallCompByNameFromRegistry(args common2.Args, ioStream cmdutil.IOStreams
|
||||
return err
|
||||
}
|
||||
|
||||
err = common.InstallComponentDefinition(k8sClient, data, ioStream, &capObj)
|
||||
err = common.InstallComponentDefinition(k8sClient, data, ioStream)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ import (
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/appfile/dryrun"
|
||||
"github.com/oam-dev/kubevela/pkg/oam"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
|
||||
)
|
||||
@@ -119,7 +118,7 @@ func (d *debugOpts) debugApplication(ctx context.Context, wargs *WorkflowArgs, c
|
||||
return d.debugWorkflow(ctx, wargs, cli, pd, ioStreams)
|
||||
}
|
||||
|
||||
dryRunOpt := dryrun.NewDryRunOption(cli, config, pd, []oam.Object{}, false)
|
||||
dryRunOpt := dryrun.NewDryRunOption(cli, config, pd, []*unstructured.Unstructured{}, false)
|
||||
comps, _, err := dryRunOpt.ExecuteDryRun(ctx, app)
|
||||
if err != nil {
|
||||
ioStreams.Info(color.RedString("%s%s", emojiFail, err.Error()))
|
||||
@@ -176,8 +175,8 @@ func (d *debugOpts) debugComponents(comps []*types.ComponentManifest, ioStreams
|
||||
var components = make(map[string]*unstructured.Unstructured)
|
||||
var traits = make(map[string][]*unstructured.Unstructured)
|
||||
for _, comp := range comps {
|
||||
components[comp.Name] = comp.StandardWorkload
|
||||
traits[comp.Name] = comp.Traits
|
||||
components[comp.Name] = comp.ComponentOutput
|
||||
traits[comp.Name] = comp.ComponentOutputsAndTraits
|
||||
}
|
||||
|
||||
if d.step != "" {
|
||||
|
||||
@@ -82,6 +82,7 @@ func DefinitionCommandGroup(c common.Args, order string, ioStreams util.IOStream
|
||||
types.TagCommandType: types.TypeExtension,
|
||||
},
|
||||
}
|
||||
cmd.SetOut(ioStreams.Out)
|
||||
cmd.AddCommand(
|
||||
NewDefinitionGetCommand(c),
|
||||
NewDefinitionListCommand(c),
|
||||
|
||||
@@ -26,17 +26,17 @@ import (
|
||||
"strings"
|
||||
|
||||
wfv1alpha1 "github.com/kubevela/workflow/api/v1alpha1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/step"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
apicommon "github.com/oam-dev/kubevela/apis/core.oam.dev/common"
|
||||
"github.com/oam-dev/kubevela/apis/core.oam.dev/v1alpha1"
|
||||
corev1beta1 "github.com/oam-dev/kubevela/apis/core.oam.dev/v1beta1"
|
||||
"github.com/oam-dev/kubevela/apis/types"
|
||||
"github.com/oam-dev/kubevela/pkg/appfile/dryrun"
|
||||
@@ -46,6 +46,7 @@ import (
|
||||
"github.com/oam-dev/kubevela/pkg/utils"
|
||||
"github.com/oam-dev/kubevela/pkg/utils/common"
|
||||
cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
|
||||
"github.com/oam-dev/kubevela/pkg/workflow/step"
|
||||
)
|
||||
|
||||
// DryRunCmdOptions contains dry-run cmd options
|
||||
@@ -130,7 +131,7 @@ func DryRunApplication(cmdOption *DryRunCmdOptions, c common.Args, namespace str
|
||||
var err error
|
||||
var buff = bytes.Buffer{}
|
||||
|
||||
var objs []oam.Object
|
||||
var objs []*unstructured.Unstructured
|
||||
if cmdOption.DefinitionFile != "" {
|
||||
objs, err = ReadDefinitionsFromFile(cmdOption.DefinitionFile)
|
||||
if err != nil {
|
||||
@@ -142,6 +143,7 @@ func DryRunApplication(cmdOption *DryRunCmdOptions, c common.Args, namespace str
|
||||
var newClient client.Client
|
||||
if cmdOption.OfflineMode {
|
||||
// We will load a fake client with all the objects present in the definitions file preloaded
|
||||
objs = includeBuiltinWorkflowStepDefinition(objs)
|
||||
newClient, err = c.GetFakeClient(objs)
|
||||
} else {
|
||||
// Load an actual client here
|
||||
@@ -185,7 +187,7 @@ func DryRunApplication(cmdOption *DryRunCmdOptions, c common.Args, namespace str
|
||||
return buff, nil
|
||||
}
|
||||
|
||||
func readObj(path string) (oam.Object, error) {
|
||||
func readObj(path string) (*unstructured.Unstructured, error) {
|
||||
switch {
|
||||
case strings.HasSuffix(path, ".cue"):
|
||||
def := pkgdef.Definition{Unstructured: unstructured.Unstructured{}}
|
||||
@@ -209,7 +211,7 @@ func readObj(path string) (oam.Object, error) {
|
||||
}
|
||||
|
||||
// ReadDefinitionsFromFile will read objects from file or dir in the format of yaml
|
||||
func ReadDefinitionsFromFile(path string) ([]oam.Object, error) {
|
||||
func ReadDefinitionsFromFile(path string) ([]*unstructured.Unstructured, error) {
|
||||
fi, err := os.Stat(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -219,10 +221,10 @@ func ReadDefinitionsFromFile(path string) ([]oam.Object, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return []oam.Object{obj}, nil
|
||||
return []*unstructured.Unstructured{obj}, nil
|
||||
}
|
||||
|
||||
var objs []oam.Object
|
||||
var objs []*unstructured.Unstructured
|
||||
//nolint:gosec
|
||||
fis, err := os.ReadDir(path)
|
||||
if err != nil {
|
||||
@@ -401,3 +403,45 @@ func getPolicyNameFromWorkflow(wf *wfv1alpha1.Workflow, policyNameMap map[string
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// includeBuiltinWorkflowStepDefinition adds builtin workflow step definition to the given objects
|
||||
// A few builtin workflow steps have cue definition. They should be included when building offline fake client.
|
||||
func includeBuiltinWorkflowStepDefinition(objs []*unstructured.Unstructured) []*unstructured.Unstructured {
|
||||
deployUnstructured, _ := oamutil.Object2Unstructured(deployDefinition)
|
||||
return append(objs, deployUnstructured)
|
||||
}
|
||||
|
||||
// deployDefinition is the definition of deploy step
|
||||
// Copied it here to make dry-run work in offline mode.
|
||||
var deployDefinition = &corev1beta1.WorkflowStepDefinition{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: corev1beta1.WorkflowStepDefinitionKind,
|
||||
APIVersion: corev1beta1.SchemeGroupVersion.String(),
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "deploy",
|
||||
Namespace: oam.SystemDefinitionNamespace,
|
||||
},
|
||||
Spec: corev1beta1.WorkflowStepDefinitionSpec{
|
||||
Schematic: &apicommon.Schematic{
|
||||
CUE: &apicommon.CUE{Template: `
|
||||
import (
|
||||
"vela/op"
|
||||
)
|
||||
|
||||
"deploy": {
|
||||
type: "workflow-step"
|
||||
annotations: {
|
||||
"category": "Application Delivery"
|
||||
}
|
||||
labels: {
|
||||
"scope": "Application"
|
||||
}
|
||||
description: "A powerful and unified deploy step for components multi-cluster delivery with policies."
|
||||
}
|
||||
// Ignore the template field for it's useless in dry-run.
|
||||
template: {}`,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -224,10 +224,7 @@ var _ = Describe("Testing dry-run", func() {
|
||||
})
|
||||
|
||||
It("Testing dry-run offline", func() {
|
||||
|
||||
c := common2.Args{}
|
||||
c.SetConfig(cfg)
|
||||
c.SetClient(k8sClient)
|
||||
opt := DryRunCmdOptions{ApplicationFiles: []string{"test-data/dry-run/testing-dry-run-6.yaml"}, DefinitionFile: "test-data/dry-run/testing-worker-def.yaml", OfflineMode: true}
|
||||
buff, err := DryRunApplication(&opt, c, "")
|
||||
Expect(err).Should(BeNil())
|
||||
@@ -237,6 +234,18 @@ var _ = Describe("Testing dry-run", func() {
|
||||
Expect(buff.String()).Should(ContainSubstring("workload.oam.dev/type: myworker"))
|
||||
})
|
||||
|
||||
It("Testing dry-run offline with deploy workflow step", func() {
|
||||
c := common2.Args{}
|
||||
opt := DryRunCmdOptions{ApplicationFiles: []string{"test-data/dry-run/testing-dry-run-7.yaml"}, DefinitionFile: "test-data/dry-run/testing-worker-def.yaml", OfflineMode: true}
|
||||
buff, err := DryRunApplication(&opt, c, "")
|
||||
Expect(err).Should(BeNil())
|
||||
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app with topology target-prod)"))
|
||||
Expect(buff.String()).Should(ContainSubstring("# Application(testing-app with topology target-default)"))
|
||||
Expect(buff.String()).Should(ContainSubstring("name: testing-dryrun"))
|
||||
Expect(buff.String()).Should(ContainSubstring("kind: Deployment"))
|
||||
Expect(buff.String()).Should(ContainSubstring("workload.oam.dev/type: myworker"))
|
||||
})
|
||||
|
||||
It("Testing dry-run with default application namespace", func() {
|
||||
c := common2.Args{}
|
||||
c.SetConfig(cfg)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user