mirror of
https://github.com/fluxcd/flagger.git
synced 2026-04-15 06:57:34 +00:00
Compare commits
289 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6ac5e19aa | ||
|
|
6a090bca51 | ||
|
|
e07a2618c2 | ||
|
|
9fcb6e9c93 | ||
|
|
a88e06db17 | ||
|
|
401d0490da | ||
|
|
3d1aedeb44 | ||
|
|
4015103815 | ||
|
|
74b98dab00 | ||
|
|
01dfa06891 | ||
|
|
90054b3b27 | ||
|
|
cff2032ac0 | ||
|
|
2d5e289142 | ||
|
|
f38183bfd1 | ||
|
|
c09a61a198 | ||
|
|
417f035afb | ||
|
|
28f2ab7bdb | ||
|
|
d6433a16b5 | ||
|
|
9b39cf16f1 | ||
|
|
d2cfcbde1a | ||
|
|
133fdecf56 | ||
|
|
3490d60e89 | ||
|
|
97d1ef0f18 | ||
|
|
ce976e28f0 | ||
|
|
adc60596f5 | ||
|
|
cf04e28774 | ||
|
|
ba29384dd4 | ||
|
|
86a4514932 | ||
|
|
61d81ff35a | ||
|
|
588f91ab7b | ||
|
|
24b968029e | ||
|
|
0ab3c07017 | ||
|
|
2d89870b14 | ||
|
|
8e86366484 | ||
|
|
e5dfbf4adc | ||
|
|
04f5c68a83 | ||
|
|
52293a35ad | ||
|
|
553184b82b | ||
|
|
6289f8e371 | ||
|
|
5e6815d531 | ||
|
|
66d69f3d22 | ||
|
|
9a0c6e7e54 | ||
|
|
2ddbaf3324 | ||
|
|
ab68d18230 | ||
|
|
214022ce7b | ||
|
|
9acc70efc3 | ||
|
|
4a12fc8499 | ||
|
|
407e28e632 | ||
|
|
82589a525d | ||
|
|
6651751fbe | ||
|
|
62fd5d2f77 | ||
|
|
0a616df01e | ||
|
|
f3be47d90b | ||
|
|
935d6f9746 | ||
|
|
ded722fb2d | ||
|
|
a437af030a | ||
|
|
e3a529e1c8 | ||
|
|
e153b8a3df | ||
|
|
c45be96f73 | ||
|
|
dfa403705d | ||
|
|
9a0f01079f | ||
|
|
b778013e07 | ||
|
|
29576900df | ||
|
|
5c70efb124 | ||
|
|
9a224a0c90 | ||
|
|
bd3249feae | ||
|
|
740477a757 | ||
|
|
27967d7780 | ||
|
|
0e6c88261f | ||
|
|
7780a85bfa | ||
|
|
1f073843bf | ||
|
|
5b03840db6 | ||
|
|
fb4af8217d | ||
|
|
757d90121b | ||
|
|
217db66a5e | ||
|
|
1a27295728 | ||
|
|
285ee6eee7 | ||
|
|
613f532b0d | ||
|
|
619253ebce | ||
|
|
3f06a0b344 | ||
|
|
cf6e241fa5 | ||
|
|
8128ab3785 | ||
|
|
c0a00e6970 | ||
|
|
2c3259bdb3 | ||
|
|
3d40ee1242 | ||
|
|
dd89cd5625 | ||
|
|
af1e210f08 | ||
|
|
4932527464 | ||
|
|
862c63e8c3 | ||
|
|
f946e0e9e8 | ||
|
|
0a2169965a | ||
|
|
169aea200c | ||
|
|
785db00796 | ||
|
|
a88c056e04 | ||
|
|
6584f452b7 | ||
|
|
16f8e15c98 | ||
|
|
5f8aeb878b | ||
|
|
d618cfcedd | ||
|
|
471da0abba | ||
|
|
b562ddd3e2 | ||
|
|
82e5e3ad93 | ||
|
|
fa30864580 | ||
|
|
dc9fc923e4 | ||
|
|
6f42af4ade | ||
|
|
28afd0acd6 | ||
|
|
0810972d31 | ||
|
|
64f393fd60 | ||
|
|
a2d147387c | ||
|
|
3a887bd79a | ||
|
|
9f5ad2ec23 | ||
|
|
d1de1d788d | ||
|
|
7e95b1a8a5 | ||
|
|
83b5800009 | ||
|
|
daab49730e | ||
|
|
825b5d103a | ||
|
|
eb8026e22b | ||
|
|
e9b8dee726 | ||
|
|
37621dead8 | ||
|
|
1f2c464b45 | ||
|
|
09b0937e18 | ||
|
|
0d0d0ef811 | ||
|
|
8935ef5e6a | ||
|
|
61eee5750b | ||
|
|
ad8e7d613a | ||
|
|
3e87c153db | ||
|
|
9189f17ff8 | ||
|
|
749e099ff0 | ||
|
|
63ec848b38 | ||
|
|
8c078e898b | ||
|
|
e784f88045 | ||
|
|
c5369e9113 | ||
|
|
d196fae71c | ||
|
|
d7bf6a2474 | ||
|
|
d796c206d3 | ||
|
|
55db424082 | ||
|
|
750a1e53aa | ||
|
|
450abb60b9 | ||
|
|
ce70a50047 | ||
|
|
f465a6cdda | ||
|
|
c1f39443d6 | ||
|
|
6112ad9c54 | ||
|
|
8dbc72d7ff | ||
|
|
dc6dd0661a | ||
|
|
475aff81ae | ||
|
|
968a193f42 | ||
|
|
22a9fd3d12 | ||
|
|
8ada61edd1 | ||
|
|
cadce1a2c2 | ||
|
|
3a7fd48d3a | ||
|
|
15ef64eb14 | ||
|
|
c0e2096f92 | ||
|
|
e4c05c3034 | ||
|
|
794fea8cc6 | ||
|
|
56b6339f8c | ||
|
|
788e692e90 | ||
|
|
a517309557 | ||
|
|
ecdde862bf | ||
|
|
0bcc814154 | ||
|
|
aaafdca6ca | ||
|
|
22c96c5af5 | ||
|
|
04a1f2fa68 | ||
|
|
efc588001f | ||
|
|
d543c8ef95 | ||
|
|
da7015397c | ||
|
|
fe32b2162d | ||
|
|
68d306ca83 | ||
|
|
7ab0eb14ea | ||
|
|
0eaf054e8b | ||
|
|
a312f6a5e1 | ||
|
|
00fcf991a6 | ||
|
|
8dbd8d509b | ||
|
|
ff25d1ee92 | ||
|
|
2d3f039d80 | ||
|
|
69cb3cd881 | ||
|
|
225e968288 | ||
|
|
f0ffb67cff | ||
|
|
dc8fe81c91 | ||
|
|
f29c74b957 | ||
|
|
dfc0c96824 | ||
|
|
1093c64d5a | ||
|
|
993385036c | ||
|
|
0c8b5048dd | ||
|
|
c90da790c5 | ||
|
|
cef1bb8e67 | ||
|
|
34b544bb47 | ||
|
|
2fd45cd0d8 | ||
|
|
aec43794d8 | ||
|
|
d35ecbeba8 | ||
|
|
e1b9d64379 | ||
|
|
137d31ac79 | ||
|
|
b30855480f | ||
|
|
cc08d31622 | ||
|
|
d021e25757 | ||
|
|
7a0e95b498 | ||
|
|
c812dcffc1 | ||
|
|
e1c4257b68 | ||
|
|
a31a46f375 | ||
|
|
a41a7bb6a4 | ||
|
|
2992a99bbc | ||
|
|
eb302fe16e | ||
|
|
2e4fe73d34 | ||
|
|
aad4f54afa | ||
|
|
311cb5f2fd | ||
|
|
388c0ef344 | ||
|
|
3feaabea76 | ||
|
|
ddc337b01a | ||
|
|
29c94d5f5e | ||
|
|
7af4498fd4 | ||
|
|
7cce4fd6d8 | ||
|
|
5a809d7b3a | ||
|
|
1802c4b7be | ||
|
|
084daaf3f9 | ||
|
|
7fc007a123 | ||
|
|
6359d5ea19 | ||
|
|
1de46a0bd3 | ||
|
|
a8769f8cf5 | ||
|
|
67bc27f515 | ||
|
|
dfb5d0847a | ||
|
|
ee37069385 | ||
|
|
e5c0ffb693 | ||
|
|
ba7fedf762 | ||
|
|
b25e12d45d | ||
|
|
2944581a70 | ||
|
|
45038cbf9f | ||
|
|
0bdffc9e10 | ||
|
|
ca6867a6b1 | ||
|
|
eee3607ab7 | ||
|
|
17075e9006 | ||
|
|
cf037c60ab | ||
|
|
27f354cc24 | ||
|
|
3d583068aa | ||
|
|
00fd1f93a9 | ||
|
|
440b88103a | ||
|
|
8747d15417 | ||
|
|
ac3140b8a2 | ||
|
|
310ca7eae8 | ||
|
|
6d6fc94855 | ||
|
|
7d29af4f41 | ||
|
|
2b80c4756c | ||
|
|
879ea26cf6 | ||
|
|
7b7cdcf7cd | ||
|
|
93a3aaa86f | ||
|
|
d960666b68 | ||
|
|
d2564874ab | ||
|
|
e71ce18b9d | ||
|
|
59849f6c05 | ||
|
|
5a6e2d165b | ||
|
|
6384bfb4a2 | ||
|
|
4303f8edfd | ||
|
|
25754a3f03 | ||
|
|
b71f0ce721 | ||
|
|
9055f96eeb | ||
|
|
073ac2206f | ||
|
|
3814e8f19d | ||
|
|
1e5d83ad21 | ||
|
|
68f0920548 | ||
|
|
0d25d84230 | ||
|
|
15a6f742e0 | ||
|
|
495a5b24f4 | ||
|
|
956daea9dd | ||
|
|
7b17286b96 | ||
|
|
e535b01de1 | ||
|
|
d151a1b5e4 | ||
|
|
7242fa7d5c | ||
|
|
9d4ebd9ddd | ||
|
|
b2e713dbc1 | ||
|
|
8bcc7bf9af | ||
|
|
3078f96830 | ||
|
|
8708e35287 | ||
|
|
a8b96f053d | ||
|
|
a487357bd5 | ||
|
|
e8aba087ac | ||
|
|
5b7a679944 | ||
|
|
8229852585 | ||
|
|
f1def19f25 | ||
|
|
44363d5d99 | ||
|
|
f3f62667bf | ||
|
|
3d8615735b | ||
|
|
d1b6b36bcd | ||
|
|
e4755a4567 | ||
|
|
2ced721cf1 | ||
|
|
cf267d0bbd | ||
|
|
49d59f3b45 | ||
|
|
699ea2b8aa | ||
|
|
064d867510 | ||
|
|
5f63c4ae63 | ||
|
|
4ebb38743d | ||
|
|
01a7f3606c | ||
|
|
699c577fa6 |
10
.github/dependabot.yml
vendored
10
.github/dependabot.yml
vendored
@@ -3,5 +3,15 @@ version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
labels: ["area/ci", "dependencies"]
|
||||
groups:
|
||||
# Group all updates together, so that they are all applied in a single PR.
|
||||
# Grouped updates are currently in beta and is subject to change.
|
||||
# xref: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#groups
|
||||
ci:
|
||||
patterns:
|
||||
- "*"
|
||||
schedule:
|
||||
# By default, this will be on a monday.
|
||||
interval: "weekly"
|
||||
|
||||
|
||||
24
.github/workflows/build.yaml
vendored
24
.github/workflows/build.yaml
vendored
@@ -14,27 +14,25 @@ permissions:
|
||||
|
||||
jobs:
|
||||
build-flagger:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on:
|
||||
group: "Default Larger Runners"
|
||||
labels: ubuntu-latest-16-cores
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Restore Go cache
|
||||
uses: actions/cache@v3.2.5
|
||||
with:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-go-
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v3
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.19.x
|
||||
go-version: 1.22.x
|
||||
cache-dependency-path: |
|
||||
**/go.sum
|
||||
**/go.mod
|
||||
- name: Download modules
|
||||
run: |
|
||||
go mod download
|
||||
go install golang.org/x/tools/cmd/goimports
|
||||
- name: Run linters
|
||||
run: make test-fmt test-codegen
|
||||
run: make fmt test-codegen
|
||||
- name: Verify CRDs
|
||||
run: make verify-crd
|
||||
- name: Run tests
|
||||
@@ -47,7 +45,7 @@ jobs:
|
||||
exit 1
|
||||
fi
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
file: ./coverage.txt
|
||||
- name: Build container image
|
||||
|
||||
21
.github/workflows/e2e.yaml
vendored
21
.github/workflows/e2e.yaml
vendored
@@ -14,7 +14,9 @@ permissions:
|
||||
|
||||
jobs:
|
||||
e2e-test:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on:
|
||||
group: "Default Larger Runners"
|
||||
labels: ubuntu-latest-16-cores
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -22,7 +24,6 @@ jobs:
|
||||
# service mesh
|
||||
- istio
|
||||
- linkerd
|
||||
- osm
|
||||
- kuma
|
||||
# ingress controllers
|
||||
- contour
|
||||
@@ -36,13 +37,21 @@ jobs:
|
||||
- apisix
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Kubernetes
|
||||
uses: helm/kind-action@v1.5.0
|
||||
uses: helm/kind-action@v1.10.0
|
||||
if: matrix.provider != 'skipper'
|
||||
with:
|
||||
version: v0.17.0
|
||||
version: v0.23.0
|
||||
cluster_name: kind
|
||||
node_image: kindest/node:v1.23.6@sha256:b1fa224cc6c7ff32455e0b1fd9cbfd3d3bc87ecaa8fcb06961ed1afb3db0f9ae
|
||||
node_image: kindest/node:v1.30.0@sha256:047357ac0cfea04663786a612ba1eaba9702bef25227a794b52890dd8bcd692e
|
||||
- name: Setup Kubernetes for skipper
|
||||
uses: helm/kind-action@v1.10.0
|
||||
if: matrix.provider == 'skipper'
|
||||
with:
|
||||
version: v0.23.0
|
||||
cluster_name: kind
|
||||
node_image: kindest/node:v1.24.12@sha256:0bdca26bd7fe65c823640b14253ea7bac4baad9336b332c94850f84d8102f873
|
||||
- name: Build container image
|
||||
run: |
|
||||
docker build -t test/flagger:latest .
|
||||
|
||||
2
.github/workflows/helm.yaml
vendored
2
.github/workflows/helm.yaml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Publish Helm charts
|
||||
uses: stefanprodan/helm-gh-pages@v1.7.0
|
||||
with:
|
||||
|
||||
20
.github/workflows/push-ld.yml
vendored
20
.github/workflows/push-ld.yml
vendored
@@ -10,13 +10,14 @@ permissions:
|
||||
|
||||
jobs:
|
||||
release-load-tester:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on:
|
||||
group: "Default Larger Runners"
|
||||
permissions:
|
||||
id-token: write
|
||||
packages: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: sigstore/cosign-installer@v2.8.1
|
||||
- uses: actions/checkout@v4
|
||||
- uses: sigstore/cosign-installer@v3.5.0
|
||||
- name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
@@ -24,26 +25,27 @@ jobs:
|
||||
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
|
||||
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Setup Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: fluxcdbot
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
- name: Generate image meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
${{ env.IMAGE }}
|
||||
tags: |
|
||||
type=raw,value=${{ steps.prep.outputs.VERSION }}
|
||||
- name: Publish image
|
||||
uses: docker/build-push-action@v4
|
||||
id: build-push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
push: true
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
@@ -58,4 +60,4 @@ jobs:
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: 1
|
||||
run: |
|
||||
cosign sign ${{ env.IMAGE }}:${{ steps.prep.outputs.VERSION }}
|
||||
cosign sign --yes ${{ env.IMAGE }}@${{ steps.build-push.outputs.digest }}
|
||||
|
||||
82
.github/workflows/release.yml
vendored
82
.github/workflows/release.yml
vendored
@@ -18,15 +18,22 @@ env:
|
||||
|
||||
jobs:
|
||||
release-flagger:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
hashes: ${{ steps.slsa.outputs.hashes }}
|
||||
runs-on:
|
||||
group: "Default Larger Runners"
|
||||
permissions:
|
||||
contents: write # needed to write releases
|
||||
id-token: write # needed for keyless signing
|
||||
packages: write # needed for ghcr access
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.22.x
|
||||
- uses: fluxcd/flux2/action@main
|
||||
- uses: sigstore/cosign-installer@v2.8.1
|
||||
- uses: sigstore/cosign-installer@v3.5.0
|
||||
- name: Prepare
|
||||
id: prep
|
||||
run: |
|
||||
@@ -40,26 +47,27 @@ jobs:
|
||||
echo "BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ')" >> $GITHUB_OUTPUT
|
||||
echo "VERSION=${VERSION}" >> $GITHUB_OUTPUT
|
||||
- name: Setup QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
- name: Setup Docker Buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: fluxcdbot
|
||||
password: ${{ secrets.GHCR_TOKEN }}
|
||||
- name: Generate image meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
${{ env.IMAGE }}
|
||||
tags: |
|
||||
type=raw,value=${{ steps.prep.outputs.VERSION }}
|
||||
- name: Publish image
|
||||
uses: docker/build-push-action@v4
|
||||
id: build-push
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
sbom: true
|
||||
provenance: true
|
||||
@@ -76,7 +84,20 @@ jobs:
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: 1
|
||||
run: |
|
||||
cosign sign ${{ env.IMAGE }}:${{ steps.prep.outputs.VERSION }}
|
||||
cosign sign --yes ${{ env.IMAGE }}@${{ steps.build-push.outputs.digest }}
|
||||
- name: Publish signed manifests to GHCR
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: 1
|
||||
run: |
|
||||
OCI_URL=$(flux push artifact \
|
||||
oci://ghcr.io/fluxcd/flagger-manifests:${{ steps.prep.outputs.VERSION }} \
|
||||
--path="./kustomize" \
|
||||
--source="$(git config --get remote.origin.url)" \
|
||||
--revision="${{ steps.prep.outputs.VERSION }}/$(git rev-parse HEAD)" \
|
||||
--output json | \
|
||||
jq -r '. | .repository + "@" + .digest')
|
||||
cosign sign --yes ${OCI_URL}
|
||||
- name: Publish Helm charts
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: stefanprodan/helm-gh-pages@v1.7.0
|
||||
@@ -86,32 +107,47 @@ jobs:
|
||||
linting: off
|
||||
- uses: fluxcd/pkg/actions/helm@main
|
||||
with:
|
||||
version: 3.10.1
|
||||
version: 3.12.3
|
||||
- name: Publish signed Helm chart to GHCR
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: 1
|
||||
run: |
|
||||
helm package charts/flagger
|
||||
helm push flagger-${{ steps.prep.outputs.VERSION }}.tgz oci://ghcr.io/fluxcd/charts
|
||||
cosign sign ghcr.io/fluxcd/charts/flagger:${{ steps.prep.outputs.VERSION }}
|
||||
helm push flagger-${{ steps.prep.outputs.VERSION }}.tgz oci://ghcr.io/fluxcd/charts |& tee .digest
|
||||
cosign sign --yes ghcr.io/fluxcd/charts/flagger@$(cat .digest | awk -F "[, ]+" '/Digest/{print $NF}')
|
||||
rm flagger-${{ steps.prep.outputs.VERSION }}.tgz
|
||||
- name: Publish signed manifests to GHCR
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
env:
|
||||
COSIGN_EXPERIMENTAL: 1
|
||||
run: |
|
||||
flux push artifact oci://ghcr.io/fluxcd/flagger-manifests:${{ steps.prep.outputs.VERSION }} \
|
||||
--path="./kustomize" \
|
||||
--source="$(git config --get remote.origin.url)" \
|
||||
--revision="${{ steps.prep.outputs.VERSION }}/$(git rev-parse HEAD)"
|
||||
cosign sign ghcr.io/fluxcd/flagger-manifests:${{ steps.prep.outputs.VERSION }}
|
||||
rm .digest
|
||||
- uses: anchore/sbom-action/download-syft@v0
|
||||
- name: Create release and SBOM
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
id: run-goreleaser
|
||||
uses: goreleaser/goreleaser-action@v5
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
with:
|
||||
version: latest
|
||||
args: release --release-notes=notes.md --rm-dist --skip-validate
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Generate SLSA metadata
|
||||
id: slsa
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
env:
|
||||
ARTIFACTS: "${{ steps.run-goreleaser.outputs.artifacts }}"
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
hashes=$(echo -E $ARTIFACTS | jq --raw-output '.[] | {name, "digest": (.extra.Digest // .extra.Checksum)} | select(.digest) | {digest} + {name} | join(" ") | sub("^sha256:";"")' | base64 -w0)
|
||||
echo "hashes=$hashes" >> $GITHUB_OUTPUT
|
||||
|
||||
release-provenance:
|
||||
needs: [release-flagger]
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
permissions:
|
||||
actions: read # for detecting the Github Actions environment.
|
||||
id-token: write # for creating OIDC tokens for signing.
|
||||
contents: write # for uploading attestations to GitHub releases.
|
||||
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
|
||||
with:
|
||||
provenance-name: "provenance.intoto.jsonl"
|
||||
base64-subjects: "${{ needs.release-flagger.outputs.hashes }}"
|
||||
upload-assets: true
|
||||
|
||||
16
.github/workflows/scan.yml
vendored
16
.github/workflows/scan.yml
vendored
@@ -17,9 +17,9 @@ jobs:
|
||||
permissions:
|
||||
security-events: write
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run FOSSA scan and upload build data
|
||||
uses: fossa-contrib/fossa-action@v2
|
||||
uses: fossa-contrib/fossa-action@v3
|
||||
with:
|
||||
# FOSSA Push-Only API Token
|
||||
fossa-api-key: 5ee8bf422db1471e0bcf2bcb289185de
|
||||
@@ -30,12 +30,16 @@ jobs:
|
||||
security-events: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: 1.22.x
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: go
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
@@ -23,6 +23,7 @@ signs:
|
||||
certificate: '${artifact}.pem'
|
||||
args:
|
||||
- sign-blob
|
||||
- "--yes"
|
||||
- '--output-certificate=${certificate}'
|
||||
- '--output-signature=${signature}'
|
||||
- '${artifact}'
|
||||
|
||||
406
CHANGELOG.md
406
CHANGELOG.md
@@ -2,6 +2,408 @@
|
||||
|
||||
All notable changes to this project are documented in this file.
|
||||
|
||||
## 1.38.0
|
||||
|
||||
**Release date:** 2024-07-30
|
||||
|
||||
This release comes with several fixes and improvements. There is a new [Keptn
|
||||
metrics provider](https://docs.flagger.app/usage/metrics#keptn) that can be used
|
||||
for flexible grading logic and analysis.
|
||||
The loadtester chart now supports ServiceAccount annotations and the Flagger
|
||||
chart now supports specifying `honorLabels` for the PodMonitor.
|
||||
|
||||
Support for Kuma has been fixed and verified against Kuma 2.7.5. Also, the
|
||||
Deployment scaling has been updated to use `Patch` instead of `Update` to avoid
|
||||
intermittent conflict errors. Furthermore, a potential panic that could be
|
||||
caused due to Prometheus returning a range vector has been fixed. Also, the
|
||||
`request-duration` inbuilt query for Nginx has been updated to be more accurate.
|
||||
|
||||
Lastly, all Go dependencies, Alpine and Kubernetes libraries were updated.
|
||||
|
||||
#### Important
|
||||
|
||||
The update to Kubernetes libraries also brings an unwanted side-effect. Due to
|
||||
a change in upstream Kubernetes, sidecar support is done through a new field,
|
||||
which may be utilized by other services in your cluster. This would change the
|
||||
hash calculated by Flagger between runs and trigger an unwanted Canary
|
||||
analysis. Unfortunately, this is unavoidable. To get around this, users could
|
||||
set the `.spec.suspend` field to be true before updating to this version and
|
||||
switch it back when they update their application.
|
||||
|
||||
#### Improvements
|
||||
- Bumps golang.org/x/net to v0.23.0
|
||||
[#1628](https://github.com/fluxcd/flagger/pull/1628)
|
||||
- feat: implement a Keptn metrics provider
|
||||
[#1630](https://github.com/fluxcd/flagger/pull/1630)
|
||||
- Update dependencies to Kubernetes 1.30
|
||||
[#1638](https://github.com/fluxcd/flagger/pull/1638)
|
||||
- loadtester: add support for annotation on service account
|
||||
[#1649](https://github.com/fluxcd/flagger/pull/1649)
|
||||
- Bump golang.org/x/net to v0.25.0 and other deps.
|
||||
[#1653](https://github.com/fluxcd/flagger/pull/1653)
|
||||
- Update Go dependencies and Alpine
|
||||
[#1656](https://github.com/fluxcd/flagger/pull/1656)
|
||||
- Helm - Add podMonitor.honor labels
|
||||
[#1676](https://github.com/fluxcd/flagger/pull/1676)
|
||||
- kuma: bump e2e version to 2.7.5
|
||||
[#1683](https://github.com/fluxcd/flagger/pull/1683)
|
||||
- Release loadtester 0.33.0
|
||||
[#1690](https://github.com/fluxcd/flagger/pull/1690)
|
||||
- Bump google.golang.org/grpc from 1.64.0 to 1.64.1
|
||||
[#1675](https://github.com/fluxcd/flagger/pull/1675)
|
||||
|
||||
#### Fixes
|
||||
- Use `Patch` instead of `Update` for Deployment scaling
|
||||
[#1634](https://github.com/fluxcd/flagger/pull/1634)
|
||||
- block panic when prom returns range vector
|
||||
[#1637](https://github.com/fluxcd/flagger/pull/1637)
|
||||
- Fix removal of empty keys from flagger chart
|
||||
[#1657](https://github.com/fluxcd/flagger/pull/1657)
|
||||
- doc: fix KEDA doc regarding namespaces
|
||||
[#1666](https://github.com/fluxcd/flagger/pull/1666)
|
||||
- Fix Nginx request-duration query
|
||||
[#1686](https://github.com/fluxcd/flagger/pull/1686)
|
||||
|
||||
## 1.37.0
|
||||
|
||||
**Release date:** 2024-03-26
|
||||
|
||||
This release updates the Istio APIs to `v1beta1` and fixes several issues related
|
||||
to Gloo routing and custom metrics.
|
||||
|
||||
Both Flagger and the load tester Go dependencies have been updated to fix various CVEs.
|
||||
Flagger and the load tester are now built with Go 1.22.
|
||||
|
||||
#### Improvements
|
||||
- Migrate Istio VirtualService/DestinationRule APIs to `v1beta1`
|
||||
[#1602](https://github.com/fluxcd/flagger/pull/1602)
|
||||
- Add `omitempty` to CRD statuses to allow better marshalling
|
||||
[#1621](https://github.com/fluxcd/flagger/pull/1621)
|
||||
- Update dependencies (Go 1.22)
|
||||
[#1622](https://github.com/fluxcd/flagger/pull/1622)
|
||||
- Update `google.golang.org/protobuf` to v1.33.0
|
||||
[#1614](https://github.com/fluxcd/flagger/pull/1614)
|
||||
|
||||
#### Fixes
|
||||
- Update reconciler to detect change in Gloo upstream spec
|
||||
[#1617](https://github.com/fluxcd/flagger/pull/1617)
|
||||
- Fix regression bug where query with no metric template returned an error
|
||||
[#1611](https://github.com/fluxcd/flagger/pull/1611)
|
||||
|
||||
## 1.36.1
|
||||
|
||||
**Release date:** 2024-03-06
|
||||
|
||||
This release fixes a bug where `.spec..progressDeadlineSeconds` wasn't respected and the Canary
|
||||
was stuck forever waiting for the Deployment to be ready.
|
||||
|
||||
Furthermore, the Go dependencies have been updated.
|
||||
|
||||
#### Improvements
|
||||
- Update Go dependencies
|
||||
[#1607](https://github.com/fluxcd/flagger/pull/1607)
|
||||
|
||||
#### Fixes
|
||||
- Fix broken link in readme
|
||||
[#1599](https://github.com/fluxcd/flagger/pull/1599)
|
||||
- scheduler: fail canary according to progress deadline
|
||||
[#1603](https://github.com/fluxcd/flagger/pull/1603)
|
||||
- Actualize link to flux in-depth guide
|
||||
[#1606](https://github.com/fluxcd/flagger/pull/1606)
|
||||
|
||||
## 1.36.0
|
||||
|
||||
**Release date:** 2024-02-07
|
||||
|
||||
This release comes with support for canary releases with traffic shifting using
|
||||
Istio TCP routing. For more information on how to enable TCP routing please
|
||||
see the [Istio tutorial](https://docs.flagger.app/tutorials/istio-progressive-delivery#canary-deployments-for-tcp-services).
|
||||
|
||||
Both Flagger and the load tester Go dependencies have been updated to fix various CVEs.
|
||||
Flagger is now built with Go 1.21 and the container base image has been updated to Alpine 3.19.
|
||||
|
||||
#### Improvements
|
||||
- Istio Canary TCP service support
|
||||
[#1564](https://github.com/fluxcd/flagger/pull/1564)
|
||||
- Update Go dependencies
|
||||
[#1595](https://github.com/fluxcd/flagger/pull/1595)
|
||||
- Build with Go 1.21 and Alpine 3.19
|
||||
[#1594](https://github.com/fluxcd/flagger/pull/1594)
|
||||
|
||||
#### Fixes
|
||||
- return an error for missing metric templates
|
||||
[#1582](https://github.com/fluxcd/flagger/pull/1582)
|
||||
- istio: make retry attempts a mandatory field
|
||||
[#1571](https://github.com/fluxcd/flagger/pull/1571)
|
||||
- fix(pdb): use the full capabilities comparison for PDBs
|
||||
[#1511](https://github.com/fluxcd/flagger/pull/1511)
|
||||
|
||||
## 1.35.0
|
||||
|
||||
**Release date:** 2023-11-30
|
||||
|
||||
This release comes with support for Gateway API `v1`. Furthermore, following the
|
||||
deprecation period, support for the `v1alpha2` API has been dropped.
|
||||
A new field `.spec.webhooks[].retries` has been added to allow specifying the
|
||||
number of retry attempts to make if the webhook server returns an unsuccessful
|
||||
response.
|
||||
Another new field `.spec.service.trafficPolicy.loadBalancer.warmupDurationSeconds`
|
||||
has been added for the corresponding field in Istio's `DestinationRule` API.
|
||||
|
||||
Lastly, two bugs related to deleting a Canary object with
|
||||
`.spec.revertOnDeletion: true` have been fixed.
|
||||
|
||||
#### Improvements
|
||||
- Support Istio DestinationRule WarmupDurationSecs
|
||||
[#1540](https://github.com/fluxcd/flagger/pull/1540)
|
||||
- feat: Webhook retries
|
||||
[#1541](https://github.com/fluxcd/flagger/pull/1541)
|
||||
- gatewayapi: add support for `v1`
|
||||
[#1557](https://github.com/fluxcd/flagger/pull/1557)
|
||||
- Update Go dependencies
|
||||
[#1558](https://github.com/fluxcd/flagger/pull/1558)
|
||||
|
||||
#### Fixes
|
||||
- set original node selector value when finalizing service
|
||||
[#1537](https://github.com/fluxcd/flagger/pull/1537)
|
||||
- controller: wait for canary deployment to be ready before removing finalizers
|
||||
[#1552](https://github.com/fluxcd/flagger/pull/1552)
|
||||
|
||||
## 1.34.0
|
||||
|
||||
**Release date:** 2023-10-04
|
||||
|
||||
This release comes with several new features. The Gateway API integration
|
||||
has been significantly improved with support for
|
||||
* [Canary releases with session affinty](https://docs.flagger.app/tutorials/gatewayapi-progressive-delivery#session-affinty)
|
||||
* [B/G deployments with traffic mirroring](https://docs.flagger.app/tutorials/gatewayapi-progressive-delivery#traffic-mirroring)
|
||||
* Filters in the generated `HTTPRoute` (`.spec.rules[].filters`)
|
||||
|
||||
Most of the Filters are derived from existing fields in the Canary spec like
|
||||
`.spec.service.headers`. To support arbitary request mirroring through the
|
||||
`RequestMirror` filter, a new field `.spec.service.mirror` has been introduced.
|
||||
|
||||
A new field `checksum` has been added to the Canary webhook payload. This field
|
||||
is computed by hashing the `.status.lastAppliedSpec` and
|
||||
`.status.trackedConfigs`. It can be used to distinguish between Canary runs.
|
||||
|
||||
Furthermore, the Gloo integration now uses strings for specifying time durations
|
||||
in order to be better compatible with protobuf duration parsing.
|
||||
|
||||
Lastly, Kubernetes packages were updated to be on 1.27.
|
||||
|
||||
#### Improvements
|
||||
- Update Kubernetes to v1.27
|
||||
[#1506](https://github.com/fluxcd/flagger/pull/1506)
|
||||
- gatewayapi: add support for session affinity
|
||||
[#1507](https://github.com/fluxcd/flagger/pull/1507)
|
||||
- gatewayapi: add support for route rule filters
|
||||
[#1512](https://github.com/fluxcd/flagger/pull/1512)
|
||||
- Update Linkerd tutorial to use Kubernetes Gateway API
|
||||
[#1516](https://github.com/fluxcd/flagger/pull/1516)
|
||||
- Add Checksum field to the Webhook payload to distinguish canary runs
|
||||
[#1521](https://github.com/fluxcd/flagger/pull/1521)
|
||||
- gatewayapi: add support for b/g mirroring
|
||||
[#1525](https://github.com/fluxcd/flagger/pull/1525)
|
||||
- Update Go dependencies
|
||||
[#1528](https://github.com/fluxcd/flagger/pull/1528)
|
||||
|
||||
#### Fixes
|
||||
- chore: fix incorrect canary name on document
|
||||
[#1502](https://github.com/fluxcd/flagger/pull/1502)
|
||||
- fix: Support for queryParams in canary match condition #880
|
||||
[#1505](https://github.com/fluxcd/flagger/pull/1505)
|
||||
- docs: fix error example in deployment strategies
|
||||
[#1518](https://github.com/fluxcd/flagger/pull/1518)
|
||||
- Change Gloo Duration type to string
|
||||
[#1524](https://github.com/fluxcd/flagger/pull/1524)
|
||||
|
||||
## 1.33.0
|
||||
|
||||
**Release date:** 2023-08-29
|
||||
|
||||
This release fixes bugs related to the Canary lifecycle. The
|
||||
`confirm-traffic-increase` webhook is no longer called if the Canary is in the
|
||||
`WaitingPromotion` phase. Furthermore, a bug which caused downtime when
|
||||
initializing the Canary deployment has been fixed.
|
||||
Also, a bug in the `request-duration` metric for Traefik which assumed the
|
||||
result to be in milliseconds instead of seconds has been addressed.
|
||||
|
||||
The loadtester now also supports running `kubectl` commands.
|
||||
|
||||
#### Improvements
|
||||
- Helm: Add option to configure honorLabels for serviceMonitor
|
||||
[#1442](https://github.com/fluxcd/flagger/pull/1442)
|
||||
- Helm: Use PodDisruptionBudget API policy/v1 if available
|
||||
[#1476](https://github.com/fluxcd/flagger/pull/1476)
|
||||
- podinfo: Update hpa version from autoscaling/v2beta2 to autoscaling/v2
|
||||
[#1477](https://github.com/fluxcd/flagger/pull/1477)
|
||||
- Helm: Allow custom labels for servicemonitor
|
||||
[#1483](https://github.com/fluxcd/flagger/pull/1483)
|
||||
- feat: loadtester support kubectl type
|
||||
[#1485](https://github.com/fluxcd/flagger/pull/1485)
|
||||
- Update Istio Gateway reference format
|
||||
[#1489](https://github.com/fluxcd/flagger/pull/1489)
|
||||
- e2e: Update Istio to v1.18
|
||||
[#1492](https://github.com/fluxcd/flagger/pull/1492)
|
||||
- add docs for kubectl in loadtester
|
||||
[#1494](https://github.com/fluxcd/flagger/pull/1494)
|
||||
|
||||
#### Fixes
|
||||
- fix: typo on "Parase", should be "Parse".
|
||||
[#1443](https://github.com/fluxcd/flagger/pull/1443)
|
||||
- Fix Traefik request-duration metric
|
||||
[#1446](https://github.com/fluxcd/flagger/pull/1446)
|
||||
- Fix initial deployment downtime
|
||||
[#1451](https://github.com/fluxcd/flagger/pull/1451)
|
||||
- Fix FAQ templating format and change reference of $workload to $target.
|
||||
[#1456](https://github.com/fluxcd/flagger/pull/1456)
|
||||
- Update doc.go
|
||||
[#1466](https://github.com/fluxcd/flagger/pull/1466)
|
||||
- Avoid running traffic increase hooks when waiting for promotion or promoting
|
||||
[#1470](https://github.com/fluxcd/flagger/pull/1470)
|
||||
|
||||
## 1.32.0
|
||||
|
||||
**Release date:** 2023-07-14
|
||||
|
||||
This release adds support for suspending a Canary using `.spec.suspend`.
|
||||
It also fixes a bug where the target deployment gets stuck at 0 replicas
|
||||
after the Canary has been deleted.
|
||||
Furthermore, the Canary API has been modified to allow specifying the
|
||||
HTTPRoute port using `.service.gatewayRefs[].port`.
|
||||
|
||||
#### Improvements
|
||||
- Helm: Add option to create service and serviceMonitor
|
||||
[#1425](https://github.com/fluxcd/flagger/pull/1425)
|
||||
- Update Alpine to 3.18
|
||||
[#1426](https://github.com/fluxcd/flagger/pull/1426)
|
||||
- Add `spec.suspend` to allow suspending canary
|
||||
[#1431](https://github.com/fluxcd/flagger/pull/1431)
|
||||
- Add support for istio LEAST_REQUEST destination rule load balancing
|
||||
[#1439](https://github.com/fluxcd/flagger/pull/1439)
|
||||
- Add gatewayRef port to Canary CRD
|
||||
[#1453](https://github.com/fluxcd/flagger/pull/1453)
|
||||
- feat: Copy slowStartConfig for Gloo upstreams
|
||||
[#1455](https://github.com/fluxcd/flagger/pull/1455)
|
||||
- Update Go dependencies
|
||||
[#1459](https://github.com/fluxcd/flagger/pull/1459)
|
||||
|
||||
#### Fixes
|
||||
- Resume target scaler during finalization
|
||||
[#1429](https://github.com/fluxcd/flagger/pull/1429)
|
||||
- Fix panic when annotation of ingress is empty
|
||||
[#1437](https://github.com/fluxcd/flagger/pull/1437)
|
||||
- Fixing namespace of HelmRepository in installation docs
|
||||
[#1458](https://github.com/fluxcd/flagger/pull/1458)
|
||||
|
||||
## 1.31.0
|
||||
|
||||
**Release date:** 2023-05-10
|
||||
|
||||
⚠️ __Breaking Changes__
|
||||
|
||||
This release adds support for Linkerd 2.12 and later. Due to changes in Linkerd
|
||||
the default namespace for Flagger's installation had to be changed from
|
||||
`linkerd` to `flagger-system` and the `flagger` Deployment is now injected with
|
||||
the Linkerd proxy. Furthermore, installing Flagger for Linkerd will result in
|
||||
the creation of an `AuthorizationPolicy` that allows access to the Prometheus
|
||||
instance in the `linkerd-viz` namespace. To upgrade your Flagger installation,
|
||||
please see the below migration guide.
|
||||
|
||||
If you use Kustomize, then follow these steps:
|
||||
* `kubectl delete -n linkerd deploy/flagger`
|
||||
* `kubectl delete -n linkerd serviceaccount flagger`
|
||||
* If you're on Linkerd >= 2.12, you'll need to install the SMI extension to enable
|
||||
support for `TrafficSplit`s:
|
||||
```bash
|
||||
curl -sL https://linkerd.github.io/linkerd-smi/install | sh
|
||||
linkerd smi install | kubectl apply -f -
|
||||
```
|
||||
* `kubectl apply -k github.com/fluxcd/flagger//kustomize/linkerd`
|
||||
|
||||
Note: If you're on Linkerd < 2.12, this will report an error about missing CRDs.
|
||||
It is safe to ignore this error.
|
||||
|
||||
If you use Helm and are on Linkerd < 2.12, then you can use `helm upgrade` to do
|
||||
a regular upgrade.
|
||||
|
||||
If you use Helm and are on Linkerd >= 2.12, then follow these steps:
|
||||
* `helm uninstall flagger -n linkerd`
|
||||
* Install the Linkerd SMI extension:
|
||||
```bash
|
||||
helm repo add l5d-smi https://linkerd.github.io/linkerd-smi
|
||||
helm install linkerd-smi l5d-smi/linkerd-smi -n linkerd-smi --create-namespace
|
||||
```
|
||||
* Install Flagger in the `flagger-system` namespace
|
||||
and create an `AuthorizationPolicy`:
|
||||
```bash
|
||||
helm repo update flagger
|
||||
helm install flagger flagger/flagger \
|
||||
--namespace flagger-system \
|
||||
--set meshProvider=linkerd \
|
||||
--set metricsServer=http://prometheus.linkerd-viz:9090 \
|
||||
--set linkerdAuthPolicy.create=true
|
||||
```
|
||||
|
||||
Furthermore, a bug which led the `confirm-rollout` webhook to be executed at
|
||||
every step of the Canary instead of only being executed before the canary
|
||||
Deployment is scaled up, has been fixed.
|
||||
|
||||
#### Improvements
|
||||
|
||||
- Add support for Linkerd 2.13
|
||||
[#1417](https://github.com/fluxcd/flagger/pull/1417)
|
||||
|
||||
#### Fixes
|
||||
|
||||
- Fix the loadtester install with flux documentation
|
||||
[#1384](https://github.com/fluxcd/flagger/pull/1384)
|
||||
- Run `confirm-rollout` checks only before scaling up deployment
|
||||
[#1414](https://github.com/fluxcd/flagger/pull/1414)
|
||||
- e2e: Remove OSM tests
|
||||
[#1423](https://github.com/fluxcd/flagger/pull/1423)
|
||||
|
||||
## 1.30.0
|
||||
|
||||
**Release date:** 2023-04-12
|
||||
|
||||
This release fixes a bug related to the lack of updates to the generated
|
||||
object's metadata according to the metadata specified in `spec.service.apex`.
|
||||
Furthermore, a bug where labels were wrongfully copied over from the canary
|
||||
deployment to primary deployment when no value was provided for
|
||||
`--include-label-prefix` has been fixed.
|
||||
This release also makes Flagger compatible with Flux's helm-controller drift
|
||||
detection.
|
||||
|
||||
#### Improvements
|
||||
|
||||
- build(deps): bump actions/cache from 3.2.5 to 3.3.1
|
||||
[#1385](https://github.com/fluxcd/flagger/pull/1385)
|
||||
- helm: Added the option to supply additional volumes
|
||||
[#1393](https://github.com/fluxcd/flagger/pull/1393)
|
||||
- build(deps): bump actions/setup-go from 3 to 4
|
||||
[#1394](https://github.com/fluxcd/flagger/pull/1394)
|
||||
- update Kuma version and docs
|
||||
[#1402](https://github.com/fluxcd/flagger/pull/1402)
|
||||
- ci: bump k8s to 1.24 and kind to 1.18
|
||||
[#1406](https://github.com/fluxcd/flagger/pull/1406)
|
||||
- Helm: Allow configuring deployment `annotations`
|
||||
[#1411](https://github.com/fluxcd/flagger/pull/1411)
|
||||
- update dependencies
|
||||
[#1412](https://github.com/fluxcd/flagger/pull/1412)
|
||||
|
||||
#### Fixes
|
||||
|
||||
- Enable updates for labels and annotations
|
||||
[#1392](https://github.com/fluxcd/flagger/pull/1392)
|
||||
- Update flagger-install-with-flux.md
|
||||
[#1398](https://github.com/fluxcd/flagger/pull/1398)
|
||||
- avoid copying canary labels to primary on promotion
|
||||
[#1405](https://github.com/fluxcd/flagger/pull/1405)
|
||||
- Disable Flux helm drift detection for managed resources
|
||||
[#1408](https://github.com/fluxcd/flagger/pull/1408)
|
||||
|
||||
## 1.29.0
|
||||
|
||||
**Release date:** 2023-02-21
|
||||
@@ -1015,7 +1417,7 @@ The upgrade procedure from 0.x to 1.0 can be found [here](https://docs.flagger.a
|
||||
Two new resources were added to the API: `MetricTemplate` and `AlertProvider`.
|
||||
The analysis can reference [metric templates](https://docs.flagger.app//usage/metrics#custom-metrics)
|
||||
to query Prometheus, Datadog and AWS CloudWatch.
|
||||
[Alerting](https://docs.flagger.app/v/master/usage/alerting#canary-configuration) can be configured on a per
|
||||
[Alerting](https://docs.flagger.app/v/main/usage/alerting#canary-configuration) can be configured on a per
|
||||
canary basis for Slack, MS Teams, Discord and Rocket.
|
||||
|
||||
#### Features
|
||||
@@ -1179,7 +1581,7 @@ The upgrade procedure from 0.x to 1.0 can be found [here](https://docs.flagger.a
|
||||
Two new resources were added to the API: `MetricTemplate` and `AlertProvider`.
|
||||
The analysis can reference [metric templates](https://docs.flagger.app//usage/metrics#custom-metrics)
|
||||
to query Prometheus, Datadog and AWS CloudWatch.
|
||||
[Alerting](https://docs.flagger.app/v/master/usage/alerting#canary-configuration) can be configured on a per
|
||||
[Alerting](https://docs.flagger.app/v/main/usage/alerting#canary-configuration) can be configured on a per
|
||||
canary basis for Slack, MS Teams, Discord and Rocket.
|
||||
|
||||
#### Features
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.19-alpine as builder
|
||||
FROM golang:1.22-alpine as builder
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
ARG REVISON
|
||||
@@ -21,7 +21,7 @@ RUN CGO_ENABLED=0 go build \
|
||||
-ldflags "-s -w -X github.com/fluxcd/flagger/pkg/version.REVISION=${REVISON}" \
|
||||
-a -o flagger ./cmd/flagger
|
||||
|
||||
FROM alpine:3.17
|
||||
FROM alpine:3.20
|
||||
|
||||
RUN apk --no-cache add ca-certificates
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.19-alpine as builder
|
||||
FROM golang:1.22-alpine as builder
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
ARG TARGETARCH
|
||||
@@ -6,15 +6,19 @@ ARG REVISION
|
||||
|
||||
RUN apk --no-cache add alpine-sdk perl curl bash tar
|
||||
|
||||
RUN HELM3_VERSION=3.11.0 && \
|
||||
RUN HELM3_VERSION=3.15.3 && \
|
||||
curl -sSL "https://get.helm.sh/helm-v${HELM3_VERSION}-linux-${TARGETARCH}.tar.gz" | tar xvz && \
|
||||
chmod +x linux-${TARGETARCH}/helm && mv linux-${TARGETARCH}/helm /usr/local/bin/helm
|
||||
|
||||
RUN GRPC_HEALTH_PROBE_VERSION=v0.4.12 && \
|
||||
RUN KUBECTL_VERSION=v1.29.7 && \
|
||||
curl -LO "https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/${TARGETARCH}/kubectl" && \
|
||||
chmod +x kubectl && mv kubectl /usr/local/bin/kubectl
|
||||
|
||||
RUN GRPC_HEALTH_PROBE_VERSION=v0.4.28 && \
|
||||
wget -qO /usr/local/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-${TARGETARCH} && \
|
||||
chmod +x /usr/local/bin/grpc_health_probe
|
||||
|
||||
RUN GHZ_VERSION=0.109.0 && \
|
||||
RUN GHZ_VERSION=0.120.0 && \
|
||||
curl -sSL "https://github.com/bojand/ghz/archive/refs/tags/v${GHZ_VERSION}.tar.gz" | tar xz -C /tmp && \
|
||||
cd /tmp/ghz-${GHZ_VERSION}/cmd/ghz && GOARCH=$TARGETARCH go build . && mv ghz /usr/local/bin && \
|
||||
chmod +x /usr/local/bin/ghz
|
||||
@@ -41,7 +45,7 @@ ARG TARGETPLATFORM
|
||||
|
||||
RUN addgroup -S app && \
|
||||
adduser -S -g app app && \
|
||||
apk --no-cache add ca-certificates curl jq libgcc wrk hey
|
||||
apk --no-cache add ca-certificates curl jq libgcc wrk hey git
|
||||
|
||||
WORKDIR /home/app
|
||||
|
||||
@@ -51,6 +55,7 @@ RUN ln -s /opt/bats/bin/bats /usr/local/bin/
|
||||
COPY --from=builder /usr/local/bin/helm /usr/local/bin/
|
||||
COPY --from=builder /usr/local/bin/ghz /usr/local/bin/
|
||||
COPY --from=builder /usr/local/bin/grpc_health_probe /usr/local/bin/
|
||||
COPY --from=builder /usr/local/bin/kubectl /usr/local/bin/
|
||||
|
||||
ADD https://raw.githubusercontent.com/grpc/grpc-proto/master/grpc/health/v1/health.proto /tmp/ghz/health.proto
|
||||
|
||||
|
||||
@@ -4,6 +4,6 @@ at https://slack.cncf.io/).
|
||||
|
||||
In alphabetical order:
|
||||
|
||||
Stefan Prodan, Weaveworks <stefan@weave.works> (github: @stefanprodan, slack: stefanprodan)
|
||||
Sanskar Jaiswal, Independent <jaiswalsanskar078@gmail.com> (github: @aryan9600, slack: aryan9600)
|
||||
Stefan Prodan, ControlPlane <stefan.prodan@gmail.com> (github: @stefanprodan, slack: stefanprodan)
|
||||
Takeshi Yoneda, Tetrate <takeshi@tetrate.io> (github: @mathetake, slack: mathetake)
|
||||
Sanskar Jaiswal, Weaveworks <sanskar.jaiswal@weave.works> (github: @aryan9600, slack: aryan9600)
|
||||
|
||||
17
Makefile
17
Makefile
@@ -6,19 +6,13 @@ build:
|
||||
CGO_ENABLED=0 go build -a -o ./bin/flagger ./cmd/flagger
|
||||
|
||||
tidy:
|
||||
rm -f go.sum; go mod tidy -compat=1.19
|
||||
rm -f go.sum; go mod tidy -compat=1.22
|
||||
|
||||
vet:
|
||||
go vet ./...
|
||||
|
||||
fmt:
|
||||
go mod tidy
|
||||
gofmt -l -s -w ./
|
||||
goimports -l -w ./
|
||||
|
||||
test-fmt:
|
||||
gofmt -l -s ./ | grep ".*\.go"; if [ "$$?" = "0" ]; then exit 1; fi
|
||||
goimports -l ./ | grep ".*\.go"; if [ "$$?" = "0" ]; then exit 1; fi
|
||||
go fmt ./...
|
||||
|
||||
codegen:
|
||||
./hack/update-codegen.sh
|
||||
@@ -26,9 +20,14 @@ codegen:
|
||||
test-codegen:
|
||||
./hack/verify-codegen.sh
|
||||
|
||||
test: test-fmt test-codegen
|
||||
test: fmt test-codegen
|
||||
go test ./...
|
||||
|
||||
test-coverage: fmt test-codegen
|
||||
go test -coverprofile cover.out ./...
|
||||
go tool cover -html=cover.out
|
||||
rm cover.out
|
||||
|
||||
crd:
|
||||
cat artifacts/flagger/crd.yaml > charts/flagger/crds/crd.yaml
|
||||
cat artifacts/flagger/crd.yaml > kustomize/base/flagger/crd.yaml
|
||||
|
||||
@@ -51,7 +51,7 @@ Flagger documentation can be found at [fluxcd.io/flagger](https://fluxcd.io/flag
|
||||
**Our list of production users has moved to <https://fluxcd.io/adopters/#flagger>**.
|
||||
|
||||
If you are using Flagger, please
|
||||
[submit a PR to add your organization](https://github.com/fluxcd/website/tree/main/adopters#readme) to the list!
|
||||
[submit a PR to add your organization](https://github.com/fluxcd/website/blob/main/data/adopters/2-flagger.yaml) to the list!
|
||||
|
||||
### Canary CRD
|
||||
|
||||
@@ -85,7 +85,7 @@ spec:
|
||||
progressDeadlineSeconds: 60
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
|
||||
@@ -11,7 +11,7 @@ spec:
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
|
||||
@@ -11,7 +11,7 @@ spec:
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
|
||||
@@ -10,7 +10,7 @@ spec:
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
@@ -20,7 +20,7 @@ spec:
|
||||
portName: http
|
||||
portDiscovery: true
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
- mesh
|
||||
hosts:
|
||||
- app.example.com
|
||||
|
||||
@@ -11,7 +11,7 @@ spec:
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
@@ -21,7 +21,7 @@ spec:
|
||||
portName: http
|
||||
portDiscovery: true
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
- mesh
|
||||
hosts:
|
||||
- app.example.com
|
||||
|
||||
@@ -11,7 +11,7 @@ spec:
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
|
||||
@@ -11,7 +11,7 @@ spec:
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
|
||||
@@ -27,6 +27,10 @@ spec:
|
||||
- name: Weight
|
||||
type: string
|
||||
jsonPath: .status.canaryWeight
|
||||
- name: Suspended
|
||||
type: boolean
|
||||
jsonPath: .spec.suspend
|
||||
priority: 1
|
||||
- name: FailedChecks
|
||||
type: string
|
||||
jsonPath: .status.failedChecks
|
||||
@@ -478,6 +482,54 @@ spec:
|
||||
uri:
|
||||
format: string
|
||||
type: string
|
||||
authority:
|
||||
format: string
|
||||
type: string
|
||||
type:
|
||||
format: string
|
||||
type: string
|
||||
mirror:
|
||||
description: Mirror defines a schema for a filter that mirrors requests.
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
backendRef:
|
||||
properties:
|
||||
group:
|
||||
default: ""
|
||||
maxLength: 253
|
||||
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
kind:
|
||||
default: Service
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
|
||||
type: string
|
||||
name:
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
namespace:
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
|
||||
type: string
|
||||
port:
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
x-kubernetes-validations:
|
||||
- message: Must have port for Service reference
|
||||
rule: '(size(self.group) == 0 && self.kind == ''Service'')
|
||||
? has(self.port) : true'
|
||||
required:
|
||||
- backendRef
|
||||
headers:
|
||||
description: Headers operations
|
||||
type: object
|
||||
@@ -557,6 +609,11 @@ spec:
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
port:
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
corsPolicy:
|
||||
description: Istio Cross-Origin Resource Sharing policy (CORS)
|
||||
type: object
|
||||
@@ -747,6 +804,10 @@ spec:
|
||||
- LEAST_CONN
|
||||
- RANDOM
|
||||
- PASSTHROUGH
|
||||
- LEAST_REQUEST
|
||||
type: string
|
||||
warmupDurationSecs:
|
||||
description: Represents the warmup duration of Service.
|
||||
type: string
|
||||
outlierDetection:
|
||||
description: Settings controlling eviction of unhealthy hosts from the load balancing pool.
|
||||
@@ -850,6 +911,9 @@ spec:
|
||||
revertOnDeletion:
|
||||
description: Revert mutated resources to original spec on deletion
|
||||
type: boolean
|
||||
suspend:
|
||||
description: Suspend Canary disabling/pausing all canary runs
|
||||
type: boolean
|
||||
analysis:
|
||||
description: Canary analysis for this canary
|
||||
type: object
|
||||
@@ -923,6 +987,34 @@ spec:
|
||||
description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax)
|
||||
format: string
|
||||
type: string
|
||||
queryParams:
|
||||
description: Query parameters for matching.
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- not:
|
||||
anyOf:
|
||||
- required:
|
||||
- exact
|
||||
- required:
|
||||
- prefix
|
||||
- required:
|
||||
- regex
|
||||
- required:
|
||||
- exact
|
||||
- required:
|
||||
- prefix
|
||||
- required:
|
||||
- regex
|
||||
properties:
|
||||
exact:
|
||||
type: string
|
||||
prefix:
|
||||
type: string
|
||||
regex:
|
||||
description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
|
||||
type: string
|
||||
type: object
|
||||
sourceLabels:
|
||||
description: Applicable only when the 'mesh' gateway is included in the service.gateways list
|
||||
type: object
|
||||
@@ -1040,6 +1132,9 @@ spec:
|
||||
description: Request timeout for this webhook
|
||||
type: string
|
||||
pattern: "^[0-9]+(m|s)"
|
||||
retries:
|
||||
description: Number of retries for this webhook
|
||||
type: number
|
||||
metadata:
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
@@ -1203,6 +1298,7 @@ spec:
|
||||
- newrelic
|
||||
- graphite
|
||||
- dynatrace
|
||||
- keptn
|
||||
address:
|
||||
description: API address of this provider
|
||||
type: string
|
||||
|
||||
@@ -22,7 +22,7 @@ spec:
|
||||
serviceAccountName: flagger
|
||||
containers:
|
||||
- name: flagger
|
||||
image: ghcr.io/fluxcd/flagger:1.29.0
|
||||
image: ghcr.io/fluxcd/flagger:1.38.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
apiVersion: v1
|
||||
name: flagger
|
||||
version: 1.29.0
|
||||
appVersion: 1.29.0
|
||||
version: 1.38.0
|
||||
appVersion: 1.38.0
|
||||
kubeVersion: ">=1.19.0-0"
|
||||
engine: gotpl
|
||||
description: Flagger is a progressive delivery operator for Kubernetes
|
||||
|
||||
@@ -40,10 +40,13 @@ $ helm upgrade -i flagger flagger/flagger \
|
||||
To install Flagger for **Linkerd** (requires Linkerd Viz extension):
|
||||
|
||||
```console
|
||||
# Note that linkerdAuthPolicy.create=true is only required for Linkerd 2.12 and
|
||||
# later
|
||||
$ helm upgrade -i flagger flagger/flagger \
|
||||
--namespace=linkerd \
|
||||
--namespace=flagger-system \
|
||||
--set meshProvider=linkerd \
|
||||
--set metricsServer=http://prometheus.linkerd-viz:9090
|
||||
--set metricsServer=http://prometheus.linkerd-viz:9090 \
|
||||
--set linkerdAuthPolicy.create=true
|
||||
```
|
||||
|
||||
To install Flagger for **AWS App Mesh**:
|
||||
@@ -137,6 +140,10 @@ The following tables lists the configurable parameters of the Flagger chart and
|
||||
| `prometheus.install` | If `true`, installs Prometheus configured to scrape all pods in the custer | `false` |
|
||||
| `prometheus.retention` | Prometheus data retention | `2h` |
|
||||
| `selectorLabels` | List of labels that Flagger uses to create pod selectors | `app,name,app.kubernetes.io/name` |
|
||||
| `serviceMonitor.enabled` | If `true`, creates service and serviceMonitor for monitoring Flagger metrics | `false` |
|
||||
| `serviceMonitor.honorLabels` | If `true`, label conflicts are resolved by keeping label values from the scraped data and ignoring the conflicting server-side labels | `false` |
|
||||
| `serviceMonitor.namespace` | Namespace Servicemonitor is installed in | the same namespace |
|
||||
| `serviceMonitor.labels` | labels for the ServiceMonitor passed to Prometheus Operator | `{}` |
|
||||
| `configTracking.enabled` | If `true`, flagger will track changes in Secrets and ConfigMaps referenced in the target deployment | `true` |
|
||||
| `eventWebhook` | If set, Flagger will publish events to the given webhook | None |
|
||||
| `slack.url` | Slack incoming webhook | None |
|
||||
@@ -150,6 +157,7 @@ The following tables lists the configurable parameters of the Flagger chart and
|
||||
| `podMonitor.namespace` | Namespace where the PodMonitor is created | the same namespace |
|
||||
| `podMonitor.interval` | Interval at which metrics should be scraped | `15s` |
|
||||
| `podMonitor.podMonitor` | Additional labels to add to the PodMonitor | `{}` |
|
||||
| `podMonitor.honorLabels` | If `true`, label conflicts are resolved by keeping label values from the scraped data and ignoring the conflicting server-side labels | `false` |
|
||||
| `leaderElection.enabled` | If `true`, Flagger will run in HA mode | `false` |
|
||||
| `leaderElection.replicaCount` | Number of replicas | `1` |
|
||||
| `serviceAccount.create` | If `true`, Flagger will create service account | `true` |
|
||||
@@ -177,7 +185,7 @@ The following tables lists the configurable parameters of the Flagger chart and
|
||||
| `podDisruptionBudget.minAvailable` | The minimal number of available replicas that will be set in the PodDisruptionBudget | `1` |
|
||||
| `podDisruptionBudget.minAvailable` | The minimal number of available replicas that will be set in the PodDisruptionBudget | `1` |
|
||||
| `noCrossNamespaceRefs` | If `true`, cross namespace references to custom resources will be disabled | `false` |
|
||||
| `namespace` | When specified, Flagger will restrict itself to watching Canary objects from that namespace | `""` |
|
||||
| `namespace` | When specified, Flagger will restrict itself to watching Canary objects from that namespace | `""` |
|
||||
|
||||
Specify each parameter using the `--set key=value[,key=value]` argument to `helm upgrade`. For example,
|
||||
|
||||
|
||||
@@ -27,6 +27,10 @@ spec:
|
||||
- name: Weight
|
||||
type: string
|
||||
jsonPath: .status.canaryWeight
|
||||
- name: Suspended
|
||||
type: boolean
|
||||
jsonPath: .spec.suspend
|
||||
priority: 1
|
||||
- name: FailedChecks
|
||||
type: string
|
||||
jsonPath: .status.failedChecks
|
||||
@@ -478,6 +482,54 @@ spec:
|
||||
uri:
|
||||
format: string
|
||||
type: string
|
||||
authority:
|
||||
format: string
|
||||
type: string
|
||||
type:
|
||||
format: string
|
||||
type: string
|
||||
mirror:
|
||||
description: Mirror defines a schema for a filter that mirrors requests.
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
backendRef:
|
||||
properties:
|
||||
group:
|
||||
default: ""
|
||||
maxLength: 253
|
||||
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
kind:
|
||||
default: Service
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
|
||||
type: string
|
||||
name:
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
namespace:
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
|
||||
type: string
|
||||
port:
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
x-kubernetes-validations:
|
||||
- message: Must have port for Service reference
|
||||
rule: '(size(self.group) == 0 && self.kind == ''Service'')
|
||||
? has(self.port) : true'
|
||||
required:
|
||||
- backendRef
|
||||
headers:
|
||||
description: Headers operations
|
||||
type: object
|
||||
@@ -557,6 +609,11 @@ spec:
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
port:
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
corsPolicy:
|
||||
description: Istio Cross-Origin Resource Sharing policy (CORS)
|
||||
type: object
|
||||
@@ -747,6 +804,10 @@ spec:
|
||||
- LEAST_CONN
|
||||
- RANDOM
|
||||
- PASSTHROUGH
|
||||
- LEAST_REQUEST
|
||||
type: string
|
||||
warmupDurationSecs:
|
||||
description: Represents the warmup duration of Service.
|
||||
type: string
|
||||
outlierDetection:
|
||||
description: Settings controlling eviction of unhealthy hosts from the load balancing pool.
|
||||
@@ -850,6 +911,9 @@ spec:
|
||||
revertOnDeletion:
|
||||
description: Revert mutated resources to original spec on deletion
|
||||
type: boolean
|
||||
suspend:
|
||||
description: Suspend Canary disabling/pausing all canary runs
|
||||
type: boolean
|
||||
analysis:
|
||||
description: Canary analysis for this canary
|
||||
type: object
|
||||
@@ -923,6 +987,34 @@ spec:
|
||||
description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax)
|
||||
format: string
|
||||
type: string
|
||||
queryParams:
|
||||
description: Query parameters for matching.
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- not:
|
||||
anyOf:
|
||||
- required:
|
||||
- exact
|
||||
- required:
|
||||
- prefix
|
||||
- required:
|
||||
- regex
|
||||
- required:
|
||||
- exact
|
||||
- required:
|
||||
- prefix
|
||||
- required:
|
||||
- regex
|
||||
properties:
|
||||
exact:
|
||||
type: string
|
||||
prefix:
|
||||
type: string
|
||||
regex:
|
||||
description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
|
||||
type: string
|
||||
type: object
|
||||
sourceLabels:
|
||||
description: Applicable only when the 'mesh' gateway is included in the service.gateways list
|
||||
type: object
|
||||
@@ -1040,6 +1132,9 @@ spec:
|
||||
description: Request timeout for this webhook
|
||||
type: string
|
||||
pattern: "^[0-9]+(m|s)"
|
||||
retries:
|
||||
description: Number of retries for this webhook
|
||||
type: number
|
||||
metadata:
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
@@ -1203,6 +1298,7 @@ spec:
|
||||
- newrelic
|
||||
- graphite
|
||||
- dynatrace
|
||||
- keptn
|
||||
address:
|
||||
description: API address of this provider
|
||||
type: string
|
||||
|
||||
@@ -4,8 +4,8 @@ kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ template "flagger.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
annotations:
|
||||
{{- if .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{ toYaml .Values.serviceAccount.annotations | indent 4 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
|
||||
16
charts/flagger/templates/authorizationpolicy.yaml
Normal file
16
charts/flagger/templates/authorizationpolicy.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
{{- if .Values.linkerdAuthPolicy.create }}
|
||||
apiVersion: policy.linkerd.io/v1alpha1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
namespace: {{ .Values.linkerdAuthPolicy.namespace }}
|
||||
name: prometheus-admin-flagger
|
||||
spec:
|
||||
targetRef:
|
||||
group: policy.linkerd.io
|
||||
kind: Server
|
||||
name: prometheus-admin
|
||||
requiredAuthenticationRefs:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "flagger.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
@@ -9,6 +9,10 @@ metadata:
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion }}
|
||||
{{- with .Values.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
replicas: {{ .Values.leaderElection.replicaCount }}
|
||||
{{- if eq .Values.leaderElection.enabled false }}
|
||||
@@ -44,11 +48,14 @@ spec:
|
||||
imagePullSecrets:
|
||||
- name: {{ .Values.image.pullSecret }}
|
||||
{{- end }}
|
||||
{{- if .Values.controlplane.kubeconfig.secretName }}
|
||||
volumes:
|
||||
{{- if .Values.controlplane.kubeconfig.secretName }}
|
||||
- name: kubeconfig
|
||||
secret:
|
||||
secretName: "{{ .Values.controlplane.kubeconfig.secretName }}"
|
||||
{{- end }}
|
||||
{{- if .Values.additionalVolumes }}
|
||||
{{- toYaml .Values.additionalVolumes | nindent 8 -}}
|
||||
{{- end }}
|
||||
{{- if .Values.podPriorityClassName }}
|
||||
priorityClassName: {{ .Values.podPriorityClassName }}
|
||||
@@ -59,11 +66,11 @@ spec:
|
||||
securityContext:
|
||||
{{ toYaml .Values.securityContext.context | indent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.controlplane.kubeconfig.secretName }}
|
||||
volumeMounts:
|
||||
{{- if .Values.controlplane.kubeconfig.secretName }}
|
||||
- name: kubeconfig
|
||||
mountPath: "/tmp/controlplane"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
{{- if .Values.podDisruptionBudget.enabled }}
|
||||
{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" -}}
|
||||
apiVersion: policy/v1
|
||||
{{- else }}
|
||||
apiVersion: policy/v1beta1
|
||||
{{- end }}
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ template "flagger.name" . }}
|
||||
|
||||
@@ -17,6 +17,7 @@ spec:
|
||||
- interval: {{ .Values.podMonitor.interval }}
|
||||
path: /metrics
|
||||
port: http
|
||||
honorLabels: {{ .Values.podMonitor.honorLabels }}
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- {{ .Release.Namespace }}
|
||||
|
||||
@@ -259,6 +259,19 @@ rules:
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- metrics.keptn.sh
|
||||
resources:
|
||||
- keptnmetrics
|
||||
- analyses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- nonResourceURLs:
|
||||
- /version
|
||||
verbs:
|
||||
|
||||
19
charts/flagger/templates/service.yaml
Normal file
19
charts/flagger/templates/service.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
{{- if .Values.serviceMonitor.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ template "flagger.name" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "flagger.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
selector:
|
||||
app.kubernetes.io/name: {{ template "flagger.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
29
charts/flagger/templates/servicemonitor.yaml
Normal file
29
charts/flagger/templates/servicemonitor.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
{{- if .Values.serviceMonitor.enabled }}
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: {{ template "flagger.name" . }}
|
||||
{{- if .Values.serviceMonitor.namespace }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{- end }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "flagger.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- with .Values.serviceMonitor.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
endpoints:
|
||||
- path: /metrics
|
||||
port: http
|
||||
interval: 30s
|
||||
scrapeTimeout: 30s
|
||||
honorLabels: {{ .Values.serviceMonitor.honorLabels }}
|
||||
namespaceSelector:
|
||||
matchNames:
|
||||
- {{ .Release.Namespace }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ template "flagger.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
@@ -1,8 +1,11 @@
|
||||
# Default values for flagger.
|
||||
|
||||
## Deployment annotations
|
||||
# annotations: {}
|
||||
|
||||
image:
|
||||
repository: ghcr.io/fluxcd/flagger
|
||||
tag: 1.29.0
|
||||
tag: 1.38.0
|
||||
pullPolicy: IfNotPresent
|
||||
pullSecret:
|
||||
|
||||
@@ -13,12 +16,22 @@ podAnnotations:
|
||||
prometheus.io/scrape: "true"
|
||||
prometheus.io/port: "8080"
|
||||
appmesh.k8s.aws/sidecarInjectorWebhook: disabled
|
||||
linkerd.io/inject: enabled
|
||||
|
||||
# priority class name for pod priority configuration
|
||||
podPriorityClassName: ""
|
||||
|
||||
metricsServer: "http://prometheus:9090"
|
||||
|
||||
# creates serviceMonitor for monitoring Flagger metrics
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
honorLabels: false
|
||||
# Set the namespace the ServiceMonitor should be deployed
|
||||
# namespace: monitoring
|
||||
# Set labels for the ServiceMonitor, use this to define your scrape label for Prometheus Operator
|
||||
# labels:
|
||||
|
||||
# accepted values are kubernetes, istio, linkerd, appmesh, contour, nginx, gloo, skipper, traefik, apisix, osm
|
||||
meshProvider: ""
|
||||
|
||||
@@ -69,6 +82,7 @@ podMonitor:
|
||||
namespace:
|
||||
interval: 15s
|
||||
additionalLabels: {}
|
||||
honorLabels: false
|
||||
|
||||
#env:
|
||||
#- name: SLACK_URL
|
||||
@@ -120,6 +134,13 @@ crd:
|
||||
# crd.create: `true` if custom resource definitions should be created
|
||||
create: false
|
||||
|
||||
linkerdAuthPolicy:
|
||||
# linkerdAuthPolicy.create: Whether to create an AuthorizationPolicy in
|
||||
# linkerd viz' namespace to allow flagger to reach viz' prometheus service
|
||||
create: false
|
||||
# linkerdAuthPolicy.namespace: linkerd-viz' namespace
|
||||
namespace: linkerd-viz
|
||||
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
@@ -177,3 +198,8 @@ podDisruptionBudget:
|
||||
podLabels: {}
|
||||
|
||||
noCrossNamespaceRefs: false
|
||||
|
||||
#Placeholder to supply additional volumes to the flagger pod
|
||||
additionalVolumes: {}
|
||||
# - name: tmpfs
|
||||
# emptyDir: {}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
apiVersion: v1
|
||||
name: loadtester
|
||||
version: 0.28.1
|
||||
appVersion: 0.28.1
|
||||
version: 0.33.0
|
||||
appVersion: 0.33.0
|
||||
kubeVersion: ">=1.19.0-0"
|
||||
engine: gotpl
|
||||
description: Flagger's load testing services based on rakyll/hey and bojand/ghz that generates traffic during canary analysis when configured as a webhook.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{{- if and (.Values.istio.enabled) (.Values.istio.gateway.enabled) }}
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: {{ include "loadtester.fullname" . }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{{- if .Values.istio.enabled }}
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: {{ include "loadtester.fullname" . }}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
{{- if .Values.podDisruptionBudget.enabled }}
|
||||
{{- if .Capabilities.APIVersions.Has "policy/v1/PodDisruptionBudget" -}}
|
||||
apiVersion: policy/v1
|
||||
{{- else }}
|
||||
apiVersion: policy/v1beta1
|
||||
{{- end }}
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ include "loadtester.fullname" . }}
|
||||
|
||||
@@ -51,4 +51,7 @@ metadata:
|
||||
app.kubernetes.io/name: {{ template "loadtester.name" . }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- if .Values.rbac.serviceAccountAnnotations }}
|
||||
annotations: {{ tpl (toYaml .Values.rbac.serviceAccountAnnotations) . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -2,7 +2,7 @@ replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: ghcr.io/fluxcd/flagger-loadtester
|
||||
tag: 0.28.1
|
||||
tag: 0.33.0
|
||||
pullPolicy: IfNotPresent
|
||||
pullSecret:
|
||||
|
||||
@@ -54,6 +54,8 @@ rbac:
|
||||
# resources: ["pods"]
|
||||
# verbs: ["list", "get"]
|
||||
rules: []
|
||||
# annotations to add to the service account
|
||||
serviceAccountAnnotations: {}
|
||||
|
||||
# name of an existing service account to use - if not creating rbac resources
|
||||
serviceAccountName: ""
|
||||
|
||||
@@ -20,7 +20,7 @@ helm upgrade -i frontend flagger/podinfo \
|
||||
--set backend=http://backend.test:9898/echo \
|
||||
--set canary.enabled=true \
|
||||
--set canary.istioIngress.enabled=true \
|
||||
--set canary.istioIngress.gateway=public-gateway.istio-system.svc.cluster.local \
|
||||
--set canary.istioIngress.gateway=istio-system/public-gateway \
|
||||
--set canary.istioIngress.host=frontend.istio.example.com
|
||||
```
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ spec:
|
||||
kind: Deployment
|
||||
name: {{ template "podinfo.fullname" . }}
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: {{ template "podinfo.fullname" . }}
|
||||
service:
|
||||
@@ -57,4 +57,4 @@ spec:
|
||||
metadata:
|
||||
cmd: "hey -z 1m -q 5 -c 2 http://{{ template "podinfo.fullname" . }}.{{ .Release.Namespace }}:{{ .Values.service.port }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{{- if .Values.hpa.enabled -}}
|
||||
apiVersion: autoscaling/v2beta1
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ template "podinfo.fullname" . }}
|
||||
|
||||
@@ -25,7 +25,7 @@ canary:
|
||||
istioIngress:
|
||||
enabled: false
|
||||
# Istio ingress gateway name
|
||||
gateway: public-gateway.istio-system.svc.cluster.local
|
||||
gateway: istio-system/public-gateway
|
||||
# external host name eg. podinfo.example.com
|
||||
host:
|
||||
analysis:
|
||||
|
||||
@@ -253,6 +253,7 @@ func main() {
|
||||
fromEnv("EVENT_WEBHOOK_URL", eventWebhook),
|
||||
clusterName,
|
||||
noCrossNamespaceRefs,
|
||||
cfg,
|
||||
)
|
||||
|
||||
// leader election context
|
||||
@@ -327,7 +328,7 @@ func startLeaderElection(ctx context.Context, run func(), ns string, kubeClient
|
||||
id = id + "_" + string(uuid.NewUUID())
|
||||
|
||||
lock, err := resourcelock.New(
|
||||
resourcelock.ConfigMapsLeasesResourceLock,
|
||||
resourcelock.LeasesResourceLock,
|
||||
ns,
|
||||
configMapName,
|
||||
kubeClient.CoreV1(),
|
||||
|
||||
@@ -22,13 +22,14 @@ import (
|
||||
"regexp"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
|
||||
"github.com/fluxcd/flagger/pkg/loadtester"
|
||||
"github.com/fluxcd/flagger/pkg/logger"
|
||||
"github.com/fluxcd/flagger/pkg/signals"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
var VERSION = "0.28.1"
|
||||
var VERSION = "0.33.0"
|
||||
var (
|
||||
logLevel string
|
||||
port string
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 41 KiB |
@@ -55,3 +55,6 @@ After installing Flagger, you can follow one of these tutorials to get started:
|
||||
* [Istio](https://github.com/stefanprodan/gitops-istio)
|
||||
* [Linkerd](https://helm.workshop.flagger.dev)
|
||||
* [AWS App Mesh](https://eks.handson.flagger.dev)
|
||||
|
||||
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation,
|
||||
please see our [Trademark Usage page](https://www.linuxfoundation.org/legal/trademark-usage).
|
||||
|
||||
@@ -391,10 +391,10 @@ sum(
|
||||
rate(
|
||||
istio_requests_total{
|
||||
reporter="destination",
|
||||
destination_workload_namespace=~"$namespace",
|
||||
destination_workload=~"$workload",
|
||||
destination_workload_namespace=~"{{ namespace }}",
|
||||
destination_workload=~"{{ target }}",
|
||||
response_code!~"5.*"
|
||||
}[$interval]
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
/
|
||||
@@ -402,9 +402,9 @@ sum(
|
||||
rate(
|
||||
istio_requests_total{
|
||||
reporter="destination",
|
||||
destination_workload_namespace=~"$namespace",
|
||||
destination_workload=~"$workload"
|
||||
}[$interval]
|
||||
destination_workload_namespace=~"{{ namespace }}",
|
||||
destination_workload=~"{{ target }}"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
```
|
||||
@@ -415,19 +415,19 @@ Envoy query (App Mesh):
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
kubernetes_namespace="$namespace",
|
||||
kubernetes_pod_name=~"$workload",
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
kubernetes_pod_name=~"{{ target }}",
|
||||
envoy_response_code!~"5.*"
|
||||
}[$interval]
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
/
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
kubernetes_namespace="$namespace",
|
||||
kubernetes_pod_name=~"$workload"
|
||||
}[$interval]
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
kubernetes_pod_name=~"{{ target }}"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
```
|
||||
@@ -438,17 +438,17 @@ Envoy query (Contour and Gloo):
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
envoy_cluster_name=~"$namespace-$workload",
|
||||
envoy_cluster_name=~"{{ namespace }}-{{ target }}",
|
||||
envoy_response_code!~"5.*"
|
||||
}[$interval]
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
/
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
envoy_cluster_name=~"$namespace-$workload",
|
||||
}[$interval]
|
||||
envoy_cluster_name=~"{{ namespace }}-{{ target }}",
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
```
|
||||
@@ -476,9 +476,9 @@ histogram_quantile(0.99,
|
||||
irate(
|
||||
istio_request_duration_milliseconds_bucket{
|
||||
reporter="destination",
|
||||
destination_workload=~"$workload",
|
||||
destination_workload_namespace=~"$namespace"
|
||||
}[$interval]
|
||||
destination_workload=~"{{ target }}",
|
||||
destination_workload_namespace=~"{{ namespace }}"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
) by (le)
|
||||
)
|
||||
@@ -491,9 +491,9 @@ histogram_quantile(0.99,
|
||||
sum(
|
||||
irate(
|
||||
envoy_cluster_upstream_rq_time_bucket{
|
||||
kubernetes_pod_name=~"$workload",
|
||||
kubernetes_namespace=~"$namespace"
|
||||
}[$interval]
|
||||
kubernetes_pod_name=~"{{ target }}",
|
||||
kubernetes_namespace=~"{{ namespace }}"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
) by (le)
|
||||
)
|
||||
@@ -515,10 +515,10 @@ If you're using Istio with Gateway API, the Prometheus query needs to include `r
|
||||
rate(
|
||||
istio_requests_total{
|
||||
reporter="source",
|
||||
destination_workload_namespace=~"$namespace",
|
||||
destination_workload=~"$workload",
|
||||
destination_workload_namespace=~"{{ namespace }}",
|
||||
destination_workload=~"{{ target }}",
|
||||
response_code!~"5.*"
|
||||
}[$interval]
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
/
|
||||
@@ -526,9 +526,9 @@ sum(
|
||||
rate(
|
||||
istio_requests_total{
|
||||
reporter="source",
|
||||
destination_workload_namespace=~"$namespace",
|
||||
destination_workload=~"$workload"
|
||||
}[$interval]
|
||||
destination_workload_namespace=~"{{ namespace }}",
|
||||
destination_workload=~"{{ target }}"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
) * 100
|
||||
```
|
||||
@@ -558,7 +558,7 @@ spec:
|
||||
portName: http-frontend
|
||||
# Istio gateways (optional)
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
- mesh
|
||||
# Istio virtual service host names (optional)
|
||||
hosts:
|
||||
@@ -600,7 +600,7 @@ spec:
|
||||
For the above spec Flagger will generate the following virtual service:
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: frontend
|
||||
@@ -614,7 +614,7 @@ metadata:
|
||||
uid: 3a4a40dd-3875-11e9-8e1d-42010a9c0fd1
|
||||
spec:
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
- mesh
|
||||
hosts:
|
||||
- frontend.example.com
|
||||
@@ -653,7 +653,7 @@ spec:
|
||||
For each destination in the virtual service a rule is generated:
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
name: frontend-primary
|
||||
@@ -664,7 +664,7 @@ spec:
|
||||
tls:
|
||||
mode: DISABLE
|
||||
---
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: DestinationRule
|
||||
metadata:
|
||||
name: frontend-canary
|
||||
@@ -751,7 +751,7 @@ spec:
|
||||
Based on the above spec, Flagger will create the following virtual service:
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: backend
|
||||
@@ -777,14 +777,14 @@ spec:
|
||||
Therefore, the following virtual service forwards the traffic to `/podinfo` by the above delegate VirtualService.
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: frontend
|
||||
namespace: test
|
||||
spec:
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
- mesh
|
||||
hosts:
|
||||
- frontend.example.com
|
||||
@@ -821,7 +821,7 @@ spec:
|
||||
service:
|
||||
port: 8080
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
hosts:
|
||||
- my-site.com
|
||||
match:
|
||||
@@ -838,7 +838,7 @@ spec:
|
||||
service:
|
||||
port: 8080
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
hosts:
|
||||
- my-site.com
|
||||
match:
|
||||
|
||||
@@ -374,7 +374,7 @@ helm upgrade -i flagger-grafana flagger/grafana \
|
||||
Expose Grafana through the public gateway by creating a virtual service \(replace `example.com` with your domain\):
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
apiVersion: networking.istio.io/v1beta1
|
||||
kind: VirtualService
|
||||
metadata:
|
||||
name: grafana
|
||||
@@ -383,7 +383,7 @@ spec:
|
||||
hosts:
|
||||
- "grafana.example.com"
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
http:
|
||||
- route:
|
||||
- destination:
|
||||
|
||||
@@ -42,7 +42,7 @@ apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: flagger
|
||||
namespace: flux-system
|
||||
namespace: flagger-system
|
||||
spec:
|
||||
interval: 1h
|
||||
url: oci://ghcr.io/fluxcd/charts
|
||||
@@ -139,7 +139,7 @@ spec:
|
||||
sourceRef:
|
||||
kind: OCIRepository
|
||||
name: flagger-loadtester
|
||||
path: ./kustomize/tester
|
||||
path: ./tester
|
||||
targetNamespace: apps
|
||||
```
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ spec:
|
||||
progressDeadlineSeconds: 60
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
|
||||
@@ -50,7 +50,7 @@ helm upgrade -i frontend flagger/podinfo \
|
||||
--set backend=http://backend.test:9898/echo \
|
||||
--set canary.enabled=true \
|
||||
--set canary.istioIngress.enabled=true \
|
||||
--set canary.istioIngress.gateway=public-gateway.istio-system.svc.cluster.local \
|
||||
--set canary.istioIngress.gateway=istio-system/public-gateway \
|
||||
--set canary.istioIngress.host=frontend.istio.example.com
|
||||
```
|
||||
|
||||
@@ -278,7 +278,7 @@ spec:
|
||||
enabled: true
|
||||
istioIngress:
|
||||
enabled: true
|
||||
gateway: public-gateway.istio-system.svc.cluster.local
|
||||
gateway: istio-system/public-gateway
|
||||
host: frontend.istio.example.com
|
||||
loadtest:
|
||||
enabled: true
|
||||
@@ -343,5 +343,5 @@ A canary deployment can fail due to any of the following reasons:
|
||||
* the Istio telemetry service is unable to collect traffic metrics
|
||||
* the metrics server \(Prometheus\) can't be reached
|
||||
|
||||
If you want to find out more about managing Helm releases with Flux here are two in-depth guides: [gitops-helm](https://github.com/stefanprodan/gitops-helm) and [gitops-istio](https://github.com/stefanprodan/gitops-istio).
|
||||
If you want to find out more about managing Helm releases with Flux here are two in-depth guides: [flux2-kustomize-helm-example](https://github.com/fluxcd/flux2-kustomize-helm-example) and [gitops-istio](https://github.com/stefanprodan/gitops-istio).
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ spec:
|
||||
name: podinfo
|
||||
# HPA reference
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
|
||||
@@ -6,55 +6,64 @@ This guide shows you how to use [Gateway API](https://gateway-api.sigs.k8s.io/)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Flagger requires a Kubernetes cluster **v1.19** or newer and any mesh/ingress that implements the `v1beta1` version of Gateway API. We'll be using Contour for the sake of this tutorial, but you can use any other implementation.
|
||||
Flagger requires a Kubernetes cluster **v1.19** or newer and any mesh/ingress that implements the `v1beta1` or the `v1` version of Gateway API.
|
||||
We'll be using Istio for the sake of this tutorial, but you can use any other implementation.
|
||||
|
||||
> Note: Flagger supports `v1alpha2` version of Gateway API, but the alpha version has been deprecated and support will be dropped in a future release.
|
||||
|
||||
Install Contour, its Gateway provisioner and Gateway API CRDs in the `projectcontour` namespace:
|
||||
Install the Gateway API CRDs
|
||||
|
||||
```bash
|
||||
https://raw.githubusercontent.com/projectcontour/contour/release-1.23/examples/render/contour-gateway-provisioner.yaml
|
||||
kubectl apply -k "github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.0.0"
|
||||
```
|
||||
|
||||
> Alternatively, you can also install the Gateway API CRDs from the upstream project:
|
||||
Install Istio:
|
||||
|
||||
```bash
|
||||
kubectl apply -k github.com/kubernetes-sigs/gateway-api/config/crd?ref=v0.6.0
|
||||
istioctl install --set profile=minimal -y
|
||||
|
||||
# Suggestion: Please change release-1.20 in below command, to your real istio version.
|
||||
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/addons/prometheus.yaml
|
||||
```
|
||||
|
||||
Install Flagger in the `flagger-system` namespace:
|
||||
|
||||
```bash
|
||||
kubectl apply -k github.com/fluxcd/flagger//kustomize/gatewayapi
|
||||
kubectl create ns flagger-system
|
||||
|
||||
helm repo add flagger https://flagger.app
|
||||
helm upgrade -i flagger flagger/flagger \
|
||||
--namespace flagger-system \
|
||||
--set prometheus.install=false \
|
||||
--set meshProvider=gatewayapi:v1 \
|
||||
--set metricsServer=http://prometheus.istio-system:9090
|
||||
```
|
||||
|
||||
Create a `GatewayClass` that specifies information about the Gateway controller:
|
||||
> Note: The above installation sets the mesh provider to be `gatewayapi:v1`. If your Gateway API implementation uses the `v1beta1` CRDs, then
|
||||
set the `--meshProvider` value to `gatewayapi:v1beta1`.
|
||||
|
||||
```yaml
|
||||
kind: GatewayClass
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
metadata:
|
||||
name: contour
|
||||
spec:
|
||||
controllerName: projectcontour.io/gateway-controller
|
||||
Create a namespace for the `Gateway`:
|
||||
|
||||
```bash
|
||||
kubectl create ns istio-ingress
|
||||
```
|
||||
|
||||
Create a `Gateway` that configures load balancing, traffic ACL, etc:
|
||||
|
||||
```yaml
|
||||
kind: Gateway
|
||||
apiVersion: gateway.networking.k8s.io/v1beta1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: contour
|
||||
namespace: projectcontour
|
||||
name: gateway
|
||||
namespace: istio-ingress
|
||||
spec:
|
||||
gatewayClassName: contour
|
||||
gatewayClassName: istio
|
||||
listeners:
|
||||
- name: http
|
||||
protocol: HTTP
|
||||
port: 80
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
- name: default
|
||||
hostname: "*.example.com"
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: All
|
||||
```
|
||||
|
||||
## Bootstrap
|
||||
@@ -90,13 +99,15 @@ metadata:
|
||||
spec:
|
||||
provider:
|
||||
type: prometheus
|
||||
address: http://flagger-prometheus:9090
|
||||
address: http://prometheus.istio-system:9090
|
||||
query: |
|
||||
histogram_quantile(0.99,
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq_time_bucket{
|
||||
envoy_cluster_name=~"{{ namespace }}_{{ target }}-canary_[0-9a-zA-Z-]+",
|
||||
istio_request_duration_milliseconds_bucket{
|
||||
reporter="source",
|
||||
destination_workload_namespace=~"{{ namespace }}",
|
||||
destination_workload=~"{{ target }}",
|
||||
}[{{ interval }}]
|
||||
)
|
||||
) by (le)
|
||||
@@ -110,21 +121,25 @@ metadata:
|
||||
spec:
|
||||
provider:
|
||||
type: prometheus
|
||||
address: http://flagger-prometheus:9090
|
||||
address: http://prometheus.istio-system:9090
|
||||
query: |
|
||||
100 - sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
envoy_cluster_name=~"{{ namespace }}_{{ target }}-canary_[0-9a-zA-Z-]+",
|
||||
envoy_response_code!~"5.*"
|
||||
istio_requests_total{
|
||||
reporter="source",
|
||||
destination_workload_namespace=~"{{ namespace }}",
|
||||
destination_workload=~"{{ target }}",
|
||||
response_code!~"5.*"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
/
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
envoy_cluster_name=~"{{ namespace }}_{{ target }}-canary_[0-9a-zA-Z-]+",
|
||||
istio_requests_total{
|
||||
reporter="source",
|
||||
destination_workload_namespace=~"{{ namespace }}",
|
||||
destination_workload=~"{{ target }}",
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
@@ -137,7 +152,7 @@ Save the above resource as metric-templates.yaml and then apply it:
|
||||
kubectl apply -f metric-templates.yaml
|
||||
```
|
||||
|
||||
Create a canary custom resource \(replace "loaclproject.contour.io" with your own domain\):
|
||||
Create a canary custom resource \(replace "www.example.com" with your own domain\):
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1beta1
|
||||
@@ -156,7 +171,7 @@ spec:
|
||||
progressDeadlineSeconds: 60
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
@@ -166,11 +181,11 @@ spec:
|
||||
targetPort: 9898
|
||||
# Gateway API HTTPRoute host names
|
||||
hosts:
|
||||
- localproject.contour.io
|
||||
- www.example.com
|
||||
# Reference to the Gateway that the generated HTTPRoute would attach to.
|
||||
gatewayRefs:
|
||||
- name: contour
|
||||
namespace: projectcontour
|
||||
- name: gateway
|
||||
namespace: istio-ingress
|
||||
analysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 1m
|
||||
@@ -213,7 +228,7 @@ spec:
|
||||
url: http://flagger-loadtester.test/
|
||||
timeout: 5s
|
||||
metadata:
|
||||
cmd: "hey -z 2m -q 10 -c 2 -host localproject.contour.io http://envoy.projectcontour/"
|
||||
cmd: "hey -z 2m -q 10 -c 2 -host www.example.com http://gateway-istio.istio-ingress/"
|
||||
```
|
||||
|
||||
Save the above resource as podinfo-canary.yaml and then apply it:
|
||||
@@ -243,26 +258,27 @@ httproutes.gateway.networking.k8s.io/podinfo
|
||||
|
||||
## Expose the app outside the cluster
|
||||
|
||||
Find the external address of Contour's Envoy load balancer:
|
||||
Find the external address of Istio's load balancer:
|
||||
|
||||
```bash
|
||||
export ADDRESS="$(kubectl -n projectcontour get svc/envoy -ojson \
|
||||
export ADDRESS="$(kubectl -n istio-ingress get svc/gateway-istio -ojson \
|
||||
| jq -r ".status.loadBalancer.ingress[].hostname")"
|
||||
echo $ADDRESS
|
||||
```
|
||||
|
||||
Configure your DNS server with a CNAME record \(AWS\) or A record \(GKE/AKS/DOKS\) and point a domain e.g. `localproject.contour.io` to the LB address.
|
||||
Configure your DNS server with a CNAME record \(AWS\) or A record \(GKE/AKS/DOKS\) and point a domain e.g. `www.example.com` to the LB address.
|
||||
|
||||
Now you can access the podinfo UI using your domain address.
|
||||
|
||||
Note that you should be using HTTPS when exposing production workloads on internet. You can obtain free TLS certs from Let's Encrypt, read this [guide](https://github.com/stefanprodan/eks-contour-ingress) on how to configure cert-manager to secure Contour with TLS certificates.
|
||||
Note that you should be using HTTPS when exposing production workloads on internet. You can obtain free TLS certs from Let's Encrypt, read this
|
||||
[guide](https://github.com/stefanprodan/istio-gke) on how to configure cert-manager to secure Istio with TLS certificates.
|
||||
|
||||
If you're using a local cluster via kind/k3s you can port forward the Envoy LoadBalancer service:
|
||||
```bash
|
||||
kubectl port-forward -n projectcontour svc/envoy 8080:80
|
||||
kubectl port-forward -n istio-ingress svc/gateway-istio 8080:80
|
||||
```
|
||||
|
||||
Now you can access podinfo via `curl -H "Host: localproject.contour.io" localhost:8080`
|
||||
Now you can access podinfo via `curl -H "Host: www.example.com" localhost:8080`
|
||||
|
||||
## Automated canary promotion
|
||||
|
||||
@@ -382,13 +398,15 @@ Events:
|
||||
Warning Synced 1m flagger Canary failed! Scaling down podinfo.test
|
||||
```
|
||||
|
||||
# A/B Testing
|
||||
## Session Affinity
|
||||
|
||||
Besides weighted routing, Flagger can be configured to route traffic to the canary based on HTTP match conditions. In an A/B testing scenario, you'll be using HTTP headers or cookies to target a certain segment of your users. This is particularly useful for frontend applications that require session affinity.
|
||||
While Flagger can perform weighted routing and A/B testing individually, with Gateway API it can combine the two leading to a Canary
|
||||
release with session affinity.
|
||||
For more information you can read the [deployment strategies docs](../usage/deployment-strategies.md#canary-release-with-session-affinity).
|
||||
|
||||

|
||||
> **Note:** The implementation must have support for the [`ResponseHeaderModifier`](https://github.com/kubernetes-sigs/gateway-api/blob/3d22aa5a08413222cb79e6b2e245870360434614/apis/v1beta1/httproute_types.go#L651) API.
|
||||
|
||||
Create a canary custom resource \(replace "loaclproject.contour.io" with your own domain\):
|
||||
Create a canary custom resource \(replace www.example.com with your own domain\):
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1beta1
|
||||
@@ -407,7 +425,7 @@ spec:
|
||||
progressDeadlineSeconds: 60
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
@@ -417,11 +435,120 @@ spec:
|
||||
targetPort: 9898
|
||||
# Gateway API HTTPRoute host names
|
||||
hosts:
|
||||
- localproject.contour.io
|
||||
- www.example.com
|
||||
# Reference to the Gateway that the generated HTTPRoute would attach to.
|
||||
gatewayRefs:
|
||||
- name: contour
|
||||
namespace: projectcontour
|
||||
- name: gateway
|
||||
namespace: istio-ingress
|
||||
analysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 1m
|
||||
# max number of failed metric checks before rollback
|
||||
threshold: 5
|
||||
# max traffic percentage routed to canary
|
||||
# percentage (0-100)
|
||||
maxWeight: 50
|
||||
# canary increment step
|
||||
# percentage (0-100)
|
||||
stepWeight: 10
|
||||
# session affinity config
|
||||
sessionAffinity:
|
||||
# name of the cookie used
|
||||
cookieName: flagger-cookie
|
||||
# max age of the cookie (in seconds)
|
||||
# optional; defaults to 86400
|
||||
maxAge: 21600
|
||||
metrics:
|
||||
- name: error-rate
|
||||
# max error rate (5xx responses)
|
||||
# percentage (0-100)
|
||||
templateRef:
|
||||
name: error-rate
|
||||
namespace: flagger-system
|
||||
thresholdRange:
|
||||
max: 1
|
||||
interval: 1m
|
||||
- name: latency
|
||||
templateRef:
|
||||
name: latency
|
||||
namespace: flagger-system
|
||||
# seconds
|
||||
thresholdRange:
|
||||
max: 0.5
|
||||
interval: 30s
|
||||
# testing (optional)
|
||||
webhooks:
|
||||
- name: smoke-test
|
||||
type: pre-rollout
|
||||
url: http://flagger-loadtester.test/
|
||||
timeout: 15s
|
||||
metadata:
|
||||
type: bash
|
||||
cmd: "curl -sd 'anon' http://podinfo-canary.test:9898/token | grep token"
|
||||
- name: load-test
|
||||
url: http://flagger-loadtester.test/
|
||||
timeout: 5s
|
||||
metadata:
|
||||
cmd: "hey -z 2m -q 10 -c 2 -host www.example.com http://gateway-istio.istio-ingress/"
|
||||
```
|
||||
|
||||
Save the above resource as podinfo-canary-session-affinity.yaml and then apply it:
|
||||
|
||||
```bash
|
||||
kubectl apply -f ./podinfo-canary-session-affinity.yaml
|
||||
```
|
||||
|
||||
Trigger a canary deployment by updating the container image:
|
||||
|
||||
```bash
|
||||
kubectl -n test set image deployment/podinfo \
|
||||
podinfod=ghcr.io/stefanprodan/podinfo:6.0.1
|
||||
```
|
||||
|
||||
You can load `www.example.com` in your browser and refresh it until you see the requests being served by `podinfo:6.0.1`.
|
||||
All subsequent requests after that will be served by `podinfo:6.0.1` and not `podinfo:6.0.0` because of the session affinity
|
||||
configured by Flagger in the HTTPRoute object.
|
||||
|
||||
# A/B Testing
|
||||
|
||||
Besides weighted routing, Flagger can be configured to route traffic to the canary based on HTTP match conditions. In an A/B testing scenario, you'll be using HTTP headers or cookies to target a certain segment of your users. This is particularly useful for frontend applications that require session affinity.
|
||||
|
||||

|
||||
|
||||
Create a canary custom resource \(replace "www.example.com" with your own domain\):
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: Canary
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: test
|
||||
spec:
|
||||
# deployment reference
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
# the maximum time in seconds for the canary deployment
|
||||
# to make progress before it is rollback (default 600s)
|
||||
progressDeadlineSeconds: 60
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
# service port number
|
||||
port: 9898
|
||||
# container port number or name (optional)
|
||||
targetPort: 9898
|
||||
# Gateway API HTTPRoute host names
|
||||
hosts:
|
||||
- www.example.com
|
||||
# Reference to the Gateway that the generated HTTPRoute would attach to.
|
||||
gatewayRefs:
|
||||
- name: gateway
|
||||
namespace: istio-ingress
|
||||
analysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 1m
|
||||
@@ -464,7 +591,7 @@ spec:
|
||||
url: http://flagger-loadtester.test/
|
||||
timeout: 5s
|
||||
metadata:
|
||||
cmd: "hey -z 2m -q 10 -c 2 -host localproject.contour.io -H 'X-Canary: insider' http://envoy.projectcontour/"
|
||||
cmd: "hey -z 2m -q 10 -c 2 -host www.example.com -H 'X-Canary: insider' http://gateway-istio.istio-ingress/"
|
||||
```
|
||||
|
||||
The above configuration will run an analysis for ten minutes targeting those users that have an insider cookie.
|
||||
@@ -485,7 +612,7 @@ podinfod=stefanprodan/podinfo:6.0.3
|
||||
Flagger detects that the deployment revision changed and starts a new rollout:
|
||||
|
||||
```text
|
||||
kubectl -n test describe canary/abtest
|
||||
kubectl -n test describe canary/podinfo
|
||||
|
||||
Status:
|
||||
Failed Checks: 0
|
||||
@@ -511,5 +638,90 @@ Events:
|
||||
Normal Synced 5s flagger Promotion completed! Scaling down podinfo.test
|
||||
```
|
||||
|
||||
## Traffic mirroring
|
||||
|
||||

|
||||
|
||||
For applications that perform read operations, Flagger can be configured to do B/G tests with traffic mirroring.
|
||||
Gateway API traffic mirroring will copy each incoming request, sending one request to the primary and one to the canary service.
|
||||
The response from the primary is sent back to the user and the response from the canary is discarded.
|
||||
Metrics are collected on both requests so that the deployment will only proceed if the canary metrics are within the threshold values.
|
||||
|
||||
Note that mirroring should be used for requests that are **idempotent** or capable of being processed twice \(once by the primary and once by the canary\).
|
||||
|
||||
You can enable mirroring by replacing `stepWeight` with `iterations` and by setting `analysis.mirror` to `true`:
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: Canary
|
||||
metadata:
|
||||
name: podinfo
|
||||
namespace: test
|
||||
spec:
|
||||
# deployment reference
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
service:
|
||||
# service port number
|
||||
port: 9898
|
||||
# container port number or name (optional)
|
||||
targetPort: 9898
|
||||
# Gateway API HTTPRoute host names
|
||||
hosts:
|
||||
- www.example.com
|
||||
# Reference to the Gateway that the generated HTTPRoute would attach to.
|
||||
gatewayRefs:
|
||||
- name: gateway
|
||||
namespace: istio-ingress
|
||||
analysis:
|
||||
# schedule interval
|
||||
interval: 1m
|
||||
# max number of failed metric checks before rollback
|
||||
threshold: 5
|
||||
# total number of iterations
|
||||
iterations: 10
|
||||
# enable traffic shadowing
|
||||
mirror: true
|
||||
# Gateway API HTTPRoute host names
|
||||
metrics:
|
||||
- name: request-success-rate
|
||||
thresholdRange:
|
||||
min: 99
|
||||
interval: 1m
|
||||
- name: request-duration
|
||||
thresholdRange:
|
||||
max: 500
|
||||
interval: 1m
|
||||
webhooks:
|
||||
- name: load-test
|
||||
url: http://flagger-loadtester.test/
|
||||
timeout: 5s
|
||||
metadata:
|
||||
cmd: "hey -z 2m -q 10 -c 2 -host www.example.com http://gateway-istio.istio-ingress/"
|
||||
```
|
||||
|
||||
With the above configuration, Flagger will run a canary release with the following steps:
|
||||
|
||||
* detect new revision \(deployment spec, secrets or configmaps changes\)
|
||||
* scale from zero the canary deployment
|
||||
* wait for the HPA to set the canary minimum replicas
|
||||
* check canary pods health
|
||||
* run the acceptance tests
|
||||
* abort the canary release if tests fail
|
||||
* start the load tests
|
||||
* mirror 100% of the traffic from primary to canary
|
||||
* check request success rate and request duration every minute
|
||||
* abort the canary release if the metrics check failure threshold is reached
|
||||
* stop traffic mirroring after the number of iterations is reached
|
||||
* route live traffic to the canary pods
|
||||
* promote the canary \(update the primary secrets, configmaps and deployment spec\)
|
||||
* wait for the primary deployment rollout to finish
|
||||
* wait for the HPA to set the primary minimum replicas
|
||||
* check primary pods health
|
||||
* switch live traffic back to primary
|
||||
* scale to zero the canary
|
||||
* send notification with the canary analysis result
|
||||
|
||||
The above procedures can be extended with [custom metrics](../usage/metrics.md) checks, [webhooks](../usage/webhooks.md), [manual promotion](../usage/webhooks.md#manual-gating) approval and [Slack or MS Teams](../usage/alerting.md) notifications.
|
||||
|
||||
@@ -110,7 +110,7 @@ spec:
|
||||
name: podinfo
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
|
||||
@@ -15,7 +15,7 @@ Install Istio with telemetry support and Prometheus:
|
||||
```bash
|
||||
istioctl manifest install --set profile=default
|
||||
|
||||
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/prometheus.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.18/samples/addons/prometheus.yaml
|
||||
```
|
||||
|
||||
Install Flagger in the `istio-system` namespace:
|
||||
@@ -84,7 +84,7 @@ spec:
|
||||
progressDeadlineSeconds: 60
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
@@ -92,7 +92,7 @@ spec:
|
||||
port: 9898
|
||||
# Istio gateways (optional)
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
# Istio virtual service host names (optional)
|
||||
hosts:
|
||||
- app.example.com
|
||||
@@ -179,7 +179,7 @@ podinfod=ghcr.io/stefanprodan/podinfo:6.0.1
|
||||
Flagger detects that the deployment revision changed and starts a new rollout:
|
||||
|
||||
```text
|
||||
kubectl -n test describe canary/abtest
|
||||
kubectl -n test describe canary/podinfo
|
||||
|
||||
Status:
|
||||
Failed Checks: 0
|
||||
|
||||
@@ -14,7 +14,7 @@ Install Istio with telemetry support and Prometheus:
|
||||
istioctl manifest install --set profile=default
|
||||
|
||||
# Suggestion: Please change release-1.8 in below command, to your real istio version.
|
||||
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.8/samples/addons/prometheus.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.18/samples/addons/prometheus.yaml
|
||||
```
|
||||
|
||||
Install Flagger in the `istio-system` namespace:
|
||||
@@ -85,7 +85,7 @@ spec:
|
||||
progressDeadlineSeconds: 60
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
@@ -95,7 +95,7 @@ spec:
|
||||
targetPort: 9898
|
||||
# Istio gateways (optional)
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
# Istio virtual service host names (optional)
|
||||
hosts:
|
||||
- app.example.com
|
||||
@@ -316,7 +316,7 @@ spec:
|
||||
progressDeadlineSeconds: 60
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
@@ -326,7 +326,7 @@ spec:
|
||||
targetPort: 9898
|
||||
# Istio gateways (optional)
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
# Istio virtual service host names (optional)
|
||||
hosts:
|
||||
- app.example.com
|
||||
@@ -480,3 +480,61 @@ With the above configuration, Flagger will run a canary release with the followi
|
||||
|
||||
The above procedure can be extended with [custom metrics](../usage/metrics.md) checks, [webhooks](../usage/webhooks.md), [manual promotion](../usage/webhooks.md#manual-gating) approval and [Slack or MS Teams](../usage/alerting.md) notifications.
|
||||
|
||||
|
||||
## Canary Deployments for TCP Services
|
||||
|
||||
Performing a Canary deployment on a TCP (non HTTP) service is nearly identical to an HTTP Canary. Besides updating your `Gateway` document to support the `TCP` routing, the only difference is you have to set the `appProtocol` field to `TCP` inside of the `service` section of your `Canary` document.
|
||||
|
||||
#### Example:
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.istio.io/v1alpha3
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: public-gateway
|
||||
namespace: istio-system
|
||||
spec:
|
||||
selector:
|
||||
istio: ingressgateway
|
||||
servers:
|
||||
- port:
|
||||
number: 7070
|
||||
name: tcp-service
|
||||
protocol: TCP # <== set the protocol to tcp here
|
||||
hosts:
|
||||
- "*"
|
||||
```
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: Canary
|
||||
# omitted for brevity
|
||||
spec:
|
||||
service:
|
||||
port: 7070
|
||||
appProtocol: TCP # <== set the appProtocol here
|
||||
targetPort: 7070
|
||||
portName: "tcp-service-port"
|
||||
```
|
||||
|
||||
If the `appProtocol` equals `TCP` then Flagger will treat this as a Canary deployment for a `TCP` service. When it creates the `VirtualService` document it will add a `TCP` section to route requests between the `primary` and `canary` services. See Istio documentation for more information on this [spec](https://istio.io/latest/docs/reference/config/networking/virtual-service/#TCPRoute).
|
||||
|
||||
The resulting `VirtualService` will include a `tcp` section similar to what is shown below:
|
||||
```yaml
|
||||
tcp:
|
||||
- route:
|
||||
- destination:
|
||||
host: tcp-service-primary
|
||||
port:
|
||||
number: 7070
|
||||
weight: 100
|
||||
- destination:
|
||||
host: tcp-service-canary
|
||||
port:
|
||||
number: 7070
|
||||
weight: 0
|
||||
```
|
||||
|
||||
Once the Canary analysis begins, Flagger will be able to adjust the weights inside of this `tcp` section to advance the Canary deployment until it either runs into an error (and is halted) or it successfully reaches the end of the analysis and is Promoted.
|
||||
|
||||
It is also important to note that if you set `appProtocol` to anything other than `TCP`, for example if you set it to `HTTP`, it will perform the Canary and treat it as an `HTTP` service. The same remains true if you do not set `appProtocol` at all. It will __ONLY__ treat a Canary as a `TCP` service if `appProtocal` equals `TCP`.
|
||||
@@ -20,6 +20,7 @@ Install Flagger:
|
||||
```bash
|
||||
helm repo add flagger https://flagger.app
|
||||
|
||||
kubectl create namespace flagger
|
||||
helm upgrade -i flagger flagger/flagger \
|
||||
--namespace flagger \
|
||||
--set prometheus.install=true \
|
||||
@@ -68,7 +69,7 @@ spec:
|
||||
- type: prometheus
|
||||
metadata:
|
||||
name: prom-trigger
|
||||
serverAddress: http://flagger-prometheus.flagger-system:9090
|
||||
serverAddress: http://flagger-prometheus.flagger:9090
|
||||
metricName: http_requests_total
|
||||
query: sum(rate(http_requests_total{ app="podinfo" }[30s]))
|
||||
threshold: '5'
|
||||
|
||||
@@ -84,7 +84,7 @@ spec:
|
||||
progressDeadlineSeconds: 60
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
|
||||
@@ -6,16 +6,16 @@ This guide shows you how to use Kuma and Flagger to automate canary deployments.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Flagger requires a Kubernetes cluster **v1.16** or newer and Kuma **1.3** or newer.
|
||||
Flagger requires a Kubernetes cluster **v1.19** or newer and Kuma **1.7** or newer.
|
||||
|
||||
Install Kuma and Prometheus (part of Kuma Metrics):
|
||||
|
||||
```bash
|
||||
kumactl install control-plane | kubectl apply -f -
|
||||
kumactl install metrics | kubectl apply -f -
|
||||
kumactl install observability --components "grafana,prometheus" | kubectl apply -f -
|
||||
```
|
||||
|
||||
Install Flagger in the `kuma-system` namespace:
|
||||
Install Flagger in the `kong-mesh-system` namespace:
|
||||
|
||||
```bash
|
||||
kubectl apply -k github.com/fluxcd/flagger//kustomize/kuma
|
||||
|
||||
@@ -2,26 +2,54 @@
|
||||
|
||||
This guide shows you how to use Linkerd and Flagger to automate canary deployments.
|
||||
|
||||

|
||||
|
||||
## Prerequisites
|
||||
|
||||
Flagger requires a Kubernetes cluster **v1.16** or newer and Linkerd **2.10** or newer.
|
||||
Flagger requires a Kubernetes cluster **v1.21** or newer and Linkerd **2.14** or newer.
|
||||
|
||||
Install Linkerd the Promethues (part of Linkerd Viz):
|
||||
Install Linkerd and Prometheus (part of Linkerd Viz):
|
||||
|
||||
```bash
|
||||
# The CRDs need to be installed beforehand
|
||||
linkerd install --crds | kubectl apply -f -
|
||||
|
||||
linkerd install | kubectl apply -f -
|
||||
linkerd viz install | kubectl apply -f -
|
||||
|
||||
# For linkerd versions 2.12 and later, the SMI extension needs to be install in
|
||||
# order to enable TrafficSplits
|
||||
curl -sL https://linkerd.github.io/linkerd-smi/install | sh
|
||||
linkerd smi install | kubectl apply -f -
|
||||
```
|
||||
|
||||
Install Flagger in the linkerd namespace:
|
||||
Install Flagger in the flagger-system namespace:
|
||||
|
||||
```bash
|
||||
kubectl apply -k github.com/fluxcd/flagger//kustomize/linkerd
|
||||
```
|
||||
|
||||
If you prefer Helm, these are the commands to install Linkerd, Linkerd Viz,
|
||||
Linkerd-SMI and Flagger:
|
||||
|
||||
```bash
|
||||
helm repo add linkerd https://helm.linkerd.io/stable
|
||||
helm install linkerd-crds linkerd/linkerd-crds -n linkerd --create-namespace
|
||||
# See https://linkerd.io/2/tasks/generate-certificates/ for how to generate the
|
||||
# certs referred below
|
||||
helm install linkerd-control-plane linkerd/linkerd-control-plane \
|
||||
-n linkerd \
|
||||
--set-file identityTrustAnchorsPEM=ca.crt \
|
||||
--set-file identity.issuer.tls.crtPEM=issuer.crt \
|
||||
--set-file identity.issuer.tls.keyPEM=issuer.key \
|
||||
|
||||
helm install linkerd-viz linkerd/linkerd-viz -n linkerd-viz --create-namespace
|
||||
|
||||
helm install flagger flagger/flagger \
|
||||
--n flagger-system \
|
||||
--set meshProvider=gatewayapi:v1beta1 \
|
||||
--set metricsServer=http://prometheus.linkerd-viz:9090 \
|
||||
--set linkerdAuthPolicy.create=true
|
||||
```
|
||||
|
||||
## Bootstrap
|
||||
|
||||
Flagger takes a Kubernetes deployment and optionally a horizontal pod autoscaler (HPA),
|
||||
@@ -47,9 +75,65 @@ Create a deployment and a horizontal pod autoscaler:
|
||||
kubectl apply -k https://github.com/fluxcd/flagger//kustomize/podinfo?ref=main
|
||||
```
|
||||
|
||||
Create a canary custom resource for the podinfo deployment:
|
||||
Create a metrics template and canary custom resources for the podinfo deployment:
|
||||
|
||||
```yaml
|
||||
---
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: MetricTemplate
|
||||
metadata:
|
||||
name: success-rate
|
||||
namespace: test
|
||||
spec:
|
||||
provider:
|
||||
type: prometheus
|
||||
address: http://prometheus.linkerd-viz:9090
|
||||
query: |
|
||||
sum(
|
||||
rate(
|
||||
response_total{
|
||||
namespace="{{ namespace }}",
|
||||
deployment=~"{{ target }}",
|
||||
classification!="failure",
|
||||
direction="{{ variables.direction }}"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
/
|
||||
sum(
|
||||
rate(
|
||||
response_total{
|
||||
namespace="{{ namespace }}",
|
||||
deployment=~"{{ target }}",
|
||||
direction="{{ variables.direction }}"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
* 100
|
||||
---
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: MetricTemplate
|
||||
metadata:
|
||||
name: latency
|
||||
namespace: test
|
||||
spec:
|
||||
provider:
|
||||
type: prometheus
|
||||
address: http://prometheus.linkerd-viz:9090
|
||||
query: |
|
||||
histogram_quantile(
|
||||
0.99,
|
||||
sum(
|
||||
rate(
|
||||
response_latency_ms_bucket{
|
||||
namespace="{{ namespace }}",
|
||||
deployment=~"{{ target }}",
|
||||
direction="{{ variables.direction }}"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
) by (le)
|
||||
)
|
||||
---
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: Canary
|
||||
metadata:
|
||||
@@ -63,7 +147,7 @@ spec:
|
||||
name: podinfo
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
# the maximum time in seconds for the canary deployment
|
||||
@@ -74,6 +158,13 @@ spec:
|
||||
port: 9898
|
||||
# container port number or name (optional)
|
||||
targetPort: 9898
|
||||
# Reference to the Service that the generated HTTPRoute would attach to.
|
||||
gatewayRefs:
|
||||
- name: podinfo
|
||||
namespace: test
|
||||
group: core
|
||||
kind: Service
|
||||
port: 9898
|
||||
analysis:
|
||||
# schedule interval (default 60s)
|
||||
interval: 30s
|
||||
@@ -87,18 +178,28 @@ spec:
|
||||
stepWeight: 5
|
||||
# Linkerd Prometheus checks
|
||||
metrics:
|
||||
- name: request-success-rate
|
||||
- name: success-rate
|
||||
templateRef:
|
||||
name: success-rate
|
||||
namespace: test
|
||||
# minimum req success rate (non 5xx responses)
|
||||
# percentage (0-100)
|
||||
thresholdRange:
|
||||
min: 99
|
||||
interval: 1m
|
||||
- name: request-duration
|
||||
templateVariables:
|
||||
direction: inbound
|
||||
- name: latency
|
||||
templateRef:
|
||||
name: latency
|
||||
namespace: test
|
||||
# maximum req duration P99
|
||||
# milliseconds
|
||||
thresholdRange:
|
||||
max: 500
|
||||
interval: 30s
|
||||
templateVariables:
|
||||
direction: inbound
|
||||
# testing (optional)
|
||||
webhooks:
|
||||
- name: acceptance-test
|
||||
@@ -310,7 +411,7 @@ watch -n 1 curl http://podinfo-canary:9898/status/404
|
||||
Watch Flagger logs:
|
||||
|
||||
```text
|
||||
kubectl -n linkerd logs deployment/flagger -f | jq .msg
|
||||
kubectl -n flagger-system logs deployment/flagger -f | jq .msg
|
||||
|
||||
Starting canary deployment for podinfo.test
|
||||
Pre-rollout check acceptance-test passed
|
||||
@@ -391,7 +492,7 @@ spec:
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
|
||||
@@ -110,7 +110,7 @@ spec:
|
||||
name: podinfo
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
# the maximum time in seconds for the canary deployment
|
||||
|
||||
@@ -86,7 +86,7 @@ spec:
|
||||
name: podinfo
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
# the maximum time in seconds for the canary deployment
|
||||
|
||||
@@ -113,7 +113,7 @@ spec:
|
||||
name: podinfo
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
# the maximum time in seconds for the canary deployment
|
||||
|
||||
@@ -103,7 +103,7 @@ spec:
|
||||
name: podinfo
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
# the maximum time in seconds for the canary deployment
|
||||
|
||||
@@ -139,7 +139,7 @@ Note that without resource requests the horizontal pod autoscaler can't determin
|
||||
A production environment should be able to handle traffic bursts without impacting the quality of service. This can be achieved with Kubernetes autoscaling capabilities. Autoscaling in Kubernetes has two dimensions: the Cluster Autoscaler that deals with node scaling operations and the Horizontal Pod Autoscaler that automatically scales the number of pods in a deployment.
|
||||
|
||||
```yaml
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
@@ -172,7 +172,7 @@ spec:
|
||||
service:
|
||||
port: 9898
|
||||
gateways:
|
||||
- public-gateway.istio-system.svc.cluster.local
|
||||
- istio-system/public-gateway
|
||||
hosts:
|
||||
- app.example.com
|
||||
retries:
|
||||
|
||||
@@ -9,9 +9,9 @@ Flagger can run automated application analysis, promotion and rollback for the f
|
||||
* **Blue/Green** \(traffic switching\)
|
||||
* Kubernetes CNI, Istio, Linkerd, App Mesh, NGINX, Contour, Gloo Edge, Open Service Mesh, Gateway API
|
||||
* **Blue/Green Mirroring** \(traffic shadowing\)
|
||||
* Istio
|
||||
* Istio, Gateway API
|
||||
* **Canary Release with Session Affinity** \(progressive traffic shifting combined with cookie based routing\)
|
||||
* Istio
|
||||
* Istio, Gateway API
|
||||
|
||||
For Canary releases and A/B testing you'll need a Layer 7 traffic management solution like
|
||||
a service mesh or an ingress controller. For Blue/Green deployments no service mesh or ingress controller is required.
|
||||
@@ -126,11 +126,11 @@ the step and the maximum weight value in 0 to 100 range.
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
canary:
|
||||
# canary.yaml
|
||||
spec:
|
||||
analysis:
|
||||
promotion:
|
||||
maxWeight: 50
|
||||
stepWeight: 20
|
||||
maxWeight: 50
|
||||
stepWeight: 20
|
||||
```
|
||||
|
||||
This configuration performs analysis starting from 20, increasing by 20 until weight goes above 50.
|
||||
@@ -148,10 +148,10 @@ In order to enable non-linear promotion a new parameter was introduced:
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
canary:
|
||||
# canary.yaml
|
||||
spec:
|
||||
analysis:
|
||||
promotion:
|
||||
stepWeights: [1, 2, 10, 80]
|
||||
stepWeights: [1, 2, 10, 80]
|
||||
```
|
||||
|
||||
This configuration performs analysis starting from 1, going through `stepWeights` values till 80.
|
||||
@@ -353,8 +353,6 @@ you should consider what will happen if a write is duplicated and handled by the
|
||||
|
||||
To use mirroring, set `spec.analysis.mirror` to `true`.
|
||||
|
||||
Istio example:
|
||||
|
||||
```yaml
|
||||
analysis:
|
||||
# schedule interval (default 60s)
|
||||
@@ -363,9 +361,10 @@ Istio example:
|
||||
iterations: 10
|
||||
# max number of failed iterations before rollback
|
||||
threshold: 2
|
||||
# Traffic shadowing (compatible with Istio only)
|
||||
# Traffic shadowing
|
||||
mirror: true
|
||||
# Weight of the traffic mirrored to your canary (defaults to 100%)
|
||||
# Only applicable for Istio.
|
||||
mirrorWeight: 100
|
||||
```
|
||||
|
||||
@@ -408,7 +407,7 @@ cookie based routing with regular weight based routing. This means once a user i
|
||||
version of our application (based on the traffic weights), they're always routed to that version, i.e.
|
||||
they're never routed back to the old version of our application.
|
||||
|
||||
You can enable this, by specifying `.spec.analsyis.sessionAffinity` in the Canary (only Istio is supported):
|
||||
You can enable this, by specifying `.spec.analsyis.sessionAffinity` in the Canary:
|
||||
|
||||
```yaml
|
||||
analysis:
|
||||
|
||||
@@ -65,7 +65,7 @@ spec:
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
autoscalerRef:
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
primaryScalerReplicas:
|
||||
@@ -379,3 +379,10 @@ On each run, Flagger calls the webhooks, checks the metrics and if the failed ch
|
||||
stops the analysis and rolls back the canary.
|
||||
If alerting is configured, Flagger will post the analysis result using the alert providers.
|
||||
|
||||
## Canary suspend
|
||||
|
||||
The `suspend` field can be set to true to suspend the Canary. If a Canary is suspended,
|
||||
its reconciliation is completely paused. This means that changes to target workloads,
|
||||
tracked ConfigMaps and Secrets don't trigger a Canary run and changes to resources generated
|
||||
by Flagger are not corrected. If the Canary was suspended during an active Canary run,
|
||||
then the run is paused without disturbing the workloads or the traffic weights.
|
||||
|
||||
@@ -668,3 +668,65 @@ Reference the template in the canary analysis:
|
||||
max: 1000
|
||||
interval: 1m
|
||||
```
|
||||
|
||||
## Keptn
|
||||
|
||||
You can create custom metric checks using the Keptn provider.
|
||||
This Provider allows to verify either the value of a single [KeptnMetric](https://keptn.sh/stable/docs/reference/crd-reference/metric/),
|
||||
representing the value of a single metric,
|
||||
or of a [Keptn Analysis](https://keptn.sh/stable/docs/reference/crd-reference/analysis/),
|
||||
which provides a flexible grading logic for analysing and prioritising a number of different
|
||||
metric values coming from different data sources.
|
||||
|
||||
This provider requires [Keptn](https://keptn.sh/stable/docs/installation/) to be installed in the cluster.
|
||||
|
||||
Example for a Keptn metric template:
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: MetricTemplate
|
||||
metadata:
|
||||
name: response-time
|
||||
namespace: istio-system
|
||||
spec:
|
||||
provider:
|
||||
type: keptn
|
||||
query: keptnmetric/my-namespace/response-time/2m/reporter=destination
|
||||
```
|
||||
|
||||
This will reference the `KeptnMetric` with the name `response-time` in
|
||||
the namespace `my-namespace`, which could look like the following:
|
||||
|
||||
```yaml
|
||||
apiVersion: metrics.keptn.sh/v1beta1
|
||||
kind: KeptnMetric
|
||||
metadata:
|
||||
name: response-time
|
||||
namespace: my-namespace
|
||||
spec:
|
||||
fetchIntervalSeconds: 10
|
||||
provider:
|
||||
name: my-prometheus-keptn-provider
|
||||
query: histogram_quantile(0.8, sum by(le) (rate(http_server_request_latency_seconds_bucket{status_code='200',
|
||||
job='simple-go-backend'}[5m[])))
|
||||
```
|
||||
|
||||
The `query` contains the following components, which are divided by `/` characters:
|
||||
|
||||
```
|
||||
<type>/<namespace>/<resource-name>/<timeframe>/<arguments>
|
||||
```
|
||||
|
||||
* **type (required)**: Must be either `keptnmetric` or `analysis`.
|
||||
* **namespace (required)**: The namespace of the referenced `KeptnMetric`/`AnalysisDefinition`.
|
||||
* **resource-name (required):** The name of the referenced `KeptnMetric`/`AnalysisDefinition`.
|
||||
* **timeframe (optional)**: The timeframe used for the Analysis.
|
||||
This will usually be set to the same value as the analysis interval of a `Canary`.
|
||||
Only relevant if the `type` is set to `analysis`.
|
||||
* **arguments (optional)**: Arguments to be passed to an `Analysis`.
|
||||
Arguments are passed as a list of key value pairs, separated by `;` characters,
|
||||
e.g. `foo=bar;bar=foo`.
|
||||
Only relevant if the `type` is set to `analysis`.
|
||||
|
||||
For the type `analysis`, the value returned by the provider is either `0`
|
||||
(if the analysis failed), or `1` (analysis passed).
|
||||
|
||||
@@ -41,6 +41,7 @@ Spec:
|
||||
- name: "start gate"
|
||||
type: confirm-rollout
|
||||
url: http://flagger-loadtester.test/gate/approve
|
||||
retries: 5
|
||||
- name: "helm test"
|
||||
type: pre-rollout
|
||||
url: http://flagger-helmtester.flagger/
|
||||
@@ -72,6 +73,7 @@ Spec:
|
||||
- name: "send to Slack"
|
||||
type: event
|
||||
url: http://event-recevier.notifications/slack
|
||||
retries: 3
|
||||
metadata:
|
||||
environment: "test"
|
||||
cluster: "flagger-test"
|
||||
@@ -83,16 +85,19 @@ Webhook payload (HTTP POST):
|
||||
|
||||
```javascript
|
||||
{
|
||||
"name": "podinfo",
|
||||
"namespace": "test",
|
||||
"phase": "Progressing",
|
||||
"metadata": {
|
||||
"test": "all",
|
||||
"token": "16688eb5e9f289f1991c"
|
||||
}
|
||||
"name": "podinfo",
|
||||
"namespace": "test",
|
||||
"phase": "Progressing",
|
||||
"checksum": "85d557f47b",
|
||||
"metadata": {
|
||||
"test": "all",
|
||||
"token": "16688eb5e9f289f1991c"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The checksum field is hashed from the TrackedConfigs and LastAppliedSpec of the Canary, it can be used to identify a Canary for a specific configuration of the deployed resources.
|
||||
|
||||
Response status codes:
|
||||
|
||||
* 200-202 - advance canary by increasing the traffic weight
|
||||
@@ -107,6 +112,7 @@ Event payload (HTTP POST):
|
||||
"name": "string (canary name)",
|
||||
"namespace": "string (canary namespace)",
|
||||
"phase": "string (canary phase)",
|
||||
"checksum": "string (canary checksum"),
|
||||
"metadata": {
|
||||
"eventMessage": "string (canary event message)",
|
||||
"eventType": "string (canary event type)",
|
||||
@@ -118,6 +124,8 @@ Event payload (HTTP POST):
|
||||
The event receiver can create alerts based on the received phase
|
||||
(possible values: `Initialized`, `Waiting`, `Progressing`, `Promoting`, `Finalising`, `Succeeded` or `Failed`).
|
||||
|
||||
The webhook request can be retried by specifying a positive integer in the `retries` field.
|
||||
|
||||
## Load Testing
|
||||
|
||||
For workloads that are not receiving constant traffic Flagger can be configured with a webhook,
|
||||
@@ -387,6 +395,22 @@ This can be done via mounting a Kubernetes secret in the tester's Deployment.
|
||||
to see if the process has finished (Default is 5s). `pollTimeout` represents the time in seconds
|
||||
the web-hook will try to call Concord before timing out (Default is 30s).
|
||||
|
||||
If you need to start a Pod/Job to run tests, you can do so using `kubectl`.
|
||||
|
||||
```yaml
|
||||
analysis:
|
||||
webhooks:
|
||||
- name: "smoke test"
|
||||
type: pre-rollout
|
||||
url: http://flagger-kubectltester.kube-system/
|
||||
timeout: 3m
|
||||
metadata:
|
||||
type: "kubectl"
|
||||
cmd: "run test --image=alpine --overrides='{ "spec": { "serviceAccount": "default:default" } }'"
|
||||
```
|
||||
|
||||
Note that you need to setup RBAC for the load tester service account in order to run `kubectl` and `helm` commands.
|
||||
|
||||
## Manual Gating
|
||||
|
||||
For manual approval of a canary deployment you can use the `confirm-rollout` and `confirm-promotion` webhooks.
|
||||
|
||||
108
go.mod
108
go.mod
@@ -1,87 +1,97 @@
|
||||
module github.com/fluxcd/flagger
|
||||
|
||||
go 1.19
|
||||
go 1.22.0
|
||||
|
||||
require (
|
||||
cloud.google.com/go/monitoring v1.12.0
|
||||
github.com/Masterminds/semver/v3 v3.2.0
|
||||
github.com/aws/aws-sdk-go v1.44.204
|
||||
cloud.google.com/go/monitoring v1.19.0
|
||||
github.com/Masterminds/semver/v3 v3.2.1
|
||||
github.com/aws/aws-sdk-go v1.53.12
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/go-logr/zapr v1.2.3
|
||||
github.com/google/go-cmp v0.5.9
|
||||
github.com/googleapis/gax-go/v2 v2.7.0
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.12.2
|
||||
github.com/prometheus/client_golang v1.14.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
go.uber.org/zap v1.24.0
|
||||
google.golang.org/api v0.110.0
|
||||
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44
|
||||
google.golang.org/grpc v1.53.0
|
||||
google.golang.org/protobuf v1.28.1
|
||||
github.com/go-logr/zapr v1.3.0
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/googleapis/gax-go/v2 v2.12.4
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.13.0
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/stretchr/testify v1.9.0
|
||||
go.uber.org/zap v1.27.0
|
||||
golang.org/x/sync v0.7.0
|
||||
google.golang.org/api v0.182.0
|
||||
google.golang.org/genproto v0.0.0-20240528184218-531527333157
|
||||
google.golang.org/grpc v1.64.1
|
||||
google.golang.org/protobuf v1.34.1
|
||||
gopkg.in/h2non/gock.v1 v1.1.2
|
||||
k8s.io/api v0.26.1
|
||||
k8s.io/apimachinery v0.26.1
|
||||
k8s.io/client-go v0.26.1
|
||||
k8s.io/code-generator v0.26.1
|
||||
k8s.io/klog/v2 v2.90.0
|
||||
k8s.io/api v0.30.3
|
||||
k8s.io/apimachinery v0.30.3
|
||||
k8s.io/client-go v0.30.3
|
||||
k8s.io/code-generator v0.30.3
|
||||
k8s.io/klog/v2 v2.120.1
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute v1.18.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/auth v0.4.2 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.3.0 // indirect
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/deepmap/oapi-codegen v1.12.4 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.10.1 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||
github.com/go-logr/logr v1.2.3 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/gnostic v0.6.9 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||
github.com/google/s2a-go v0.1.7 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/imdario/mergo v0.3.15 // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/oapi-codegen/runtime v1.0.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.3.0 // indirect
|
||||
github.com/prometheus/common v0.40.0 // indirect
|
||||
github.com/prometheus/procfs v0.9.0 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.48.0 // indirect
|
||||
github.com/prometheus/procfs v0.12.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/oauth2 v0.5.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/term v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.24.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/net v0.26.0 // indirect
|
||||
golang.org/x/oauth2 v0.20.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/term v0.21.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240521202816-d264139d666e // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/gengo v0.0.0-20221011193443-fad74ee6edd9 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20230217203603-ff9a8e8fa21d // indirect
|
||||
k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
|
||||
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
331
go.sum
331
go.sum
@@ -1,69 +1,57 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.107.0 h1:qkj22L7bgkl6vIeZDlOY2po43Mx/TIa2Wsa7VR+PEww=
|
||||
cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY=
|
||||
cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/longrunning v0.3.0 h1:NjljC+FYPV3uh5/OwWT6pVU+doBqMg2x/rZlE+CamDs=
|
||||
cloud.google.com/go/monitoring v1.12.0 h1:+X79DyOP/Ny23XIqSIb37AvFWSxDN15w/ktklVvPLso=
|
||||
cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w=
|
||||
cloud.google.com/go/auth v0.4.2 h1:sb0eyLkhRtpq5jA+a8KWw0W70YcdVca7KJ8TM0AFYDg=
|
||||
cloud.google.com/go/auth v0.4.2/go.mod h1:Kqvlz1cf1sNA0D+sYJnkPQOP+JMHkuHeIgVmCRtZOLc=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q=
|
||||
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
|
||||
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||
cloud.google.com/go/monitoring v1.19.0 h1:NCXf8hfQi+Kmr56QJezXRZ6GPb80ZI7El1XztyUuLQI=
|
||||
cloud.google.com/go/monitoring v1.19.0/go.mod h1:25IeMR5cQ5BoZ8j1eogHE5VPJLlReQ7zFp5OiLgiGZw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
|
||||
github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
||||
github.com/aws/aws-sdk-go v1.44.204 h1:7/tPUXfNOHB390A63t6fJIwmlwVQAkAwcbzKsU2/6OQ=
|
||||
github.com/aws/aws-sdk-go v1.44.204/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/aws/aws-sdk-go v1.53.12 h1:8f8K+YaTy2qwtGwVIo2Ftq22UCH96xQAX7Q0lyZKDiA=
|
||||
github.com/aws/aws-sdk-go v1.53.12/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/deepmap/oapi-codegen v1.12.4 h1:pPmn6qI9MuOtCz82WY2Xaw46EQjgvxednXXrP7g5Q2s=
|
||||
github.com/deepmap/oapi-codegen v1.12.4/go.mod h1:3lgHGMu6myQ2vqbbTXH2H1o4eXFTGnFiDaOaKKl5yas=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ=
|
||||
github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
|
||||
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
|
||||
github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/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.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
@@ -72,50 +60,53 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0=
|
||||
github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
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-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o=
|
||||
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
|
||||
github.com/googleapis/gax-go/v2 v2.7.0 h1:IcsPKeInNvYi7eqSaDjiZqDDKu5rsmunY0Y1YupQSSQ=
|
||||
github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg=
|
||||
github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.12.2 h1:uYABKdrEKlYm+++qfKdbgaHKBPmoWR5wpbmj6MBB/2g=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.12.2/go.mod h1:YteV91FiQxRdccyJ2cHvj2f/5sq4y4Njqu1fQzsQCOU=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
||||
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
|
||||
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.13.0 h1:ioBbLmR5NMbAjP4UVA5r9b5xGjpABD7j65pI8kFphDM=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.13.0/go.mod h1:k+spCbt9hcvqvUiz0sr5D8LolXHqAAOfPw9v/RIRHl4=
|
||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf h1:7JTmneyiNEwVBOHSjoMxiWAqB992atOeepeFYegn5RU=
|
||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
@@ -129,18 +120,19 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm
|
||||
github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -150,174 +142,139 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||
github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs=
|
||||
github.com/onsi/gomega v1.23.0 h1:/oxKu9c2HVap+F3PfKort2Hw5DEU+HGlW8n+tguWsys=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/oapi-codegen/runtime v1.0.0 h1:P4rqFX5fMFWqRzY9M/3YF9+aPSPPB06IzP2P7oOxrWo=
|
||||
github.com/oapi-codegen/runtime v1.0.0/go.mod h1:LmCUMQuPB4M/nLXilQXhHw+BLZdDb18B34OO356yJ/A=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
|
||||
github.com/onsi/gomega v1.31.0 h1:54UJxxj6cPInHS3a35wm6BK/F9nHYueZ1NVujHDrnXE=
|
||||
github.com/onsi/gomega v1.31.0/go.mod h1:DW9aCi7U6Yi40wNVAvT6kzFnEVEI5n3DloYBiKiT6zk=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
|
||||
github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=
|
||||
github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE=
|
||||
github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
|
||||
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
|
||||
github.com/prometheus/common v0.40.0 h1:Afz7EVRqGg2Mqqf4JuF9vdvp1pi220m55Pi9T2JnO4Q=
|
||||
github.com/prometheus/common v0.40.0/go.mod h1:L65ZJPSmfn/UBWLQIHV7dBrKFidB/wPlF1y5TlSt9OE=
|
||||
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/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE=
|
||||
github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc=
|
||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||
go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0 h1:4Pp6oUg3+e/6M4C0A/3kJ2VYa++dsWVTtGgLVj5xtHg=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
|
||||
golang.org/x/mod v0.17.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-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
|
||||
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
|
||||
golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo=
|
||||
golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
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=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
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=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
|
||||
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=
|
||||
google.golang.org/api v0.110.0 h1:l+rh0KYUooe9JGbGVx71tbFo4SMbMTXK3I3ia2QSEeU=
|
||||
google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI=
|
||||
google.golang.org/api v0.182.0 h1:if5fPvudRQ78GeRx3RayIoiuV7modtErPIZC/T2bIvE=
|
||||
google.golang.org/api v0.182.0/go.mod h1:cGhjy4caqA5yXRzEhkHI8Y9mfyC2VLTlER2l08xaqtM=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44 h1:EfLuoKW5WfkgVdDy7dTK8qSbH37AX5mj/MFh+bGPz14=
|
||||
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA=
|
||||
google.golang.org/genproto v0.0.0-20240528184218-531527333157 h1:u7WMYrIrVvs0TF5yaKwKNbcJyySYf+HAIFXxWltJOXE=
|
||||
google.golang.org/genproto v0.0.0-20240528184218-531527333157/go.mod h1:ubQlAQnzejB8uZzszhrTCU2Fyp6Vi7ZE5nn0c3W8+qQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240521202816-d264139d666e h1:SkdGTrROJl2jRGT/Fxv5QUf9jtdKCQh4KQJXbXVLAi0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240521202816-d264139d666e/go.mod h1:LweJcLbyVij6rCex8YunD8DYR5VDonap/jYl3ZRxcIU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e h1:Elxv5MwEkCI9f5SkoL6afed6NTdxaGoAo39eANBwHL8=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240521202816-d264139d666e/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
|
||||
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
|
||||
google.golang.org/grpc v1.64.1 h1:LKtvyfbX3UGVPFcGqJ9ItpVWW6oN/2XqTxfAnwRRXiA=
|
||||
google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
@@ -327,54 +284,42 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
|
||||
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
|
||||
google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ=
|
||||
k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg=
|
||||
k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ=
|
||||
k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
|
||||
k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU=
|
||||
k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE=
|
||||
k8s.io/code-generator v0.26.1 h1:dusFDsnNSKlMFYhzIM0jAO1OlnTN5WYwQQ+Ai12IIlo=
|
||||
k8s.io/code-generator v0.26.1/go.mod h1:OMoJ5Dqx1wgaQzKgc+ZWaZPfGjdRq/Y3WubFrZmeI3I=
|
||||
k8s.io/gengo v0.0.0-20221011193443-fad74ee6edd9 h1:iu3o/SxaHVI7tKPtkGzD3M9IzrE21j+CUKH98NQJ8Ms=
|
||||
k8s.io/gengo v0.0.0-20221011193443-fad74ee6edd9/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.90.0 h1:VkTxIV/FjRXn1fgNNcKGM8cfmL1Z33ZjXRTVxKCoF5M=
|
||||
k8s.io/klog/v2 v2.90.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
|
||||
k8s.io/kube-openapi v0.0.0-20230217203603-ff9a8e8fa21d h1:oFDpQ7FfzinCtrFOl4izwOWsdTprlS2A9IXBENMW0UA=
|
||||
k8s.io/kube-openapi v0.0.0-20230217203603-ff9a8e8fa21d/go.mod h1:/BYxry62FuDzmI+i9B+X2pqfySRmSOW2ARmj5Zbqhj0=
|
||||
k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY=
|
||||
k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/api v0.30.3 h1:ImHwK9DCsPA9uoU3rVh4QHAHHK5dTSv1nxJUapx8hoQ=
|
||||
k8s.io/api v0.30.3/go.mod h1:GPc8jlzoe5JG3pb0KJCSLX5oAFIW3/qNJITlDj8BH04=
|
||||
k8s.io/apimachinery v0.30.3 h1:q1laaWCmrszyQuSQCfNB8cFgCuDAoPszKY4ucAjDwHc=
|
||||
k8s.io/apimachinery v0.30.3/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
|
||||
k8s.io/client-go v0.30.3 h1:bHrJu3xQZNXIi8/MoxYtZBBWQQXwy16zqJwloXXfD3k=
|
||||
k8s.io/client-go v0.30.3/go.mod h1:8d4pf8vYu665/kUbsxWAQ/JDBNWqfFeZnvFiVdmx89U=
|
||||
k8s.io/code-generator v0.30.3 h1:bmtnLJKagDS5f5uOEpLyJiDfIMKXGMKgOLBdde+w0Mc=
|
||||
k8s.io/code-generator v0.30.3/go.mod h1:PFgBiv+miFV7TZYp+RXgROkhA+sWYZ+mtpbMLofMke8=
|
||||
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70 h1:NGrVE502P0s0/1hudf8zjgwki1X/TByhmAoILTarmzo=
|
||||
k8s.io/gengo/v2 v2.0.0-20240228010128-51d4e06bde70/go.mod h1:VH3AT8AaQOqiGjMF9p0/IM1Dj+82ZwjfxUP1IxaHE+8=
|
||||
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
|
||||
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag=
|
||||
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98=
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI=
|
||||
k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
|
||||
@@ -25,14 +25,23 @@ trap "cleanup" EXIT SIGINT
|
||||
|
||||
echo ">> Temporary output directory ${TEMP_DIR}"
|
||||
|
||||
# Ensure we can execute.
|
||||
chmod +x ${CODEGEN_PKG}/generate-groups.sh
|
||||
PACKAGE_PATH_BASE="github.com/fluxcd/flagger"
|
||||
|
||||
${CODEGEN_PKG}/generate-groups.sh all \
|
||||
github.com/fluxcd/flagger/pkg/client github.com/fluxcd/flagger/pkg/apis \
|
||||
"flagger:v1beta1 appmesh:v1beta2 appmesh:v1beta1 istio:v1alpha3 smi:v1alpha1 smi:v1alpha2 smi:v1alpha3 gloo/gloo:v1 gloo/gateway:v1 projectcontour:v1 traefik:v1alpha1 kuma:v1alpha1 gatewayapi:v1alpha2 gatewayapi:v1beta1 keda:v1alpha1 apisix:v2" \
|
||||
--output-base "${TEMP_DIR}" \
|
||||
--go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt
|
||||
mkdir -p "${TEMP_DIR}/${PACKAGE_PATH_BASE}/pkg/client/informers" \
|
||||
"${TEMP_DIR}/${PACKAGE_PATH_BASE}/pkg/client/listers" \
|
||||
"${TEMP_DIR}/${PACKAGE_PATH_BASE}/pkg/client/clientset"
|
||||
|
||||
# Ensure we can execute.
|
||||
chmod +x ${CODEGEN_PKG}/kube_codegen.sh
|
||||
|
||||
source ${CODEGEN_PKG}/kube_codegen.sh kube::codegen::gen_client \
|
||||
--output-dir "${TEMP_DIR}" \
|
||||
--output-pkg "${PACKAGE_PATH_BASE}/pkg/client" \
|
||||
--with-watch \
|
||||
--boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \
|
||||
./pkgs/apis
|
||||
|
||||
ls -lha $TEMP_DIR
|
||||
|
||||
# Copy everything back.
|
||||
cp -r "${TEMP_DIR}/github.com/fluxcd/flagger/." "${SCRIPT_ROOT}/"
|
||||
cp -r "${TEMP_DIR}/${PACKAGE_PATH_BASE}/." "${SCRIPT_ROOT}/"
|
||||
|
||||
@@ -27,6 +27,10 @@ spec:
|
||||
- name: Weight
|
||||
type: string
|
||||
jsonPath: .status.canaryWeight
|
||||
- name: Suspended
|
||||
type: boolean
|
||||
jsonPath: .spec.suspend
|
||||
priority: 1
|
||||
- name: FailedChecks
|
||||
type: string
|
||||
jsonPath: .status.failedChecks
|
||||
@@ -478,6 +482,54 @@ spec:
|
||||
uri:
|
||||
format: string
|
||||
type: string
|
||||
authority:
|
||||
format: string
|
||||
type: string
|
||||
type:
|
||||
format: string
|
||||
type: string
|
||||
mirror:
|
||||
description: Mirror defines a schema for a filter that mirrors requests.
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
backendRef:
|
||||
properties:
|
||||
group:
|
||||
default: ""
|
||||
maxLength: 253
|
||||
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
kind:
|
||||
default: Service
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
|
||||
type: string
|
||||
name:
|
||||
maxLength: 253
|
||||
minLength: 1
|
||||
type: string
|
||||
namespace:
|
||||
maxLength: 63
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
|
||||
type: string
|
||||
port:
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
x-kubernetes-validations:
|
||||
- message: Must have port for Service reference
|
||||
rule: '(size(self.group) == 0 && self.kind == ''Service'')
|
||||
? has(self.port) : true'
|
||||
required:
|
||||
- backendRef
|
||||
headers:
|
||||
description: Headers operations
|
||||
type: object
|
||||
@@ -557,6 +609,11 @@ spec:
|
||||
minLength: 1
|
||||
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
|
||||
type: string
|
||||
port:
|
||||
format: int32
|
||||
maximum: 65535
|
||||
minimum: 1
|
||||
type: integer
|
||||
corsPolicy:
|
||||
description: Istio Cross-Origin Resource Sharing policy (CORS)
|
||||
type: object
|
||||
@@ -747,6 +804,10 @@ spec:
|
||||
- LEAST_CONN
|
||||
- RANDOM
|
||||
- PASSTHROUGH
|
||||
- LEAST_REQUEST
|
||||
type: string
|
||||
warmupDurationSecs:
|
||||
description: Represents the warmup duration of Service.
|
||||
type: string
|
||||
outlierDetection:
|
||||
description: Settings controlling eviction of unhealthy hosts from the load balancing pool.
|
||||
@@ -850,6 +911,9 @@ spec:
|
||||
revertOnDeletion:
|
||||
description: Revert mutated resources to original spec on deletion
|
||||
type: boolean
|
||||
suspend:
|
||||
description: Suspend Canary disabling/pausing all canary runs
|
||||
type: boolean
|
||||
analysis:
|
||||
description: Canary analysis for this canary
|
||||
type: object
|
||||
@@ -923,6 +987,34 @@ spec:
|
||||
description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax)
|
||||
format: string
|
||||
type: string
|
||||
queryParams:
|
||||
description: Query parameters for matching.
|
||||
type: object
|
||||
additionalProperties:
|
||||
oneOf:
|
||||
- not:
|
||||
anyOf:
|
||||
- required:
|
||||
- exact
|
||||
- required:
|
||||
- prefix
|
||||
- required:
|
||||
- regex
|
||||
- required:
|
||||
- exact
|
||||
- required:
|
||||
- prefix
|
||||
- required:
|
||||
- regex
|
||||
properties:
|
||||
exact:
|
||||
type: string
|
||||
prefix:
|
||||
type: string
|
||||
regex:
|
||||
description: RE2 style regex-based match (https://github.com/google/re2/wiki/Syntax).
|
||||
type: string
|
||||
type: object
|
||||
sourceLabels:
|
||||
description: Applicable only when the 'mesh' gateway is included in the service.gateways list
|
||||
type: object
|
||||
@@ -1040,6 +1132,9 @@ spec:
|
||||
description: Request timeout for this webhook
|
||||
type: string
|
||||
pattern: "^[0-9]+(m|s)"
|
||||
retries:
|
||||
description: Number of retries for this webhook
|
||||
type: number
|
||||
metadata:
|
||||
description: Metadata (key-value pairs) for this webhook
|
||||
type: object
|
||||
@@ -1203,6 +1298,7 @@ spec:
|
||||
- newrelic
|
||||
- graphite
|
||||
- dynatrace
|
||||
- keptn
|
||||
address:
|
||||
description: API address of this provider
|
||||
type: string
|
||||
|
||||
@@ -9,4 +9,4 @@ resources:
|
||||
images:
|
||||
- name: ghcr.io/fluxcd/flagger
|
||||
newName: ghcr.io/fluxcd/flagger
|
||||
newTag: 1.29.0
|
||||
newTag: 1.38.0
|
||||
|
||||
@@ -241,6 +241,19 @@ rules:
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- metrics.keptn.sh
|
||||
resources:
|
||||
- keptnmetrics
|
||||
- analyses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- nonResourceURLs:
|
||||
- /version
|
||||
verbs:
|
||||
|
||||
@@ -10,5 +10,5 @@ spec:
|
||||
args:
|
||||
- -log-level=info
|
||||
- -include-label-prefix=app.kubernetes.io
|
||||
- -mesh-provider=gatewayapi:v1beta1
|
||||
- -mesh-provider=gatewayapi:v1
|
||||
- -metrics-server=http://flagger-prometheus:9090
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
namespace: kuma-system
|
||||
namespace: kong-mesh-system
|
||||
bases:
|
||||
- ../base/flagger/
|
||||
patchesStrategicMerge:
|
||||
- patch.yaml
|
||||
resources:
|
||||
- mesh.yaml
|
||||
|
||||
10
kustomize/kuma/mesh.yaml
Normal file
10
kustomize/kuma/mesh.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
apiVersion: kuma.io/v1alpha1
|
||||
kind: Mesh
|
||||
metadata:
|
||||
name: default
|
||||
spec:
|
||||
metrics:
|
||||
enabledBackend: prometheus-1
|
||||
backends:
|
||||
- name: prometheus-1
|
||||
type: prometheus
|
||||
@@ -11,4 +11,4 @@ spec:
|
||||
- -log-level=info
|
||||
- -include-label-prefix=app.kubernetes.io
|
||||
- -mesh-provider=kuma
|
||||
- -metrics-server=http://prometheus-server.kuma-metrics:80
|
||||
- -metrics-server=http://prometheus-server.mesh-observability:80
|
||||
|
||||
14
kustomize/linkerd/authorizationpolicy.yaml
Normal file
14
kustomize/linkerd/authorizationpolicy.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
apiVersion: policy.linkerd.io/v1alpha1
|
||||
kind: AuthorizationPolicy
|
||||
metadata:
|
||||
namespace: linkerd-viz
|
||||
name: prometheus-admin-flagger
|
||||
spec:
|
||||
targetRef:
|
||||
group: policy.linkerd.io
|
||||
kind: Server
|
||||
name: prometheus-admin
|
||||
requiredAuthenticationRefs:
|
||||
- kind: ServiceAccount
|
||||
name: flagger
|
||||
namespace: flagger-system
|
||||
@@ -1,5 +1,18 @@
|
||||
namespace: linkerd
|
||||
namespace: flagger-system
|
||||
bases:
|
||||
- ../base/flagger/
|
||||
- namespace.yaml
|
||||
- authorizationpolicy.yaml
|
||||
patchesStrategicMerge:
|
||||
- patch.yaml
|
||||
# restore overridden namespace field
|
||||
patchesJson6902:
|
||||
- target:
|
||||
group: policy.linkerd.io
|
||||
version: v1alpha1
|
||||
kind: AuthorizationPolicy
|
||||
name: prometheus-admin-flagger
|
||||
patch: |-
|
||||
- op: replace
|
||||
path: /metadata/namespace
|
||||
value: linkerd-viz
|
||||
|
||||
6
kustomize/linkerd/namespace.yaml
Normal file
6
kustomize/linkerd/namespace.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
annotations:
|
||||
linkerd.io/inject: enabled
|
||||
name: flagger-system
|
||||
@@ -10,7 +10,7 @@ spec:
|
||||
args:
|
||||
- -log-level=info
|
||||
- -include-label-prefix=app.kubernetes.io
|
||||
- -mesh-provider=linkerd
|
||||
- -mesh-provider=gatewayapi:v1beta1
|
||||
- -metrics-server=http://prometheus.linkerd-viz:9090
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
@@ -24,4 +24,4 @@ roleRef:
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: flagger
|
||||
namespace: linkerd
|
||||
namespace: flagger-system
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
apiVersion: autoscaling/v2beta2
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: podinfo
|
||||
|
||||
@@ -19,7 +19,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: loadtester
|
||||
image: ghcr.io/fluxcd/flagger-loadtester:0.28.1
|
||||
image: ghcr.io/fluxcd/flagger-loadtester:0.33.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- name: http
|
||||
|
||||
@@ -34,7 +34,7 @@ type AlertProvider struct {
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec AlertProviderSpec `json:"spec"`
|
||||
Status AlertProviderStatus `json:"status"`
|
||||
Status AlertProviderStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/fluxcd/flagger/pkg/apis/gatewayapi/v1beta1"
|
||||
istiov1alpha3 "github.com/fluxcd/flagger/pkg/apis/istio/v1alpha3"
|
||||
istiov1beta1 "github.com/fluxcd/flagger/pkg/apis/istio/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
)
|
||||
@@ -46,7 +46,7 @@ type Canary struct {
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec CanarySpec `json:"spec"`
|
||||
Status CanaryStatus `json:"status"`
|
||||
Status CanaryStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
@@ -110,6 +110,12 @@ type CanarySpec struct {
|
||||
// revert canary mutation on deletion of canary resource
|
||||
// +optional
|
||||
RevertOnDeletion bool `json:"revertOnDeletion,omitempty"`
|
||||
|
||||
// Suspend, if set to true will suspend the Canary, disabling any canary runs
|
||||
// regardless of any changes to its target, services, etc. Note that if the
|
||||
// Canary is suspended during an analysis, its paused until the Canary is unsuspended.
|
||||
// +optional
|
||||
Suspend bool `json:"suspend,omitempty"`
|
||||
}
|
||||
|
||||
// CanaryService defines how ClusterIP services, service mesh or ingress routing objects are generated
|
||||
@@ -167,27 +173,31 @@ type CanaryService struct {
|
||||
|
||||
// TrafficPolicy attached to the generated Istio destination rules
|
||||
// +optional
|
||||
TrafficPolicy *istiov1alpha3.TrafficPolicy `json:"trafficPolicy,omitempty"`
|
||||
TrafficPolicy *istiov1beta1.TrafficPolicy `json:"trafficPolicy,omitempty"`
|
||||
|
||||
// URI match conditions for the generated service
|
||||
// +optional
|
||||
Match []istiov1alpha3.HTTPMatchRequest `json:"match,omitempty"`
|
||||
Match []istiov1beta1.HTTPMatchRequest `json:"match,omitempty"`
|
||||
|
||||
// Rewrite HTTP URIs for the generated service
|
||||
// +optional
|
||||
Rewrite *istiov1alpha3.HTTPRewrite `json:"rewrite,omitempty"`
|
||||
Rewrite *HTTPRewrite `json:"rewrite,omitempty"`
|
||||
|
||||
// Retries policy for the generated virtual service
|
||||
// +optional
|
||||
Retries *istiov1alpha3.HTTPRetry `json:"retries,omitempty"`
|
||||
Retries *istiov1beta1.HTTPRetry `json:"retries,omitempty"`
|
||||
|
||||
// Headers operations for the generated Istio virtual service
|
||||
// +optional
|
||||
Headers *istiov1alpha3.Headers `json:"headers,omitempty"`
|
||||
Headers *istiov1beta1.Headers `json:"headers,omitempty"`
|
||||
|
||||
// Mirror specifies the destination for request mirroring.
|
||||
// Responses from this destination are dropped.
|
||||
Mirror []v1beta1.HTTPRequestMirrorFilter `json:"mirror,omitempty"`
|
||||
|
||||
// Cross-Origin Resource Sharing policy for the generated Istio virtual service
|
||||
// +optional
|
||||
CorsPolicy *istiov1alpha3.CorsPolicy `json:"corsPolicy,omitempty"`
|
||||
CorsPolicy *istiov1beta1.CorsPolicy `json:"corsPolicy,omitempty"`
|
||||
|
||||
// Mesh name of the generated App Mesh virtual nodes and virtual service
|
||||
// +optional
|
||||
@@ -265,7 +275,7 @@ type CanaryAnalysis struct {
|
||||
|
||||
// A/B testing HTTP header match conditions
|
||||
// +optional
|
||||
Match []istiov1alpha3.HTTPMatchRequest `json:"match,omitempty"`
|
||||
Match []istiov1beta1.HTTPMatchRequest `json:"match,omitempty"`
|
||||
|
||||
// SessionAffinity represents the session affinity settings for a canary run.
|
||||
// +optional
|
||||
@@ -384,6 +394,10 @@ type CanaryWebhook struct {
|
||||
// Metadata (key-value pairs) for this webhook
|
||||
// +optional
|
||||
Metadata *map[string]string `json:"metadata,omitempty"`
|
||||
|
||||
// Number of retries for this webhook
|
||||
// +optional
|
||||
Retries int `json:"retries,omitempty"`
|
||||
}
|
||||
|
||||
// CanaryWebhookPayload holds the deployment info and metadata sent to webhooks
|
||||
@@ -397,6 +411,11 @@ type CanaryWebhookPayload struct {
|
||||
// Phase of the canary analysis
|
||||
Phase CanaryPhase `json:"phase"`
|
||||
|
||||
// Hash from the TrackedConfigs and LastAppliedSpec of the Canary.
|
||||
// Can be used to identify a Canary for a specific configuration of the
|
||||
// deployed resources.
|
||||
Checksum string `json:"checksum"`
|
||||
|
||||
// Metadata (key-value pairs) for this webhook
|
||||
Metadata map[string]string `json:"metadata,omitempty"`
|
||||
}
|
||||
@@ -437,14 +456,15 @@ type LocalObjectReference struct {
|
||||
|
||||
type AutoscalerRefernce struct {
|
||||
// API version of the scaler
|
||||
// +optional
|
||||
// +required
|
||||
APIVersion string `json:"apiVersion,omitempty"`
|
||||
|
||||
// Kind of the scaler
|
||||
// +optional
|
||||
// +required
|
||||
Kind string `json:"kind,omitempty"`
|
||||
|
||||
// Name of the scaler
|
||||
// +required
|
||||
Name string `json:"name"`
|
||||
|
||||
// PrimaryScalerQueries maps a unique id to a query for the primary
|
||||
@@ -472,6 +492,41 @@ type CustomMetadata struct {
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPRewrite holds information about how to modify a request URI during
|
||||
// forwarding.
|
||||
type HTTPRewrite struct {
|
||||
// rewrite the path (or the prefix) portion of the URI with this
|
||||
// value. If the original URI was matched based on prefix, the value
|
||||
// provided in this field will replace the corresponding matched prefix.
|
||||
Uri string `json:"uri,omitempty"`
|
||||
|
||||
// rewrite the Authority/Host header with this value.
|
||||
Authority string `json:"authority,omitempty"`
|
||||
|
||||
// Type is the type of path modification to make.
|
||||
// +optional
|
||||
Type string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// GetType returns the type of HTTP path rewrite to be performed.
|
||||
func (r *HTTPRewrite) GetType() string {
|
||||
if r.Type == string(v1beta1.PrefixMatchHTTPPathModifier) {
|
||||
return r.Type
|
||||
}
|
||||
return string(v1beta1.FullPathHTTPPathModifier)
|
||||
}
|
||||
|
||||
// GetIstioRewrite returns a istiov1beta1.HTTPRewrite object.
|
||||
func (s *CanaryService) GetIstioRewrite() *istiov1beta1.HTTPRewrite {
|
||||
if s.Rewrite != nil {
|
||||
return &istiov1beta1.HTTPRewrite{
|
||||
Authority: s.Rewrite.Authority,
|
||||
Uri: s.Rewrite.Uri,
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetMaxAge returns the max age of a cookie in seconds.
|
||||
func (s *SessionAffinity) GetMaxAge() int {
|
||||
if s.MaxAge == 0 {
|
||||
|
||||
@@ -36,7 +36,7 @@ type MetricTemplate struct {
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec MetricTemplateSpec `json:"spec"`
|
||||
Status MetricTemplateStatus `json:"status"`
|
||||
Status MetricTemplateStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
@@ -23,7 +23,7 @@ package v1beta1
|
||||
|
||||
import (
|
||||
gatewayapiv1beta1 "github.com/fluxcd/flagger/pkg/apis/gatewayapi/v1beta1"
|
||||
v1alpha3 "github.com/fluxcd/flagger/pkg/apis/istio/v1alpha3"
|
||||
istiov1beta1 "github.com/fluxcd/flagger/pkg/apis/istio/v1beta1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
@@ -263,7 +263,7 @@ func (in *CanaryAnalysis) DeepCopyInto(out *CanaryAnalysis) {
|
||||
}
|
||||
if in.Match != nil {
|
||||
in, out := &in.Match, &out.Match
|
||||
*out = make([]v1alpha3.HTTPMatchRequest, len(*in))
|
||||
*out = make([]istiov1beta1.HTTPMatchRequest, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
@@ -393,34 +393,41 @@ func (in *CanaryService) DeepCopyInto(out *CanaryService) {
|
||||
}
|
||||
if in.TrafficPolicy != nil {
|
||||
in, out := &in.TrafficPolicy, &out.TrafficPolicy
|
||||
*out = new(v1alpha3.TrafficPolicy)
|
||||
*out = new(istiov1beta1.TrafficPolicy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Match != nil {
|
||||
in, out := &in.Match, &out.Match
|
||||
*out = make([]v1alpha3.HTTPMatchRequest, len(*in))
|
||||
*out = make([]istiov1beta1.HTTPMatchRequest, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Rewrite != nil {
|
||||
in, out := &in.Rewrite, &out.Rewrite
|
||||
*out = new(v1alpha3.HTTPRewrite)
|
||||
*out = new(HTTPRewrite)
|
||||
**out = **in
|
||||
}
|
||||
if in.Retries != nil {
|
||||
in, out := &in.Retries, &out.Retries
|
||||
*out = new(v1alpha3.HTTPRetry)
|
||||
*out = new(istiov1beta1.HTTPRetry)
|
||||
**out = **in
|
||||
}
|
||||
if in.Headers != nil {
|
||||
in, out := &in.Headers, &out.Headers
|
||||
*out = new(v1alpha3.Headers)
|
||||
*out = new(istiov1beta1.Headers)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Mirror != nil {
|
||||
in, out := &in.Mirror, &out.Mirror
|
||||
*out = make([]gatewayapiv1beta1.HTTPRequestMirrorFilter, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.CorsPolicy != nil {
|
||||
in, out := &in.CorsPolicy, &out.CorsPolicy
|
||||
*out = new(v1alpha3.CorsPolicy)
|
||||
*out = new(istiov1beta1.CorsPolicy)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Backends != nil {
|
||||
@@ -666,6 +673,22 @@ func (in *CustomMetadata) DeepCopy() *CustomMetadata {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPRewrite) DeepCopyInto(out *HTTPRewrite) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRewrite.
|
||||
func (in *HTTPRewrite) DeepCopy() *HTTPRewrite {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HTTPRewrite)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LocalObjectReference) DeepCopyInto(out *LocalObjectReference) {
|
||||
*out = *in
|
||||
|
||||
6
pkg/apis/gatewayapi/v1/doc.go
Normal file
6
pkg/apis/gatewayapi/v1/doc.go
Normal file
@@ -0,0 +1,6 @@
|
||||
// Package v1 contains API Schema definitions for the
|
||||
// gateway.networking.k8s.io API group.
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
package v1
|
||||
1203
pkg/apis/gatewayapi/v1/httproute_types.go
Normal file
1203
pkg/apis/gatewayapi/v1/httproute_types.go
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,12 +1,9 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes 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.
|
||||
@@ -14,7 +11,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha2
|
||||
package v1
|
||||
|
||||
// LocalObjectReference identifies an API object within the namespace of the
|
||||
// referrer.
|
||||
@@ -25,8 +22,8 @@ package v1alpha2
|
||||
// be rejected by the implementation, with appropriate Conditions set
|
||||
// on the containing object.
|
||||
type LocalObjectReference struct {
|
||||
// Group is the group of the referent. For example, "networking.k8s.io".
|
||||
// When unspecified (empty string), core API group is inferred.
|
||||
// Group is the group of the referent. For example, "gateway.networking.k8s.io".
|
||||
// When unspecified or empty string, core API group is inferred.
|
||||
Group Group `json:"group"`
|
||||
|
||||
// Kind is kind of the referent. For example "HTTPRoute" or "Service".
|
||||
@@ -46,8 +43,8 @@ type LocalObjectReference struct {
|
||||
// be rejected by the implementation, with appropriate Conditions set
|
||||
// on the containing object.
|
||||
type SecretObjectReference struct {
|
||||
// Group is the group of the referent. For example, "networking.k8s.io".
|
||||
// When unspecified (empty string), core API group is inferred.
|
||||
// Group is the group of the referent. For example, "gateway.networking.k8s.io".
|
||||
// When unspecified or empty string, core API group is inferred.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default=""
|
||||
@@ -65,9 +62,9 @@ type SecretObjectReference struct {
|
||||
// Namespace is the namespace of the backend. When unspecified, the local
|
||||
// namespace is inferred.
|
||||
//
|
||||
// Note that when a namespace is specified, a ReferencePolicy object
|
||||
// Note that when a namespace is specified, a ReferenceGrant object
|
||||
// is required in the referent namespace to allow that namespace's
|
||||
// owner to accept the reference. See the ReferencePolicy documentation
|
||||
// owner to accept the reference. See the ReferenceGrant documentation
|
||||
// for details.
|
||||
//
|
||||
// Support: Core
|
||||
@@ -80,9 +77,9 @@ type SecretObjectReference struct {
|
||||
// specific to BackendRef. It includes a few additional fields and features
|
||||
// than a regular ObjectReference.
|
||||
//
|
||||
// Note that when a namespace is specified, a ReferencePolicy object
|
||||
// Note that when a namespace is specified, a ReferenceGrant object
|
||||
// is required in the referent namespace to allow that namespace's
|
||||
// owner to accept the reference. See the ReferencePolicy documentation
|
||||
// owner to accept the reference. See the ReferenceGrant documentation
|
||||
// for details.
|
||||
//
|
||||
// The API object must be valid in the cluster; the Group and Kind must
|
||||
@@ -92,14 +89,15 @@ type SecretObjectReference struct {
|
||||
// be rejected by the implementation, with appropriate Conditions set
|
||||
// on the containing object.
|
||||
type BackendObjectReference struct {
|
||||
// Group is the group of the referent. For example, "networking.k8s.io".
|
||||
// When unspecified (empty string), core API group is inferred.
|
||||
// Group is the group of the referent. For example, "gateway.networking.k8s.io".
|
||||
// When unspecified or empty string, core API group is inferred.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default=""
|
||||
Group *Group `json:"group,omitempty"`
|
||||
|
||||
// Kind is kind of the referent. For example "HTTPRoute" or "Service".
|
||||
// Defaults to "Service" when not specified.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default=Service
|
||||
@@ -111,9 +109,9 @@ type BackendObjectReference struct {
|
||||
// Namespace is the namespace of the backend. When unspecified, the local
|
||||
// namespace is inferred.
|
||||
//
|
||||
// Note that when a namespace is specified, a ReferencePolicy object
|
||||
// Note that when a namespace is specified, a ReferenceGrant object
|
||||
// is required in the referent namespace to allow that namespace's
|
||||
// owner to accept the reference. See the ReferencePolicy documentation
|
||||
// owner to accept the reference. See the ReferenceGrant documentation
|
||||
// for details.
|
||||
//
|
||||
// Support: Core
|
||||
@@ -122,7 +120,8 @@ type BackendObjectReference struct {
|
||||
Namespace *Namespace `json:"namespace,omitempty"`
|
||||
|
||||
// Port specifies the destination port number to use for this resource.
|
||||
// Port is required when the referent is a Kubernetes Service.
|
||||
// Port is required when the referent is a Kubernetes Service. In this
|
||||
// case, the port number is the service port number, not the target port.
|
||||
// For other resources, destination port might be derived from the referent
|
||||
// resource or this field.
|
||||
//
|
||||
@@ -1,4 +1,4 @@
|
||||
package v1alpha2
|
||||
package v1
|
||||
|
||||
import (
|
||||
"github.com/fluxcd/flagger/pkg/apis/gatewayapi"
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
// SchemeGroupVersion is the identifier for the API which includes
|
||||
// the name of the group and the version of the API
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: gatewayapi.GroupName, Version: "v1alpha2"}
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: gatewayapi.GroupName, Version: "v1"}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
738
pkg/apis/gatewayapi/v1/shared_types.go
Normal file
738
pkg/apis/gatewayapi/v1/shared_types.go
Normal file
@@ -0,0 +1,738 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes 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 v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ParentReference identifies an API object (usually a Gateway) that can be considered
|
||||
// a parent of this resource (usually a route). There are two kinds of parent resources
|
||||
// with "Core" support:
|
||||
//
|
||||
// * Gateway (Gateway conformance profile)
|
||||
// * Service (Mesh conformance profile, experimental, ClusterIP Services only)
|
||||
//
|
||||
// This API may be extended in the future to support additional kinds of parent
|
||||
// resources.
|
||||
//
|
||||
// The API object must be valid in the cluster; the Group and Kind must
|
||||
// be registered in the cluster for this reference to be valid.
|
||||
type ParentReference struct {
|
||||
// Group is the group of the referent.
|
||||
// When unspecified, "gateway.networking.k8s.io" is inferred.
|
||||
// To set the core API group (such as for a "Service" kind referent),
|
||||
// Group must be explicitly set to "" (empty string).
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +kubebuilder:default=gateway.networking.k8s.io
|
||||
// +optional
|
||||
Group *Group `json:"group,omitempty"`
|
||||
|
||||
// Kind is kind of the referent.
|
||||
//
|
||||
// There are two kinds of parent resources with "Core" support:
|
||||
//
|
||||
// * Gateway (Gateway conformance profile)
|
||||
// * Service (Mesh conformance profile, experimental, ClusterIP Services only)
|
||||
//
|
||||
// Support for other resources is Implementation-Specific.
|
||||
//
|
||||
// +kubebuilder:default=Gateway
|
||||
// +optional
|
||||
Kind *Kind `json:"kind,omitempty"`
|
||||
|
||||
// Namespace is the namespace of the referent. When unspecified, this refers
|
||||
// to the local namespace of the Route.
|
||||
//
|
||||
// Note that there are specific rules for ParentRefs which cross namespace
|
||||
// boundaries. Cross-namespace references are only valid if they are explicitly
|
||||
// allowed by something in the namespace they are referring to. For example:
|
||||
// Gateway has the AllowedRoutes field, and ReferenceGrant provides a
|
||||
// generic way to enable any other kind of cross-namespace reference.
|
||||
//
|
||||
// <gateway:experimental:description>
|
||||
// ParentRefs from a Route to a Service in the same namespace are "producer"
|
||||
// routes, which apply default routing rules to inbound connections from
|
||||
// any namespace to the Service.
|
||||
//
|
||||
// ParentRefs from a Route to a Service in a different namespace are
|
||||
// "consumer" routes, and these routing rules are only applied to outbound
|
||||
// connections originating from the same namespace as the Route, for which
|
||||
// the intended destination of the connections are a Service targeted as a
|
||||
// ParentRef of the Route.
|
||||
// </gateway:experimental:description>
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +optional
|
||||
Namespace *Namespace `json:"namespace,omitempty"`
|
||||
|
||||
// Name is the name of the referent.
|
||||
//
|
||||
// Support: Core
|
||||
Name ObjectName `json:"name"`
|
||||
|
||||
// SectionName is the name of a section within the target resource. In the
|
||||
// following resources, SectionName is interpreted as the following:
|
||||
//
|
||||
// * Gateway: Listener Name. When both Port (experimental) and SectionName
|
||||
// are specified, the name and port of the selected listener must match
|
||||
// both specified values.
|
||||
// * Service: Port Name. When both Port (experimental) and SectionName
|
||||
// are specified, the name and port of the selected listener must match
|
||||
// both specified values. Note that attaching Routes to Services as Parents
|
||||
// is part of experimental Mesh support and is not supported for any other
|
||||
// purpose.
|
||||
//
|
||||
// Implementations MAY choose to support attaching Routes to other resources.
|
||||
// If that is the case, they MUST clearly document how SectionName is
|
||||
// interpreted.
|
||||
//
|
||||
// When unspecified (empty string), this will reference the entire resource.
|
||||
// For the purpose of status, an attachment is considered successful if at
|
||||
// least one section in the parent resource accepts it. For example, Gateway
|
||||
// listeners can restrict which Routes can attach to them by Route kind,
|
||||
// namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from
|
||||
// the referencing Route, the Route MUST be considered successfully
|
||||
// attached. If no Gateway listeners accept attachment from this Route, the
|
||||
// Route MUST be considered detached from the Gateway.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +optional
|
||||
SectionName *SectionName `json:"sectionName,omitempty"`
|
||||
|
||||
// Port is the network port this Route targets. It can be interpreted
|
||||
// differently based on the type of parent resource.
|
||||
//
|
||||
// When the parent resource is a Gateway, this targets all listeners
|
||||
// listening on the specified port that also support this kind of Route(and
|
||||
// select this Route). It's not recommended to set `Port` unless the
|
||||
// networking behaviors specified in a Route must apply to a specific port
|
||||
// as opposed to a listener(s) whose port(s) may be changed. When both Port
|
||||
// and SectionName are specified, the name and port of the selected listener
|
||||
// must match both specified values.
|
||||
//
|
||||
// <gateway:experimental:description>
|
||||
// When the parent resource is a Service, this targets a specific port in the
|
||||
// Service spec. When both Port (experimental) and SectionName are specified,
|
||||
// the name and port of the selected port must match both specified values.
|
||||
// </gateway:experimental:description>
|
||||
//
|
||||
// Implementations MAY choose to support other parent resources.
|
||||
// Implementations supporting other types of parent resources MUST clearly
|
||||
// document how/if Port is interpreted.
|
||||
//
|
||||
// For the purpose of status, an attachment is considered successful as
|
||||
// long as the parent resource accepts it partially. For example, Gateway
|
||||
// listeners can restrict which Routes can attach to them by Route kind,
|
||||
// namespace, or hostname. If 1 of 2 Gateway listeners accept attachment
|
||||
// from the referencing Route, the Route MUST be considered successfully
|
||||
// attached. If no Gateway listeners accept attachment from this Route,
|
||||
// the Route MUST be considered detached from the Gateway.
|
||||
//
|
||||
// Support: Extended
|
||||
//
|
||||
// +optional
|
||||
// <gateway:experimental>
|
||||
Port *PortNumber `json:"port,omitempty"`
|
||||
}
|
||||
|
||||
// CommonRouteSpec defines the common attributes that all Routes MUST include
|
||||
// within their spec.
|
||||
type CommonRouteSpec struct {
|
||||
// ParentRefs references the resources (usually Gateways) that a Route wants
|
||||
// to be attached to. Note that the referenced parent resource needs to
|
||||
// allow this for the attachment to be complete. For Gateways, that means
|
||||
// the Gateway needs to allow attachment from Routes of this kind and
|
||||
// namespace. For Services, that means the Service must either be in the same
|
||||
// namespace for a "producer" route, or the mesh implementation must support
|
||||
// and allow "consumer" routes for the referenced Service. ReferenceGrant is
|
||||
// not applicable for governing ParentRefs to Services - it is not possible to
|
||||
// create a "producer" route for a Service in a different namespace from the
|
||||
// Route.
|
||||
//
|
||||
// There are two kinds of parent resources with "Core" support:
|
||||
//
|
||||
// * Gateway (Gateway conformance profile)
|
||||
// <gateway:experimental:description>
|
||||
// * Service (Mesh conformance profile, experimental, ClusterIP Services only)
|
||||
// </gateway:experimental:description>
|
||||
// This API may be extended in the future to support additional kinds of parent
|
||||
// resources.
|
||||
//
|
||||
// ParentRefs must be _distinct_. This means either that:
|
||||
//
|
||||
// * They select different objects. If this is the case, then parentRef
|
||||
// entries are distinct. In terms of fields, this means that the
|
||||
// multi-part key defined by `group`, `kind`, `namespace`, and `name` must
|
||||
// be unique across all parentRef entries in the Route.
|
||||
// * They do not select different objects, but for each optional field used,
|
||||
// each ParentRef that selects the same object must set the same set of
|
||||
// optional fields to different values. If one ParentRef sets a
|
||||
// combination of optional fields, all must set the same combination.
|
||||
//
|
||||
// Some examples:
|
||||
//
|
||||
// * If one ParentRef sets `sectionName`, all ParentRefs referencing the
|
||||
// same object must also set `sectionName`.
|
||||
// * If one ParentRef sets `port`, all ParentRefs referencing the same
|
||||
// object must also set `port`.
|
||||
// * If one ParentRef sets `sectionName` and `port`, all ParentRefs
|
||||
// referencing the same object must also set `sectionName` and `port`.
|
||||
//
|
||||
// It is possible to separately reference multiple distinct objects that may
|
||||
// be collapsed by an implementation. For example, some implementations may
|
||||
// choose to merge compatible Gateway Listeners together. If that is the
|
||||
// case, the list of routes attached to those resources should also be
|
||||
// merged.
|
||||
//
|
||||
// Note that for ParentRefs that cross namespace boundaries, there are specific
|
||||
// rules. Cross-namespace references are only valid if they are explicitly
|
||||
// allowed by something in the namespace they are referring to. For example,
|
||||
// Gateway has the AllowedRoutes field, and ReferenceGrant provides a
|
||||
// generic way to enable other kinds of cross-namespace reference.
|
||||
//
|
||||
// <gateway:experimental:description>
|
||||
// ParentRefs from a Route to a Service in the same namespace are "producer"
|
||||
// routes, which apply default routing rules to inbound connections from
|
||||
// any namespace to the Service.
|
||||
//
|
||||
// ParentRefs from a Route to a Service in a different namespace are
|
||||
// "consumer" routes, and these routing rules are only applied to outbound
|
||||
// connections originating from the same namespace as the Route, for which
|
||||
// the intended destination of the connections are a Service targeted as a
|
||||
// ParentRef of the Route.
|
||||
// </gateway:experimental:description>
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=32
|
||||
// <gateway:standard:validation:XValidation:message="sectionName must be specified when parentRefs includes 2 or more references to the same parent",rule="self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))">
|
||||
// <gateway:standard:validation:XValidation:message="sectionName must be unique when parentRefs includes 2 or more references to the same parent",rule="self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))">
|
||||
// <gateway:experimental:validation:XValidation:message="sectionName or port must be specified when parentRefs includes 2 or more references to the same parent",rule="self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))">
|
||||
// <gateway:experimental:validation:XValidation:message="sectionName or port must be unique when parentRefs includes 2 or more references to the same parent",rule="self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))">
|
||||
ParentRefs []ParentReference `json:"parentRefs,omitempty"`
|
||||
}
|
||||
|
||||
// PortNumber defines a network port.
|
||||
//
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +kubebuilder:validation:Maximum=65535
|
||||
type PortNumber int32
|
||||
|
||||
// BackendRef defines how a Route should forward a request to a Kubernetes
|
||||
// resource.
|
||||
//
|
||||
// Note that when a namespace different than the local namespace is specified, a
|
||||
// ReferenceGrant object is required in the referent namespace to allow that
|
||||
// namespace's owner to accept the reference. See the ReferenceGrant
|
||||
// documentation for details.
|
||||
//
|
||||
// <gateway:experimental:description>
|
||||
//
|
||||
// When the BackendRef points to a Kubernetes Service, implementations SHOULD
|
||||
// honor the appProtocol field if it is set for the target Service Port.
|
||||
//
|
||||
// Implementations supporting appProtocol SHOULD recognize the Kubernetes
|
||||
// Standard Application Protocols defined in KEP-3726.
|
||||
//
|
||||
// If a Service appProtocol isn't specified, an implementation MAY infer the
|
||||
// backend protocol through its own means. Implementations MAY infer the
|
||||
// protocol from the Route type referring to the backend Service.
|
||||
//
|
||||
// If a Route is not able to send traffic to the backend using the specified
|
||||
// protocol then the backend is considered invalid. Implementations MUST set the
|
||||
// "ResolvedRefs" condition to "False" with the "UnsupportedProtocol" reason.
|
||||
//
|
||||
// </gateway:experimental:description>
|
||||
//
|
||||
// Note that when the BackendTLSPolicy object is enabled by the implementation,
|
||||
// there are some extra rules about validity to consider here. See the fields
|
||||
// where this struct is used for more information about the exact behavior.
|
||||
type BackendRef struct {
|
||||
// BackendObjectReference references a Kubernetes object.
|
||||
BackendObjectReference `json:",inline"`
|
||||
|
||||
// Weight specifies the proportion of requests forwarded to the referenced
|
||||
// backend. This is computed as weight/(sum of all weights in this
|
||||
// BackendRefs list). For non-zero values, there may be some epsilon from
|
||||
// the exact proportion defined here depending on the precision an
|
||||
// implementation supports. Weight is not a percentage and the sum of
|
||||
// weights does not need to equal 100.
|
||||
//
|
||||
// If only one backend is specified and it has a weight greater than 0, 100%
|
||||
// of the traffic is forwarded to that backend. If weight is set to 0, no
|
||||
// traffic should be forwarded for this entry. If unspecified, weight
|
||||
// defaults to 1.
|
||||
//
|
||||
// Support for this field varies based on the context where used.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default=1
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
// +kubebuilder:validation:Maximum=1000000
|
||||
Weight *int32 `json:"weight,omitempty"`
|
||||
}
|
||||
|
||||
// RouteConditionType is a type of condition for a route.
|
||||
type RouteConditionType string
|
||||
|
||||
// RouteConditionReason is a reason for a route condition.
|
||||
type RouteConditionReason string
|
||||
|
||||
const (
|
||||
// This condition indicates whether the route has been accepted or rejected
|
||||
// by a Gateway, and why.
|
||||
//
|
||||
// Possible reasons for this condition to be True are:
|
||||
//
|
||||
// * "Accepted"
|
||||
//
|
||||
// Possible reasons for this condition to be False are:
|
||||
//
|
||||
// * "NotAllowedByListeners"
|
||||
// * "NoMatchingListenerHostname"
|
||||
// * "NoMatchingParent"
|
||||
// * "UnsupportedValue"
|
||||
//
|
||||
// Possible reasons for this condition to be Unknown are:
|
||||
//
|
||||
// * "Pending"
|
||||
//
|
||||
// Controllers may raise this condition with other reasons,
|
||||
// but should prefer to use the reasons listed above to improve
|
||||
// interoperability.
|
||||
RouteConditionAccepted RouteConditionType = "Accepted"
|
||||
|
||||
// This reason is used with the "Accepted" condition when the Route has been
|
||||
// accepted by the Gateway.
|
||||
RouteReasonAccepted RouteConditionReason = "Accepted"
|
||||
|
||||
// This reason is used with the "Accepted" condition when the route has not
|
||||
// been accepted by a Gateway because the Gateway has no Listener whose
|
||||
// allowedRoutes criteria permit the route
|
||||
RouteReasonNotAllowedByListeners RouteConditionReason = "NotAllowedByListeners"
|
||||
|
||||
// This reason is used with the "Accepted" condition when the Gateway has no
|
||||
// compatible Listeners whose Hostname matches the route
|
||||
RouteReasonNoMatchingListenerHostname RouteConditionReason = "NoMatchingListenerHostname"
|
||||
|
||||
// This reason is used with the "Accepted" condition when there are
|
||||
// no matching Parents. In the case of Gateways, this can occur when
|
||||
// a Route ParentRef specifies a Port and/or SectionName that does not
|
||||
// match any Listeners in the Gateway.
|
||||
RouteReasonNoMatchingParent RouteConditionReason = "NoMatchingParent"
|
||||
|
||||
// This reason is used with the "Accepted" condition when a value for an Enum
|
||||
// is not recognized.
|
||||
RouteReasonUnsupportedValue RouteConditionReason = "UnsupportedValue"
|
||||
|
||||
// This reason is used with the "Accepted" when a controller has not yet
|
||||
// reconciled the route.
|
||||
RouteReasonPending RouteConditionReason = "Pending"
|
||||
|
||||
// This reason is used with the "Accepted" condition when there
|
||||
// are incompatible filters present on a route rule (for example if
|
||||
// the URLRewrite and RequestRedirect are both present on an HTTPRoute).
|
||||
RouteReasonIncompatibleFilters RouteConditionReason = "IncompatibleFilters"
|
||||
)
|
||||
|
||||
const (
|
||||
// This condition indicates whether the controller was able to resolve all
|
||||
// the object references for the Route.
|
||||
//
|
||||
// Possible reasons for this condition to be True are:
|
||||
//
|
||||
// * "ResolvedRefs"
|
||||
//
|
||||
// Possible reasons for this condition to be False are:
|
||||
//
|
||||
// * "RefNotPermitted"
|
||||
// * "InvalidKind"
|
||||
// * "BackendNotFound"
|
||||
// * "UnsupportedProtocol"
|
||||
//
|
||||
// Controllers may raise this condition with other reasons,
|
||||
// but should prefer to use the reasons listed above to improve
|
||||
// interoperability.
|
||||
RouteConditionResolvedRefs RouteConditionType = "ResolvedRefs"
|
||||
|
||||
// This reason is used with the "ResolvedRefs" condition when the condition
|
||||
// is true.
|
||||
RouteReasonResolvedRefs RouteConditionReason = "ResolvedRefs"
|
||||
|
||||
// This reason is used with the "ResolvedRefs" condition when
|
||||
// one of the Listener's Routes has a BackendRef to an object in
|
||||
// another namespace, where the object in the other namespace does
|
||||
// not have a ReferenceGrant explicitly allowing the reference.
|
||||
RouteReasonRefNotPermitted RouteConditionReason = "RefNotPermitted"
|
||||
|
||||
// This reason is used with the "ResolvedRefs" condition when
|
||||
// one of the Route's rules has a reference to an unknown or unsupported
|
||||
// Group and/or Kind.
|
||||
RouteReasonInvalidKind RouteConditionReason = "InvalidKind"
|
||||
|
||||
// This reason is used with the "ResolvedRefs" condition when one of the
|
||||
// Route's rules has a reference to a resource that does not exist.
|
||||
RouteReasonBackendNotFound RouteConditionReason = "BackendNotFound"
|
||||
|
||||
// This reason is used with the "ResolvedRefs" condition when one of the
|
||||
// Route's rules has a reference to a resource with an app protocol that
|
||||
// is not supported by this implementation.
|
||||
RouteReasonUnsupportedProtocol RouteConditionReason = "UnsupportedProtocol"
|
||||
)
|
||||
|
||||
const (
|
||||
// This condition indicates that the Route contains a combination of both
|
||||
// valid and invalid rules.
|
||||
//
|
||||
// When this happens, implementations MUST take one of the following
|
||||
// approaches:
|
||||
//
|
||||
// 1) Drop Rule(s): With this approach, implementations will drop the
|
||||
// invalid Route Rule(s) until they are fully valid again. The message
|
||||
// for this condition MUST start with the prefix "Dropped Rule" and
|
||||
// include information about which Rules have been dropped. In this
|
||||
// state, the "Accepted" condition MUST be set to "True" with the latest
|
||||
// generation of the resource.
|
||||
// 2) Fall Back: With this approach, implementations will fall back to the
|
||||
// last known good state of the entire Route. The message for this
|
||||
// condition MUST start with the prefix "Fall Back" and include
|
||||
// information about why the current Rule(s) are invalid. To represent
|
||||
// this, the "Accepted" condition MUST be set to "True" with the
|
||||
// generation of the last known good state of the resource.
|
||||
//
|
||||
// Reverting to the last known good state should only be done by
|
||||
// implementations that have a means of restoring that state if/when they
|
||||
// are restarted.
|
||||
//
|
||||
// This condition MUST NOT be set if a Route is fully valid, fully invalid,
|
||||
// or not accepted. By extension, that means that this condition MUST only
|
||||
// be set when it is "True".
|
||||
//
|
||||
// Possible reasons for this condition to be True are:
|
||||
//
|
||||
// * "UnsupportedValue"
|
||||
//
|
||||
// Controllers may raise this condition with other reasons, but should
|
||||
// prefer to use the reasons listed above to improve interoperability.
|
||||
RouteConditionPartiallyInvalid RouteConditionType = "PartiallyInvalid"
|
||||
)
|
||||
|
||||
// RouteParentStatus describes the status of a route with respect to an
|
||||
// associated Parent.
|
||||
type RouteParentStatus struct {
|
||||
// ParentRef corresponds with a ParentRef in the spec that this
|
||||
// RouteParentStatus struct describes the status of.
|
||||
ParentRef ParentReference `json:"parentRef"`
|
||||
|
||||
// ControllerName is a domain/path string that indicates the name of the
|
||||
// controller that wrote this status. This corresponds with the
|
||||
// controllerName field on GatewayClass.
|
||||
//
|
||||
// Example: "example.net/gateway-controller".
|
||||
//
|
||||
// The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
|
||||
// valid Kubernetes names
|
||||
// (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
|
||||
//
|
||||
// Controllers MUST populate this field when writing status. Controllers should ensure that
|
||||
// entries to status populated with their ControllerName are cleaned up when they are no
|
||||
// longer necessary.
|
||||
ControllerName GatewayController `json:"controllerName"`
|
||||
|
||||
// Conditions describes the status of the route with respect to the Gateway.
|
||||
// Note that the route's availability is also subject to the Gateway's own
|
||||
// status conditions and listener status.
|
||||
//
|
||||
// If the Route's ParentRef specifies an existing Gateway that supports
|
||||
// Routes of this kind AND that Gateway's controller has sufficient access,
|
||||
// then that Gateway's controller MUST set the "Accepted" condition on the
|
||||
// Route, to indicate whether the route has been accepted or rejected by the
|
||||
// Gateway, and why.
|
||||
//
|
||||
// A Route MUST be considered "Accepted" if at least one of the Route's
|
||||
// rules is implemented by the Gateway.
|
||||
//
|
||||
// There are a number of cases where the "Accepted" condition may not be set
|
||||
// due to lack of controller visibility, that includes when:
|
||||
//
|
||||
// * The Route refers to a non-existent parent.
|
||||
// * The Route is of a type that the controller does not support.
|
||||
// * The Route is in a namespace the controller does not have access to.
|
||||
//
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=8
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// RouteStatus defines the common attributes that all Routes MUST include within
|
||||
// their status.
|
||||
type RouteStatus struct {
|
||||
// Parents is a list of parent resources (usually Gateways) that are
|
||||
// associated with the route, and the status of the route with respect to
|
||||
// each parent. When this route attaches to a parent, the controller that
|
||||
// manages the parent must add an entry to this list when the controller
|
||||
// first sees the route and should update the entry as appropriate when the
|
||||
// route or gateway is modified.
|
||||
//
|
||||
// Note that parent references that cannot be resolved by an implementation
|
||||
// of this API will not be added to this list. Implementations of this API
|
||||
// can only populate Route status for the Gateways/parent resources they are
|
||||
// responsible for.
|
||||
//
|
||||
// A maximum of 32 Gateways will be represented in this list. An empty list
|
||||
// means the route has not been attached to any Gateway.
|
||||
//
|
||||
// +kubebuilder:validation:MaxItems=32
|
||||
Parents []RouteParentStatus `json:"parents"`
|
||||
}
|
||||
|
||||
// Hostname is the fully qualified domain name of a network host. This matches
|
||||
// the RFC 1123 definition of a hostname with 2 notable exceptions:
|
||||
//
|
||||
// 1. IPs are not allowed.
|
||||
// 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
|
||||
// label must appear by itself as the first label.
|
||||
//
|
||||
// Hostname can be "precise" which is a domain name without the terminating
|
||||
// dot of a network host (e.g. "foo.example.com") or "wildcard", which is a
|
||||
// domain name prefixed with a single wildcard label (e.g. `*.example.com`).
|
||||
//
|
||||
// Note that as per RFC1035 and RFC1123, a *label* must consist of lower case
|
||||
// alphanumeric characters or '-', and must start and end with an alphanumeric
|
||||
// character. No other punctuation is allowed.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
||||
type Hostname string
|
||||
|
||||
// PreciseHostname is the fully qualified domain name of a network host. This
|
||||
// matches the RFC 1123 definition of a hostname with 1 notable exception that
|
||||
// numeric IP addresses are not allowed.
|
||||
//
|
||||
// Note that as per RFC1035 and RFC1123, a *label* must consist of lower case
|
||||
// alphanumeric characters or '-', and must start and end with an alphanumeric
|
||||
// character. No other punctuation is allowed.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
||||
type PreciseHostname string
|
||||
|
||||
// Group refers to a Kubernetes Group. It must either be an empty string or a
|
||||
// RFC 1123 subdomain.
|
||||
//
|
||||
// This validation is based off of the corresponding Kubernetes validation:
|
||||
// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L208
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "" - empty string implies core Kubernetes API group
|
||||
// * "gateway.networking.k8s.io"
|
||||
// * "foo.example.com"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * "example.com/bar" - "/" is an invalid character
|
||||
//
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
||||
type Group string
|
||||
|
||||
// Kind refers to a Kubernetes Kind.
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "Service"
|
||||
// * "HTTPRoute"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * "invalid/kind" - "/" is an invalid character
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=63
|
||||
// +kubebuilder:validation:Pattern=`^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$`
|
||||
type Kind string
|
||||
|
||||
// ObjectName refers to the name of a Kubernetes object.
|
||||
// Object names can have a variety of forms, including RFC1123 subdomains,
|
||||
// RFC 1123 labels, or RFC 1035 labels.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
type ObjectName string
|
||||
|
||||
// Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.
|
||||
//
|
||||
// This validation is based off of the corresponding Kubernetes validation:
|
||||
// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187
|
||||
//
|
||||
// This is used for Namespace name validation here:
|
||||
// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "example"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * "example.com" - "." is an invalid character
|
||||
//
|
||||
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=63
|
||||
type Namespace string
|
||||
|
||||
// SectionName is the name of a section in a Kubernetes resource.
|
||||
//
|
||||
// This validation is based off of the corresponding Kubernetes validation:
|
||||
// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L208
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "example.com"
|
||||
// * "foo.example.com"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * "example.com/bar" - "/" is an invalid character
|
||||
//
|
||||
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
type SectionName string
|
||||
|
||||
// GatewayController is the name of a Gateway API controller. It must be a
|
||||
// domain prefixed path.
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "example.com/bar"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * "example.com" - must include path
|
||||
// * "foo.example.com" - must include path
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$`
|
||||
type GatewayController string
|
||||
|
||||
// AnnotationKey is the key of an annotation in Gateway API. This is used for
|
||||
// validation of maps such as TLS options. This matches the Kubernetes
|
||||
// "qualified name" validation that is used for annotations and other common
|
||||
// values.
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * example
|
||||
// * example.com
|
||||
// * example.com/path
|
||||
// * example.com/path.html
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * example~ - "~" is an invalid character
|
||||
// * example.com. - can not start or end with "."
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]/?)*$`
|
||||
type AnnotationKey string
|
||||
|
||||
// AnnotationValue is the value of an annotation in Gateway API. This is used
|
||||
// for validation of maps such as TLS options. This roughly matches Kubernetes
|
||||
// annotation validation, although the length validation in that case is based
|
||||
// on the entire size of the annotations struct.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=0
|
||||
// +kubebuilder:validation:MaxLength=4096
|
||||
type AnnotationValue string
|
||||
|
||||
// AddressType defines how a network address is represented as a text string.
|
||||
// This may take two possible forms:
|
||||
//
|
||||
// * A predefined CamelCase string identifier (currently limited to `IPAddress` or `Hostname`)
|
||||
// * A domain-prefixed string identifier (like `acme.io/CustomAddressType`)
|
||||
//
|
||||
// Values `IPAddress` and `Hostname` have Extended support.
|
||||
//
|
||||
// The `NamedAddress` value has been deprecated in favor of implementation
|
||||
// specific domain-prefixed strings.
|
||||
//
|
||||
// All other values, including domain-prefixed values have Implementation-specific support,
|
||||
// which are used in implementation-specific behaviors. Support for additional
|
||||
// predefined CamelCase identifiers may be added in future releases.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^Hostname|IPAddress|NamedAddress|[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$`
|
||||
type AddressType string
|
||||
|
||||
// HeaderName is the name of a header or query parameter.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=256
|
||||
// +kubebuilder:validation:Pattern=`^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$`
|
||||
// +k8s:deepcopy-gen=false
|
||||
type HeaderName string
|
||||
|
||||
// Duration is a string value representing a duration in time. The format is as specified
|
||||
// in GEP-2257, a strict subset of the syntax parsed by Golang time.ParseDuration.
|
||||
//
|
||||
// +kubebuilder:validation:Pattern=`^([0-9]{1,5}(h|m|s|ms)){1,4}$`
|
||||
type Duration string
|
||||
|
||||
const (
|
||||
// A textual representation of a numeric IP address. IPv4
|
||||
// addresses must be in dotted-decimal form. IPv6 addresses
|
||||
// must be in a standard IPv6 text representation
|
||||
// (see [RFC 5952](https://tools.ietf.org/html/rfc5952)).
|
||||
//
|
||||
// This type is intended for specific addresses. Address ranges are not
|
||||
// supported (e.g. you can not use a CIDR range like 127.0.0.0/24 as an
|
||||
// IPAddress).
|
||||
//
|
||||
// Support: Extended
|
||||
IPAddressType AddressType = "IPAddress"
|
||||
|
||||
// A Hostname represents a DNS based ingress point. This is similar to the
|
||||
// corresponding hostname field in Kubernetes load balancer status. For
|
||||
// example, this concept may be used for cloud load balancers where a DNS
|
||||
// name is used to expose a load balancer.
|
||||
//
|
||||
// Support: Extended
|
||||
HostnameAddressType AddressType = "Hostname"
|
||||
|
||||
// A NamedAddress provides a way to reference a specific IP address by name.
|
||||
// For example, this may be a name or other unique identifier that refers
|
||||
// to a resource on a cloud provider such as a static IP.
|
||||
//
|
||||
// The `NamedAddress` type has been deprecated in favor of implementation
|
||||
// specific domain-prefixed strings.
|
||||
//
|
||||
// Support: Implementation-specific
|
||||
NamedAddressType AddressType = "NamedAddress"
|
||||
)
|
||||
@@ -19,64 +19,13 @@ limitations under the License.
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha2
|
||||
package v1
|
||||
|
||||
import (
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AddressMatch) DeepCopyInto(out *AddressMatch) {
|
||||
*out = *in
|
||||
if in.Type != nil {
|
||||
in, out := &in.Type, &out.Type
|
||||
*out = new(AddressType)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressMatch.
|
||||
func (in *AddressMatch) DeepCopy() *AddressMatch {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AddressMatch)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AddressRouteMatches) DeepCopyInto(out *AddressRouteMatches) {
|
||||
*out = *in
|
||||
if in.SourceAddresses != nil {
|
||||
in, out := &in.SourceAddresses, &out.SourceAddresses
|
||||
*out = make([]AddressMatch, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.DestinationAddresses != nil {
|
||||
in, out := &in.DestinationAddresses, &out.DestinationAddresses
|
||||
*out = make([]AddressMatch, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AddressRouteMatches.
|
||||
func (in *AddressRouteMatches) DeepCopy() *AddressRouteMatches {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AddressRouteMatches)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *BackendObjectReference) DeepCopyInto(out *BackendObjectReference) {
|
||||
*out = *in
|
||||
@@ -198,6 +147,37 @@ func (in *HTTPHeader) DeepCopy() *HTTPHeader {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPHeaderFilter) DeepCopyInto(out *HTTPHeaderFilter) {
|
||||
*out = *in
|
||||
if in.Set != nil {
|
||||
in, out := &in.Set, &out.Set
|
||||
*out = make([]HTTPHeader, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Add != nil {
|
||||
in, out := &in.Add, &out.Add
|
||||
*out = make([]HTTPHeader, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Remove != nil {
|
||||
in, out := &in.Remove, &out.Remove
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeaderFilter.
|
||||
func (in *HTTPHeaderFilter) DeepCopy() *HTTPHeaderFilter {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HTTPHeaderFilter)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPHeaderMatch) DeepCopyInto(out *HTTPHeaderMatch) {
|
||||
*out = *in
|
||||
@@ -248,6 +228,16 @@ func (in *HTTPPathMatch) DeepCopy() *HTTPPathMatch {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPPathModifier) DeepCopyInto(out *HTTPPathModifier) {
|
||||
*out = *in
|
||||
if in.ReplaceFullPath != nil {
|
||||
in, out := &in.ReplaceFullPath, &out.ReplaceFullPath
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.ReplacePrefixMatch != nil {
|
||||
in, out := &in.ReplacePrefixMatch, &out.ReplacePrefixMatch
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -282,37 +272,6 @@ func (in *HTTPQueryParamMatch) DeepCopy() *HTTPQueryParamMatch {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPRequestHeaderFilter) DeepCopyInto(out *HTTPRequestHeaderFilter) {
|
||||
*out = *in
|
||||
if in.Set != nil {
|
||||
in, out := &in.Set, &out.Set
|
||||
*out = make([]HTTPHeader, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Add != nil {
|
||||
in, out := &in.Add, &out.Add
|
||||
*out = make([]HTTPHeader, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Remove != nil {
|
||||
in, out := &in.Remove, &out.Remove
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRequestHeaderFilter.
|
||||
func (in *HTTPRequestHeaderFilter) DeepCopy() *HTTPRequestHeaderFilter {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HTTPRequestHeaderFilter)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPRequestMirrorFilter) DeepCopyInto(out *HTTPRequestMirrorFilter) {
|
||||
*out = *in
|
||||
@@ -346,7 +305,7 @@ func (in *HTTPRequestRedirectFilter) DeepCopyInto(out *HTTPRequestRedirectFilter
|
||||
if in.Path != nil {
|
||||
in, out := &in.Path, &out.Path
|
||||
*out = new(HTTPPathModifier)
|
||||
**out = **in
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Port != nil {
|
||||
in, out := &in.Port, &out.Port
|
||||
@@ -377,6 +336,7 @@ func (in *HTTPRoute) DeepCopyInto(out *HTTPRoute) {
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -403,7 +363,12 @@ func (in *HTTPRouteFilter) DeepCopyInto(out *HTTPRouteFilter) {
|
||||
*out = *in
|
||||
if in.RequestHeaderModifier != nil {
|
||||
in, out := &in.RequestHeaderModifier, &out.RequestHeaderModifier
|
||||
*out = new(HTTPRequestHeaderFilter)
|
||||
*out = new(HTTPHeaderFilter)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ResponseHeaderModifier != nil {
|
||||
in, out := &in.ResponseHeaderModifier, &out.ResponseHeaderModifier
|
||||
*out = new(HTTPHeaderFilter)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.RequestMirror != nil {
|
||||
@@ -536,6 +501,11 @@ func (in *HTTPRouteRule) DeepCopyInto(out *HTTPRouteRule) {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Timeouts != nil {
|
||||
in, out := &in.Timeouts, &out.Timeouts
|
||||
*out = new(HTTPRouteTimeouts)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -595,18 +565,44 @@ func (in *HTTPRouteStatus) DeepCopy() *HTTPRouteStatus {
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPRouteTimeouts) DeepCopyInto(out *HTTPRouteTimeouts) {
|
||||
*out = *in
|
||||
if in.Request != nil {
|
||||
in, out := &in.Request, &out.Request
|
||||
*out = new(Duration)
|
||||
**out = **in
|
||||
}
|
||||
if in.BackendRequest != nil {
|
||||
in, out := &in.BackendRequest, &out.BackendRequest
|
||||
*out = new(Duration)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPRouteTimeouts.
|
||||
func (in *HTTPRouteTimeouts) DeepCopy() *HTTPRouteTimeouts {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HTTPRouteTimeouts)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HTTPURLRewriteFilter) DeepCopyInto(out *HTTPURLRewriteFilter) {
|
||||
*out = *in
|
||||
if in.Hostname != nil {
|
||||
in, out := &in.Hostname, &out.Hostname
|
||||
*out = new(Hostname)
|
||||
*out = new(PreciseHostname)
|
||||
**out = **in
|
||||
}
|
||||
if in.Path != nil {
|
||||
in, out := &in.Path, &out.Path
|
||||
*out = new(HTTPPathModifier)
|
||||
**out = **in
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -660,6 +656,11 @@ func (in *ParentReference) DeepCopyInto(out *ParentReference) {
|
||||
*out = new(SectionName)
|
||||
**out = **in
|
||||
}
|
||||
if in.Port != nil {
|
||||
in, out := &in.Port, &out.Port
|
||||
*out = new(PortNumber)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -679,7 +680,7 @@ func (in *RouteParentStatus) DeepCopyInto(out *RouteParentStatus) {
|
||||
in.ParentRef.DeepCopyInto(&out.ParentRef)
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]v1.Condition, len(*in))
|
||||
*out = make([]metav1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// Package v1alpha2 contains API Schema definitions for the
|
||||
// gateway.networking.k8s.io API group.
|
||||
|
||||
package v1alpha2
|
||||
@@ -1,881 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes 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 v1alpha2
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:resource:categories=gateway-api
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:storageversion
|
||||
// +kubebuilder:printcolumn:name="Hostnames",type=string,JSONPath=`.spec.hostnames`
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
|
||||
// HTTPRoute provides a way to route HTTP requests. This includes the capability
|
||||
// to match requests by hostname, path, header, or query param. Filters can be
|
||||
// used to specify additional processing steps. Backends specify where matching
|
||||
// requests should be routed.
|
||||
type HTTPRoute struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec defines the desired state of HTTPRoute.
|
||||
Spec HTTPRouteSpec `json:"spec"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// HTTPRouteList contains a list of HTTPRoute.
|
||||
type HTTPRouteList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []HTTPRoute `json:"items"`
|
||||
}
|
||||
|
||||
// HTTPRouteSpec defines the desired state of HTTPRoute
|
||||
type HTTPRouteSpec struct {
|
||||
CommonRouteSpec `json:",inline"`
|
||||
|
||||
// Hostnames defines a set of hostname that should match against the HTTP
|
||||
// Host header to select a HTTPRoute to process the request. This matches
|
||||
// the RFC 1123 definition of a hostname with 2 notable exceptions:
|
||||
//
|
||||
// 1. IPs are not allowed.
|
||||
// 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
|
||||
// label must appear by itself as the first label.
|
||||
//
|
||||
// If a hostname is specified by both the Listener and HTTPRoute, there
|
||||
// must be at least one intersecting hostname for the HTTPRoute to be
|
||||
// attached to the Listener. For example:
|
||||
//
|
||||
// * A Listener with `test.example.com` as the hostname matches HTTPRoutes
|
||||
// that have either not specified any hostnames, or have specified at
|
||||
// least one of `test.example.com` or `*.example.com`.
|
||||
// * A Listener with `*.example.com` as the hostname matches HTTPRoutes
|
||||
// that have either not specified any hostnames or have specified at least
|
||||
// one hostname that matches the Listener hostname. For example,
|
||||
// `test.example.com` and `*.example.com` would both match. On the other
|
||||
// hand, `example.com` and `test.example.net` would not match.
|
||||
//
|
||||
// If both the Listener and HTTPRoute have specified hostnames, any
|
||||
// HTTPRoute hostnames that do not match the Listener hostname MUST be
|
||||
// ignored. For example, if a Listener specified `*.example.com`, and the
|
||||
// HTTPRoute specified `test.example.com` and `test.example.net`,
|
||||
// `test.example.net` must not be considered for a match.
|
||||
//
|
||||
// If both the Listener and HTTPRoute have specified hostnames, and none
|
||||
// match with the criteria above, then the HTTPRoute is not accepted. The
|
||||
// implementation must raise an 'Accepted' Condition with a status of
|
||||
// `False` in the corresponding RouteParentStatus.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=16
|
||||
Hostnames []Hostname `json:"hostnames,omitempty"`
|
||||
|
||||
// Rules are a list of HTTP matchers, filters and actions.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=16
|
||||
// +kubebuilder:default={{matches: {{path: {type: "PathPrefix", value: "/"}}}}}
|
||||
Rules []HTTPRouteRule `json:"rules,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPRouteRule defines semantics for matching an HTTP request based on
|
||||
// conditions (matches), processing it (filters), and forwarding the request to
|
||||
// an API object (backendRefs).
|
||||
type HTTPRouteRule struct {
|
||||
// Matches define conditions used for matching the rule against incoming
|
||||
// HTTP requests. Each match is independent, i.e. this rule will be matched
|
||||
// if **any** one of the matches is satisfied.
|
||||
//
|
||||
// For example, take the following matches configuration:
|
||||
//
|
||||
// ```
|
||||
// matches:
|
||||
// - path:
|
||||
// value: "/foo"
|
||||
// headers:
|
||||
// - name: "version"
|
||||
// value: "v2"
|
||||
// - path:
|
||||
// value: "/v2/foo"
|
||||
// ```
|
||||
//
|
||||
// For a request to match against this rule, a request must satisfy
|
||||
// EITHER of the two conditions:
|
||||
//
|
||||
// - path prefixed with `/foo` AND contains the header `version: v2`
|
||||
// - path prefix of `/v2/foo`
|
||||
//
|
||||
// See the documentation for HTTPRouteMatch on how to specify multiple
|
||||
// match conditions that should be ANDed together.
|
||||
//
|
||||
// If no matches are specified, the default is a prefix
|
||||
// path match on "/", which has the effect of matching every
|
||||
// HTTP request.
|
||||
//
|
||||
// Proxy or Load Balancer routing configuration generated from HTTPRoutes
|
||||
// MUST prioritize rules based on the following criteria, continuing on
|
||||
// ties. Precedence must be given to the the Rule with the largest number
|
||||
// of:
|
||||
//
|
||||
// * Characters in a matching non-wildcard hostname.
|
||||
// * Characters in a matching hostname.
|
||||
// * Characters in a matching path.
|
||||
// * Header matches.
|
||||
// * Query param matches.
|
||||
//
|
||||
// If ties still exist across multiple Routes, matching precedence MUST be
|
||||
// determined in order of the following criteria, continuing on ties:
|
||||
//
|
||||
// * The oldest Route based on creation timestamp.
|
||||
// * The Route appearing first in alphabetical order by
|
||||
// "{namespace}/{name}".
|
||||
//
|
||||
// If ties still exist within the Route that has been given precedence,
|
||||
// matching precedence MUST be granted to the first matching rule meeting
|
||||
// the above criteria.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=8
|
||||
// +kubebuilder:default={{path:{ type: "PathPrefix", value: "/"}}}
|
||||
Matches []HTTPRouteMatch `json:"matches,omitempty"`
|
||||
|
||||
// Filters define the filters that are applied to requests that match
|
||||
// this rule.
|
||||
//
|
||||
// The effects of ordering of multiple behaviors are currently unspecified.
|
||||
// This can change in the future based on feedback during the alpha stage.
|
||||
//
|
||||
// Conformance-levels at this level are defined based on the type of filter:
|
||||
//
|
||||
// - ALL core filters MUST be supported by all implementations.
|
||||
// - Implementers are encouraged to support extended filters.
|
||||
// - Implementation-specific custom filters have no API guarantees across
|
||||
// implementations.
|
||||
//
|
||||
// Specifying a core filter multiple times has unspecified or custom
|
||||
// conformance.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=16
|
||||
Filters []HTTPRouteFilter `json:"filters,omitempty"`
|
||||
|
||||
// BackendRefs defines the backend(s) where matching requests should be
|
||||
// sent.
|
||||
|
||||
// If unspecified or invalid (refers to a non-existent resource or a Service
|
||||
// with no endpoints), the rule performs no forwarding. If there are also no
|
||||
// filters specified that would result in a response being sent, a HTTP 503
|
||||
// status code is returned. 503 responses must be sent so that the overall
|
||||
// weight is respected; if an invalid backend is requested to have 80% of
|
||||
// requests, then 80% of requests must get a 503 instead.
|
||||
//
|
||||
// Support: Core for Kubernetes Service
|
||||
// Support: Custom for any other resource
|
||||
//
|
||||
// Support for weight: Core
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=16
|
||||
BackendRefs []HTTPBackendRef `json:"backendRefs,omitempty"`
|
||||
}
|
||||
|
||||
// PathMatchType specifies the semantics of how HTTP paths should be compared.
|
||||
// Valid PathMatchType values are:
|
||||
//
|
||||
// * "Exact"
|
||||
// * "PathPrefix"
|
||||
// * "RegularExpression"
|
||||
//
|
||||
// PathPrefix and Exact paths must be syntactically valid:
|
||||
//
|
||||
// - Must begin with the `/` character
|
||||
// - Must not contain consecutive `/` characters (e.g. `/foo///`, `//`).
|
||||
//
|
||||
// +kubebuilder:validation:Enum=Exact;PathPrefix;RegularExpression
|
||||
type PathMatchType string
|
||||
|
||||
const (
|
||||
// Matches the URL path exactly and with case sensitivity.
|
||||
PathMatchExact PathMatchType = "Exact"
|
||||
|
||||
// Matches based on a URL path prefix split by `/`. Matching is
|
||||
// case sensitive and done on a path element by element basis. A
|
||||
// path element refers to the list of labels in the path split by
|
||||
// the `/` separator. When specified, a trailing `/` is ignored.
|
||||
//
|
||||
// For example. the paths `/abc`, `/abc/`, and `/abc/def` would all match
|
||||
// the prefix `/abc`, but the path `/abcd` would not.
|
||||
//
|
||||
// "PathPrefix" is semantically equivalent to the "Prefix" path type in the
|
||||
// Kubernetes Ingress API.
|
||||
PathMatchPathPrefix PathMatchType = "PathPrefix"
|
||||
|
||||
// Matches if the URL path matches the given regular expression with
|
||||
// case sensitivity.
|
||||
//
|
||||
// Since `"RegularExpression"` has custom conformance, implementations
|
||||
// can support POSIX, PCRE, RE2 or any other regular expression dialect.
|
||||
// Please read the implementation's documentation to determine the supported
|
||||
// dialect.
|
||||
PathMatchRegularExpression PathMatchType = "RegularExpression"
|
||||
)
|
||||
|
||||
// HTTPPathMatch describes how to select a HTTP route by matching the HTTP request path.
|
||||
type HTTPPathMatch struct {
|
||||
// Type specifies how to match against the path Value.
|
||||
//
|
||||
// Support: Core (Exact, PathPrefix)
|
||||
//
|
||||
// Support: Custom (RegularExpression)
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default=PathPrefix
|
||||
Type *PathMatchType `json:"type,omitempty"`
|
||||
|
||||
// Value of the HTTP path to match against.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default="/"
|
||||
// +kubebuilder:validation:MaxLength=1024
|
||||
Value *string `json:"value,omitempty"`
|
||||
}
|
||||
|
||||
// HeaderMatchType specifies the semantics of how HTTP header values should be
|
||||
// compared. Valid HeaderMatchType values are:
|
||||
//
|
||||
// * "Exact"
|
||||
// * "RegularExpression"
|
||||
//
|
||||
// +kubebuilder:validation:Enum=Exact;RegularExpression
|
||||
type HeaderMatchType string
|
||||
|
||||
// HeaderMatchType constants.
|
||||
const (
|
||||
HeaderMatchExact HeaderMatchType = "Exact"
|
||||
HeaderMatchRegularExpression HeaderMatchType = "RegularExpression"
|
||||
)
|
||||
|
||||
// HTTPHeaderName is the name of an HTTP header.
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "Authorization"
|
||||
// * "Set-Cookie"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// - ":method" - ":" is an invalid character. This means that HTTP/2 pseudo
|
||||
// headers are not currently supported by this type.
|
||||
// - "/invalid" - "/" is an invalid character
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=256
|
||||
// +kubebuilder:validation:Pattern=`^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$`
|
||||
type HTTPHeaderName string
|
||||
|
||||
// HTTPHeaderMatch describes how to select a HTTP route by matching HTTP request
|
||||
// headers.
|
||||
type HTTPHeaderMatch struct {
|
||||
// Type specifies how to match against the value of the header.
|
||||
//
|
||||
// Support: Core (Exact)
|
||||
//
|
||||
// Support: Custom (RegularExpression)
|
||||
//
|
||||
// Since RegularExpression HeaderMatchType has custom conformance,
|
||||
// implementations can support POSIX, PCRE or any other dialects of regular
|
||||
// expressions. Please read the implementation's documentation to determine
|
||||
// the supported dialect.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default=Exact
|
||||
Type *HeaderMatchType `json:"type,omitempty"`
|
||||
|
||||
// Name is the name of the HTTP Header to be matched. Name matching MUST be
|
||||
// case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
|
||||
//
|
||||
// If multiple entries specify equivalent header names, only the first
|
||||
// entry with an equivalent name MUST be considered for a match. Subsequent
|
||||
// entries with an equivalent header name MUST be ignored. Due to the
|
||||
// case-insensitivity of header names, "foo" and "Foo" are considered
|
||||
// equivalent.
|
||||
//
|
||||
// When a header is repeated in an HTTP request, it is
|
||||
// implementation-specific behavior as to how this is represented.
|
||||
// Generally, proxies should follow the guidance from the RFC:
|
||||
// https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding
|
||||
// processing a repeated header, with special handling for "Set-Cookie".
|
||||
Name HTTPHeaderName `json:"name"`
|
||||
|
||||
// Value is the value of HTTP Header to be matched.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=4096
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// QueryParamMatchType specifies the semantics of how HTTP query parameter
|
||||
// values should be compared. Valid QueryParamMatchType values are:
|
||||
//
|
||||
// * "Exact"
|
||||
// * "RegularExpression"
|
||||
//
|
||||
// +kubebuilder:validation:Enum=Exact;RegularExpression
|
||||
type QueryParamMatchType string
|
||||
|
||||
// QueryParamMatchType constants.
|
||||
const (
|
||||
QueryParamMatchExact QueryParamMatchType = "Exact"
|
||||
QueryParamMatchRegularExpression QueryParamMatchType = "RegularExpression"
|
||||
)
|
||||
|
||||
// HTTPQueryParamMatch describes how to select a HTTP route by matching HTTP
|
||||
// query parameters.
|
||||
type HTTPQueryParamMatch struct {
|
||||
// Type specifies how to match against the value of the query parameter.
|
||||
//
|
||||
// Support: Extended (Exact)
|
||||
//
|
||||
// Support: Custom (RegularExpression)
|
||||
//
|
||||
// Since RegularExpression QueryParamMatchType has custom conformance,
|
||||
// implementations can support POSIX, PCRE or any other dialects of regular
|
||||
// expressions. Please read the implementation's documentation to determine
|
||||
// the supported dialect.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default=Exact
|
||||
Type *QueryParamMatchType `json:"type,omitempty"`
|
||||
|
||||
// Name is the name of the HTTP query param to be matched. This must be an
|
||||
// exact string match. (See
|
||||
// https://tools.ietf.org/html/rfc7230#section-2.7.3).
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=256
|
||||
Name string `json:"name"`
|
||||
|
||||
// Value is the value of HTTP query param to be matched.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=1024
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// HTTPMethod describes how to select a HTTP route by matching the HTTP
|
||||
// method as defined by
|
||||
// [RFC 7231](https://datatracker.ietf.org/doc/html/rfc7231#section-4) and
|
||||
// [RFC 5789](https://datatracker.ietf.org/doc/html/rfc5789#section-2).
|
||||
// The value is expected in upper case.
|
||||
// +kubebuilder:validation:Enum=GET;HEAD;POST;PUT;DELETE;CONNECT;OPTIONS;TRACE;PATCH
|
||||
type HTTPMethod string
|
||||
|
||||
const (
|
||||
HTTPMethodGet HTTPMethod = "GET"
|
||||
HTTPMethodHead HTTPMethod = "HEAD"
|
||||
HTTPMethodPost HTTPMethod = "POST"
|
||||
HTTPMethodPut HTTPMethod = "PUT"
|
||||
HTTPMethodDelete HTTPMethod = "DELETE"
|
||||
HTTPMethodConnect HTTPMethod = "CONNECT"
|
||||
HTTPMethodOptions HTTPMethod = "OPTIONS"
|
||||
HTTPMethodTrace HTTPMethod = "TRACE"
|
||||
HTTPMethodPatch HTTPMethod = "PATCH"
|
||||
)
|
||||
|
||||
// HTTPRouteMatch defines the predicate used to match requests to a given
|
||||
// action. Multiple match types are ANDed together, i.e. the match will
|
||||
// evaluate to true only if all conditions are satisfied.
|
||||
//
|
||||
// For example, the match below will match a HTTP request only if its path
|
||||
// starts with `/foo` AND it contains the `version: v1` header:
|
||||
//
|
||||
// ```
|
||||
// match:
|
||||
//
|
||||
// path:
|
||||
// value: "/foo"
|
||||
// headers:
|
||||
// - name: "version"
|
||||
// value "v1"
|
||||
//
|
||||
// ```
|
||||
type HTTPRouteMatch struct {
|
||||
// Path specifies a HTTP request path matcher. If this field is not
|
||||
// specified, a default prefix match on the "/" path is provided.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default={type: "PathPrefix", value: "/"}
|
||||
Path *HTTPPathMatch `json:"path,omitempty"`
|
||||
|
||||
// Headers specifies HTTP request header matchers. Multiple match values are
|
||||
// ANDed together, meaning, a request must match all the specified headers
|
||||
// to select the route.
|
||||
//
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=16
|
||||
Headers []HTTPHeaderMatch `json:"headers,omitempty"`
|
||||
|
||||
// QueryParams specifies HTTP query parameter matchers. Multiple match
|
||||
// values are ANDed together, meaning, a request must match all the
|
||||
// specified query parameters to select the route.
|
||||
//
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=16
|
||||
QueryParams []HTTPQueryParamMatch `json:"queryParams,omitempty"`
|
||||
|
||||
// Method specifies HTTP method matcher.
|
||||
// When specified, this route will be matched only if the request has the
|
||||
// specified method.
|
||||
//
|
||||
// Support: Extended
|
||||
//
|
||||
// +optional
|
||||
Method *HTTPMethod `json:"method,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPRouteFilter defines processing steps that must be completed during the
|
||||
// request or response lifecycle. HTTPRouteFilters are meant as an extension
|
||||
// point to express processing that may be done in Gateway implementations. Some
|
||||
// examples include request or response modification, implementing
|
||||
// authentication strategies, rate-limiting, and traffic shaping. API
|
||||
// guarantee/conformance is defined based on the type of the filter.
|
||||
type HTTPRouteFilter struct {
|
||||
// Type identifies the type of filter to apply. As with other API fields,
|
||||
// types are classified into three conformance levels:
|
||||
//
|
||||
// - Core: Filter types and their corresponding configuration defined by
|
||||
// "Support: Core" in this package, e.g. "RequestHeaderModifier". All
|
||||
// implementations must support core filters.
|
||||
//
|
||||
// - Extended: Filter types and their corresponding configuration defined by
|
||||
// "Support: Extended" in this package, e.g. "RequestMirror". Implementers
|
||||
// are encouraged to support extended filters.
|
||||
//
|
||||
// - Custom: Filters that are defined and supported by specific vendors.
|
||||
// In the future, filters showing convergence in behavior across multiple
|
||||
// implementations will be considered for inclusion in extended or core
|
||||
// conformance levels. Filter-specific configuration for such filters
|
||||
// is specified using the ExtensionRef field. `Type` should be set to
|
||||
// "ExtensionRef" for custom filters.
|
||||
//
|
||||
// Implementers are encouraged to define custom implementation types to
|
||||
// extend the core API with implementation-specific behavior.
|
||||
//
|
||||
// If a reference to a custom filter type cannot be resolved, the filter
|
||||
// MUST NOT be skipped. Instead, requests that would have been processed by
|
||||
// that filter MUST receive a HTTP error response.
|
||||
//
|
||||
// +unionDiscriminator
|
||||
// +kubebuilder:validation:Enum=RequestHeaderModifier;RequestMirror;RequestRedirect;ExtensionRef
|
||||
// <gateway:experimental:validation:Enum=RequestHeaderModifier;RequestMirror;RequestRedirect;URLRewrite;ExtensionRef>
|
||||
Type HTTPRouteFilterType `json:"type"`
|
||||
|
||||
// RequestHeaderModifier defines a schema for a filter that modifies request
|
||||
// headers.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +optional
|
||||
RequestHeaderModifier *HTTPRequestHeaderFilter `json:"requestHeaderModifier,omitempty"`
|
||||
|
||||
// RequestMirror defines a schema for a filter that mirrors requests.
|
||||
// Requests are sent to the specified destination, but responses from
|
||||
// that destination are ignored.
|
||||
//
|
||||
// Support: Extended
|
||||
//
|
||||
// +optional
|
||||
RequestMirror *HTTPRequestMirrorFilter `json:"requestMirror,omitempty"`
|
||||
|
||||
// RequestRedirect defines a schema for a filter that responds to the
|
||||
// request with an HTTP redirection.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +optional
|
||||
RequestRedirect *HTTPRequestRedirectFilter `json:"requestRedirect,omitempty"`
|
||||
|
||||
// URLRewrite defines a schema for a filter that responds to the
|
||||
// request with an HTTP redirection.
|
||||
//
|
||||
// Support: Extended
|
||||
//
|
||||
// <gateway:experimental>
|
||||
// +optional
|
||||
URLRewrite *HTTPURLRewriteFilter `json:"urlRewrite,omitempty"`
|
||||
|
||||
// ExtensionRef is an optional, implementation-specific extension to the
|
||||
// "filter" behavior. For example, resource "myroutefilter" in group
|
||||
// "networking.example.net"). ExtensionRef MUST NOT be used for core and
|
||||
// extended filters.
|
||||
//
|
||||
// Support: Implementation-specific
|
||||
//
|
||||
// +optional
|
||||
ExtensionRef *LocalObjectReference `json:"extensionRef,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPRouteFilterType identifies a type of HTTPRoute filter.
|
||||
type HTTPRouteFilterType string
|
||||
|
||||
const (
|
||||
// HTTPRouteFilterRequestHeaderModifier can be used to add or remove an HTTP
|
||||
// header from an HTTP request before it is sent to the upstream target.
|
||||
//
|
||||
// Support in HTTPRouteRule: Core
|
||||
//
|
||||
// Support in HTTPBackendRef: Extended
|
||||
HTTPRouteFilterRequestHeaderModifier HTTPRouteFilterType = "RequestHeaderModifier"
|
||||
|
||||
// HTTPRouteFilterRequestRedirect can be used to redirect a request to
|
||||
// another location. This filter can also be used for HTTP to HTTPS
|
||||
// redirects. This may not be used on the same Route rule or BackendRef as a
|
||||
// URLRewrite filter.
|
||||
//
|
||||
// Support in HTTPRouteRule: Core
|
||||
//
|
||||
// Support in HTTPBackendRef: Extended
|
||||
HTTPRouteFilterRequestRedirect HTTPRouteFilterType = "RequestRedirect"
|
||||
|
||||
// HTTPRouteFilterURLRewrite can be used to modify a request during
|
||||
// forwarding. At most one of these filters may be used on a Route rule.
|
||||
// This may not be used on the same Route rule or BackendRef as a
|
||||
// RequestRedirect filter.
|
||||
//
|
||||
// Support in HTTPRouteRule: Extended
|
||||
//
|
||||
// Support in HTTPBackendRef: Extended
|
||||
//
|
||||
// <gateway:experimental>
|
||||
HTTPRouteFilterURLRewrite HTTPRouteFilterType = "URLRewrite"
|
||||
|
||||
// HTTPRouteFilterRequestMirror can be used to mirror HTTP requests to a
|
||||
// different backend. The responses from this backend MUST be ignored by
|
||||
// the Gateway.
|
||||
//
|
||||
// Support in HTTPRouteRule: Extended
|
||||
//
|
||||
// Support in HTTPBackendRef: Extended
|
||||
HTTPRouteFilterRequestMirror HTTPRouteFilterType = "RequestMirror"
|
||||
|
||||
// HTTPRouteFilterExtensionRef should be used for configuring custom
|
||||
// HTTP filters.
|
||||
//
|
||||
// Support in HTTPRouteRule: Custom
|
||||
//
|
||||
// Support in HTTPBackendRef: Custom
|
||||
HTTPRouteFilterExtensionRef HTTPRouteFilterType = "ExtensionRef"
|
||||
)
|
||||
|
||||
// HTTPHeader represents an HTTP Header name and value as defined by RFC 7230.
|
||||
type HTTPHeader struct {
|
||||
// Name is the name of the HTTP Header to be matched. Name matching MUST be
|
||||
// case insensitive. (See https://tools.ietf.org/html/rfc7230#section-3.2).
|
||||
//
|
||||
// If multiple entries specify equivalent header names, the first entry with
|
||||
// an equivalent name MUST be considered for a match. Subsequent entries
|
||||
// with an equivalent header name MUST be ignored. Due to the
|
||||
// case-insensitivity of header names, "foo" and "Foo" are considered
|
||||
// equivalent.
|
||||
Name HTTPHeaderName `json:"name"`
|
||||
|
||||
// Value is the value of HTTP Header to be matched.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=4096
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// HTTPRequestHeaderFilter defines configuration for the RequestHeaderModifier
|
||||
// filter.
|
||||
type HTTPRequestHeaderFilter struct {
|
||||
// Set overwrites the request with the given header (name, value)
|
||||
// before the action.
|
||||
//
|
||||
// Input:
|
||||
// GET /foo HTTP/1.1
|
||||
// my-header: foo
|
||||
//
|
||||
// Config:
|
||||
// set:
|
||||
// - name: "my-header"
|
||||
// value: "bar"
|
||||
//
|
||||
// Output:
|
||||
// GET /foo HTTP/1.1
|
||||
// my-header: bar
|
||||
//
|
||||
// +optional
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +kubebuilder:validation:MaxItems=16
|
||||
Set []HTTPHeader `json:"set,omitempty"`
|
||||
|
||||
// Add adds the given header(s) (name, value) to the request
|
||||
// before the action. It appends to any existing values associated
|
||||
// with the header name.
|
||||
//
|
||||
// Input:
|
||||
// GET /foo HTTP/1.1
|
||||
// my-header: foo
|
||||
//
|
||||
// Config:
|
||||
// add:
|
||||
// - name: "my-header"
|
||||
// value: "bar"
|
||||
//
|
||||
// Output:
|
||||
// GET /foo HTTP/1.1
|
||||
// my-header: foo
|
||||
// my-header: bar
|
||||
//
|
||||
// +optional
|
||||
// +listType=map
|
||||
// +listMapKey=name
|
||||
// +kubebuilder:validation:MaxItems=16
|
||||
Add []HTTPHeader `json:"add,omitempty"`
|
||||
|
||||
// Remove the given header(s) from the HTTP request before the action. The
|
||||
// value of Remove is a list of HTTP header names. Note that the header
|
||||
// names are case-insensitive (see
|
||||
// https://datatracker.ietf.org/doc/html/rfc2616#section-4.2).
|
||||
//
|
||||
// Input:
|
||||
// GET /foo HTTP/1.1
|
||||
// my-header1: foo
|
||||
// my-header2: bar
|
||||
// my-header3: baz
|
||||
//
|
||||
// Config:
|
||||
// remove: ["my-header1", "my-header3"]
|
||||
//
|
||||
// Output:
|
||||
// GET /foo HTTP/1.1
|
||||
// my-header2: bar
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=16
|
||||
Remove []string `json:"remove,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPPathModifierType defines the type of path redirect.
|
||||
type HTTPPathModifierType string
|
||||
|
||||
const (
|
||||
// This type of modifier indicates that the complete path will be replaced
|
||||
// by the path redirect value.
|
||||
AbsoluteHTTPPathModifier HTTPPathModifierType = "Absolute"
|
||||
|
||||
// This type of modifier indicates that any prefix path matches will be
|
||||
// replaced by the substitution value. For example, a path with a prefix
|
||||
// match of "/foo" and a ReplacePrefixMatch substitution of "/bar" will have
|
||||
// the "/foo" prefix replaced with "/bar" in matching requests.
|
||||
PrefixMatchHTTPPathModifier HTTPPathModifierType = "ReplacePrefixMatch"
|
||||
)
|
||||
|
||||
// HTTPPathModifier defines configuration for path modifiers.
|
||||
// <gateway:experimental>
|
||||
type HTTPPathModifier struct {
|
||||
// Type defines the type of path modifier.
|
||||
//
|
||||
// <gateway:experimental>
|
||||
// +kubebuilder:validation:Enum=Absolute;ReplacePrefixMatch
|
||||
Type HTTPPathModifierType `json:"type"`
|
||||
|
||||
// Substitution defines the HTTP path value to substitute. An empty value
|
||||
// ("") indicates that the portion of the path to be changed should be
|
||||
// removed from the resulting path. For example, a request to "/foo/bar"
|
||||
// with a prefix match of "/foo" would be modified to "/bar".
|
||||
//
|
||||
// <gateway:experimental>
|
||||
// +kubebuilder:validation:MaxLength=1024
|
||||
Substitution string `json:"substitution"`
|
||||
}
|
||||
|
||||
// HTTPRequestRedirect defines a filter that redirects a request. This filter
|
||||
// MUST not be used on the same Route rule as a HTTPURLRewrite filter.
|
||||
type HTTPRequestRedirectFilter struct {
|
||||
// Scheme is the scheme to be used in the value of the `Location`
|
||||
// header in the response.
|
||||
// When empty, the scheme of the request is used.
|
||||
//
|
||||
// Support: Extended
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=http;https
|
||||
Scheme *string `json:"scheme,omitempty"`
|
||||
|
||||
// Hostname is the hostname to be used in the value of the `Location`
|
||||
// header in the response.
|
||||
// When empty, the hostname of the request is used.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +optional
|
||||
Hostname *PreciseHostname `json:"hostname,omitempty"`
|
||||
|
||||
// Path defines parameters used to modify the path of the incoming request.
|
||||
// The modified path is then used to construct the `Location` header. When
|
||||
// empty, the request path is used as-is.
|
||||
//
|
||||
// Support: Extended
|
||||
//
|
||||
// <gateway:experimental>
|
||||
// +optional
|
||||
Path *HTTPPathModifier `json:"path,omitempty"`
|
||||
|
||||
// Port is the port to be used in the value of the `Location`
|
||||
// header in the response.
|
||||
// When empty, port (if specified) of the request is used.
|
||||
//
|
||||
// Support: Extended
|
||||
//
|
||||
// +optional
|
||||
Port *PortNumber `json:"port,omitempty"`
|
||||
|
||||
// StatusCode is the HTTP status code to be used in response.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default=302
|
||||
// +kubebuilder:validation:Enum=301;302
|
||||
StatusCode *int `json:"statusCode,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPURLRewriteFilter defines a filter that modifies a request during
|
||||
// forwarding. At most one of these filters may be used on a Route rule. This
|
||||
// may not be used on the same Route rule as a HTTPRequestRedirect filter.
|
||||
//
|
||||
// <gateway:experimental>
|
||||
// Support: Extended
|
||||
type HTTPURLRewriteFilter struct {
|
||||
// Hostname is the value to be used to replace the Host header value during
|
||||
// forwarding.
|
||||
//
|
||||
// Support: Extended
|
||||
//
|
||||
// <gateway:experimental>
|
||||
// +optional
|
||||
Hostname *Hostname `json:"hostname,omitempty"`
|
||||
|
||||
// Path defines a path rewrite.
|
||||
//
|
||||
// Support: Extended
|
||||
//
|
||||
// <gateway:experimental>
|
||||
// +optional
|
||||
Path *HTTPPathModifier `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPRequestMirrorFilter defines configuration for the RequestMirror filter.
|
||||
type HTTPRequestMirrorFilter struct {
|
||||
// BackendRef references a resource where mirrored requests are sent.
|
||||
//
|
||||
// If the referent cannot be found, this BackendRef is invalid and must be
|
||||
// dropped from the Gateway. The controller must ensure the "ResolvedRefs"
|
||||
// condition on the Route status is set to `status: False` and not configure
|
||||
// this backend in the underlying implementation.
|
||||
//
|
||||
// If there is a cross-namespace reference to an *existing* object
|
||||
// that is not allowed by a ReferencePolicy, the controller must ensure the
|
||||
// "ResolvedRefs" condition on the Route is set to `status: False`,
|
||||
// with the "RefNotPermitted" reason and not configure this backend in the
|
||||
// underlying implementation.
|
||||
//
|
||||
// In either error case, the Message of the `ResolvedRefs` Condition
|
||||
// should be used to provide more detail about the problem.
|
||||
//
|
||||
// Support: Extended for Kubernetes Service
|
||||
// Support: Custom for any other resource
|
||||
BackendRef BackendObjectReference `json:"backendRef"`
|
||||
}
|
||||
|
||||
// HTTPBackendRef defines how a HTTPRoute should forward an HTTP request.
|
||||
type HTTPBackendRef struct {
|
||||
// BackendRef is a reference to a backend to forward matched requests to.
|
||||
//
|
||||
// If the referent cannot be found, this HTTPBackendRef is invalid and must
|
||||
// be dropped from the Gateway. The controller must ensure the
|
||||
// "ResolvedRefs" condition on the Route is set to `status: False` and not
|
||||
// configure this backend in the underlying implementation.
|
||||
//
|
||||
// If there is a cross-namespace reference to an *existing* object
|
||||
// that is not covered by a ReferencePolicy, the controller must ensure the
|
||||
// "ResolvedRefs" condition on the Route is set to `status: False`,
|
||||
// with the "RefNotPermitted" reason and not configure this backend in the
|
||||
// underlying implementation.
|
||||
//
|
||||
// In either error case, the Message of the `ResolvedRefs` Condition
|
||||
// should be used to provide more detail about the problem.
|
||||
//
|
||||
// Support: Custom
|
||||
//
|
||||
// +optional
|
||||
BackendRef `json:",inline"`
|
||||
|
||||
// Filters defined at this level should be executed if and only if the
|
||||
// request is being forwarded to the backend defined here.
|
||||
//
|
||||
// Support: Custom (For broader support of filters, use the Filters field
|
||||
// in HTTPRouteRule.)
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=16
|
||||
Filters []HTTPRouteFilter `json:"filters,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPRouteStatus defines the observed state of HTTPRoute.
|
||||
type HTTPRouteStatus struct {
|
||||
RouteStatus `json:",inline"`
|
||||
}
|
||||
|
||||
// Hostname is the fully qualified domain name of a network host. This matches
|
||||
// the RFC 1123 definition of a hostname with 2 notable exceptions:
|
||||
//
|
||||
// 1. IPs are not allowed.
|
||||
// 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard
|
||||
// label must appear by itself as the first label.
|
||||
//
|
||||
// Hostname can be "precise" which is a domain name without the terminating
|
||||
// dot of a network host (e.g. "foo.example.com") or "wildcard", which is a
|
||||
// domain name prefixed with a single wildcard label (e.g. `*.example.com`).
|
||||
//
|
||||
// Note that as per RFC1035 and RFC1123, a *label* must consist of lower case
|
||||
// alphanumeric characters or '-', and must start and end with an alphanumeric
|
||||
// character. No other punctuation is allowed.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^(\*\.)?[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
||||
type Hostname string
|
||||
|
||||
// PortNumber defines a network port.
|
||||
//
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +kubebuilder:validation:Maximum=65535
|
||||
type PortNumber int32
|
||||
@@ -1,427 +0,0 @@
|
||||
/*
|
||||
Copyright 2020 The Kubernetes 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 v1alpha2
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// ParentReference identifies an API object (usually a Gateway) that can be considered
|
||||
// a parent of this resource (usually a route). The only kind of parent resource
|
||||
// with "Core" support is Gateway. This API may be extended in the future to
|
||||
// support additional kinds of parent resources, such as HTTPRoute.
|
||||
//
|
||||
// The API object must be valid in the cluster; the Group and Kind must
|
||||
// be registered in the cluster for this reference to be valid.
|
||||
//
|
||||
// References to objects with invalid Group and Kind are not valid, and must
|
||||
// be rejected by the implementation, with appropriate Conditions set
|
||||
// on the containing object.
|
||||
type ParentReference struct {
|
||||
// Group is the group of the referent.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +kubebuilder:default=gateway.networking.k8s.io
|
||||
// +optional
|
||||
Group *Group `json:"group,omitempty"`
|
||||
|
||||
// Kind is kind of the referent.
|
||||
//
|
||||
// Support: Core (Gateway)
|
||||
// Support: Custom (Other Resources)
|
||||
//
|
||||
// +kubebuilder:default=Gateway
|
||||
// +optional
|
||||
Kind *Kind `json:"kind,omitempty"`
|
||||
|
||||
// Namespace is the namespace of the referent. When unspecified (or empty
|
||||
// string), this refers to the local namespace of the Route.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +optional
|
||||
Namespace *Namespace `json:"namespace,omitempty"`
|
||||
|
||||
// Name is the name of the referent.
|
||||
//
|
||||
// Support: Core
|
||||
Name ObjectName `json:"name"`
|
||||
|
||||
// SectionName is the name of a section within the target resource. In the
|
||||
// following resources, SectionName is interpreted as the following:
|
||||
//
|
||||
// * Gateway: Listener Name
|
||||
//
|
||||
// Implementations MAY choose to support attaching Routes to other resources.
|
||||
// If that is the case, they MUST clearly document how SectionName is
|
||||
// interpreted.
|
||||
//
|
||||
// When unspecified (empty string), this will reference the entire resource.
|
||||
// For the purpose of status, an attachment is considered successful if at
|
||||
// least one section in the parent resource accepts it. For example, Gateway
|
||||
// listeners can restrict which Routes can attach to them by Route kind,
|
||||
// namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from
|
||||
// the referencing Route, the Route MUST be considered successfully
|
||||
// attached. If no Gateway listeners accept attachment from this Route, the
|
||||
// Route MUST be considered detached from the Gateway.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +optional
|
||||
SectionName *SectionName `json:"sectionName,omitempty"`
|
||||
}
|
||||
|
||||
// CommonRouteSpec defines the common attributes that all Routes MUST include
|
||||
// within their spec.
|
||||
type CommonRouteSpec struct {
|
||||
// ParentRefs references the resources (usually Gateways) that a Route wants
|
||||
// to be attached to. Note that the referenced parent resource needs to
|
||||
// allow this for the attachment to be complete. For Gateways, that means
|
||||
// the Gateway needs to allow attachment from Routes of this kind and
|
||||
// namespace.
|
||||
//
|
||||
// The only kind of parent resource with "Core" support is Gateway. This API
|
||||
// may be extended in the future to support additional kinds of parent
|
||||
// resources such as one of the route kinds.
|
||||
//
|
||||
// It is invalid to reference an identical parent more than once. It is
|
||||
// valid to reference multiple distinct sections within the same parent
|
||||
// resource, such as 2 Listeners within a Gateway.
|
||||
//
|
||||
// It is possible to separately reference multiple distinct objects that may
|
||||
// be collapsed by an implementation. For example, some implementations may
|
||||
// choose to merge compatible Gateway Listeners together. If that is the
|
||||
// case, the list of routes attached to those resources should also be
|
||||
// merged.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:MaxItems=32
|
||||
ParentRefs []ParentReference `json:"parentRefs,omitempty"`
|
||||
}
|
||||
|
||||
// BackendRef defines how a Route should forward a request to a Kubernetes
|
||||
// resource.
|
||||
//
|
||||
// Note that when a namespace is specified, a ReferencePolicy object
|
||||
// is required in the referent namespace to allow that namespace's
|
||||
// owner to accept the reference. See the ReferencePolicy documentation
|
||||
// for details.
|
||||
type BackendRef struct {
|
||||
// BackendObjectReference references a Kubernetes object.
|
||||
BackendObjectReference `json:",inline"`
|
||||
|
||||
// Weight specifies the proportion of requests forwarded to the referenced
|
||||
// backend. This is computed as weight/(sum of all weights in this
|
||||
// BackendRefs list). For non-zero values, there may be some epsilon from
|
||||
// the exact proportion defined here depending on the precision an
|
||||
// implementation supports. Weight is not a percentage and the sum of
|
||||
// weights does not need to equal 100.
|
||||
//
|
||||
// If only one backend is specified and it has a weight greater than 0, 100%
|
||||
// of the traffic is forwarded to that backend. If weight is set to 0, no
|
||||
// traffic should be forwarded for this entry. If unspecified, weight
|
||||
// defaults to 1.
|
||||
//
|
||||
// Support for this field varies based on the context where used.
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:default=1
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
// +kubebuilder:validation:Maximum=1000000
|
||||
Weight *int32 `json:"weight,omitempty"`
|
||||
}
|
||||
|
||||
// RouteConditionType is a type of condition for a route.
|
||||
type RouteConditionType string
|
||||
|
||||
const (
|
||||
// This condition indicates whether the route has been accepted or rejected
|
||||
// by a Gateway, and why.
|
||||
ConditionRouteAccepted RouteConditionType = "Accepted"
|
||||
|
||||
// This condition indicates whether the controller was able to resolve all
|
||||
// the object references for the Route.
|
||||
ConditionRouteResolvedRefs RouteConditionType = "ResolvedRefs"
|
||||
)
|
||||
|
||||
// RouteParentStatus describes the status of a route with respect to an
|
||||
// associated Parent.
|
||||
type RouteParentStatus struct {
|
||||
// ParentRef corresponds with a ParentRef in the spec that this
|
||||
// RouteParentStatus struct describes the status of.
|
||||
ParentRef ParentReference `json:"parentRef"`
|
||||
|
||||
// ControllerName is a domain/path string that indicates the name of the
|
||||
// controller that wrote this status. This corresponds with the
|
||||
// controllerName field on GatewayClass.
|
||||
//
|
||||
// Example: "example.net/gateway-controller".
|
||||
//
|
||||
// The format of this field is DOMAIN "/" PATH, where DOMAIN and PATH are
|
||||
// valid Kubernetes names
|
||||
// (https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names).
|
||||
ControllerName GatewayController `json:"controllerName"`
|
||||
|
||||
// Conditions describes the status of the route with respect to the Gateway.
|
||||
// Note that the route's availability is also subject to the Gateway's own
|
||||
// status conditions and listener status.
|
||||
//
|
||||
// If the Route's ParentRef specifies an existing Gateway that supports
|
||||
// Routes of this kind AND that Gateway's controller has sufficient access,
|
||||
// then that Gateway's controller MUST set the "Accepted" condition on the
|
||||
// Route, to indicate whether the route has been accepted or rejected by the
|
||||
// Gateway, and why.
|
||||
//
|
||||
// A Route MUST be considered "Accepted" if at least one of the Route's
|
||||
// rules is implemented by the Gateway.
|
||||
//
|
||||
// There are a number of cases where the "Accepted" condition may not be set
|
||||
// due to lack of controller visibility, that includes when:
|
||||
//
|
||||
// * The Route refers to a non-existent parent.
|
||||
// * The Route is of a type that the controller does not support.
|
||||
// * The Route is in a namespace the the controller does not have access to.
|
||||
//
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=8
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// RouteStatus defines the common attributes that all Routes MUST include within
|
||||
// their status.
|
||||
type RouteStatus struct {
|
||||
// Parents is a list of parent resources (usually Gateways) that are
|
||||
// associated with the route, and the status of the route with respect to
|
||||
// each parent. When this route attaches to a parent, the controller that
|
||||
// manages the parent must add an entry to this list when the controller
|
||||
// first sees the route and should update the entry as appropriate when the
|
||||
// route or gateway is modified.
|
||||
//
|
||||
// Note that parent references that cannot be resolved by an implementation
|
||||
// of this API will not be added to this list. Implementations of this API
|
||||
// can only populate Route status for the Gateways/parent resources they are
|
||||
// responsible for.
|
||||
//
|
||||
// A maximum of 32 Gateways will be represented in this list. An empty list
|
||||
// means the route has not been attached to any Gateway.
|
||||
//
|
||||
// +kubebuilder:validation:MaxItems=32
|
||||
Parents []RouteParentStatus `json:"parents"`
|
||||
}
|
||||
|
||||
// PreciseHostname is the fully qualified domain name of a network host. This matches
|
||||
// the RFC 1123 definition of a hostname with 1 notable exception that
|
||||
// numeric IP addresses are not allowed.
|
||||
//
|
||||
// PreciseHostname can be "precise" which is a domain name without the terminating
|
||||
// dot of a network host (e.g. "foo.example.com").
|
||||
//
|
||||
// Note that as per RFC1035 and RFC1123, a *label* must consist of lower case
|
||||
// alphanumeric characters or '-', and must start and end with an alphanumeric
|
||||
// character. No other punctuation is allowed.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
||||
type PreciseHostname string
|
||||
|
||||
// Group refers to a Kubernetes Group. It must either be an empty string or a
|
||||
// RFC 1123 subdomain.
|
||||
//
|
||||
// This validation is based off of the corresponding Kubernetes validation:
|
||||
// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L208
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "" - empty string implies core Kubernetes API group
|
||||
// * "networking.k8s.io"
|
||||
// * "foo.example.com"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * "example.com/bar" - "/" is an invalid character
|
||||
//
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
||||
type Group string
|
||||
|
||||
// Kind refers to a Kubernetes Kind.
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "Service"
|
||||
// * "HTTPRoute"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * "invalid/kind" - "/" is an invalid character
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=63
|
||||
// +kubebuilder:validation:Pattern=`^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$`
|
||||
type Kind string
|
||||
|
||||
// ObjectName refers to the name of a Kubernetes object.
|
||||
// Object names can have a variety of forms, including RFC1123 subdomains,
|
||||
// RFC 1123 labels, or RFC 1035 labels.
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
type ObjectName string
|
||||
|
||||
// Namespace refers to a Kubernetes namespace. It must be a RFC 1123 label.
|
||||
//
|
||||
// This validation is based off of the corresponding Kubernetes validation:
|
||||
// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L187
|
||||
//
|
||||
// This is used for Namespace name validation here:
|
||||
// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/api/validation/generic.go#L63
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "example"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * "example.com" - "." is an invalid character
|
||||
//
|
||||
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?$`
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=63
|
||||
type Namespace string
|
||||
|
||||
// SectionName is the name of a section in a Kubernetes resource.
|
||||
//
|
||||
// This validation is based off of the corresponding Kubernetes validation:
|
||||
// https://github.com/kubernetes/apimachinery/blob/02cfb53916346d085a6c6c7c66f882e3c6b0eca6/pkg/util/validation/validation.go#L208
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "example.com"
|
||||
// * "foo.example.com"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * "example.com/bar" - "/" is an invalid character
|
||||
//
|
||||
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$`
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
type SectionName string
|
||||
|
||||
// GatewayController is the name of a Gateway API controller. It must be a
|
||||
// domain prefixed path.
|
||||
//
|
||||
// Valid values include:
|
||||
//
|
||||
// * "example.com/bar"
|
||||
//
|
||||
// Invalid values include:
|
||||
//
|
||||
// * "example.com" - must include path
|
||||
// * "foo.example.com" - must include path
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
// +kubebuilder:validation:Pattern=`^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*\/[A-Za-z0-9\/\-._~%!$&'()*+,;=:]+$`
|
||||
type GatewayController string
|
||||
|
||||
// AddressRouteMatches defines AddressMatch rules for inbound traffic according to
|
||||
// source and/or destination address of a packet or connection.
|
||||
type AddressRouteMatches struct {
|
||||
// SourceAddresses indicates the originating (source) network
|
||||
// addresses which are valid for routing traffic.
|
||||
//
|
||||
// Support: Extended
|
||||
SourceAddresses []AddressMatch `json:"sourceAddresses"`
|
||||
|
||||
// DestinationAddresses indicates the destination network addresses
|
||||
// which are valid for routing traffic.
|
||||
//
|
||||
// Support: Extended
|
||||
DestinationAddresses []AddressMatch `json:"destinationAddresses"`
|
||||
}
|
||||
|
||||
// AddressMatch defines matching rules for network addresses by type.
|
||||
type AddressMatch struct {
|
||||
// Type of the address, either IPAddress or NamedAddress.
|
||||
//
|
||||
// If NamedAddress is used this is a custom and specific value for each
|
||||
// implementation to handle (and add validation for) according to their
|
||||
// own needs.
|
||||
//
|
||||
// For IPAddress the implementor may expect either IPv4 or IPv6.
|
||||
//
|
||||
// Support: Core (IPAddress)
|
||||
// Support: Custom (NamedAddress)
|
||||
//
|
||||
// +optional
|
||||
// +kubebuilder:validation:Enum=IPAddress;NamedAddress
|
||||
// +kubebuilder:default=IPAddress
|
||||
Type *AddressType `json:"type,omitempty"`
|
||||
|
||||
// Value of the address. The validity of the values will depend
|
||||
// on the type and support by the controller.
|
||||
//
|
||||
// If implementations support proxy-protocol (see:
|
||||
// https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) they
|
||||
// must respect the connection metadata from proxy-protocol
|
||||
// in the match logic implemented for these address values.
|
||||
//
|
||||
// Examples: `1.2.3.4`, `128::1`, `my-named-address`.
|
||||
//
|
||||
// Support: Core
|
||||
//
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=253
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// AddressType defines how a network address is represented as a text string.
|
||||
type AddressType string
|
||||
|
||||
const (
|
||||
// A textual representation of a numeric IP address. IPv4
|
||||
// addresses must be in dotted-decimal form. IPv6 addresses
|
||||
// must be in a standard IPv6 text representation
|
||||
// (see [RFC 5952](https://tools.ietf.org/html/rfc5952)).
|
||||
//
|
||||
// This type is intended for specific addresses. Address ranges are not
|
||||
// supported (e.g. you can not use a CIDR range like 127.0.0.0/24 as an
|
||||
// IPAddress).
|
||||
//
|
||||
// Support: Extended
|
||||
IPAddressType AddressType = "IPAddress"
|
||||
|
||||
// A Hostname represents a DNS based ingress point. This is similar to the
|
||||
// corresponding hostname field in Kubernetes load balancer status. For
|
||||
// example, this concept may be used for cloud load balancers where a DNS
|
||||
// name is used to expose a load balancer.
|
||||
//
|
||||
// Support: Extended
|
||||
HostnameAddressType AddressType = "Hostname"
|
||||
|
||||
// A NamedAddress provides a way to reference a specific IP address by name.
|
||||
// For example, this may be a name or other unique identifier that refers
|
||||
// to a resource on a cloud provider such as a static IP.
|
||||
//
|
||||
// Support: Implementation-Specific
|
||||
NamedAddressType AddressType = "NamedAddress"
|
||||
)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user