mirror of
https://github.com/vmware-tanzu/velero.git
synced 2026-08-21 14:46:07 +00:00
Merge origin/main into dependabot branch
Agent-Logs-Url: https://github.com/velero-io/velero/sessions/7f0d29fc-2b25-469f-abfa-8cef55e1a3a1 Co-authored-by: blackpiglet <59276555+blackpiglet@users.noreply.github.com>
This commit is contained in:
co-authored by
blackpiglet
parent
244f8bfbcb
commit
c45ec750e1
@@ -7,6 +7,10 @@ on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened, ready_for_review]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
# Automatically assigns reviewers and owner
|
||||
add-reviews:
|
||||
@@ -16,4 +20,3 @@ jobs:
|
||||
uses: kentaro-m/auto-assign-action@v2.0.0
|
||||
with:
|
||||
configuration-path: ".github/auto-assignees.yml"
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
@@ -8,6 +8,10 @@ on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened, synchronize, ready_for_review]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
# Automatically labels PRs based on file globs in the change.
|
||||
triage:
|
||||
@@ -15,5 +19,4 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/labeler@v5
|
||||
with:
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
configuration-path: .github/labeler.yml
|
||||
|
||||
@@ -5,6 +5,10 @@ on:
|
||||
pull_request_target:
|
||||
types: [opened, ready_for_review, reopened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
auto-request-review:
|
||||
name: Auto Request Review
|
||||
@@ -13,5 +17,5 @@ jobs:
|
||||
- name: Request a PR review based on files types/paths, and/or groups the author belongs to
|
||||
uses: necojackarc/auto-request-review@v0.13.0
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
config: .github/auto-assignees.yml
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -71,7 +71,7 @@ jobs:
|
||||
run: |
|
||||
echo "Building MinIO image from Bitnami Dockerfile..."
|
||||
git clone --depth 1 https://github.com/bitnami/containers.git /tmp/bitnami-containers
|
||||
cd /tmp/bitnami-containers/bitnami/minio/2025/debian-12
|
||||
cd /tmp/bitnami-containers/bitnami/minio/2026/debian-12
|
||||
docker build -t bitnami/minio:local .
|
||||
docker save bitnami/minio:local > ${{ github.workspace }}/minio-image.tar
|
||||
# Create json of k8s versions to test
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
version=$(grep '^go ' go.mod | awk '{print $2}' | cut -d. -f1-2)
|
||||
else
|
||||
goDirectiveVersion=$(grep '^go ' go.mod | awk '{print $2}')
|
||||
toolChainVersion=$(grep '^toolchain ' go.mod | awk '{print $2}')
|
||||
toolChainVersion=$(grep '^toolchain ' go.mod | awk '{print $2}' | sed 's/^go//')
|
||||
version=$(printf "%s\n%s\n" "$goDirectiveVersion" "$toolChainVersion" | sort -V | tail -n1)
|
||||
fi
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ on:
|
||||
- 'release-**'
|
||||
paths:
|
||||
- 'Dockerfile'
|
||||
- 'Dockerfile-Windows'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -32,6 +33,6 @@ jobs:
|
||||
# by push, so BRANCH and TAG are empty by default. docker-push.sh will
|
||||
# only build Velero image without pushing.
|
||||
- name: Make Velero container without pushing to registry.
|
||||
if: github.repository == 'vmware-tanzu/velero'
|
||||
if: github.repository == 'velero-io/velero'
|
||||
run: |
|
||||
./hack/docker-push.sh
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
else:
|
||||
print(f' # {original} — cannot auto-suggest rename (non-UTF-8)')
|
||||
print()
|
||||
print('See https://github.com/vmware-tanzu/velero/pull/9552 for context.')
|
||||
print('See https://github.com/velero-io/velero/pull/9552 for context.')
|
||||
sys.exit(1)
|
||||
else:
|
||||
print('All file paths are valid for Go module zip.')
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
name: Checkout
|
||||
|
||||
- name: Verify .goreleaser.yml and try a dryrun release.
|
||||
if: github.repository == 'vmware-tanzu/velero'
|
||||
if: github.repository == 'velero-io/velero'
|
||||
run: |
|
||||
CHANGELOG=$(ls changelogs | sort -V -r | head -n 1)
|
||||
GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} \
|
||||
|
||||
@@ -28,5 +28,5 @@ jobs:
|
||||
- name: Linter check
|
||||
uses: golangci/golangci-lint-action@v9
|
||||
with:
|
||||
version: v2.5.0
|
||||
version: v2.12.0
|
||||
args: --verbose
|
||||
|
||||
@@ -5,6 +5,10 @@ on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
execute:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
|
||||
# Only try to publish the container image from the root repo; forks don't have permission to do so and will always get failures.
|
||||
- name: Publish container image
|
||||
if: github.repository == 'vmware-tanzu/velero'
|
||||
if: github.repository == 'velero-io/velero'
|
||||
run: |
|
||||
docker login -u ${{ secrets.DOCKER_USER }} -p ${{ secrets.DOCKER_PASSWORD }}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
verbose: true
|
||||
# Only try to publish the container image from the root repo; forks don't have permission to do so and will always get failures.
|
||||
- name: Publish container image
|
||||
if: github.repository == 'vmware-tanzu/velero'
|
||||
if: github.repository == 'velero-io/velero'
|
||||
run: |
|
||||
sudo swapoff -a
|
||||
sudo rm -f /mnt/swapfile
|
||||
|
||||
+4
-1
@@ -317,7 +317,7 @@ linters:
|
||||
- errchkjson
|
||||
- exptostd
|
||||
- ginkgolinter
|
||||
- goconst
|
||||
#- goconst # Disable goconst for now, as it reports a lot of false positives. We can enable it later after refactoring the codebase to reduce the number of string literals.
|
||||
- goheader
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
@@ -383,6 +383,9 @@ linters:
|
||||
linters:
|
||||
- dupword
|
||||
text: "bucket"
|
||||
- text: "non-constant format string"
|
||||
linters:
|
||||
- govet
|
||||
|
||||
generated: lax
|
||||
presets:
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ checksum:
|
||||
name_template: 'CHECKSUM'
|
||||
release:
|
||||
github:
|
||||
owner: vmware-tanzu
|
||||
owner: velero-io
|
||||
name: velero
|
||||
draft: true
|
||||
prerelease: auto
|
||||
|
||||
+22
-1
@@ -1,3 +1,23 @@
|
||||
# Velero Code of Conduct
|
||||
|
||||
Velero is a [Cloud Native Computing Foundation](https://www.cncf.io/) sandbox
|
||||
project. As a CNCF project, the Velero community follows the
|
||||
[**CNCF Code of Conduct**](https://github.com/cncf/foundation/blob/main/code-of-conduct.md).
|
||||
|
||||
The text below is the project's adopted Code of Conduct, based on the
|
||||
[Contributor Covenant](https://www.contributor-covenant.org/), and is
|
||||
substantively aligned with the CNCF Code of Conduct. Where any conflict exists,
|
||||
the CNCF Code of Conduct prevails.
|
||||
|
||||
Instances of unacceptable behavior may be reported to the CNCF Code of
|
||||
Conduct Committee at [conduct@cncf.io](mailto:conduct@cncf.io). For more
|
||||
detailed instructions on how to submit a report, including how to submit a
|
||||
report anonymously, please see the CNCF
|
||||
[Incident Resolution Procedures](https://github.com/cncf/foundation/blob/main/code-of-conduct/coc-incident-resolution-procedures.md).
|
||||
You can expect a response within three business days.
|
||||
|
||||
---
|
||||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
@@ -59,7 +79,8 @@ representative at an online or offline event.
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement at oss-coc@vmware.com.
|
||||
reported by contacting the CNCF Code of Conduct Committee at
|
||||
[conduct@cncf.io](mailto:conduct@cncf.io).
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
# Velero binary build section
|
||||
FROM --platform=$BUILDPLATFORM golang:1.25-trixie AS velero-builder
|
||||
FROM --platform=$BUILDPLATFORM golang:1.26-trixie AS velero-builder
|
||||
|
||||
ARG GOPROXY
|
||||
ARG BIN
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
ARG OS_VERSION=1809
|
||||
|
||||
# Velero binary build section
|
||||
FROM --platform=$BUILDPLATFORM golang:1.25-trixie AS velero-builder
|
||||
FROM --platform=$BUILDPLATFORM golang:1.26-trixie AS velero-builder
|
||||
|
||||
ARG GOPROXY
|
||||
ARG BIN
|
||||
|
||||
@@ -211,6 +211,7 @@ shell: build-dirs build-env
|
||||
-v "$$(pwd)/.go/std/$(GOOS)/$(GOARCH):/usr/local/go/pkg/$(GOOS)_$(GOARCH)_static:delegated" \
|
||||
-v "$$(pwd)/.go/go-build:/.cache/go-build:delegated" \
|
||||
-v "$$(pwd)/.go/golangci-lint:/.cache/golangci-lint:delegated" \
|
||||
-v "$$(pwd)/.go/goimports:/.cache/goimports:delegated" \
|
||||
-w /github.com/vmware-tanzu/velero \
|
||||
$(BUILDER_IMAGE) \
|
||||
/bin/sh $(CMD)
|
||||
@@ -342,7 +343,7 @@ update-crd:
|
||||
|
||||
build-dirs:
|
||||
@mkdir -p _output/bin/$(GOOS)/$(GOARCH)
|
||||
@mkdir -p .go/src/$(PKG) .go/pkg .go/bin .go/std/$(GOOS)/$(GOARCH) .go/go-build .go/golangci-lint
|
||||
@mkdir -p .go/src/$(PKG) .go/pkg .go/bin .go/std/$(GOOS)/$(GOARCH) .go/go-build .go/golangci-lint .go/goimports
|
||||
|
||||
build-env:
|
||||
@# if we have overridden the value for the build-image Dockerfile,
|
||||
|
||||
@@ -52,7 +52,7 @@ git_sha = str(local("git rev-parse HEAD", quiet = True, echo_off = True)).strip(
|
||||
|
||||
tilt_helper_dockerfile_header = """
|
||||
# Tilt image
|
||||
FROM golang:1.25 as tilt-helper
|
||||
FROM golang:1.26 as tilt-helper
|
||||
|
||||
# Support live reloading with Tilt
|
||||
RUN wget --output-document /restart.sh --quiet https://raw.githubusercontent.com/windmilleng/rerun-process-wrapper/master/restart.sh && \
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Wildcard namespaces: Log warning on empty resolution
|
||||
@@ -0,0 +1 @@
|
||||
update go-hclog to current version
|
||||
@@ -0,0 +1 @@
|
||||
Fix issue #9658, Honor --stderrthreshold when --logtostderr is enabled
|
||||
@@ -0,0 +1 @@
|
||||
Fix wildcard expansion when includes is empty and excludes has wildcards
|
||||
@@ -0,0 +1 @@
|
||||
Fix issue #9709, add interfaces for CBT service and CBT bitmap
|
||||
@@ -0,0 +1 @@
|
||||
Remove Restic code path from PodVolumeRestore.
|
||||
@@ -0,0 +1 @@
|
||||
fix: lint permission issue
|
||||
@@ -35,7 +35,7 @@ func main() {
|
||||
for {
|
||||
<-ticker.C
|
||||
if done() {
|
||||
fmt.Println("All restic restores are done")
|
||||
fmt.Println("All PodVolumeRestores are done")
|
||||
err := removeFolder()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@@ -65,6 +65,7 @@ func done() bool {
|
||||
|
||||
doneFile := filepath.Join("/restores", child.Name(), ".velero", os.Args[1])
|
||||
|
||||
// #nosec G304,G703 -- doneFile is generated from internal logic and not user-controllable.
|
||||
if _, err := os.Stat(doneFile); os.IsNotExist(err) {
|
||||
fmt.Printf("The filesystem restore done file %s is not found yet. Retry later.\n", doneFile)
|
||||
return false
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module github.com/vmware-tanzu/velero
|
||||
|
||||
go 1.25.0
|
||||
go 1.26.0
|
||||
|
||||
require (
|
||||
cloud.google.com/go/storage v1.57.2
|
||||
@@ -22,13 +22,13 @@ require (
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/hashicorp/go-hclog v0.14.1
|
||||
github.com/hashicorp/go-plugin v1.6.0
|
||||
github.com/hashicorp/go-hclog v1.6.3
|
||||
github.com/hashicorp/go-plugin v1.7.0
|
||||
github.com/joho/godotenv v1.3.0
|
||||
github.com/kopia/kopia v0.16.0
|
||||
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0
|
||||
github.com/onsi/ginkgo/v2 v2.22.0
|
||||
github.com/onsi/gomega v1.36.1
|
||||
github.com/onsi/ginkgo/v2 v2.28.3
|
||||
github.com/onsi/gomega v1.40.0
|
||||
github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/prometheus/client_golang v1.23.2
|
||||
@@ -36,47 +36,48 @@ require (
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/spf13/afero v1.10.0
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/spf13/pflag v1.0.10
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/vmware-tanzu/crash-diagnostics v0.3.7
|
||||
go.uber.org/zap v1.27.1
|
||||
golang.org/x/mod v0.30.0
|
||||
golang.org/x/oauth2 v0.34.0
|
||||
golang.org/x/sys v0.40.0
|
||||
golang.org/x/text v0.32.0
|
||||
google.golang.org/api v0.256.0
|
||||
google.golang.org/grpc v1.79.3
|
||||
google.golang.org/protobuf v1.36.10
|
||||
golang.org/x/mod v0.35.0
|
||||
golang.org/x/oauth2 v0.36.0
|
||||
golang.org/x/sys v0.43.0
|
||||
golang.org/x/text v0.36.0
|
||||
google.golang.org/api v0.277.0
|
||||
google.golang.org/grpc v1.80.0
|
||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.33.3
|
||||
k8s.io/apiextensions-apiserver v0.33.3
|
||||
k8s.io/apimachinery v0.33.3
|
||||
k8s.io/cli-runtime v0.33.3
|
||||
k8s.io/client-go v0.33.3
|
||||
k8s.io/klog/v2 v2.130.1
|
||||
k8s.io/kube-aggregator v0.33.3
|
||||
k8s.io/metrics v0.33.3
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738
|
||||
sigs.k8s.io/controller-runtime v0.21.0
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3
|
||||
sigs.k8s.io/yaml v1.4.0
|
||||
k8s.io/api v0.36.0
|
||||
k8s.io/apiextensions-apiserver v0.36.0
|
||||
k8s.io/apimachinery v0.36.0
|
||||
k8s.io/cli-runtime v0.36.0
|
||||
k8s.io/client-go v0.36.0
|
||||
k8s.io/klog/v2 v2.140.0
|
||||
k8s.io/kube-aggregator v0.36.0
|
||||
k8s.io/metrics v0.36.0
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2
|
||||
sigs.k8s.io/controller-runtime v0.24.0
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730
|
||||
sigs.k8s.io/yaml v1.6.0
|
||||
)
|
||||
|
||||
require (
|
||||
cel.dev/expr v0.25.1 // indirect
|
||||
cloud.google.com/go v0.121.6 // indirect
|
||||
cloud.google.com/go/auth v0.17.0 // indirect
|
||||
cloud.google.com/go/auth v0.20.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.9.0 // indirect
|
||||
cloud.google.com/go/iam v1.5.2 // indirect
|
||||
cloud.google.com/go/monitoring v1.24.2 // indirect
|
||||
cloud.google.com/go/iam v1.5.3 // indirect
|
||||
cloud.google.com/go/monitoring v1.24.3 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 // indirect
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect
|
||||
@@ -91,19 +92,18 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 // indirect
|
||||
github.com/aws/smithy-go v1.24.2 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/blang/semver/v4 v4.0.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/chmduquesne/rollinghash v4.0.0+incompatible // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/edsrzf/mmap-go v1.2.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.13.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
@@ -114,18 +114,16 @@ require (
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/gofrs/flock v0.13.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/gnostic-models v0.6.9 // indirect
|
||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect
|
||||
github.com/google/gnostic-models v0.7.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.7 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.15.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.15 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.22.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
|
||||
github.com/hashicorp/cronexpr v1.1.3 // indirect
|
||||
github.com/hashicorp/yamux v0.1.1 // indirect
|
||||
github.com/hashicorp/yamux v0.1.2 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
@@ -143,24 +141,22 @@ require (
|
||||
github.com/minio/crc64nvme v1.1.0 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.97 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
|
||||
github.com/moby/spdystream v0.5.0 // indirect
|
||||
github.com/moby/spdystream v0.5.1 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||
github.com/mxk/go-vss v1.2.0 // indirect
|
||||
github.com/natefinch/atomic v1.0.1 // indirect
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/oklog/run v1.0.0 // indirect
|
||||
github.com/oklog/run v1.1.0 // indirect
|
||||
github.com/philhofer/fwd v1.2.0 // indirect
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/common v0.67.4 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/prometheus/common v0.67.5 // indirect
|
||||
github.com/prometheus/procfs v0.19.2 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
github.com/spiffe/go-spiffe/v2 v2.6.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
@@ -170,32 +166,34 @@ require (
|
||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.39.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.40.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 // indirect
|
||||
go.opentelemetry.io/otel v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.43.0 // indirect
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect
|
||||
golang.org/x/net v0.48.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/term v0.38.0 // indirect
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
golang.org/x/tools v0.39.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/crypto v0.50.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
|
||||
golang.org/x/net v0.53.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/term v0.42.0 // indirect
|
||||
golang.org/x/time v0.15.0 // indirect
|
||||
golang.org/x/tools v0.44.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect
|
||||
k8s.io/streaming v0.36.0 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 // indirect
|
||||
)
|
||||
|
||||
replace github.com/kopia/kopia => github.com/project-velero/kopia v0.0.0-20251230033609-d946b1e75197
|
||||
|
||||
@@ -26,8 +26,8 @@ cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb
|
||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||
cloud.google.com/go v0.121.6 h1:waZiuajrI28iAf40cWgycWNgaXPO06dupuS+sgibK6c=
|
||||
cloud.google.com/go v0.121.6/go.mod h1:coChdst4Ea5vUpiALcYKXEpR1S9ZgXbhEzzMcMR66vI=
|
||||
cloud.google.com/go/auth v0.17.0 h1:74yCm7hCj2rUyyAocqnFzsAYXgJhrG26XCFimrc/Kz4=
|
||||
cloud.google.com/go/auth v0.17.0/go.mod h1:6wv/t5/6rOPAX4fJiRjKkJCvswLwdet7G8+UGXt7nCQ=
|
||||
cloud.google.com/go/auth v0.20.0 h1:kXTssoVb4azsVDoUiF8KvxAqrsQcQtB53DcSgta74CA=
|
||||
cloud.google.com/go/auth v0.20.0/go.mod h1:942/yi/itH1SsmpyrbnTMDgGfdy2BUqIKyd0cyYLc5Q=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
@@ -41,14 +41,14 @@ cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCB
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/iam v1.5.2 h1:qgFRAGEmd8z6dJ/qyEchAuL9jpswyODjA2lS+w234g8=
|
||||
cloud.google.com/go/iam v1.5.2/go.mod h1:SE1vg0N81zQqLzQEwxL2WI6yhetBdbNQuTvIKCSkUHE=
|
||||
cloud.google.com/go/logging v1.13.0 h1:7j0HgAp0B94o1YRDqiqm26w4q1rDMH7XNRU34lJXHYc=
|
||||
cloud.google.com/go/logging v1.13.0/go.mod h1:36CoKh6KA/M0PbhPKMq6/qety2DCAErbhXT62TuXALA=
|
||||
cloud.google.com/go/longrunning v0.7.0 h1:FV0+SYF1RIj59gyoWDRi45GiYUMM3K1qO51qoboQT1E=
|
||||
cloud.google.com/go/longrunning v0.7.0/go.mod h1:ySn2yXmjbK9Ba0zsQqunhDkYi0+9rlXIwnoAf+h+TPY=
|
||||
cloud.google.com/go/monitoring v1.24.2 h1:5OTsoJ1dXYIiMiuL+sYscLc9BumrL3CarVLL7dd7lHM=
|
||||
cloud.google.com/go/monitoring v1.24.2/go.mod h1:x7yzPWcgDRnPEv3sI+jJGBkwl5qINf+6qY4eq0I9B4U=
|
||||
cloud.google.com/go/iam v1.5.3 h1:+vMINPiDF2ognBJ97ABAYYwRgsaqxPbQDlMnbHMjolc=
|
||||
cloud.google.com/go/iam v1.5.3/go.mod h1:MR3v9oLkZCTlaqljW6Eb2d3HGDGK5/bDv93jhfISFvU=
|
||||
cloud.google.com/go/logging v1.13.2 h1:qqlHCBvieJT9Cdq4QqYx1KPadCQ2noD4FK02eNqHAjA=
|
||||
cloud.google.com/go/logging v1.13.2/go.mod h1:zaybliM3yun1J8mU2dVQ1/qDzjbOqEijZCn6hSBtKak=
|
||||
cloud.google.com/go/longrunning v0.8.0 h1:LiKK77J3bx5gDLi4SMViHixjD2ohlkwBi+mKA7EhfW8=
|
||||
cloud.google.com/go/longrunning v0.8.0/go.mod h1:UmErU2Onzi+fKDg2gR7dusz11Pe26aknR4kHmJJqIfk=
|
||||
cloud.google.com/go/monitoring v1.24.3 h1:dde+gMNc0UhPZD1Azu6at2e79bfdztVDS5lvhOdsgaE=
|
||||
cloud.google.com/go/monitoring v1.24.3/go.mod h1:nYP6W0tm3N9H/bOw8am7t62YTzZY+zUeQ+Bi6+2eonI=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
@@ -61,8 +61,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
||||
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
|
||||
cloud.google.com/go/storage v1.57.2 h1:sVlym3cHGYhrp6XZKkKb+92I1V42ks2qKKpB0CF5Mb4=
|
||||
cloud.google.com/go/storage v1.57.2/go.mod h1:n5ijg4yiRXXpCu0sJTD6k+eMf7GRrJmPyr9YxLXGHOk=
|
||||
cloud.google.com/go/trace v1.11.6 h1:2O2zjPzqPYAHrn3OKl029qlqG6W8ZdYaOWRyr8NgMT4=
|
||||
cloud.google.com/go/trace v1.11.6/go.mod h1:GA855OeDEBiBMzcckLPE2kDunIpC72N+Pq8WFieFjnI=
|
||||
cloud.google.com/go/trace v1.11.7 h1:kDNDX8JkaAG3R2nq1lIdkb7FCSi1rCmsEtKVsty7p+U=
|
||||
cloud.google.com/go/trace v1.11.7/go.mod h1:TNn9d5V3fQVf6s4SCveVMIBS2LJUqo73GACmq/Tky0s=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0 h1:JXg2dwJUmPB9JmtVmdEB16APJ7jurfbY5jnfXpJoRMc=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.20.0/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw=
|
||||
@@ -101,14 +101,16 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5 h1:IEjq88XO4PuBDcvmjQJcQGg+w+UaafSy8G5Kcb5tBhI=
|
||||
github.com/GehirnInc/crypt v0.0.0-20230320061759-8cc1b52080c5/go.mod h1:exZ0C/1emQJAw5tHOaUDyY1ycttqBAPcxuzf7QbY6ec=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0 h1:sBEjpZlNHzK1voKq9695PJSX2o5NEXl7/OL3coiIY0c=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.30.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0 h1:DHa2U07rk8syqvCge0QIGMCE1WxGj9njT44GH7zNJLQ=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.31.0/go.mod h1:P4WPRUkOhJC13W//jWpyfJNDAIpvRbAUIYLX/4jtlE0=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0 h1:owcC2UnmsZycprQ5RfRgjydWhuoxg71LUfyiQdijZuM=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/exporter/metric v0.53.0/go.mod h1:ZPpqegjbE99EPKsu3iUWV22A04wzGPcAY/ziSIQEEgs=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0 h1:4LP6hvB4I5ouTbGgWtixJhgED6xdf67twf9PoY96Tbg=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/cloudmock v0.53.0/go.mod h1:jUZ5LYlw40WMd07qxcQJD5M40aUxrfwqQX1g7zxYnrQ=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0 h1:Ron4zCA/yk6U7WOBXhTJcDpsUBG9npumK6xw2auFltQ=
|
||||
github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.53.0/go.mod h1:cSgYe11MCNYunTnRXrKiR/tHc0eoKjICUuWpNZoVCOo=
|
||||
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
@@ -170,12 +172,10 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
|
||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
||||
github.com/bombsimon/logrusr/v3 v3.0.0 h1:tcAoLfuAhKP9npBxWzSdpsvKPQt1XV02nSf2lZA82TQ=
|
||||
github.com/bombsimon/logrusr/v3 v3.0.0/go.mod h1:PksPPgSFEL2I52pla2glgCyyd2OqOHAnFF5E+g8Ixco=
|
||||
github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA=
|
||||
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
|
||||
github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
|
||||
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
||||
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.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
@@ -200,7 +200,7 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
|
||||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
|
||||
github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
|
||||
@@ -219,8 +219,8 @@ github.com/edsrzf/mmap-go v1.2.0 h1:hXLYlkbaPzt1SaQk+anYwKSRNhufIDCchSPkUD6dD84=
|
||||
github.com/edsrzf/mmap-go v1.2.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
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/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes=
|
||||
github.com/emicklei/go-restful/v3 v3.13.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=
|
||||
@@ -242,6 +242,7 @@ github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
|
||||
github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
|
||||
github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
@@ -253,11 +254,17 @@ github.com/frankban/quicktest v1.13.1/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
|
||||
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
|
||||
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
|
||||
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
|
||||
github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE=
|
||||
github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
|
||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@@ -299,6 +306,8 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
||||
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
@@ -306,7 +315,6 @@ github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
|
||||
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
@@ -348,10 +356,8 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
|
||||
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
|
||||
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
||||
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||
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=
|
||||
@@ -364,7 +370,6 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.5.4/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.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
@@ -389,8 +394,8 @@ github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLe
|
||||
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo=
|
||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 h1:EwtI+Al+DeppwYX2oXJCETMO23COyaKGP6fHVpkpWpg=
|
||||
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
||||
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
||||
@@ -399,12 +404,12 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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.7 h1:zrn2Ee/nWmHulBx5sAVrGgAa0f2/R35S4DJwfFaUPFQ=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.7/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.15 h1:xolVQTEXusUcAA5UgtyRLjelpFFHWlPQ4XfWGc7MBas=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.15/go.mod h1:vqVt9yG9480NtzREnTlmGSBmFrA+bzb0yl0TxoBQXOg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.15.0 h1:SyjDc1mGgZU5LncH8gimWo9lW1DtIfPibOG81vgd/bo=
|
||||
github.com/googleapis/gax-go/v2 v2.15.0/go.mod h1:zVVkkxAQHa1RQpg9z2AUCMnKhi0Qld9rcmyfL1OZhoc=
|
||||
github.com/googleapis/gax-go/v2 v2.22.0 h1:PjIWBpgGIVKGoCXuiCoP64altEJCj3/Ei+kSU5vlZD4=
|
||||
github.com/googleapis/gax-go/v2 v2.22.0/go.mod h1:irWBbALSr0Sk3qlqb9SyJ1h68WjgeFuiOzI4Rqw5+aY=
|
||||
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
||||
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
@@ -428,13 +433,13 @@ github.com/hashicorp/cronexpr v1.1.3 h1:rl5IkxXN2m681EfivTlccqIryzYJSXRGRNa0xeG7
|
||||
github.com/hashicorp/cronexpr v1.1.3/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU=
|
||||
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
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-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-plugin v1.6.0 h1:wgd4KxHJTVGGqWBq4QPB1i5BZNEx9BR8+OFmHDmTk8A=
|
||||
github.com/hashicorp/go-plugin v1.6.0/go.mod h1:lBS5MtSSBZk0SHc66KACcjjlU6WzEVP/8pwz68aMkCI=
|
||||
github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA=
|
||||
github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
|
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
|
||||
@@ -448,8 +453,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE=
|
||||
github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8=
|
||||
github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
@@ -458,8 +463,8 @@ github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
|
||||
github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
|
||||
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
|
||||
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
|
||||
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
|
||||
@@ -469,6 +474,8 @@ github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqx
|
||||
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
|
||||
github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
@@ -522,16 +529,21 @@ github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7
|
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
|
||||
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
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/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
|
||||
github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/minio/crc64nvme v1.1.0 h1:e/tAguZ+4cw32D+IO/8GSf5UVr9y+3eJcxZI2WOO/7Q=
|
||||
github.com/minio/crc64nvme v1.1.0/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
|
||||
@@ -542,7 +554,6 @@ github.com/minio/minio-go/v7 v7.0.97/go.mod h1:re5VXuo0pwEtoNLsNuSr0RrLfT/MBtohw
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0 h1:fzU/JVNcaqHQEcVFAKeR41fkiLdIPrefOvVG1VZ96U0=
|
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
|
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
|
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
|
||||
@@ -550,8 +561,8 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
|
||||
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
|
||||
github.com/moby/spdystream v0.5.1 h1:9sNYeYZUcci9R6/w7KDaFWEWeV4LStVG78Mpyq/Zm/Y=
|
||||
github.com/moby/spdystream v0.5.1/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
|
||||
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
|
||||
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -559,14 +570,14 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/mxk/go-vss v1.2.0 h1:JpdOPc/P6B3XyRoddn0iMiG/ADBi3AuEsv8RlTb+JeE=
|
||||
github.com/mxk/go-vss v1.2.0/go.mod h1:ZQ4yFxCG54vqPnCd+p2IxAe5jwZdz56wSjbwzBXiFd8=
|
||||
@@ -576,21 +587,21 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
|
||||
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA=
|
||||
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
|
||||
github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg=
|
||||
github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo=
|
||||
github.com/onsi/ginkgo/v2 v2.28.3 h1:4JvMdwtFU0imd8fHx25OJXoDMRexnf8v5NHKYSTTji4=
|
||||
github.com/onsi/ginkgo/v2 v2.28.3/go.mod h1:+aXOY+vzZ5mu2iI2HpTZUPmM//oQfsNFX6gU9kNcA44=
|
||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw=
|
||||
github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog=
|
||||
github.com/onsi/gomega v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc=
|
||||
github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
@@ -628,12 +639,12 @@ github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNw
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
|
||||
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+Lvsc=
|
||||
github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI=
|
||||
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
|
||||
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
|
||||
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||
@@ -668,14 +679,16 @@ github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
|
||||
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
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/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
||||
@@ -696,6 +709,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
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.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
@@ -703,6 +717,14 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD
|
||||
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
|
||||
github.com/tg123/go-htpasswd v1.2.4 h1:HgH8KKCjdmo7jjXWN9k1nefPBd7Be3tFCTjc2jPraPU=
|
||||
github.com/tg123/go-htpasswd v1.2.4/go.mod h1:EKThQok9xHkun6NBMynNv6Jmu24A33XdZzzl4Q7H1+0=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww=
|
||||
github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
|
||||
@@ -744,22 +766,22 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.39.0 h1:kWRNZMsfBHZ+uHjiH4y7Etn2FK26LAGkNFw7RHv1DhE=
|
||||
go.opentelemetry.io/contrib/detectors/gcp v1.39.0/go.mod h1:t/OGqzHBa5v6RHZwrDBJ2OirWc+4q/w2fTbLZwAKjTk=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 h1:q4XOmH/0opmeuJtPsbFNivyl7bCt7yRBbeEm2sC/XtQ=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0/go.mod h1:snMWehoOh2wsEwnvvwtDyFCxVeDAODenXHtn5vzrKjo=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
|
||||
go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=
|
||||
go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 h1:yI1/OhfEPy7J9eoa6Sj051C7n5dvpj0QX8g4sRchg04=
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0/go.mod h1:NoUCKYWK+3ecatC4HjkRktREheMeEtrXoQxrqYFeHSc=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg=
|
||||
go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I=
|
||||
go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY=
|
||||
go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw=
|
||||
go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=
|
||||
go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=
|
||||
go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8=
|
||||
go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4AtAlbuWdCYw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg=
|
||||
go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=
|
||||
go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=
|
||||
go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM=
|
||||
go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A=
|
||||
go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
||||
go.starlark.net v0.0.0-20201006213952-227f4aabceb5/go.mod h1:f0znQkUKRrkk36XxWbGjMqQM8wGv/xHBVE2qc3B5oFU=
|
||||
go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY=
|
||||
@@ -778,6 +800,8 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
|
||||
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
@@ -790,8 +814,8 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
|
||||
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -802,8 +826,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
|
||||
golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 h1:fQsdNF2N+/YewlRZiricy4P1iimyPKZ/xwniHj8Q2a0=
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93/go.mod h1:EPRbTFwzwjXj9NpYyyrvenVh9Y+GFeEvMNh7Xuz7xgU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -829,8 +853,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk=
|
||||
golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc=
|
||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
||||
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-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -876,8 +900,8 @@ golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLd
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -891,8 +915,8 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
|
||||
golang.org/x/oauth2 v0.34.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
|
||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||
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=
|
||||
@@ -904,8 +928,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -914,7 +938,6 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
|
||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -926,12 +949,12 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -965,18 +988,20 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
|
||||
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
|
||||
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
|
||||
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -986,14 +1011,14 @@ golang.org/x/text v0.3.4/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.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
||||
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
|
||||
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||
golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U=
|
||||
golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
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=
|
||||
@@ -1047,16 +1072,16 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ=
|
||||
golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ=
|
||||
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
|
||||
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
@@ -1079,8 +1104,8 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR
|
||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
||||
google.golang.org/api v0.256.0 h1:u6Khm8+F9sxbCTYNoBHg6/Hwv0N/i+V94MvkOSor6oI=
|
||||
google.golang.org/api v0.256.0/go.mod h1:KIgPhksXADEKJlnEoRa9qAII4rXcy40vfI8HRqcU964=
|
||||
google.golang.org/api v0.277.0 h1:HJfyJUiNeBBUMai7ez8u14wkp/gH/I4wpGbbO9o+cSk=
|
||||
google.golang.org/api v0.277.0/go.mod h1:B9TqLBwJqVjp1mtt7WeoQwWRwvu/400y5lETOql+giQ=
|
||||
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.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -1132,12 +1157,12 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822 h1:rHWScKit0gvAPuOnu87KpaYtjK5zBMLcULh7gxkCXu4=
|
||||
google.golang.org/genproto v0.0.0-20250603155806-513f23925822/go.mod h1:HubltRL7rMh0LfnQPkMH4NPDFEWp0jw3vixw7jEM53s=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0=
|
||||
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4 h1:tEkOQcXgF6dH1G+MVKZrfpYvozGrzb91k6ha7jireSM=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260427160629-7cedc36a6bc4/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@@ -1159,8 +1184,8 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM=
|
||||
google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4=
|
||||
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=
|
||||
@@ -1174,8 +1199,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
|
||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
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=
|
||||
@@ -1184,8 +1209,8 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
@@ -1216,50 +1241,51 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8=
|
||||
k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8=
|
||||
k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE=
|
||||
k8s.io/apiextensions-apiserver v0.33.3 h1:qmOcAHN6DjfD0v9kxL5udB27SRP6SG/MTopmge3MwEs=
|
||||
k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8=
|
||||
k8s.io/api v0.36.0 h1:SgqDhZzHdOtMk40xVSvCXkP9ME0H05hPM3p9AB1kL80=
|
||||
k8s.io/api v0.36.0/go.mod h1:m1LVrGPNYax5NBHdO+QuAedXyuzTt4RryI/qnmNvs34=
|
||||
k8s.io/apiextensions-apiserver v0.36.0 h1:Wt7E8J+VBCbj4FjiBfDTK/neXDDjyJVJc7xfuOHImZ0=
|
||||
k8s.io/apiextensions-apiserver v0.36.0/go.mod h1:kGDjH0msuiIB3tgsYRV0kS9GqpMYMUsQ3GHv7TApyug=
|
||||
k8s.io/apimachinery v0.22.2/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
|
||||
k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA=
|
||||
k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
|
||||
k8s.io/apimachinery v0.36.0 h1:jZyPzhd5Z+3h9vJLt0z9XdzW9VzNzWAUw+P1xZ9PXtQ=
|
||||
k8s.io/apimachinery v0.36.0/go.mod h1:FklypaRJt6n5wUIwWXIP6GJlIpUizTgfo1T/As+Tyxc=
|
||||
k8s.io/cli-runtime v0.22.2/go.mod h1:tkm2YeORFpbgQHEK/igqttvPTRIHFRz5kATlw53zlMI=
|
||||
k8s.io/cli-runtime v0.33.3 h1:Dgy4vPjNIu8LMJBSvs8W0LcdV0PX/8aGG1DA1W8lklA=
|
||||
k8s.io/cli-runtime v0.33.3/go.mod h1:yklhLklD4vLS8HNGgC9wGiuHWze4g7x6XQZ+8edsKEo=
|
||||
k8s.io/cli-runtime v0.36.0 h1:HNxciQpQMMOKS0/GiUXcKDyA6J2FDILJj9NmP2BZrTg=
|
||||
k8s.io/cli-runtime v0.36.0/go.mod h1:KObkknK9Ro5LYX+1RdiKc7C8CvGg4aX+V/Zv+E8WPHA=
|
||||
k8s.io/client-go v0.22.2/go.mod h1:sAlhrkVDf50ZHx6z4K0S40wISNTarf1r800F+RlCF6U=
|
||||
k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA=
|
||||
k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg=
|
||||
k8s.io/client-go v0.36.0 h1:pOYi7C4RHChYjMiHpZSpSbIM6ZxVbRXBy7CuiIwqA3c=
|
||||
k8s.io/client-go v0.36.0/go.mod h1:ZKKcpwF0aLYfkHFCjillCKaTK/yBkEDHTDXCFY6AS9Y=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-aggregator v0.33.3 h1:Pa6hQpKJMX0p0D2wwcxXJgu02++gYcGWXoW1z1ZJDfo=
|
||||
k8s.io/kube-aggregator v0.33.3/go.mod h1:hwvkUoQ8q6gv0+SgNnlmQ3eUue1zHhJKTHsX7BwxwSE=
|
||||
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
|
||||
k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0=
|
||||
k8s.io/kube-aggregator v0.36.0 h1:yrR+aw41p4/Wur55FCcfozPSBHH70HIs5j+J6ZphExg=
|
||||
k8s.io/kube-aggregator v0.36.0/go.mod h1:2CkdUvPZjEbKnlhn+wxj6z3yity7H4xsTrFX+M/t1UE=
|
||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4=
|
||||
k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8=
|
||||
k8s.io/metrics v0.33.3 h1:9CcqBz15JZfISqwca33gdHS8I6XfsK1vA8WUdEnG70g=
|
||||
k8s.io/metrics v0.33.3/go.mod h1:Aw+cdg4AYHw0HvUY+lCyq40FOO84awrqvJRTw0cmXDs=
|
||||
k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg=
|
||||
k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0=
|
||||
k8s.io/metrics v0.36.0 h1:VF41Mv9ZWKKQ4jEiJ0n3Tp6jdyO+oM6dbKcJn6Y/DVg=
|
||||
k8s.io/metrics v0.36.0/go.mod h1:FY1dgPJZqnSfnOYbVdBEdRNUdy0n1nUCU6yxSMUrVG4=
|
||||
k8s.io/streaming v0.36.0 h1:agnTxU+NFulUrtYzXUGKO3ndEa8jKwht1Kwn9nu9x+4=
|
||||
k8s.io/streaming v0.36.0/go.mod h1:z6fV3D+NVkoeqRMtWwlUZK6U17SY/LqNzOxWL6GyR/s=
|
||||
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
|
||||
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2 h1:AZYQSJemyQB5eRxqcPky+/7EdBj0xi3g0ZcxxJ7vbWU=
|
||||
k8s.io/utils v0.0.0-20260210185600-b8788abfbbc2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/controller-runtime v0.21.0 h1:CYfjpEuicjUecRk+KAeyYh+ouUBn4llGyDYytIGcJS8=
|
||||
sigs.k8s.io/controller-runtime v0.21.0/go.mod h1:OSg14+F65eWqIu4DceX7k/+QRAbTTvxeQSNSOQpukWM=
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
|
||||
sigs.k8s.io/controller-runtime v0.24.0 h1:Ck6N2LdS8Lovy1o25BB4r1xjvLEKUl1s2o9kU+KWDE4=
|
||||
sigs.k8s.io/controller-runtime v0.24.0/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw=
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||
sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
|
||||
sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM=
|
||||
sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2 h1:kwVWMx5yS1CrnFWA/2QHyRVJ8jM6dBA80uLmm0wJkk8=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
FROM --platform=$TARGETPLATFORM golang:1.25-trixie
|
||||
FROM --platform=$TARGETPLATFORM golang:1.26-trixie
|
||||
|
||||
ARG GOPROXY
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
|
||||
func main() {
|
||||
outTemplateFilename := os.Args[1]
|
||||
// #nosec G304,G703 -- outTemplateFilename is generated from internal logic and not user-controllable
|
||||
outFile, err := os.OpenFile(outTemplateFilename, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
@@ -51,11 +51,13 @@ if [[ "${PUBLISH:-}" != "TRUE" ]]; then
|
||||
echo "Not set to publish"
|
||||
goreleaser release \
|
||||
--clean \
|
||||
--parallelism 2 \
|
||||
--release-notes="${RELEASE_NOTES_FILE}" \
|
||||
--snapshot # Generate an unversioned snapshot release, skipping all validations and without publishing any artifacts (implies --skip-publish, --skip-announce and --skip-validate)
|
||||
else
|
||||
echo "Getting ready to publish"
|
||||
goreleaser release \
|
||||
--clean \
|
||||
--parallelism 2 \
|
||||
--release-notes="${RELEASE_NOTES_FILE}"
|
||||
fi
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
# The following variables are needed:
|
||||
|
||||
# - $VELERO_VERSION: defines the tag of Velero that any https://github.com/vmware-tanzu/velero/...
|
||||
# - $VELERO_VERSION: defines the tag of Velero that any https://github.com/velero-io/velero/...
|
||||
# links in the docs should redirect to.
|
||||
# - $REMOTE: defines the remote that should be used when pushing tags and branches. Defaults to "upstream"
|
||||
# - $publish: TRUE/FALSE value where FALSE (or not including it) will indicate a dry-run, and TRUE, or simply adding 'publish',
|
||||
|
||||
+3
-1
@@ -41,5 +41,7 @@ fi
|
||||
# but the user and group don't exist inside the container, when the code(https://github.com/kubernetes-sigs/controller-runtime/blob/v0.10.2/pkg/internal/testing/addr/manager.go#L44)
|
||||
# tries to get the cache directory, it gets the directory "/" and then get the permission error when trying to create directory under "/".
|
||||
# Specifying the cache directory by environment variable "XDG_CACHE_HOME" to workaround it
|
||||
XDG_CACHE_HOME=/tmp/ go test -installsuffix "static" -short -timeout 1200s -coverprofile=coverage.out "${TARGETS[@]}"
|
||||
# Add -vet parameter to filter out `printf` rule to avoid the false positive report for `non-constant format string in call to ...`.
|
||||
# https://pkg.go.dev/cmd/go#hdr-Test_packages:~:text=Only%20a%20high%2Dconfidence%20subset%20of%20the%20default%20go%20vet%20checks%20are%20used.%20That%20subset%20is%3A%20atomic%2C%20bool%2C%20buildtags%2C%20directive%2C%20errorsas%2C%20ifaceassert%2C%20nilfunc%2C%20printf%2C%20stringintconv%2C%20and%20tests.
|
||||
XDG_CACHE_HOME=/tmp/ go test -vet="atomic,bool,buildtags,directive,errorsas,ifaceassert,nilfunc,stringintconv,tests" -installsuffix "static" -short -timeout 1200s -coverprofile=coverage.out "${TARGETS[@]}"
|
||||
echo "Success!"
|
||||
|
||||
@@ -38,7 +38,7 @@ const (
|
||||
ConfigmapRefType string = "configmap"
|
||||
// skip action implies the volume would be skipped from the backup operation
|
||||
Skip VolumeActionType = "skip"
|
||||
// fs-backup action implies that the volume would be backed up via file system copy method using the uploader(kopia/restic) configured by the user
|
||||
// fs-backup action implies that the volume would be backed up via file system copy method using the uploader(kopia) configured by the user
|
||||
FSBackup VolumeActionType = "fs-backup"
|
||||
// snapshot action can have 3 different meaning based on velero configuration and backup spec - cloud provider based snapshots, local csi snapshots and datamover snapshots
|
||||
Snapshot VolumeActionType = "snapshot"
|
||||
|
||||
@@ -122,7 +122,7 @@ func RunRestartableDelegateTests(
|
||||
// If Function returns nil as struct return type, we cannot just
|
||||
// compare the interface to nil as its type will not be nil,
|
||||
// only the value will be
|
||||
if expected[i] == nil && reflect.ValueOf(a).Kind() == reflect.Ptr {
|
||||
if expected[i] == nil && reflect.ValueOf(a).Kind() == reflect.Pointer {
|
||||
assert.True(t, reflect.ValueOf(a).IsNil())
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -279,7 +279,7 @@ func TestExecute(t *testing.T) {
|
||||
err := crClient.List(t.Context(), dataUploadList, &crclient.ListOptions{LabelSelector: labels.SelectorFromSet(map[string]string{velerov1api.BackupNameLabel: tc.backup.Name})})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, dataUploadList.Items, 1)
|
||||
require.True(t, cmp.Equal(tc.expectedDataUpload, &dataUploadList.Items[0], cmpopts.IgnoreFields(velerov2alpha1.DataUpload{}, "ResourceVersion", "Name", "Spec.CSISnapshot.VolumeSnapshot")))
|
||||
require.Empty(t, cmp.Diff(tc.expectedDataUpload, &dataUploadList.Items[0], cmpopts.IgnoreFields(velerov2alpha1.DataUpload{}, "TypeMeta", "ResourceVersion", "Name", "Spec.CSISnapshot.VolumeSnapshot")))
|
||||
}
|
||||
|
||||
if tc.expectedPVC != nil {
|
||||
@@ -488,7 +488,7 @@ func TestCancel(t *testing.T) {
|
||||
err = crClient.Get(t.Context(), crclient.ObjectKey{Namespace: tc.dataUpload.Namespace, Name: tc.dataUpload.Name}, du)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.True(t, cmp.Equal(tc.expectedDataUpload, *du, cmpopts.IgnoreFields(velerov2alpha1.DataUpload{}, "ResourceVersion")))
|
||||
require.Empty(t, cmp.Diff(tc.expectedDataUpload, *du, cmpopts.IgnoreFields(velerov2alpha1.DataUpload{}, "TypeMeta", "ResourceVersion")))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+30
-11
@@ -167,15 +167,15 @@ func NewKubernetesBackupper(
|
||||
}, nil
|
||||
}
|
||||
|
||||
// getNamespaceIncludesExcludesAndArgoCDNamespaces returns an IncludesExcludes list containing which namespaces to
|
||||
// include and exclude from the backup and a list of namespaces managed by ArgoCD.
|
||||
func getNamespaceIncludesExcludesAndArgoCDNamespaces(backup *velerov1api.Backup, kbClient kbclient.Client) (*collections.NamespaceIncludesExcludes, []string, error) {
|
||||
// getNamespaceIncludesExcludes returns an IncludesExcludes list containing which namespaces to
|
||||
// include and exclude from the backup.
|
||||
func getNamespaceIncludesExcludes(backup *velerov1api.Backup, kbClient kbclient.Client) (*collections.NamespaceIncludesExcludes, error) {
|
||||
nsList := corev1api.NamespaceList{}
|
||||
activeNamespaces := []string{}
|
||||
nsManagedByArgoCD := []string{}
|
||||
if err := kbClient.List(context.Background(), &nsList); err != nil {
|
||||
return nil, nsManagedByArgoCD, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
activeNamespaces := []string{}
|
||||
for _, ns := range nsList.Items {
|
||||
activeNamespaces = append(activeNamespaces, ns.Name)
|
||||
}
|
||||
@@ -188,10 +188,20 @@ func getNamespaceIncludesExcludesAndArgoCDNamespaces(backup *velerov1api.Backup,
|
||||
|
||||
// Expand wildcards if needed
|
||||
if err := includesExcludes.ExpandIncludesExcludes(); err != nil {
|
||||
return nil, []string{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check for ArgoCD managed namespaces in the namespaces that will be included
|
||||
return includesExcludes, nil
|
||||
}
|
||||
|
||||
// getArgoCDManagedNamespaces returns a list of namespaces managed by ArgoCD that should be included in the backup.
|
||||
func getArgoCDManagedNamespaces(kbClient kbclient.Client, includesExcludes *collections.NamespaceIncludesExcludes) ([]string, error) {
|
||||
nsList := corev1api.NamespaceList{}
|
||||
if err := kbClient.List(context.Background(), &nsList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nsManagedByArgoCD := []string{}
|
||||
for _, ns := range nsList.Items {
|
||||
nsLabels := ns.GetLabels()
|
||||
if len(nsLabels[ArgoCDManagedByNamespaceLabel]) > 0 && includesExcludes.ShouldInclude(ns.Name) {
|
||||
@@ -199,7 +209,7 @@ func getNamespaceIncludesExcludesAndArgoCDNamespaces(backup *velerov1api.Backup,
|
||||
}
|
||||
}
|
||||
|
||||
return includesExcludes, nsManagedByArgoCD, nil
|
||||
return nsManagedByArgoCD, nil
|
||||
}
|
||||
|
||||
func getResourceHooks(hookSpecs []velerov1api.BackupResourceHookSpec, discoveryHelper discovery.Helper) ([]hook.ResourceHook, error) {
|
||||
@@ -274,13 +284,18 @@ func (kb *kubernetesBackupper) BackupWithResolvers(
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
var err error
|
||||
var nsManagedByArgoCD []string
|
||||
backupRequest.NamespaceIncludesExcludes, nsManagedByArgoCD, err = getNamespaceIncludesExcludesAndArgoCDNamespaces(backupRequest.Backup, kb.kbClient)
|
||||
backupRequest.NamespaceIncludesExcludes, err = getNamespaceIncludesExcludes(backupRequest.Backup, kb.kbClient)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("error getting namespace includes/excludes")
|
||||
return err
|
||||
}
|
||||
|
||||
nsManagedByArgoCD, err := getArgoCDManagedNamespaces(kb.kbClient, backupRequest.NamespaceIncludesExcludes)
|
||||
if err != nil {
|
||||
log.WithError(err).Errorf("error getting ArgoCD managed namespaces")
|
||||
return err
|
||||
}
|
||||
|
||||
if backupRequest.NamespaceIncludesExcludes.IsWildcardExpanded() {
|
||||
expandedIncludes := backupRequest.NamespaceIncludesExcludes.GetIncludes()
|
||||
expandedExcludes := backupRequest.NamespaceIncludesExcludes.GetExcludes()
|
||||
@@ -292,6 +307,10 @@ func (kb *kubernetesBackupper) BackupWithResolvers(
|
||||
return err
|
||||
}
|
||||
|
||||
if len(wildcardResult) == 0 {
|
||||
log.Warnf("no namespaces matched the resolution of wildcard patterns ")
|
||||
}
|
||||
|
||||
log.WithFields(logrus.Fields{
|
||||
"expandedIncludes": expandedIncludes,
|
||||
"expandedExcludes": expandedExcludes,
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright The Velero Contributors.
|
||||
|
||||
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 cbtservice
|
||||
|
||||
import "context"
|
||||
|
||||
// Range defines the range of a change
|
||||
type Range struct {
|
||||
Offset int64
|
||||
Length int64
|
||||
}
|
||||
|
||||
// SourceInfo is the information provided to the uploader, the uploader calls CBT service with this information
|
||||
type SourceInfo struct {
|
||||
// Snapshot is the identifier of the current snapshot
|
||||
Snapshot string
|
||||
|
||||
// ChangeID is the identifier associated to the current snapshot that is used as changeID for following backups
|
||||
ChangeID string
|
||||
|
||||
// VolumeID is the identifier uniquely identifier a volume in the storage to which the CBT is associated
|
||||
VolumeID string
|
||||
}
|
||||
|
||||
// Service defines the methods for CBT service which could be implemented by Kubernetes SnapshotMetadataService or other customized services
|
||||
type Service interface {
|
||||
// GetAllocatedBlocks enumerates the allocated blocks of the snapshot and call the record callback
|
||||
GetAllocatedBlocks(ctx context.Context, snapshot string, record func([]Range) error) error
|
||||
|
||||
// GetChangedBlocks enumerates the changed blocks of the snapshot since PIT of changeID and call the record callback
|
||||
GetChangedBlocks(ctx context.Context, snapshot string, changeID string, record func([]Range) error) error
|
||||
}
|
||||
@@ -37,7 +37,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
cacheutil "k8s.io/client-go/tools/cache"
|
||||
@@ -430,10 +429,6 @@ func (s *nodeAgentServer) run() {
|
||||
s.logger.WithError(err).Fatal("Unable to create the pod volume restore controller")
|
||||
}
|
||||
|
||||
if err := controller.InitLegacyPodVolumeRestoreReconciler(s.mgr.GetClient(), s.mgr, s.kubeClient, s.dataPathMgr, s.namespace, s.config.resourceTimeout, s.logger); err != nil {
|
||||
s.logger.WithError(err).Fatal("Unable to create the legacy pod volume restore controller")
|
||||
}
|
||||
|
||||
dataUploadReconciler := controller.NewDataUploadReconciler(
|
||||
s.mgr.GetClient(),
|
||||
s.mgr,
|
||||
@@ -509,8 +504,6 @@ func (s *nodeAgentServer) run() {
|
||||
if err := pvrReconciler.AttemptPVRResume(s.ctx, s.logger.WithField("node", s.nodeName), s.namespace); err != nil {
|
||||
s.logger.WithError(errors.WithStack(err)).Error("Failed to attempt PVR resume")
|
||||
}
|
||||
|
||||
s.markLegacyPVRsFailed(s.mgr.GetClient())
|
||||
}()
|
||||
|
||||
s.logger.Info("Controllers starting...")
|
||||
@@ -604,47 +597,6 @@ func (s *nodeAgentServer) validatePodVolumesHostPath(client kubernetes.Interface
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *nodeAgentServer) markLegacyPVRsFailed(client ctrlclient.Client) {
|
||||
pvrs := &velerov1api.PodVolumeRestoreList{}
|
||||
if err := client.List(s.ctx, pvrs, &ctrlclient.ListOptions{Namespace: s.namespace}); err != nil {
|
||||
s.logger.WithError(errors.WithStack(err)).Error("failed to list podvolumerestores")
|
||||
return
|
||||
}
|
||||
|
||||
for i, pvr := range pvrs.Items {
|
||||
if !controller.IsLegacyPVR(&pvr) {
|
||||
continue
|
||||
}
|
||||
|
||||
if pvr.Status.Phase != velerov1api.PodVolumeRestorePhaseInProgress {
|
||||
s.logger.Debugf("the status of podvolumerestore %q is %q, skip", pvr.GetName(), pvr.Status.Phase)
|
||||
continue
|
||||
}
|
||||
|
||||
pod := &corev1api.Pod{}
|
||||
if err := client.Get(s.ctx, types.NamespacedName{
|
||||
Namespace: pvr.Spec.Pod.Namespace,
|
||||
Name: pvr.Spec.Pod.Name,
|
||||
}, pod); err != nil {
|
||||
s.logger.WithError(errors.WithStack(err)).Errorf("failed to get pod \"%s/%s\" of podvolumerestore %q",
|
||||
pvr.Spec.Pod.Namespace, pvr.Spec.Pod.Name, pvr.GetName())
|
||||
continue
|
||||
}
|
||||
if pod.Spec.NodeName != s.nodeName {
|
||||
s.logger.Debugf("the node of pod referenced by podvolumerestore %q is %q, not %q, skip", pvr.GetName(), pod.Spec.NodeName, s.nodeName)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := controller.UpdatePVRStatusToFailed(s.ctx, client, &pvrs.Items[i], errors.New("cannot survive from node-agent restart"),
|
||||
fmt.Sprintf("get a legacy podvolumerestore with status %q during the server starting, mark it as %q", velerov1api.PodVolumeRestorePhaseInProgress, velerov1api.PodVolumeRestorePhaseFailed),
|
||||
time.Now(), s.logger); err != nil {
|
||||
s.logger.WithError(errors.WithStack(err)).Errorf("failed to patch podvolumerestore %q", pvr.GetName())
|
||||
continue
|
||||
}
|
||||
s.logger.WithField("podvolumerestore", pvr.GetName()).Warn(pvr.Status.Message)
|
||||
}
|
||||
}
|
||||
|
||||
var getConfigsFunc = nodeagent.GetConfigs
|
||||
|
||||
func (s *nodeAgentServer) getDataPathConfigs() error {
|
||||
|
||||
@@ -1164,8 +1164,8 @@ func markPodVolumeRestoresCancel(ctx context.Context, client ctrlclient.Client,
|
||||
|
||||
for i := range pvrs.Items {
|
||||
pvr := pvrs.Items[i]
|
||||
if controller.IsLegacyPVR(&pvr) {
|
||||
log.WithField("PVR", pvr.GetName()).Warn("Found a legacy PVR during velero server restart, cannot stop it")
|
||||
if _, err := uploader.ValidateUploaderType(pvr.Spec.UploaderType); err != nil {
|
||||
log.WithField("PVR", pvr.Name).Warnf("invalid uploader type %s, skip marking cancel for this PVR", pvr.Spec.UploaderType)
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -132,6 +132,11 @@ operations can also be performed as 'velero backup get' and 'velero schedule cre
|
||||
|
||||
// init and add the klog flags
|
||||
klog.InitFlags(flag.CommandLine)
|
||||
// Opt into the new klog behavior so that -stderrthreshold is honored even
|
||||
// when -logtostderr=true (the default).
|
||||
// Ref: kubernetes/klog#212, kubernetes/klog#432
|
||||
flag.CommandLine.Set("legacy_stderr_threshold_behavior", "false") //nolint:errcheck // flag is registered by klog.InitFlags above
|
||||
flag.CommandLine.Set("stderrthreshold", "INFO") //nolint:errcheck // flag is registered by klog.InitFlags above
|
||||
c.PersistentFlags().AddGoFlagSet(flag.CommandLine)
|
||||
|
||||
return c
|
||||
|
||||
@@ -570,6 +570,13 @@ func (b *backupReconciler) prepareBackupRequest(ctx context.Context, backup *vel
|
||||
}
|
||||
}
|
||||
|
||||
// Empty IncludedNamespaces means "include all namespaces". Normalize
|
||||
// to ["*"] so that downstream wildcard expansion does not collapse
|
||||
// an empty-includes + wildcard-excludes combination into "back up nothing".
|
||||
if len(request.Spec.IncludedNamespaces) == 0 {
|
||||
request.Spec.IncludedNamespaces = []string{"*"}
|
||||
}
|
||||
|
||||
// validate the included/excluded namespaces
|
||||
for _, err := range collections.ValidateNamespaceIncludesExcludes(request.Spec.IncludedNamespaces, request.Spec.ExcludedNamespaces) {
|
||||
request.Status.ValidationErrors = append(request.Status.ValidationErrors, fmt.Sprintf("Invalid included/excluded namespace lists: %v", err))
|
||||
|
||||
@@ -27,6 +27,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
snapshotv1api "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@@ -320,6 +321,34 @@ func TestBackupLocationLabel(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrepareBackupRequest_EmptyIncludedNamespacesNormalizedToWildcard(t *testing.T) {
|
||||
formatFlag := logging.FormatText
|
||||
logger := logging.DefaultLogger(logrus.DebugLevel, formatFlag)
|
||||
|
||||
apiServer := velerotest.NewAPIServer(t)
|
||||
discoveryHelper, err := discovery.NewHelper(apiServer.DiscoveryClient, logger)
|
||||
require.NoError(t, err)
|
||||
|
||||
backupLocation := builder.ForBackupStorageLocation("velero", "loc-1").Result()
|
||||
fakeClient := velerotest.NewFakeControllerRuntimeClient(t, backupLocation)
|
||||
|
||||
c := &backupReconciler{
|
||||
discoveryHelper: discoveryHelper,
|
||||
kbClient: fakeClient,
|
||||
defaultBackupLocation: backupLocation.Name,
|
||||
clock: &clock.RealClock{},
|
||||
formatFlag: formatFlag,
|
||||
}
|
||||
|
||||
backup := defaultBackup().Result()
|
||||
backup.Spec.IncludedNamespaces = nil
|
||||
|
||||
res := c.prepareBackupRequest(ctx, backup, logger)
|
||||
defer res.WorkerPool.Stop()
|
||||
|
||||
assert.Equal(t, []string{"*"}, res.Spec.IncludedNamespaces)
|
||||
}
|
||||
|
||||
func Test_prepareBackupRequest_BackupStorageLocation(t *testing.T) {
|
||||
var (
|
||||
defaultBackupTTL = metav1.Duration{Duration: 24 * 30 * time.Hour}
|
||||
@@ -709,6 +738,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -748,6 +778,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: "alt-loc",
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -791,6 +822,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: "read-write",
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -831,6 +863,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
Spec: velerov1api.BackupSpec{
|
||||
TTL: metav1.Duration{Duration: 10 * time.Minute},
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -871,6 +904,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -912,6 +946,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -953,6 +988,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -994,6 +1030,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -1035,6 +1072,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -1077,6 +1115,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -1119,6 +1158,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.True(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -1161,6 +1201,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -1204,6 +1245,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -1247,6 +1289,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -1290,6 +1333,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -1334,6 +1378,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.False(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -1377,6 +1422,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
ExcludedClusterScopedResources: autoExcludeClusterScopedResources,
|
||||
@@ -1424,6 +1470,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
IncludedClusterScopedResources: []string{"storageclasses"},
|
||||
@@ -1473,6 +1520,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
},
|
||||
Spec: velerov1api.BackupSpec{
|
||||
StorageLocation: defaultBackupLocation.Name,
|
||||
IncludedNamespaces: []string{"*"},
|
||||
DefaultVolumesToFsBackup: boolptr.False(),
|
||||
SnapshotMoveData: boolptr.True(),
|
||||
IncludedClusterScopedResources: []string{"storageclasses"},
|
||||
@@ -1609,7 +1657,7 @@ func TestProcessBackupCompletions(t *testing.T) {
|
||||
err = c.kbClient.Get(t.Context(), kbclient.ObjectKey{Namespace: test.backup.Namespace, Name: test.backup.Name}, res)
|
||||
require.NoError(t, err)
|
||||
res.ResourceVersion = ""
|
||||
assert.Equal(t, test.expectedResult, res)
|
||||
assert.Empty(t, cmp.Diff(test.expectedResult, res, cmpopts.IgnoreFields(velerov1api.Backup{}, "TypeMeta")))
|
||||
// reset defaultBackupLocation resourceVersion
|
||||
defaultBackupLocation.ObjectMeta.ResourceVersion = ""
|
||||
})
|
||||
|
||||
@@ -603,7 +603,7 @@ func (r *PodVolumeRestoreReconciler) closeDataPath(ctx context.Context, pvrName
|
||||
func (r *PodVolumeRestoreReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
gp := kube.NewGenericEventPredicate(func(object client.Object) bool {
|
||||
pvr := object.(*velerov1api.PodVolumeRestore)
|
||||
if IsLegacyPVR(pvr) {
|
||||
if _, err := uploader.ValidateUploaderType(pvr.Spec.UploaderType); err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -628,7 +628,8 @@ func (r *PodVolumeRestoreReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
|
||||
pred := kube.NewAllEventPredicate(func(obj client.Object) bool {
|
||||
pvr := obj.(*velerov1api.PodVolumeRestore)
|
||||
return !IsLegacyPVR(pvr)
|
||||
_, err := uploader.ValidateUploaderType(pvr.Spec.UploaderType)
|
||||
return err == nil
|
||||
})
|
||||
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
@@ -678,7 +679,7 @@ func (r *PodVolumeRestoreReconciler) findPVRForTargetPod(ctx context.Context, po
|
||||
|
||||
requests := []reconcile.Request{}
|
||||
for _, item := range list.Items {
|
||||
if IsLegacyPVR(&item) {
|
||||
if _, err := uploader.ValidateUploaderType(item.Spec.UploaderType); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -708,6 +709,11 @@ func (r *PodVolumeRestoreReconciler) findPVRForRestorePod(ctx context.Context, p
|
||||
"PVR": pvr.Name,
|
||||
})
|
||||
|
||||
if _, err := uploader.ValidateUploaderType(pvr.Spec.UploaderType); err != nil {
|
||||
log.WithField("uploaderType", pvr.Spec.UploaderType).Debug("skip PVR with invalid uploader type")
|
||||
return []reconcile.Request{}
|
||||
}
|
||||
|
||||
if pvr.Status.Phase != velerov1api.PodVolumeRestorePhaseAccepted {
|
||||
return []reconcile.Request{}
|
||||
}
|
||||
@@ -1029,7 +1035,7 @@ func (r *PodVolumeRestoreReconciler) AttemptPVRResume(ctx context.Context, logge
|
||||
|
||||
for i := range pvrs.Items {
|
||||
pvr := &pvrs.Items[i]
|
||||
if IsLegacyPVR(pvr) {
|
||||
if _, err := uploader.ValidateUploaderType(pvr.Spec.UploaderType); err != nil {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
Copyright The Velero Contributors.
|
||||
|
||||
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 controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
clocks "k8s.io/utils/clock"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/builder"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/handler"
|
||||
"sigs.k8s.io/controller-runtime/pkg/manager"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
|
||||
"github.com/vmware-tanzu/velero/internal/credentials"
|
||||
veleroapishared "github.com/vmware-tanzu/velero/pkg/apis/velero/shared"
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
"github.com/vmware-tanzu/velero/pkg/datapath"
|
||||
"github.com/vmware-tanzu/velero/pkg/exposer"
|
||||
"github.com/vmware-tanzu/velero/pkg/podvolume"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
"github.com/vmware-tanzu/velero/pkg/restorehelper"
|
||||
"github.com/vmware-tanzu/velero/pkg/uploader"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/boolptr"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/filesystem"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/kube"
|
||||
)
|
||||
|
||||
func InitLegacyPodVolumeRestoreReconciler(client client.Client, mgr manager.Manager, kubeClient kubernetes.Interface, dataPathMgr *datapath.Manager, namespace string,
|
||||
resourceTimeout time.Duration, logger logrus.FieldLogger) error {
|
||||
log := logger.WithField("controller", "PodVolumeRestoreLegacy")
|
||||
|
||||
credentialFileStore, err := credentials.NewNamespacedFileStore(client, namespace, credentials.DefaultStoreDirectory(), filesystem.NewFileSystem())
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error creating credentials file store")
|
||||
}
|
||||
|
||||
credSecretStore, err := credentials.NewNamespacedSecretStore(client, namespace)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "error creating secret file store")
|
||||
}
|
||||
|
||||
credentialGetter := &credentials.CredentialGetter{FromFile: credentialFileStore, FromSecret: credSecretStore}
|
||||
ensurer := repository.NewEnsurer(client, log, resourceTimeout)
|
||||
|
||||
reconciler := &PodVolumeRestoreReconcilerLegacy{
|
||||
Client: client,
|
||||
kubeClient: kubeClient,
|
||||
logger: log,
|
||||
repositoryEnsurer: ensurer,
|
||||
credentialGetter: credentialGetter,
|
||||
fileSystem: filesystem.NewFileSystem(),
|
||||
clock: &clocks.RealClock{},
|
||||
dataPathMgr: dataPathMgr,
|
||||
}
|
||||
|
||||
if err = reconciler.SetupWithManager(mgr); err != nil {
|
||||
return errors.Wrapf(err, "error setup controller manager")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type PodVolumeRestoreReconcilerLegacy struct {
|
||||
client.Client
|
||||
kubeClient kubernetes.Interface
|
||||
logger logrus.FieldLogger
|
||||
repositoryEnsurer *repository.Ensurer
|
||||
credentialGetter *credentials.CredentialGetter
|
||||
fileSystem filesystem.Interface
|
||||
clock clocks.WithTickerAndDelayedExecution
|
||||
dataPathMgr *datapath.Manager
|
||||
}
|
||||
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=podvolumerestores,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=velero.io,resources=podvolumerestores/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups="",resources=pods,verbs=get
|
||||
// +kubebuilder:rbac:groups="",resources=persistentvolumes,verbs=get
|
||||
// +kubebuilder:rbac:groups="",resources=persistentvolumerclaims,verbs=get
|
||||
|
||||
func (c *PodVolumeRestoreReconcilerLegacy) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
log := c.logger.WithField("PodVolumeRestore", req.NamespacedName.String())
|
||||
log.Info("Reconciling PVR by legacy controller")
|
||||
|
||||
pvr := &velerov1api.PodVolumeRestore{}
|
||||
if err := c.Get(ctx, types.NamespacedName{Namespace: req.Namespace, Name: req.Name}, pvr); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
log.Warn("PodVolumeRestore not found, skip")
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
log.WithError(err).Error("Unable to get the PodVolumeRestore")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
log = log.WithField("pod", fmt.Sprintf("%s/%s", pvr.Spec.Pod.Namespace, pvr.Spec.Pod.Name))
|
||||
if len(pvr.OwnerReferences) == 1 {
|
||||
log = log.WithField("restore", fmt.Sprintf("%s/%s", pvr.Namespace, pvr.OwnerReferences[0].Name))
|
||||
}
|
||||
|
||||
shouldProcess, pod, err := shouldProcess(ctx, c.Client, log, pvr)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
if !shouldProcess {
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
initContainerIndex := getInitContainerIndex(pod)
|
||||
if initContainerIndex > 0 {
|
||||
log.Warnf(`Init containers before the %s container may cause issues
|
||||
if they interfere with volumes being restored: %s index %d`, restorehelper.WaitInitContainer, restorehelper.WaitInitContainer, initContainerIndex)
|
||||
}
|
||||
|
||||
log.Info("Restore starting")
|
||||
|
||||
callbacks := datapath.Callbacks{
|
||||
OnCompleted: c.OnDataPathCompleted,
|
||||
OnFailed: c.OnDataPathFailed,
|
||||
OnCancelled: c.OnDataPathCancelled,
|
||||
OnProgress: c.OnDataPathProgress,
|
||||
}
|
||||
|
||||
fsRestore, err := c.dataPathMgr.CreateFileSystemBR(pvr.Name, pVBRRequestor, ctx, c.Client, pvr.Namespace, callbacks, log)
|
||||
if err != nil {
|
||||
if err == datapath.ConcurrentLimitExceed {
|
||||
return ctrl.Result{Requeue: true, RequeueAfter: time.Second * 5}, nil
|
||||
} else {
|
||||
return c.errorOut(ctx, pvr, err, "error to create data path", log)
|
||||
}
|
||||
}
|
||||
|
||||
original := pvr.DeepCopy()
|
||||
pvr.Status.Phase = velerov1api.PodVolumeRestorePhaseInProgress
|
||||
pvr.Status.StartTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||
if err = c.Patch(ctx, pvr, client.MergeFrom(original)); err != nil {
|
||||
c.closeDataPath(ctx, pvr.Name)
|
||||
return c.errorOut(ctx, pvr, err, "error to update status to in progress", log)
|
||||
}
|
||||
|
||||
volumePath, err := exposer.GetPodVolumeHostPath(ctx, pod, pvr.Spec.Volume, c.kubeClient, c.fileSystem, log)
|
||||
if err != nil {
|
||||
c.closeDataPath(ctx, pvr.Name)
|
||||
return c.errorOut(ctx, pvr, err, "error exposing host path for pod volume", log)
|
||||
}
|
||||
|
||||
log.WithField("path", volumePath.ByPath).Debugf("Found host path")
|
||||
|
||||
if err := fsRestore.Init(ctx, &datapath.FSBRInitParam{
|
||||
BSLName: pvr.Spec.BackupStorageLocation,
|
||||
SourceNamespace: pvr.Spec.SourceNamespace,
|
||||
UploaderType: pvr.Spec.UploaderType,
|
||||
RepositoryType: podvolume.GetPvrRepositoryType(pvr),
|
||||
RepoIdentifier: pvr.Spec.RepoIdentifier,
|
||||
RepositoryEnsurer: c.repositoryEnsurer,
|
||||
CredentialGetter: c.credentialGetter,
|
||||
}); err != nil {
|
||||
c.closeDataPath(ctx, pvr.Name)
|
||||
return c.errorOut(ctx, pvr, err, "error to initialize data path", log)
|
||||
}
|
||||
|
||||
if err := fsRestore.StartRestore(pvr.Spec.SnapshotID, volumePath, pvr.Spec.UploaderSettings); err != nil {
|
||||
c.closeDataPath(ctx, pvr.Name)
|
||||
return c.errorOut(ctx, pvr, err, "error starting data path restore", log)
|
||||
}
|
||||
|
||||
log.WithField("path", volumePath.ByPath).Info("Async fs restore data path started")
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (c *PodVolumeRestoreReconcilerLegacy) errorOut(ctx context.Context, pvr *velerov1api.PodVolumeRestore, err error, msg string, log logrus.FieldLogger) (ctrl.Result, error) {
|
||||
_ = UpdatePVRStatusToFailed(ctx, c.Client, pvr, err, msg, c.clock.Now(), log)
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
func (c *PodVolumeRestoreReconcilerLegacy) SetupWithManager(mgr ctrl.Manager) error {
|
||||
// The pod may not being scheduled at the point when its PVRs are initially reconciled.
|
||||
// By watching the pods, we can trigger the PVR reconciliation again once the pod is finally scheduled on the node.
|
||||
pred := kube.NewAllEventPredicate(func(obj client.Object) bool {
|
||||
pvr := obj.(*velerov1api.PodVolumeRestore)
|
||||
return IsLegacyPVR(pvr)
|
||||
})
|
||||
|
||||
return ctrl.NewControllerManagedBy(mgr).Named("podvolumerestorelegacy").
|
||||
For(&velerov1api.PodVolumeRestore{}, builder.WithPredicates(pred)).
|
||||
Watches(&corev1api.Pod{}, handler.EnqueueRequestsFromMapFunc(c.findVolumeRestoresForPod)).
|
||||
Complete(c)
|
||||
}
|
||||
|
||||
func (c *PodVolumeRestoreReconcilerLegacy) findVolumeRestoresForPod(ctx context.Context, pod client.Object) []reconcile.Request {
|
||||
list := &velerov1api.PodVolumeRestoreList{}
|
||||
options := &client.ListOptions{
|
||||
LabelSelector: labels.Set(map[string]string{
|
||||
velerov1api.PodUIDLabel: string(pod.GetUID()),
|
||||
}).AsSelector(),
|
||||
}
|
||||
if err := c.Client.List(context.TODO(), list, options); err != nil {
|
||||
c.logger.WithField("pod", fmt.Sprintf("%s/%s", pod.GetNamespace(), pod.GetName())).WithError(err).
|
||||
Error("unable to list PodVolumeRestores")
|
||||
return []reconcile.Request{}
|
||||
}
|
||||
|
||||
requests := []reconcile.Request{}
|
||||
for _, item := range list.Items {
|
||||
if !IsLegacyPVR(&item) {
|
||||
continue
|
||||
}
|
||||
|
||||
requests = append(requests, reconcile.Request{
|
||||
NamespacedName: types.NamespacedName{
|
||||
Namespace: item.GetNamespace(),
|
||||
Name: item.GetName(),
|
||||
},
|
||||
})
|
||||
}
|
||||
return requests
|
||||
}
|
||||
|
||||
func (c *PodVolumeRestoreReconcilerLegacy) OnDataPathCompleted(ctx context.Context, namespace string, pvrName string, result datapath.Result) {
|
||||
defer c.dataPathMgr.RemoveAsyncBR(pvrName)
|
||||
|
||||
log := c.logger.WithField("pvr", pvrName)
|
||||
|
||||
log.WithField("PVR", pvrName).Info("Async fs restore data path completed")
|
||||
|
||||
var pvr velerov1api.PodVolumeRestore
|
||||
if err := c.Client.Get(ctx, types.NamespacedName{Name: pvrName, Namespace: namespace}, &pvr); err != nil {
|
||||
log.WithError(err).Warn("Failed to get PVR on completion")
|
||||
return
|
||||
}
|
||||
|
||||
volumePath := result.Restore.Target.ByPath
|
||||
if volumePath == "" {
|
||||
_, _ = c.errorOut(ctx, &pvr, errors.New("path is empty"), "invalid restore target", log)
|
||||
return
|
||||
}
|
||||
|
||||
// Remove the .velero directory from the restored volume (it may contain done files from previous restores
|
||||
// of this volume, which we don't want to carry over). If this fails for any reason, log and continue, since
|
||||
// this is non-essential cleanup (the done files are named based on restore UID and the init container looks
|
||||
// for the one specific to the restore being executed).
|
||||
if err := os.RemoveAll(filepath.Join(volumePath, ".velero")); err != nil {
|
||||
log.WithError(err).Warnf("error removing .velero directory from directory %s", volumePath)
|
||||
}
|
||||
|
||||
var restoreUID types.UID
|
||||
for _, owner := range pvr.OwnerReferences {
|
||||
if boolptr.IsSetToTrue(owner.Controller) {
|
||||
restoreUID = owner.UID
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Create the .velero directory within the volume dir so we can write a done file
|
||||
// for this restore.
|
||||
if err := os.MkdirAll(filepath.Join(volumePath, ".velero"), 0755); err != nil {
|
||||
_, _ = c.errorOut(ctx, &pvr, err, "error creating .velero directory for done file", log)
|
||||
return
|
||||
}
|
||||
|
||||
// Write a done file with name=<restore-uid> into the just-created .velero dir
|
||||
// within the volume. The velero init container on the pod is waiting
|
||||
// for this file to exist in each restored volume before completing.
|
||||
if err := os.WriteFile(filepath.Join(volumePath, ".velero", string(restoreUID)), nil, 0644); err != nil { //nolint:gosec // Internal usage. No need to check.
|
||||
_, _ = c.errorOut(ctx, &pvr, err, "error writing done file", log)
|
||||
return
|
||||
}
|
||||
|
||||
original := pvr.DeepCopy()
|
||||
pvr.Status.Phase = velerov1api.PodVolumeRestorePhaseCompleted
|
||||
pvr.Status.CompletionTimestamp = &metav1.Time{Time: c.clock.Now()}
|
||||
if err := c.Patch(ctx, &pvr, client.MergeFrom(original)); err != nil {
|
||||
log.WithError(err).Error("error updating PodVolumeRestore status")
|
||||
}
|
||||
|
||||
log.Info("Restore completed")
|
||||
}
|
||||
|
||||
func (c *PodVolumeRestoreReconcilerLegacy) OnDataPathFailed(ctx context.Context, namespace string, pvrName string, err error) {
|
||||
defer c.dataPathMgr.RemoveAsyncBR(pvrName)
|
||||
|
||||
log := c.logger.WithField("pvr", pvrName)
|
||||
|
||||
log.WithError(err).Error("Async fs restore data path failed")
|
||||
|
||||
var pvr velerov1api.PodVolumeRestore
|
||||
if getErr := c.Client.Get(ctx, types.NamespacedName{Name: pvrName, Namespace: namespace}, &pvr); getErr != nil {
|
||||
log.WithError(getErr).Warn("Failed to get PVR on failure")
|
||||
} else {
|
||||
_, _ = c.errorOut(ctx, &pvr, err, "data path restore failed", log)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *PodVolumeRestoreReconcilerLegacy) OnDataPathCancelled(ctx context.Context, namespace string, pvrName string) {
|
||||
defer c.dataPathMgr.RemoveAsyncBR(pvrName)
|
||||
|
||||
log := c.logger.WithField("pvr", pvrName)
|
||||
|
||||
log.Warn("Async fs restore data path canceled")
|
||||
|
||||
var pvr velerov1api.PodVolumeRestore
|
||||
if getErr := c.Client.Get(ctx, types.NamespacedName{Name: pvrName, Namespace: namespace}, &pvr); getErr != nil {
|
||||
log.WithError(getErr).Warn("Failed to get PVR on cancel")
|
||||
} else {
|
||||
_, _ = c.errorOut(ctx, &pvr, errors.New("PVR is canceled"), "data path restore canceled", log)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *PodVolumeRestoreReconcilerLegacy) OnDataPathProgress(ctx context.Context, namespace string, pvrName string, progress *uploader.Progress) {
|
||||
log := c.logger.WithField("pvr", pvrName)
|
||||
|
||||
var pvr velerov1api.PodVolumeRestore
|
||||
if err := c.Client.Get(ctx, types.NamespacedName{Name: pvrName, Namespace: namespace}, &pvr); err != nil {
|
||||
log.WithError(err).Warn("Failed to get PVB on progress")
|
||||
return
|
||||
}
|
||||
|
||||
original := pvr.DeepCopy()
|
||||
pvr.Status.Progress = veleroapishared.DataMoveOperationProgress{TotalBytes: progress.TotalBytes, BytesDone: progress.BytesDone}
|
||||
|
||||
if err := c.Client.Patch(ctx, &pvr, client.MergeFrom(original)); err != nil {
|
||||
log.WithError(err).Error("Failed to update progress")
|
||||
}
|
||||
}
|
||||
|
||||
func (c *PodVolumeRestoreReconcilerLegacy) closeDataPath(ctx context.Context, pvbName string) {
|
||||
fsRestore := c.dataPathMgr.GetAsyncBR(pvbName)
|
||||
if fsRestore != nil {
|
||||
fsRestore.Close(ctx)
|
||||
}
|
||||
|
||||
c.dataPathMgr.RemoveAsyncBR(pvbName)
|
||||
}
|
||||
|
||||
func IsLegacyPVR(pvr *velerov1api.PodVolumeRestore) bool {
|
||||
return pvr.Spec.UploaderType == "restic"
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
Copyright The Velero Contributors.
|
||||
|
||||
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 controller
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
)
|
||||
|
||||
func TestFindVolumeRestoresForPodLegacy(t *testing.T) {
|
||||
pod := &corev1api.Pod{}
|
||||
pod.UID = "uid"
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypes(velerov1api.SchemeGroupVersion, &velerov1api.PodVolumeRestore{}, &velerov1api.PodVolumeRestoreList{})
|
||||
clientBuilder := fake.NewClientBuilder().WithScheme(scheme)
|
||||
|
||||
// no matching PVR
|
||||
reconciler := &PodVolumeRestoreReconcilerLegacy{
|
||||
Client: clientBuilder.Build(),
|
||||
logger: logrus.New(),
|
||||
}
|
||||
requests := reconciler.findVolumeRestoresForPod(t.Context(), pod)
|
||||
assert.Empty(t, requests)
|
||||
|
||||
// contain one matching PVR
|
||||
reconciler.Client = clientBuilder.WithLists(&velerov1api.PodVolumeRestoreList{
|
||||
Items: []velerov1api.PodVolumeRestore{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvr1",
|
||||
Labels: map[string]string{
|
||||
velerov1api.PodUIDLabel: string(pod.GetUID()),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvr2",
|
||||
Labels: map[string]string{
|
||||
velerov1api.PodUIDLabel: "non-matching-uid",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvr3",
|
||||
Labels: map[string]string{
|
||||
velerov1api.PodUIDLabel: string(pod.GetUID()),
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.PodVolumeRestoreSpec{
|
||||
UploaderType: "kopia",
|
||||
},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pvr4",
|
||||
Labels: map[string]string{
|
||||
velerov1api.PodUIDLabel: string(pod.GetUID()),
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.PodVolumeRestoreSpec{
|
||||
UploaderType: "restic",
|
||||
},
|
||||
},
|
||||
},
|
||||
}).Build()
|
||||
requests = reconciler.findVolumeRestoresForPod(t.Context(), pod)
|
||||
assert.Len(t, requests, 1)
|
||||
}
|
||||
@@ -506,18 +506,17 @@ func TestFindPVRForTargetPod(t *testing.T) {
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
scheme.AddKnownTypes(velerov1api.SchemeGroupVersion, &velerov1api.PodVolumeRestore{}, &velerov1api.PodVolumeRestoreList{})
|
||||
clientBuilder := fake.NewClientBuilder().WithScheme(scheme)
|
||||
|
||||
// no matching PVR
|
||||
reconciler := &PodVolumeRestoreReconciler{
|
||||
client: clientBuilder.Build(),
|
||||
client: fake.NewClientBuilder().WithScheme(scheme).Build(),
|
||||
logger: logrus.New(),
|
||||
}
|
||||
requests := reconciler.findPVRForTargetPod(t.Context(), pod)
|
||||
assert.Empty(t, requests)
|
||||
|
||||
// contain one matching PVR
|
||||
reconciler.client = clientBuilder.WithLists(&velerov1api.PodVolumeRestoreList{
|
||||
reconciler.client = fake.NewClientBuilder().WithScheme(scheme).WithLists(&velerov1api.PodVolumeRestoreList{
|
||||
Items: []velerov1api.PodVolumeRestore{
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -526,6 +525,7 @@ func TestFindPVRForTargetPod(t *testing.T) {
|
||||
velerov1api.PodUIDLabel: string(pod.GetUID()),
|
||||
},
|
||||
},
|
||||
Spec: velerov1api.PodVolumeRestoreSpec{UploaderType: uploader.KopiaType},
|
||||
},
|
||||
{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
@@ -688,6 +688,7 @@ func TestPodVolumeRestoreReconcile(t *testing.T) {
|
||||
mockClose bool
|
||||
needExclusiveUpdateError error
|
||||
constrained bool
|
||||
preserveEmptyUploader bool
|
||||
expected *velerov1api.PodVolumeRestore
|
||||
expectDeleted bool
|
||||
expectCancelRecord bool
|
||||
@@ -939,6 +940,13 @@ func TestPodVolumeRestoreReconcile(t *testing.T) {
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if !test.preserveEmptyUploader && test.pvr != nil && test.pvr.Spec.UploaderType == "" {
|
||||
test.pvr.Spec.UploaderType = uploader.KopiaType
|
||||
}
|
||||
if !test.preserveEmptyUploader && test.expected != nil && test.expected.Spec.UploaderType == "" {
|
||||
test.expected.Spec.UploaderType = uploader.KopiaType
|
||||
}
|
||||
|
||||
objs := []runtime.Object{daemonSet, node}
|
||||
|
||||
ctlObj := []client.Object{}
|
||||
@@ -1396,7 +1404,7 @@ func TestFindPVBForRestorePod(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "find pvr for pod",
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(),
|
||||
pod: builder.ForPod(velerov1api.DefaultNamespace, pvrName).Labels(map[string]string{velerov1api.PVRLabel: pvrName}).Status(corev1api.PodStatus{Phase: corev1api.PodRunning}).Result(),
|
||||
checkFunc: func(pvr *velerov1api.PodVolumeRestore, requests []reconcile.Request) {
|
||||
// Assert that the function returns a single request
|
||||
@@ -1407,7 +1415,7 @@ func TestFindPVBForRestorePod(t *testing.T) {
|
||||
},
|
||||
}, {
|
||||
name: "no selected label found for pod",
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(),
|
||||
pod: builder.ForPod(velerov1api.DefaultNamespace, pvrName).Result(),
|
||||
checkFunc: func(pvr *velerov1api.PodVolumeRestore, requests []reconcile.Request) {
|
||||
// Assert that the function returns a single request
|
||||
@@ -1415,7 +1423,7 @@ func TestFindPVBForRestorePod(t *testing.T) {
|
||||
},
|
||||
}, {
|
||||
name: "no matched pod",
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(),
|
||||
pod: builder.ForPod(velerov1api.DefaultNamespace, pvrName).Labels(map[string]string{velerov1api.PVRLabel: "non-existing-pvr"}).Result(),
|
||||
checkFunc: func(pvr *velerov1api.PodVolumeRestore, requests []reconcile.Request) {
|
||||
assert.Empty(t, requests)
|
||||
@@ -1423,12 +1431,20 @@ func TestFindPVBForRestorePod(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "pvr not accept",
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseInProgress).Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseInProgress).Result(),
|
||||
pod: builder.ForPod(velerov1api.DefaultNamespace, pvrName).Labels(map[string]string{velerov1api.PVRLabel: pvrName}).Result(),
|
||||
checkFunc: func(pvr *velerov1api.PodVolumeRestore, requests []reconcile.Request) {
|
||||
assert.Empty(t, requests)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid uploader type",
|
||||
pvr: pvrBuilder().UploaderType("restic").Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(),
|
||||
pod: builder.ForPod(velerov1api.DefaultNamespace, pvrName).Labels(map[string]string{velerov1api.PVRLabel: pvrName}).Status(corev1api.PodStatus{Phase: corev1api.PodRunning}).Result(),
|
||||
checkFunc: func(pvr *velerov1api.PodVolumeRestore, requests []reconcile.Request) {
|
||||
assert.Empty(t, requests)
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
ctx := t.Context()
|
||||
@@ -1613,32 +1629,32 @@ func TestAttemptPVRResume(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "Other pvr",
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhasePrepared).Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhasePrepared).Result(),
|
||||
},
|
||||
{
|
||||
name: "Other pvr",
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseAccepted).Result(),
|
||||
},
|
||||
{
|
||||
name: "InProgress pvr, not the current node",
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseInProgress).Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseInProgress).Result(),
|
||||
inProgressPvrs: []string{pvrName},
|
||||
},
|
||||
{
|
||||
name: "InProgress pvr, no resume error",
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(),
|
||||
inProgressPvrs: []string{pvrName},
|
||||
},
|
||||
{
|
||||
name: "InProgress pvr, resume error, cancel error",
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(),
|
||||
resumeErr: errors.New("fake-resume-error"),
|
||||
needErrs: []bool{false, false, true, false, false, false},
|
||||
inProgressPvrs: []string{pvrName},
|
||||
},
|
||||
{
|
||||
name: "InProgress pvr, resume error, cancel succeed",
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhaseInProgress).Node("node-1").Result(),
|
||||
resumeErr: errors.New("fake-resume-error"),
|
||||
cancelledPvrs: []string{pvrName},
|
||||
inProgressPvrs: []string{pvrName},
|
||||
@@ -1646,7 +1662,7 @@ func TestAttemptPVRResume(t *testing.T) {
|
||||
{
|
||||
name: "Error",
|
||||
needErrs: []bool{false, false, false, false, false, true},
|
||||
pvr: pvrBuilder().Phase(velerov1api.PodVolumeRestorePhasePrepared).Result(),
|
||||
pvr: pvrBuilder().UploaderType(uploader.KopiaType).Phase(velerov1api.PodVolumeRestorePhasePrepared).Result(),
|
||||
expectedError: "error to list PVRs: List error",
|
||||
},
|
||||
}
|
||||
|
||||
@@ -198,7 +198,8 @@ func DaemonSet(namespace string, opts ...podTemplateOption) *appsv1api.DaemonSet
|
||||
Secret: &corev1api.SecretVolumeSource{
|
||||
// read-only for Owner, Group, Public
|
||||
DefaultMode: ptr.To(int32(0444)),
|
||||
SecretName: "cloud-credentials",
|
||||
// #nosec G101 -- This is a reference to a Secret resource name, not a credential
|
||||
SecretName: "cloud-credentials",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -454,7 +454,8 @@ func Deployment(namespace string, opts ...podTemplateOption) *appsv1api.Deployme
|
||||
Secret: &corev1api.SecretVolumeSource{
|
||||
// read-only for Owner, Group, Public
|
||||
DefaultMode: ptr.To(int32(0444)),
|
||||
SecretName: "cloud-credentials",
|
||||
// #nosec G101 -- This is a reference to a Secret resource name, not a credential
|
||||
SecretName: "cloud-credentials",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -196,3 +196,21 @@ func (l *logrusAdapter) Name() string {
|
||||
func (l *logrusAdapter) StandardWriter(opts *hclog.StandardLoggerOptions) io.Writer {
|
||||
panic("not implemented")
|
||||
}
|
||||
|
||||
// GetLevel returns the current level
|
||||
func (l *logrusAdapter) GetLevel() hclog.Level {
|
||||
switch l.level {
|
||||
case logrus.TraceLevel:
|
||||
return hclog.Trace
|
||||
case logrus.DebugLevel:
|
||||
return hclog.Debug
|
||||
case logrus.InfoLevel:
|
||||
return hclog.Info
|
||||
case logrus.WarnLevel:
|
||||
return hclog.Warn
|
||||
case logrus.ErrorLevel:
|
||||
return hclog.Error
|
||||
default:
|
||||
return hclog.NoLevel
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ func NewServer() Server {
|
||||
func (s *server) BindFlags(flags *pflag.FlagSet) Server {
|
||||
s.flagSet = flags
|
||||
s.config.BindFlags(flags)
|
||||
s.flagSet.ParseErrorsWhitelist.UnknownFlags = true // Velero.io word list : ignore
|
||||
s.flagSet.ParseErrorsAllowlist.UnknownFlags = true // Velero.io word list : ignore
|
||||
return s
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import (
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
ctrlcache "sigs.k8s.io/controller-runtime/pkg/cache"
|
||||
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
ctrlfake "sigs.k8s.io/controller-runtime/pkg/client/fake"
|
||||
|
||||
@@ -40,9 +41,61 @@ import (
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/kube"
|
||||
)
|
||||
|
||||
type fakeInformerRegistration struct{}
|
||||
|
||||
func (fakeInformerRegistration) HasSynced() bool { return true }
|
||||
|
||||
func (fakeInformerRegistration) HasSyncedChecker() cache.DoneChecker {
|
||||
return fakeDoneChecker{name: "fakeInformerRegistration"}
|
||||
}
|
||||
|
||||
type fakeDoneChecker struct {
|
||||
name string
|
||||
}
|
||||
|
||||
func (f fakeDoneChecker) Name() string { return f.name }
|
||||
|
||||
func (f fakeDoneChecker) Done() <-chan struct{} {
|
||||
ch := make(chan struct{})
|
||||
close(ch)
|
||||
return ch
|
||||
}
|
||||
|
||||
type fakeInformer struct {
|
||||
handler cache.ResourceEventHandler
|
||||
}
|
||||
|
||||
func (f *fakeInformer) AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) {
|
||||
f.handler = handler
|
||||
return fakeInformerRegistration{}, nil
|
||||
}
|
||||
|
||||
func (f *fakeInformer) AddEventHandlerWithResyncPeriod(handler cache.ResourceEventHandler, _ time.Duration) (cache.ResourceEventHandlerRegistration, error) {
|
||||
return f.AddEventHandler(handler)
|
||||
}
|
||||
|
||||
func (f *fakeInformer) AddEventHandlerWithOptions(handler cache.ResourceEventHandler, _ cache.HandlerOptions) (cache.ResourceEventHandlerRegistration, error) {
|
||||
return f.AddEventHandler(handler)
|
||||
}
|
||||
|
||||
func (f *fakeInformer) RemoveEventHandler(_ cache.ResourceEventHandlerRegistration) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeInformer) AddIndexers(_ cache.Indexers) error { return nil }
|
||||
|
||||
func (f *fakeInformer) HasSynced() bool { return true }
|
||||
|
||||
func (f *fakeInformer) HasSyncedChecker() cache.DoneChecker {
|
||||
return fakeDoneChecker{name: "fakeInformer"}
|
||||
}
|
||||
|
||||
func (f *fakeInformer) IsStopped() bool { return false }
|
||||
|
||||
var _ ctrlcache.Informer = (*fakeInformer)(nil)
|
||||
|
||||
func TestIsHostPathVolume(t *testing.T) {
|
||||
// hostPath pod volume
|
||||
vol := &corev1api.Volume{
|
||||
@@ -557,27 +610,16 @@ func TestBackupPodVolumes(t *testing.T) {
|
||||
objList = append(objList, test.kubeClientObj...)
|
||||
fakeCtrlClient := fakeClientBuilder.WithRuntimeObjects(objList...).Build()
|
||||
|
||||
fakeCRWatchClient := velerotest.NewFakeControllerRuntimeWatchClient(t, test.kubeClientObj...)
|
||||
lw := kube.InternalLW{
|
||||
Client: fakeCRWatchClient,
|
||||
Namespace: velerov1api.DefaultNamespace,
|
||||
ObjectList: new(velerov1api.PodVolumeBackupList),
|
||||
}
|
||||
|
||||
pvbInformer := cache.NewSharedIndexInformer(&lw, &velerov1api.PodVolumeBackup{}, 0, cache.Indexers{})
|
||||
|
||||
go pvbInformer.Run(ctx.Done())
|
||||
require.True(t, cache.WaitForCacheSync(ctx.Done(), pvbInformer.HasSynced))
|
||||
// This test validates creation-time behavior only, so we don't need
|
||||
// informer sync/watch to be running.
|
||||
pvbInformer := cache.NewSharedIndexInformer(&cache.ListWatch{}, &velerov1api.PodVolumeBackup{}, 0, cache.Indexers{})
|
||||
|
||||
ensurer := repository.NewEnsurer(fakeCtrlClient, velerotest.NewLogger(), time.Millisecond)
|
||||
|
||||
backupObj := builder.ForBackup(velerov1api.DefaultNamespace, "fake-backup").Result()
|
||||
backupObj.Spec.StorageLocation = test.bsl
|
||||
|
||||
factory := NewBackupperFactory(repository.NewRepoLocker(), ensurer, fakeCtrlClient, pvbInformer, velerotest.NewLogger())
|
||||
bp, err := factory.NewBackupper(ctx, log, backupObj, test.uploaderType)
|
||||
|
||||
require.NoError(t, err)
|
||||
bp := newBackupper(ctx, log, repository.NewRepoLocker(), ensurer, pvbInformer, fakeCtrlClient, test.uploaderType, backupObj)
|
||||
|
||||
if test.mockGetRepositoryType {
|
||||
funcGetRepositoryType = func() string { return "" }
|
||||
@@ -587,9 +629,7 @@ func TestBackupPodVolumes(t *testing.T) {
|
||||
|
||||
pvbs, _, errs := bp.BackupPodVolumes(backupObj, test.sourcePod, test.volumes, nil, velerotest.NewLogger())
|
||||
|
||||
if test.errs == nil {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
if test.errs != nil {
|
||||
for i := 0; i < len(errs); i++ {
|
||||
require.EqualError(t, errs[i], test.errs[i])
|
||||
}
|
||||
@@ -760,17 +800,7 @@ func TestWaitAllPodVolumesProcessed(t *testing.T) {
|
||||
velerov1api.AddToScheme(scheme)
|
||||
client := ctrlfake.NewClientBuilder().WithScheme(scheme).WithObjects(objs...).Build()
|
||||
|
||||
lw := kube.InternalLW{
|
||||
Client: client,
|
||||
Namespace: velerov1api.DefaultNamespace,
|
||||
ObjectList: new(velerov1api.PodVolumeBackupList),
|
||||
}
|
||||
|
||||
informer := cache.NewSharedIndexInformer(&lw, &velerov1api.PodVolumeBackup{}, 0, cache.Indexers{})
|
||||
|
||||
ctx := t.Context()
|
||||
go informer.Run(ctx.Done())
|
||||
require.True(t, cache.WaitForCacheSync(ctx.Done(), informer.HasSynced))
|
||||
informer := &fakeInformer{}
|
||||
|
||||
logger := logrus.New()
|
||||
logHook := &logHook{}
|
||||
@@ -787,9 +817,13 @@ func TestWaitAllPodVolumesProcessed(t *testing.T) {
|
||||
err := client.Get(t.Context(), ctrlclient.ObjectKey{Namespace: c.pvb.Namespace, Name: c.pvb.Name}, pvb)
|
||||
require.NoError(t, err)
|
||||
|
||||
oldPVB := pvb.DeepCopy()
|
||||
pvb.Status = *c.statusToBeUpdated
|
||||
err = client.Update(t.Context(), pvb)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.NotNil(t, informer.handler)
|
||||
informer.handler.OnUpdate(oldPVB, pvb)
|
||||
}
|
||||
|
||||
pvbs := backuper.WaitAllPodVolumesProcessed(logger)
|
||||
|
||||
@@ -25,7 +25,6 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
appsv1api "k8s.io/api/apps/v1"
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -39,7 +38,6 @@ import (
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
"github.com/vmware-tanzu/velero/pkg/repository"
|
||||
velerotest "github.com/vmware-tanzu/velero/pkg/test"
|
||||
"github.com/vmware-tanzu/velero/pkg/util/kube"
|
||||
)
|
||||
|
||||
func TestGetVolumesRepositoryType(t *testing.T) {
|
||||
@@ -359,27 +357,14 @@ func TestRestorePodVolumes(t *testing.T) {
|
||||
fakeKubeClient := kubefake.NewSimpleClientset(test.kubeClientObj...)
|
||||
var kubeClient kubernetes.Interface = fakeKubeClient
|
||||
|
||||
fakeCRWatchClient := velerotest.NewFakeControllerRuntimeWatchClient(t, test.kubeClientObj...)
|
||||
lw := kube.InternalLW{
|
||||
Client: fakeCRWatchClient,
|
||||
Namespace: velerov1api.DefaultNamespace,
|
||||
ObjectList: new(velerov1api.PodVolumeRestoreList),
|
||||
}
|
||||
|
||||
pvrInformer := cache.NewSharedIndexInformer(&lw, &velerov1api.PodVolumeBackup{}, 0, cache.Indexers{})
|
||||
|
||||
go pvrInformer.Run(ctx.Done())
|
||||
require.True(t, cache.WaitForCacheSync(ctx.Done(), pvrInformer.HasSynced))
|
||||
// This test verifies restore behavior itself, not informer sync/watch.
|
||||
pvrInformer := cache.NewSharedIndexInformer(&cache.ListWatch{}, &velerov1api.PodVolumeRestore{}, 0, cache.Indexers{})
|
||||
|
||||
ensurer := repository.NewEnsurer(fakeCRClient, velerotest.NewLogger(), time.Millisecond)
|
||||
|
||||
restoreObj := builder.ForRestore(velerov1api.DefaultNamespace, "fake-restore").Result()
|
||||
|
||||
factory := NewRestorerFactory(repository.NewRepoLocker(), ensurer, kubeClient,
|
||||
fakeCRClient, pvrInformer, velerotest.NewLogger())
|
||||
rs, err := factory.NewRestorer(ctx, restoreObj)
|
||||
|
||||
require.NoError(t, err)
|
||||
rs := newRestorer(ctx, repository.NewRepoLocker(), ensurer, pvrInformer, kubeClient, fakeCRClient, restoreObj, velerotest.NewLogger())
|
||||
|
||||
go func() {
|
||||
if test.ctx != nil {
|
||||
@@ -388,7 +373,7 @@ func TestRestorePodVolumes(t *testing.T) {
|
||||
} else if test.retPVRs != nil {
|
||||
time.Sleep(time.Second)
|
||||
for _, pvr := range test.retPVRs {
|
||||
rs.(*restorer).results[resultsKey(test.restoredPod.Namespace, test.restoredPod.Name)] <- pvr
|
||||
rs.results[resultsKey(test.restoredPod.Namespace, test.restoredPod.Name)] <- pvr
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -19,6 +19,9 @@ package repository
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"testing"
|
||||
@@ -153,7 +156,7 @@ func TestGetBackupRepository(t *testing.T) {
|
||||
|
||||
if backupRepo != nil && tc.expected != nil {
|
||||
backupRepo.ResourceVersion = tc.expected.ResourceVersion
|
||||
require.Equal(t, *tc.expected, *backupRepo)
|
||||
require.Empty(t, cmp.Diff(*tc.expected, *backupRepo, cmpopts.IgnoreFields(velerov1api.BackupRepository{}, "TypeMeta")))
|
||||
} else {
|
||||
require.Equal(t, tc.expected, backupRepo)
|
||||
}
|
||||
|
||||
@@ -359,7 +359,7 @@ func TestCancel(t *testing.T) {
|
||||
err = pvcRIA.crClient.Get(t.Context(), crclient.ObjectKey{Namespace: tc.dataDownload.Namespace, Name: tc.dataDownload.Name}, resultDataDownload)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.True(t, cmp.Equal(tc.expectedDataDownload, *resultDataDownload, cmpopts.IgnoreFields(velerov2alpha1.DataDownload{}, "ResourceVersion", "Name")))
|
||||
require.Empty(t, cmp.Diff(tc.expectedDataDownload, *resultDataDownload, cmpopts.IgnoreFields(velerov2alpha1.DataDownload{}, "TypeMeta", "ResourceVersion", "Name")))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -523,7 +523,7 @@ func TestExecute(t *testing.T) {
|
||||
LabelSelector: labels.SelectorFromSet(tc.expectedDataDownload.Labels),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.True(t, cmp.Equal(tc.expectedDataDownload, &dataDownloadList.Items[0], cmpopts.IgnoreFields(velerov2alpha1.DataDownload{}, "ResourceVersion", "Name")))
|
||||
require.Empty(t, cmp.Diff(tc.expectedDataDownload, &dataDownloadList.Items[0], cmpopts.IgnoreFields(velerov2alpha1.DataDownload{}, "TypeMeta", "ResourceVersion", "Name")))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ func deleteHealthCheckNodePort(service *corev1api.Service) error {
|
||||
continue
|
||||
}
|
||||
fields := new(map[string]any)
|
||||
if err := json.Unmarshal(entry.FieldsV1.Raw, fields); err != nil {
|
||||
if err := json.Unmarshal(entry.FieldsV1.GetRawBytes(), fields); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ func deleteNodePorts(service *corev1api.Service) error {
|
||||
continue
|
||||
}
|
||||
fields := new(map[string]any)
|
||||
if err := json.Unmarshal(entry.FieldsV1.Raw, fields); err != nil {
|
||||
if err := json.Unmarshal(entry.FieldsV1.GetRawBytes(), fields); err != nil {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ func AssertDeepEqual(t *testing.T, expected, actual any) bool {
|
||||
}
|
||||
|
||||
if !equality.Semantic.DeepEqual(expected, actual) {
|
||||
s := diff.ObjectDiff(expected, actual)
|
||||
s := diff.Diff(expected, actual)
|
||||
return assert.Fail(t, fmt.Sprintf("Objects not equal:\n\n%s", s))
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright The Velero Contributors.
|
||||
|
||||
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 cbt
|
||||
|
||||
import "github.com/vmware-tanzu/velero/pkg/cbtservice"
|
||||
|
||||
// Bitmap defines the methods to store and iterate the CBT bitmap
|
||||
type Bitmap interface {
|
||||
// Set sets bits within the provided range
|
||||
Set(cbtservice.Range)
|
||||
|
||||
// SetFull sets all bits to the bitmap
|
||||
SetFull()
|
||||
|
||||
// Snapshot returns snapshot of the bitmap
|
||||
SourceID() string
|
||||
|
||||
// ChangeID returns the changeID of the bitmap
|
||||
ChangeID() string
|
||||
|
||||
// Iterator returns the iterator for the CBT Bitmap
|
||||
Iterator() Iterator
|
||||
}
|
||||
|
||||
// Iterator defines the methods to iterate the CBT bitmap and query the associated information
|
||||
type Iterator interface {
|
||||
// ChangeID returns the changeID of the bitmap
|
||||
ChangeID() string
|
||||
|
||||
// Snapshot returns snapshot of the bitmap
|
||||
Snapshot() string
|
||||
|
||||
// BlockSize returns the granularity of the bitmap
|
||||
BlockSize() int
|
||||
|
||||
// Count returns the toal number of count in the bitmap
|
||||
Count() uint64
|
||||
|
||||
// Next returns the offset of the next set block and whether it comes to the end of the iteration
|
||||
Next() (int64, bool)
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright The Velero Contributors.
|
||||
|
||||
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 cbt
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/cbtservice"
|
||||
)
|
||||
|
||||
// SetBitmapOrFull translates the allocated/changed blocks from CBT service to the given bitmap or set the bitmap to full when error happens
|
||||
func SetBitmapOrFull(ctx context.Context, service cbtservice.Service, bitmap Bitmap) error {
|
||||
var err error
|
||||
if bitmap.ChangeID() == "" {
|
||||
err = setFromAllocatedBlocks(ctx, service, bitmap)
|
||||
} else {
|
||||
err = setFromChangedBlocks(ctx, service, bitmap)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
bitmap.SetFull()
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO implement in following PRs
|
||||
func setFromAllocatedBlocks(_ context.Context, _ cbtservice.Service, _ Bitmap) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO implement in following PRs
|
||||
func setFromChangedBlocks(_ context.Context, _ cbtservice.Service, _ Bitmap) error {
|
||||
return nil
|
||||
}
|
||||
@@ -173,7 +173,6 @@ func (nie *NamespaceIncludesExcludes) ExpandIncludesExcludes() error {
|
||||
}
|
||||
|
||||
// ResolveNamespaceList returns a list of all namespaces which will be backed up.
|
||||
// The second return value indicates whether wildcard expansion was performed.
|
||||
func (nie *NamespaceIncludesExcludes) ResolveNamespaceList() ([]string, error) {
|
||||
// Check if this is being called by non-backup processing e.g. backup queue controller
|
||||
if !nie.wildcardExpanded {
|
||||
|
||||
@@ -2004,7 +2004,7 @@ func TestGetVSCForVS(t *testing.T) {
|
||||
}
|
||||
|
||||
if tc.expectedVSC != nil {
|
||||
require.True(t, cmp.Equal(tc.expectedVSC, vsc, cmpopts.IgnoreFields(snapshotv1api.VolumeSnapshotContent{}, "ResourceVersion")))
|
||||
require.Empty(t, cmp.Diff(tc.expectedVSC, vsc, cmpopts.IgnoreFields(snapshotv1api.VolumeSnapshotContent{}, "TypeMeta", "ResourceVersion")))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Code generated by mockery v2.42.1. DO NOT EDIT.
|
||||
// Code generated by mockery v2.53.5. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
@@ -7,14 +7,10 @@ import (
|
||||
|
||||
client "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
meta "k8s.io/apimachinery/pkg/api/meta"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
meta "k8s.io/apimachinery/pkg/api/meta"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
@@ -23,6 +19,31 @@ type Client struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Apply provides a mock function with given fields: ctx, obj, opts
|
||||
func (_m *Client) Apply(ctx context.Context, obj runtime.ApplyConfiguration, opts ...client.ApplyOption) error {
|
||||
_va := make([]interface{}, len(opts))
|
||||
for _i := range opts {
|
||||
_va[_i] = opts[_i]
|
||||
}
|
||||
var _ca []interface{}
|
||||
_ca = append(_ca, ctx, obj)
|
||||
_ca = append(_ca, _va...)
|
||||
ret := _m.Called(_ca...)
|
||||
|
||||
if len(ret) == 0 {
|
||||
panic("no return value specified for Apply")
|
||||
}
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(context.Context, runtime.ApplyConfiguration, ...client.ApplyOption) error); ok {
|
||||
r0 = rf(ctx, obj, opts...)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Create provides a mock function with given fields: ctx, obj, opts
|
||||
func (_m *Client) Create(ctx context.Context, obj client.Object, opts ...client.CreateOption) error {
|
||||
_va := make([]interface{}, len(opts))
|
||||
@@ -229,7 +250,7 @@ func (_m *Client) Patch(ctx context.Context, obj client.Object, patch client.Pat
|
||||
return r0
|
||||
}
|
||||
|
||||
// RESTMapper provides a mock function with given fields:
|
||||
// RESTMapper provides a mock function with no fields
|
||||
func (_m *Client) RESTMapper() meta.RESTMapper {
|
||||
ret := _m.Called()
|
||||
|
||||
@@ -249,7 +270,7 @@ func (_m *Client) RESTMapper() meta.RESTMapper {
|
||||
return r0
|
||||
}
|
||||
|
||||
// Scheme provides a mock function with given fields:
|
||||
// Scheme provides a mock function with no fields
|
||||
func (_m *Client) Scheme() *runtime.Scheme {
|
||||
ret := _m.Called()
|
||||
|
||||
@@ -269,7 +290,7 @@ func (_m *Client) Scheme() *runtime.Scheme {
|
||||
return r0
|
||||
}
|
||||
|
||||
// Status provides a mock function with given fields:
|
||||
// Status provides a mock function with no fields
|
||||
func (_m *Client) Status() client.SubResourceWriter {
|
||||
ret := _m.Called()
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package kube
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -24,9 +25,7 @@ import (
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
crclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -91,8 +90,6 @@ func TestPredicate(t *testing.T) {
|
||||
},
|
||||
)
|
||||
|
||||
require.NoError(t, source.Start(ctx, queue))
|
||||
|
||||
// Should not patch a backup storage location object status phase
|
||||
// if the location's validation frequency is specifically set to zero
|
||||
require.NoError(t, client.Create(ctx, &velerov1.BackupStorageLocation{
|
||||
@@ -107,6 +104,8 @@ func TestPredicate(t *testing.T) {
|
||||
LastValidationTime: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
}))
|
||||
|
||||
require.NoError(t, source.Start(ctx, queue))
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
require.Equal(t, 0, queue.Len())
|
||||
@@ -127,24 +126,20 @@ func TestOrder(t *testing.T) {
|
||||
1*time.Second,
|
||||
PeriodicalEnqueueSourceOption{
|
||||
OrderFunc: func(objList crclient.ObjectList) crclient.ObjectList {
|
||||
locationList := &velerov1.BackupStorageLocationList{}
|
||||
objArray := make([]runtime.Object, 0)
|
||||
locationList, ok := objList.(*velerov1.BackupStorageLocationList)
|
||||
if !ok {
|
||||
return objList
|
||||
}
|
||||
|
||||
// Generate BSL array.
|
||||
locations, _ := meta.ExtractList(objList)
|
||||
// Move default BSL to tail of array.
|
||||
objArray = append(objArray, locations[1])
|
||||
objArray = append(objArray, locations[0])
|
||||
|
||||
meta.SetList(locationList, objArray)
|
||||
sort.SliceStable(locationList.Items, func(i, j int) bool {
|
||||
return locationList.Items[i].Spec.Default && !locationList.Items[j].Spec.Default
|
||||
})
|
||||
|
||||
return locationList
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
require.NoError(t, source.Start(ctx, queue))
|
||||
|
||||
// Should not patch a backup storage location object status phase
|
||||
// if the location's validation frequency is specifically set to zero
|
||||
require.NoError(t, client.Create(ctx, &velerov1.BackupStorageLocation{
|
||||
@@ -172,6 +167,8 @@ func TestOrder(t *testing.T) {
|
||||
LastValidationTime: &metav1.Time{Time: time.Now()},
|
||||
},
|
||||
}))
|
||||
|
||||
require.NoError(t, source.Start(ctx, queue))
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
first, _ := queue.Get()
|
||||
|
||||
@@ -9,6 +9,11 @@ import (
|
||||
)
|
||||
|
||||
func ShouldExpandWildcards(includes []string, excludes []string) bool {
|
||||
// Empty includes is equivalent to * (match all) - don't expand
|
||||
if len(includes) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
wildcardFound := false
|
||||
for _, include := range includes {
|
||||
// Special case: "*" alone means "match all" - don't expand
|
||||
|
||||
@@ -68,6 +68,12 @@ func TestShouldExpandWildcards(t *testing.T) {
|
||||
excludes: []string{},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "empty includes with wildcard excludes - should not expand",
|
||||
includes: []string{},
|
||||
excludes: []string{"ns*"},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "complex wildcard patterns",
|
||||
includes: []string{"*-prod"},
|
||||
|
||||
@@ -5,6 +5,8 @@ layout: docs
|
||||
|
||||
When using `--include-namespaces` and `--exclude-namespaces` flags with backup and restore commands, you can use glob patterns to match multiple namespaces.
|
||||
|
||||
Note: If the resolution of namespace patterns results in no namespaces, the backup will succeed with a warning.
|
||||
|
||||
## Supported Patterns
|
||||
|
||||
Velero supports the following glob pattern characters:
|
||||
|
||||
@@ -685,6 +685,12 @@ var _ = Describe(
|
||||
LoadAffinities,
|
||||
)
|
||||
|
||||
var _ = Describe(
|
||||
"Test data mover dynamic Cache PVC injection",
|
||||
Label("NodeAgentConfig", "CachePVC"),
|
||||
CachePVCTest,
|
||||
)
|
||||
|
||||
func GetKubeConfigContext() error {
|
||||
var err error
|
||||
var tcDefault, tcStandby k8s.TestClient
|
||||
|
||||
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
Copyright the Velero contributors.
|
||||
|
||||
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 nodeagentconfig
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/pkg/errors"
|
||||
corev1api "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
velerov1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v1"
|
||||
velerov2alpha1api "github.com/vmware-tanzu/velero/pkg/apis/velero/v2alpha1"
|
||||
"github.com/vmware-tanzu/velero/pkg/builder"
|
||||
"github.com/vmware-tanzu/velero/test"
|
||||
. "github.com/vmware-tanzu/velero/test/e2e/test"
|
||||
k8sutil "github.com/vmware-tanzu/velero/test/util/k8s"
|
||||
veleroutil "github.com/vmware-tanzu/velero/test/util/velero"
|
||||
)
|
||||
|
||||
type CachePVCTestCase struct {
|
||||
TestCase
|
||||
nodeAgentConfigMapName string
|
||||
repoConfigMapName string
|
||||
}
|
||||
|
||||
var CachePVCTest func() = TestFunc(&CachePVCTestCase{
|
||||
nodeAgentConfigMapName: "node-agent-config-cache",
|
||||
repoConfigMapName: "backup-repo-config-cache",
|
||||
})
|
||||
|
||||
func (c *CachePVCTestCase) Init() error {
|
||||
c.TestCase.Init()
|
||||
c.CaseBaseName = "cache-pvc-" + c.UUIDgen
|
||||
c.BackupName = "backup-" + c.CaseBaseName
|
||||
c.RestoreName = "restore-" + c.CaseBaseName
|
||||
c.NamespacesTotal = 1
|
||||
c.NSIncluded = &[]string{}
|
||||
for nsNum := 0; nsNum < c.NamespacesTotal; nsNum++ {
|
||||
createNSName := fmt.Sprintf("%s-%00000d", c.CaseBaseName, nsNum)
|
||||
*c.NSIncluded = append(*c.NSIncluded, createNSName)
|
||||
}
|
||||
|
||||
c.VeleroCfg.UseNodeAgent = true
|
||||
c.VeleroCfg.UseNodeAgentWindows = true
|
||||
|
||||
// Ensure Data Mover is used to trigger DataUpload/DataDownload pods
|
||||
c.BackupArgs = []string{
|
||||
"create", "--namespace", c.VeleroCfg.VeleroNamespace, "backup", c.BackupName,
|
||||
"--include-namespaces", strings.Join(*c.NSIncluded, ","),
|
||||
"--snapshot-volumes=true", "--snapshot-move-data",
|
||||
}
|
||||
|
||||
c.RestoreArgs = []string{
|
||||
"create", "--namespace", c.VeleroCfg.VeleroNamespace, "restore", c.RestoreName,
|
||||
"--from-backup", c.BackupName,
|
||||
}
|
||||
|
||||
c.TestMsg = &TestMSG{
|
||||
Desc: "Validate dynamically provisioned Cache PVC for data mover pods",
|
||||
FailedMSG: "Failed to apply and validate cache PVC configuration in data mover pods.",
|
||||
Text: "Should dynamically provision a Cache PVC for data mover restore pods to avoid node root FS exhaustion.",
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CachePVCTestCase) InstallVelero() error {
|
||||
fmt.Println("Start to uninstall Velero")
|
||||
if err := veleroutil.VeleroUninstall(c.Ctx, c.VeleroCfg); err != nil {
|
||||
fmt.Printf("Fail to uninstall Velero: %s\n", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
// 1. Construct node-agent ConfigMap (Define Cache PVC StorageClass and trigger threshold)
|
||||
// Set residentThresholdInMB to 0 to force Velero to create a PVC even for tiny E2E test data.
|
||||
nodeAgentConfigJSON := fmt.Sprintf(`{"cachePVC": {"residentThresholdInMB": 0, "storageClass": "%s"}}`, test.StorageClassName)
|
||||
nodeAgentConfig := builder.ForConfigMap(c.VeleroCfg.VeleroNamespace, c.nodeAgentConfigMapName).
|
||||
Data("node-agent-config", nodeAgentConfigJSON).Result()
|
||||
|
||||
// 2. Construct backup repository ConfigMap (Define cacheLimitMB)
|
||||
repoConfigJSON := `{"cacheLimitMB": 2048}` // Set 2GB cache limit
|
||||
repoConfig := builder.ForConfigMap(c.VeleroCfg.VeleroNamespace, c.repoConfigMapName).
|
||||
Data(test.UploaderTypeKopia, repoConfigJSON).Result()
|
||||
|
||||
c.VeleroCfg.NodeAgentConfigMap = c.nodeAgentConfigMapName
|
||||
c.VeleroCfg.BackupRepoConfigMap = c.repoConfigMapName
|
||||
|
||||
// Deploy Velero with the two Cache configuration ConfigMaps
|
||||
return veleroutil.PrepareVelero(c.Ctx, c.CaseBaseName, c.VeleroCfg, nodeAgentConfig, repoConfig)
|
||||
}
|
||||
|
||||
func (c *CachePVCTestCase) CreateResources() error {
|
||||
for _, ns := range *c.NSIncluded {
|
||||
if err := k8sutil.CreateNamespace(c.Ctx, c.Client, ns); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pvc, err := k8sutil.CreatePVC(c.Client, ns, "volume-1", test.StorageClassName, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
vols := k8sutil.CreateVolumes(pvc.Name, []string{"volume-1"})
|
||||
|
||||
deployment := k8sutil.NewDeployment(
|
||||
c.CaseBaseName,
|
||||
ns,
|
||||
1,
|
||||
map[string]string{"app": "test"},
|
||||
c.VeleroCfg.ImageRegistryProxy,
|
||||
c.VeleroCfg.WorkerOS,
|
||||
).WithVolume(vols).Result()
|
||||
|
||||
deployment, err = k8sutil.CreateDeployment(c.Client.ClientGo, ns, deployment)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create deployment")
|
||||
}
|
||||
|
||||
if err := k8sutil.WaitForReadyDeployment(c.Client.ClientGo, deployment.Namespace, deployment.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// verifyCacheVolumeInPod correctly verifies that the Pod mounted a dynamic PVC instead of an emptyDir
|
||||
func (c *CachePVCTestCase) verifyCacheVolumeInPod(pod corev1api.Pod) error {
|
||||
for _, vol := range pod.Spec.Volumes {
|
||||
if vol.PersistentVolumeClaim != nil {
|
||||
// Velero dynamically provisioned cache volumes typically have 'cache' in the name
|
||||
if strings.Contains(vol.PersistentVolumeClaim.ClaimName, "cache") || strings.Contains(vol.Name, "cache") {
|
||||
return nil // Success: Found the dynamically provisioned Cache PVC
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("Dynamically provisioned Cache PVC not found in pod %s, feature failed!", pod.Name)
|
||||
}
|
||||
|
||||
func (c *CachePVCTestCase) Backup() error {
|
||||
if err := veleroutil.VeleroCmdExec(c.Ctx, c.VeleroCfg.VeleroCLI, c.BackupArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Waiting for backup to complete...")
|
||||
|
||||
// Wait for backup completion
|
||||
wait.PollUntilContextTimeout(c.Ctx, 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) {
|
||||
backup := new(velerov1api.Backup)
|
||||
if err := c.VeleroCfg.ClientToInstallVelero.Kubebuilder.Get(
|
||||
c.Ctx,
|
||||
client.ObjectKey{Namespace: c.VeleroCfg.VeleroNamespace, Name: c.BackupName},
|
||||
backup,
|
||||
); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if backup.Status.Phase != velerov1api.BackupPhaseCompleted &&
|
||||
backup.Status.Phase != velerov1api.BackupPhaseFailed &&
|
||||
backup.Status.Phase != velerov1api.BackupPhasePartiallyFailed {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *CachePVCTestCase) Restore() error {
|
||||
if err := veleroutil.VeleroCmdExec(c.Ctx, c.VeleroCfg.VeleroCLI, c.RestoreArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
restorePodList := new(corev1api.PodList)
|
||||
|
||||
wait.PollUntilContextTimeout(c.Ctx, 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) {
|
||||
ddList := new(velerov2alpha1api.DataDownloadList)
|
||||
if err := c.VeleroCfg.ClientToInstallVelero.Kubebuilder.List(
|
||||
c.Ctx,
|
||||
ddList,
|
||||
&client.ListOptions{Namespace: c.VeleroCfg.VeleroNamespace},
|
||||
); err != nil {
|
||||
return false, err
|
||||
} else if len(ddList.Items) <= 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if err := c.VeleroCfg.ClientToInstallVelero.Kubebuilder.List(
|
||||
c.Ctx,
|
||||
restorePodList,
|
||||
&client.ListOptions{
|
||||
LabelSelector: labels.SelectorFromSet(map[string]string{
|
||||
velerov1api.DataDownloadLabel: ddList.Items[0].Name,
|
||||
}),
|
||||
}); err != nil {
|
||||
return false, err
|
||||
} else if len(restorePodList.Items) <= 0 {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
})
|
||||
|
||||
fmt.Println("Start to verify restore data mover pod content.")
|
||||
Expect(restorePodList.Items).ToNot(BeEmpty())
|
||||
|
||||
// Ensure the Data Mover pod is using a true PVC for caching
|
||||
err := c.verifyCacheVolumeInPod(restorePodList.Items[0])
|
||||
Expect(err).To(Succeed(), "Injected Cache PVC should exist in DataDownload Pod")
|
||||
fmt.Println("Restore data mover pod content verification completed successfully.")
|
||||
|
||||
// Wait for restore completion
|
||||
wait.PollUntilContextTimeout(c.Ctx, 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) {
|
||||
restore := new(velerov1api.Restore)
|
||||
if err := c.VeleroCfg.ClientToInstallVelero.Kubebuilder.Get(
|
||||
c.Ctx,
|
||||
client.ObjectKey{Namespace: c.VeleroCfg.VeleroNamespace, Name: c.RestoreName},
|
||||
restore,
|
||||
); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
if restore.Status.Phase != velerov1api.RestorePhaseCompleted &&
|
||||
restore.Status.Phase != velerov1api.RestorePhaseFailed &&
|
||||
restore.Status.Phase != velerov1api.RestorePhasePartiallyFailed {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -77,6 +77,14 @@ var LoadAffinities func() = TestFunc(&NodeAgentConfigTestCase{
|
||||
IgnoreDelayBinding: true,
|
||||
},
|
||||
PriorityClassName: test.PriorityClassNameForDataMover,
|
||||
// Explicitly add custom labels and annotations to be tested
|
||||
PodLabels: map[string]string{
|
||||
"spectrocloud.com/connection": "proxy", // Tests appending custom labels (Issue #9435)
|
||||
"azure.workload.identity/use": "true", // Tests overwriting built-in labels
|
||||
},
|
||||
PodAnnotations: map[string]string{
|
||||
"test-data-mover-annotation": "true",
|
||||
},
|
||||
},
|
||||
nodeAgentConfigMapName: "node-agent-config",
|
||||
})
|
||||
@@ -247,6 +255,16 @@ func (n *NodeAgentConfigTestCase) Backup() error {
|
||||
// but we can verify if the expected affinity is contained in the pod affinity.
|
||||
Expect(backupPodList.Items[0].Spec.Affinity.String()).To(ContainSubstring(expectedLabelKey))
|
||||
|
||||
// Verify PodLabels
|
||||
for k, v := range n.nodeAgentConfigs.PodLabels {
|
||||
Expect(backupPodList.Items[0].Labels[k]).To(Equal(v))
|
||||
}
|
||||
|
||||
// Verify PodAnnotations
|
||||
for k, v := range n.nodeAgentConfigs.PodAnnotations {
|
||||
Expect(backupPodList.Items[0].Annotations[k]).To(Equal(v))
|
||||
}
|
||||
|
||||
fmt.Println("backupPod content verification completed successfully.")
|
||||
|
||||
wait.PollUntilContextTimeout(n.Ctx, 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) {
|
||||
@@ -328,6 +346,16 @@ func (n *NodeAgentConfigTestCase) Restore() error {
|
||||
// but we can verify if the expected affinity is contained in the pod affinity.
|
||||
Expect(restorePodList.Items[0].Spec.Affinity.String()).To(ContainSubstring(expectedLabelKey))
|
||||
|
||||
// Verify PodLabels
|
||||
for k, v := range n.nodeAgentConfigs.PodLabels {
|
||||
Expect(restorePodList.Items[0].Labels[k]).To(Equal(v))
|
||||
}
|
||||
|
||||
// Verify PodAnnotations
|
||||
for k, v := range n.nodeAgentConfigs.PodAnnotations {
|
||||
Expect(restorePodList.Items[0].Annotations[k]).To(Equal(v))
|
||||
}
|
||||
|
||||
fmt.Println("restorePod content verification completed successfully.")
|
||||
|
||||
wait.PollUntilContextTimeout(n.Ctx, 5*time.Second, 5*time.Minute, true, func(ctx context.Context) (bool, error) {
|
||||
|
||||
Reference in New Issue
Block a user