mirror of
https://github.com/cloudnative-pg/plugin-barman-cloud.git
synced 2026-07-09 11:12:21 +02:00
Compare commits
16 Commits
40c7be34e9
...
a8761e9949
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8761e9949 | ||
|
|
58f4fed40b | ||
|
|
6cf473d5e8 | ||
|
|
d6eee8deb8 | ||
|
|
5702a48881 | ||
|
|
e19063d345 | ||
|
|
a5717b1658 | ||
|
|
6fdecfde21 | ||
|
|
7154a3caca | ||
|
|
dd541aae44 | ||
|
|
28350ae87b | ||
|
|
4bbaf18cd3 | ||
|
|
a81f6e3d73 | ||
|
|
313b5cc202 | ||
|
|
81efbc50ff | ||
|
|
9383cf828b |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@ -44,7 +44,7 @@ jobs:
|
||||
- name: Install Dagger
|
||||
env:
|
||||
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
||||
DAGGER_VERSION: 0.20.6
|
||||
DAGGER_VERSION: 0.20.7
|
||||
run: |
|
||||
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
|
||||
- name: Run CI task
|
||||
|
||||
2
.github/workflows/release-please.yml
vendored
2
.github/workflows/release-please.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
||||
- name: Install Dagger
|
||||
env:
|
||||
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
||||
DAGGER_VERSION: 0.20.6
|
||||
DAGGER_VERSION: 0.20.7
|
||||
run: |
|
||||
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
|
||||
- name: Create image and manifest
|
||||
|
||||
2
.github/workflows/release-publish.yml
vendored
2
.github/workflows/release-publish.yml
vendored
@ -21,7 +21,7 @@ jobs:
|
||||
- name: Install Dagger
|
||||
env:
|
||||
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
||||
DAGGER_VERSION: 0.20.6
|
||||
DAGGER_VERSION: 0.20.7
|
||||
run: |
|
||||
curl -L https://dl.dagger.io/dagger/install.sh | BIN_DIR=$HOME/.local/bin sh
|
||||
- name: Create image and manifest
|
||||
|
||||
@ -16,7 +16,7 @@ linters:
|
||||
- gocyclo
|
||||
- goheader
|
||||
- gomoddirectives
|
||||
- gomodguard
|
||||
- gomodguard_v2
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- govet
|
||||
|
||||
22
Taskfile.yml
22
Taskfile.yml
@ -21,9 +21,9 @@ tasks:
|
||||
desc: Run golangci-lint
|
||||
env:
|
||||
# renovate: datasource=git-refs depName=golangci-lint lookupName=https://github.com/sagikazarmark/daggerverse currentValue=main
|
||||
DAGGER_GOLANGCI_LINT_SHA: 5dcc7e4c4cd5ed230046955f42e27f2166545155
|
||||
DAGGER_GOLANGCI_LINT_SHA: 5f2dc1bd1014cf79757f4605f2f731ed962d4da7
|
||||
# renovate: datasource=docker depName=golangci/golangci-lint versioning=semver
|
||||
GOLANGCI_LINT_VERSION: v2.11.4
|
||||
GOLANGCI_LINT_VERSION: v2.12.1
|
||||
cmds:
|
||||
- >
|
||||
GITHUB_REF= dagger -sc "github.com/sagikazarmark/daggerverse/golangci-lint@${DAGGER_GOLANGCI_LINT_SHA}
|
||||
@ -46,7 +46,7 @@ tasks:
|
||||
- wordlist-ordered
|
||||
env:
|
||||
# renovate: datasource=git-refs depName=spellcheck lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
|
||||
DAGGER_SPELLCHECK_SHA: f84ac0c681fcfff4d6f138bf53d44d023f615b48
|
||||
DAGGER_SPELLCHECK_SHA: 4489fed0c41e439bce805b17410d3c47c0923ff4
|
||||
cmds:
|
||||
- >
|
||||
GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/spellcheck@${DAGGER_SPELLCHECK_SHA}
|
||||
@ -60,7 +60,7 @@ tasks:
|
||||
desc: Check for conventional commits
|
||||
env:
|
||||
# renovate: datasource=git-refs depName=commitlint lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
|
||||
DAGGER_COMMITLINT_SHA: f84ac0c681fcfff4d6f138bf53d44d023f615b48
|
||||
DAGGER_COMMITLINT_SHA: 4489fed0c41e439bce805b17410d3c47c0923ff4
|
||||
cmds:
|
||||
- >
|
||||
GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/commitlint@${DAGGER_COMMITLINT_SHA}
|
||||
@ -74,7 +74,7 @@ tasks:
|
||||
- wordlist-ordered
|
||||
env:
|
||||
# renovate: datasource=git-refs depName=uncommitted lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
|
||||
DAGGER_UNCOMMITTED_SHA: f84ac0c681fcfff4d6f138bf53d44d023f615b48
|
||||
DAGGER_UNCOMMITTED_SHA: 4489fed0c41e439bce805b17410d3c47c0923ff4
|
||||
cmds:
|
||||
- GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/uncommitted@${DAGGER_UNCOMMITTED_SHA} check-uncommitted --source . stdout
|
||||
sources:
|
||||
@ -86,7 +86,7 @@ tasks:
|
||||
- controller-gen
|
||||
env:
|
||||
# renovate: datasource=git-refs depName=crd-gen-refs lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
|
||||
DAGGER_CRDGENREF_SHA: f84ac0c681fcfff4d6f138bf53d44d023f615b48
|
||||
DAGGER_CRDGENREF_SHA: 4489fed0c41e439bce805b17410d3c47c0923ff4
|
||||
# renovate: datasource=go depName=github.com/elastic/crd-ref-docs
|
||||
CRDREFDOCS_VERSION: v0.3.0
|
||||
cmds:
|
||||
@ -133,7 +133,7 @@ tasks:
|
||||
# renovate: datasource=git-refs depname=kubernetes packageName=https://github.com/kubernetes/kubernetes versioning=semver
|
||||
K8S_VERSION: 1.31.0
|
||||
# renovate: datasource=git-refs depName=controller-runtime packageName=https://github.com/kubernetes-sigs/controller-runtime versioning=semver
|
||||
SETUP_ENVTEST_VERSION: 0.23.3
|
||||
SETUP_ENVTEST_VERSION: 0.24.0
|
||||
cmds:
|
||||
- >
|
||||
GITHUB_REF= dagger -s call -m ./dagger/gotest
|
||||
@ -206,7 +206,7 @@ tasks:
|
||||
- start-build-network
|
||||
vars:
|
||||
# renovate: datasource=github-tags depName=dagger/dagger versioning=semver
|
||||
DAGGER_VERSION: 0.20.6
|
||||
DAGGER_VERSION: 0.20.7
|
||||
DAGGER_ENGINE_IMAGE: registry.dagger.io/engine:v{{ .DAGGER_VERSION }}
|
||||
cmds:
|
||||
- >
|
||||
@ -381,7 +381,7 @@ tasks:
|
||||
run: once
|
||||
env:
|
||||
# renovate: datasource=git-refs depName=controller-gen lookupName=https://github.com/cloudnative-pg/daggerverse currentValue=main
|
||||
DAGGER_CONTROLLER_GEN_SHA: f84ac0c681fcfff4d6f138bf53d44d023f615b48
|
||||
DAGGER_CONTROLLER_GEN_SHA: 4489fed0c41e439bce805b17410d3c47c0923ff4
|
||||
cmds:
|
||||
- >
|
||||
GITHUB_REF= dagger -s call -m github.com/cloudnative-pg/daggerverse/controller-gen@${DAGGER_CONTROLLER_GEN_SHA}
|
||||
@ -453,7 +453,7 @@ tasks:
|
||||
IMAGE_VERSION: '{{regexReplaceAll "(\\d+)/merge" .GITHUB_REF_NAME "pr-${1}"}}'
|
||||
env:
|
||||
# renovate: datasource=git-refs depName=kustomize lookupName=https://github.com/sagikazarmark/daggerverse currentValue=main
|
||||
DAGGER_KUSTOMIZE_SHA: 5dcc7e4c4cd5ed230046955f42e27f2166545155
|
||||
DAGGER_KUSTOMIZE_SHA: 5f2dc1bd1014cf79757f4605f2f731ed962d4da7
|
||||
cmds:
|
||||
- >
|
||||
dagger -s call -m https://github.com/sagikazarmark/daggerverse/kustomize@${DAGGER_KUSTOMIZE_SHA}
|
||||
@ -483,7 +483,7 @@ tasks:
|
||||
- GITHUB_TOKEN
|
||||
env:
|
||||
# renovate: datasource=git-refs depName=gh lookupName=https://github.com/sagikazarmark/daggerverse
|
||||
DAGGER_GH_SHA: 5dcc7e4c4cd5ed230046955f42e27f2166545155
|
||||
DAGGER_GH_SHA: 5f2dc1bd1014cf79757f4605f2f731ed962d4da7
|
||||
preconditions:
|
||||
- sh: "[[ {{.GITHUB_REF}} =~ 'refs/tags/v.*' ]]"
|
||||
msg: not a tag, failing
|
||||
|
||||
@ -20,17 +20,19 @@ SPDX-License-Identifier: Apache-2.0
|
||||
package v1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects.
|
||||
GroupVersion = schema.GroupVersion{Group: "barmancloud.cnpg.io", Version: "v1"}
|
||||
var GroupVersion = schema.GroupVersion{Group: "barmancloud.cnpg.io", Version: "v1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme.
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
// AddKnownTypes add to the passed schema the Kubernetes types
|
||||
// exposed by this package.
|
||||
func AddKnownTypes(scheme *runtime.Scheme) {
|
||||
scheme.AddKnownTypes(GroupVersion,
|
||||
&ObjectStore{}, &ObjectStoreList{})
|
||||
|
||||
// AddToScheme adds the types in this group-version to the given scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, GroupVersion)
|
||||
}
|
||||
|
||||
@ -124,7 +124,3 @@ type ObjectStoreList struct {
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ObjectStore `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&ObjectStore{}, &ObjectStoreList{})
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ package v1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
|
||||
61
go.mod
61
go.mod
@ -1,6 +1,6 @@
|
||||
module github.com/cloudnative-pg/plugin-barman-cloud
|
||||
|
||||
go 1.25.0
|
||||
go 1.26.0
|
||||
|
||||
toolchain go1.26.2
|
||||
|
||||
@ -12,18 +12,18 @@ require (
|
||||
github.com/cloudnative-pg/cnpg-i v0.5.0
|
||||
github.com/cloudnative-pg/cnpg-i-machinery v0.4.2
|
||||
github.com/cloudnative-pg/machinery v0.4.0
|
||||
github.com/onsi/ginkgo/v2 v2.28.2
|
||||
github.com/onsi/gomega v1.39.1
|
||||
github.com/onsi/ginkgo/v2 v2.28.3
|
||||
github.com/onsi/gomega v1.40.0
|
||||
github.com/spf13/cobra v1.10.2
|
||||
github.com/spf13/viper v1.21.0
|
||||
google.golang.org/grpc v1.80.0
|
||||
google.golang.org/grpc v1.81.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.35.4
|
||||
k8s.io/apiextensions-apiserver v0.35.4
|
||||
k8s.io/apimachinery v0.35.4
|
||||
k8s.io/client-go v0.35.4
|
||||
k8s.io/api v0.36.0
|
||||
k8s.io/apiextensions-apiserver v0.36.0
|
||||
k8s.io/apimachinery v0.36.0
|
||||
k8s.io/client-go v0.36.0
|
||||
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5
|
||||
sigs.k8s.io/controller-runtime v0.23.3
|
||||
sigs.k8s.io/controller-runtime v0.24.0
|
||||
sigs.k8s.io/kustomize/api v0.21.1
|
||||
sigs.k8s.io/kustomize/kyaml v0.21.1
|
||||
)
|
||||
@ -63,15 +63,14 @@ require (
|
||||
github.com/go-openapi/swag/yamlutils v0.25.4 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/cel-go v0.26.0 // indirect
|
||||
github.com/google/gnostic-models v0.7.1 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 // indirect
|
||||
github.com/google/pprof v0.0.0-20260402051712-545e8a4df936 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.4.0 // indirect
|
||||
@ -81,13 +80,12 @@ require (
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.87.1 // indirect
|
||||
github.com/prometheus/client_golang v1.23.2 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.67.4 // indirect
|
||||
github.com/prometheus/common v0.67.5 // indirect
|
||||
github.com/prometheus/procfs v0.19.2 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/snorwin/jsonpatch v1.5.0 // indirect
|
||||
@ -101,39 +99,40 @@ require (
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/xlab/treeprint v1.2.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 // indirect
|
||||
go.opentelemetry.io/otel v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.43.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.1 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect
|
||||
golang.org/x/mod v0.33.0 // indirect
|
||||
golang.org/x/net v0.52.0 // indirect
|
||||
golang.org/x/oauth2 v0.35.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
|
||||
golang.org/x/mod v0.35.0 // indirect
|
||||
golang.org/x/net v0.53.0 // indirect
|
||||
golang.org/x/oauth2 v0.36.0 // indirect
|
||||
golang.org/x/sync v0.20.0 // indirect
|
||||
golang.org/x/sys v0.43.0 // indirect
|
||||
golang.org/x/term v0.41.0 // indirect
|
||||
golang.org/x/text v0.35.0 // indirect
|
||||
golang.org/x/term v0.42.0 // indirect
|
||||
golang.org/x/text v0.36.0 // indirect
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
golang.org/x/tools v0.42.0 // indirect
|
||||
golang.org/x/tools v0.44.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/apiserver v0.35.4 // indirect
|
||||
k8s.io/component-base v0.35.4 // indirect
|
||||
k8s.io/apiserver v0.36.0 // indirect
|
||||
k8s.io/component-base v0.36.0 // indirect
|
||||
k8s.io/klog/v2 v2.140.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect
|
||||
k8s.io/streaming v0.36.0 // indirect
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 // indirect
|
||||
sigs.k8s.io/gateway-api v1.5.0 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
|
||||
118
go.sum
118
go.sum
@ -108,8 +108,6 @@ 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/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
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/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=
|
||||
github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
|
||||
github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c=
|
||||
@ -119,16 +117,16 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83 h1:z2ogiKUYzX5Is6zr/vP9vJGqPwcdqsWjOt+V8J7+bTc=
|
||||
github.com/google/pprof v0.0.0-20260115054156-294ebfa9ad83/go.mod h1:MxpfABSjhmINe3F1It9d+8exIHFvUqtLIRCdOGNXqiI=
|
||||
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/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3 h1:B+8ClL/kCQkRiU82d9xajRPKYMrB7E0MbtzWVi1K4ns=
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.3/go.mod h1:NbCUVmiS4foBGBHOYlCT25+YmGpJ32dZPi75pGEUpj4=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7 h1:X+2YciYSxvMQK0UZ7sg45ZVabVZBeBuvMkmuI2V3Fak=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.7/go.mod h1:lW34nIZuQ8UDPdkon5fmfp2l3+ZkQ2me/+oecHYLOII=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
|
||||
@ -163,12 +161,10 @@ github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
|
||||
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/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/onsi/ginkgo/v2 v2.28.2 h1:DTrMfpqxiNUyQ3Y0zhn1n3cOO2euFgQPYIpkWwxVFps=
|
||||
github.com/onsi/ginkgo/v2 v2.28.2/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE=
|
||||
github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
|
||||
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
|
||||
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 v1.40.0 h1:Vtol0e1MghCD2ZVIilPDIg44XSL9l2QAn8ZNaljWcJc=
|
||||
github.com/onsi/gomega v1.40.0/go.mod h1:M/Uqpu/8qTjtzCLUA2zJHX9Iilrau25x1PdoSRbWh5A=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
@ -182,8 +178,8 @@ github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h
|
||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
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.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
|
||||
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
@ -241,14 +237,14 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
|
||||
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
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/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0=
|
||||
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/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0 h1:QKdN8ly8zEMrByybbQgv8cWBcdAarwmIPZ6FThrWXJs=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.40.0/go.mod h1:bTdK1nhqF76qiPoCCdyFIV+N/sRHYXYCTQc+3VCi3MI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0 h1:DvJDOPmSWQHWywQS6lKL+pb8s3gBLOZUtw4N+mavW1I=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.40.0/go.mod h1:EtekO9DEJb4/jRyN4v4Qjc2yA7AtfCBuz2FynRUWTXs=
|
||||
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=
|
||||
@ -257,8 +253,8 @@ go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfC
|
||||
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.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
|
||||
go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
|
||||
go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A=
|
||||
go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
@ -269,38 +265,38 @@ 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/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4=
|
||||
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc=
|
||||
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||
golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
|
||||
golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
|
||||
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
|
||||
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
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/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.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
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.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
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.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
|
||||
golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
|
||||
golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8=
|
||||
golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA=
|
||||
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.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
||||
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
||||
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/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
|
||||
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
|
||||
gomodules.xyz/jsonpatch/v2 v2.5.0 h1:JELs8RLM12qJGXU4u/TO3V25KW8GreMKl9pdkk14RM0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.5.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409 h1:merA0rdPeUV3YIIfHHcH4qBkiQAc1nfCKSI7lB4cV2M=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260128011058-8636f8732409/go.mod h1:fl8J1IvUjCilwZzQowmw2b7HQB2eAuYBabMXzWurF+I=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171 h1:tu/dtnW1o3wfaxCOjSLn5IRX4YDcJrtlpzYkhHhGaC4=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260226221140-a57be14db171/go.mod h1:M5krXqk4GhBKvB596udGL3UyjL4I1+cTbK0orROM9ng=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:ndE4FoJqsIceKP2oYSnUZqhTdYufCYYkqwtFzfrhI7w=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
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 v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw=
|
||||
google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
|
||||
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/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
@ -312,28 +308,30 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.35.4 h1:P7nFYKl5vo9AGUp1Z+Pmd3p2tA7bX2wbFWCvDeRv988=
|
||||
k8s.io/api v0.35.4/go.mod h1:yl4lqySWOgYJJf9RERXKUwE9g2y+CkuwG+xmcOK8wXU=
|
||||
k8s.io/apiextensions-apiserver v0.35.4 h1:HeP+Upp7ItdvnyGmub0yoix+2z5+ev4M5cE5TCgtOUU=
|
||||
k8s.io/apiextensions-apiserver v0.35.4/go.mod h1:ogQlk+stIE8mnoRthSYCwlOS12fVqgWFiErMwPaXA7c=
|
||||
k8s.io/apimachinery v0.35.4 h1:xtdom9RG7e+yDp71uoXoJDWEE2eOiHgeO4GdBzwWpds=
|
||||
k8s.io/apimachinery v0.35.4/go.mod h1:NNi1taPOpep0jOj+oRha3mBJPqvi0hGdaV8TCqGQ+cc=
|
||||
k8s.io/apiserver v0.35.4 h1:vtuFqNFmF9bPRdHDL2lpK6qCTPWDreZJL4LRPwVM6ho=
|
||||
k8s.io/apiserver v0.35.4/go.mod h1:JnBcb+J8kFXKpZkgcbcUnPBBHi4qgBii1I7dLxFY/oo=
|
||||
k8s.io/client-go v0.35.4 h1:DN6fyaGuzK64UvnKO5fOA6ymSjvfGAnCAHAR0C66kD8=
|
||||
k8s.io/client-go v0.35.4/go.mod h1:2Pg9WpsS4NeOpoYTfHHfMxBG8zFMSAUi4O/qoiJC3nY=
|
||||
k8s.io/component-base v0.35.4 h1:6n1tNJ87johN0Hif0Fs8K2GMthsaUwMqCebUDLYyv7U=
|
||||
k8s.io/component-base v0.35.4/go.mod h1:qaDJgz5c1KYKla9occFmlJEfPpkuA55s90G509R+PeY=
|
||||
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.36.0 h1:jZyPzhd5Z+3h9vJLt0z9XdzW9VzNzWAUw+P1xZ9PXtQ=
|
||||
k8s.io/apimachinery v0.36.0/go.mod h1:FklypaRJt6n5wUIwWXIP6GJlIpUizTgfo1T/As+Tyxc=
|
||||
k8s.io/apiserver v0.36.0 h1:Jg5OFAENUACByUCg15CmhZAYrr5ZyJ+jodyA1mHl3YE=
|
||||
k8s.io/apiserver v0.36.0/go.mod h1:mHvwdHf+qKEm+1/hYm756SV+oREOKSPnsjagOpx6Vho=
|
||||
k8s.io/client-go v0.36.0 h1:pOYi7C4RHChYjMiHpZSpSbIM6ZxVbRXBy7CuiIwqA3c=
|
||||
k8s.io/client-go v0.36.0/go.mod h1:ZKKcpwF0aLYfkHFCjillCKaTK/yBkEDHTDXCFY6AS9Y=
|
||||
k8s.io/component-base v0.36.0 h1:hFjEktssxiJhrK1zfybkH4kJOi8iZuF+mIDCqS5+jRo=
|
||||
k8s.io/component-base v0.36.0/go.mod h1:JZvIfcNHk+uck+8LhJzhSBtydWXaZNQwX2OdL+Mnwsk=
|
||||
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-openapi v0.0.0-20260127142750-a19766b6e2d4 h1:HhDfevmPS+OalTjQRKbTHppRIz01AWi8s45TMXStgYY=
|
||||
k8s.io/kube-openapi v0.0.0-20260127142750-a19766b6e2d4/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
||||
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/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-20260319190234-28399d86e0b5 h1:kBawHLSnx/mYHmRnNUf9d4CpjREbeZuxoSGOX/J+aYM=
|
||||
k8s.io/utils v0.0.0-20260319190234-28399d86e0b5/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 h1:qPrZsv1cwQiFeieFlRqT627fVZ+tyfou/+S5S0H5ua0=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
|
||||
sigs.k8s.io/controller-runtime v0.23.3 h1:VjB/vhoPoA9l1kEKZHBMnQF33tdCLQKJtydy4iqwZ80=
|
||||
sigs.k8s.io/controller-runtime v0.23.3/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0 h1:hSfpvjjTQXQY2Fol2CS0QHMNs/WI1MOSGzCm1KhM5ec=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.34.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
|
||||
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/gateway-api v1.5.0 h1:duoo14Ky/fJXpjpmyMISE2RTBGnfCg8zICfTYLTnBJA=
|
||||
sigs.k8s.io/gateway-api v1.5.0/go.mod h1:GvCETiaMAlLym5CovLxGjS0NysqFk3+Yuq3/rh6QL2o=
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
||||
|
||||
@ -29,7 +29,6 @@ import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
|
||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||
)
|
||||
@ -40,7 +39,7 @@ import (
|
||||
func GenerateScheme(ctx context.Context) *runtime.Scheme {
|
||||
result := runtime.NewScheme()
|
||||
|
||||
utilruntime.Must(barmancloudv1.AddToScheme(result))
|
||||
barmancloudv1.AddKnownTypes(result)
|
||||
utilruntime.Must(clientgoscheme.AddToScheme(result))
|
||||
|
||||
cnpgGroup := viper.GetString("custom-cnpg-group")
|
||||
@ -54,11 +53,11 @@ func GenerateScheme(ctx context.Context) *runtime.Scheme {
|
||||
|
||||
// Proceed with custom registration of the CNPG scheme
|
||||
schemeGroupVersion := schema.GroupVersion{Group: cnpgGroup, Version: cnpgVersion}
|
||||
schemeBuilder := &scheme.Builder{GroupVersion: schemeGroupVersion}
|
||||
schemeBuilder.Register(&cnpgv1.Cluster{}, &cnpgv1.ClusterList{})
|
||||
schemeBuilder.Register(&cnpgv1.Backup{}, &cnpgv1.BackupList{})
|
||||
schemeBuilder.Register(&cnpgv1.ScheduledBackup{}, &cnpgv1.ScheduledBackupList{})
|
||||
utilruntime.Must(schemeBuilder.AddToScheme(result))
|
||||
result.AddKnownTypes(schemeGroupVersion,
|
||||
&cnpgv1.Cluster{}, &cnpgv1.ClusterList{},
|
||||
&cnpgv1.Backup{}, &cnpgv1.BackupList{},
|
||||
&cnpgv1.ScheduledBackup{}, &cnpgv1.ScheduledBackupList{},
|
||||
)
|
||||
|
||||
schemeLog := log.FromContext(ctx)
|
||||
schemeLog.Info("CNPG types registration", "schemeGroupVersion", schemeGroupVersion)
|
||||
|
||||
@ -39,7 +39,7 @@ var scheme = buildScheme()
|
||||
func buildScheme() *runtime.Scheme {
|
||||
scheme := runtime.NewScheme()
|
||||
_ = corev1.AddToScheme(scheme)
|
||||
_ = barmancloudv1.AddToScheme(scheme)
|
||||
barmancloudv1.AddKnownTypes(scheme)
|
||||
|
||||
return scheme
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@ var _ = Describe("Metrics Collect method", func() {
|
||||
BeforeEach(func() {
|
||||
ctx = context.Background()
|
||||
scheme := runtime.NewScheme()
|
||||
Expect(barmancloudv1.AddToScheme(scheme)).To(Succeed())
|
||||
barmancloudv1.AddKnownTypes(scheme)
|
||||
|
||||
// Timestamps for the test
|
||||
firstRecoverabilityPoint := metav1.NewTime(time.Now().Add(-24 * time.Hour))
|
||||
|
||||
@ -28,8 +28,24 @@ const PluginName = "barman-cloud.cloudnative-pg.io"
|
||||
const (
|
||||
// ClusterLabelName is the label applied to RBAC resources created
|
||||
// by this plugin. Its value is the name of the owning Cluster.
|
||||
//
|
||||
// Discovery contract: internal/controller/objectstore_controller.go
|
||||
// selects Roles by this key when an ObjectStore is reconciled.
|
||||
// Renaming or removing the label would break that controller; new
|
||||
// recommended-label keys are added alongside it, never in place
|
||||
// of it.
|
||||
ClusterLabelName = "barmancloud.cnpg.io/cluster"
|
||||
|
||||
// AppLabelValue is the value applied to app.kubernetes.io/name on
|
||||
// every plugin-managed object. It identifies the application as
|
||||
// the Barman Cloud plugin (see issue #545).
|
||||
AppLabelValue = "barman-cloud-plugin"
|
||||
|
||||
// ManagedByLabelValue is the value applied to app.kubernetes.io/managed-by
|
||||
// on every plugin-managed object. It identifies this plugin as
|
||||
// the controller responsible for the object.
|
||||
ManagedByLabelValue = "plugin-barman-cloud"
|
||||
|
||||
// CheckEmptyWalArchiveFile is the name of the file in the PGDATA that,
|
||||
// if present, requires the WAL archiver to check that the backup object
|
||||
// store is empty.
|
||||
|
||||
@ -41,6 +41,9 @@ import (
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
||||
)
|
||||
|
||||
// fullRecoveryJobName is the name of the restore job.
|
||||
const fullRecoveryJobName = "full-recovery"
|
||||
|
||||
// LifecycleImplementation is the implementation of the lifecycle handler
|
||||
type LifecycleImplementation struct {
|
||||
lifecycle.UnimplementedOperatorLifecycleServer
|
||||
@ -48,6 +51,8 @@ type LifecycleImplementation struct {
|
||||
}
|
||||
|
||||
// GetCapabilities exposes the lifecycle capabilities
|
||||
//
|
||||
//nolint:goconst
|
||||
func (impl LifecycleImplementation) GetCapabilities(
|
||||
_ context.Context,
|
||||
_ *lifecycle.OperatorLifecycleCapabilitiesRequest,
|
||||
@ -186,7 +191,7 @@ func reconcileJob(
|
||||
contextLogger.Debug("starting job reconciliation")
|
||||
|
||||
jobRole := getCNPGJobRole(&job)
|
||||
if jobRole != "full-recovery" &&
|
||||
if jobRole != fullRecoveryJobName &&
|
||||
jobRole != "snapshot-recovery" {
|
||||
contextLogger.Debug("job is not a recovery job, skipping")
|
||||
return nil, nil
|
||||
|
||||
@ -55,7 +55,7 @@ var _ = Describe("LifecycleImplementation", func() {
|
||||
// helper to build a fake client with our scheme and optional objects
|
||||
buildClientFunc := func(objs ...runtime.Object) *fake.ClientBuilder {
|
||||
s := runtime.NewScheme()
|
||||
_ = barmancloudv1.AddToScheme(s)
|
||||
barmancloudv1.AddKnownTypes(s)
|
||||
return fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(objs...)
|
||||
}
|
||||
|
||||
@ -139,10 +139,10 @@ var _ = Describe("LifecycleImplementation", func() {
|
||||
Spec: batchv1.JobSpec{Template: corev1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
utils.JobRoleLabelName: "full-recovery",
|
||||
utils.JobRoleLabelName: fullRecoveryJobName,
|
||||
},
|
||||
},
|
||||
Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: "full-recovery"}}},
|
||||
Spec: corev1.PodSpec{Containers: []corev1.Container{{Name: fullRecoveryJobName}}},
|
||||
}},
|
||||
}
|
||||
jobJSON, _ := json.Marshal(job)
|
||||
@ -351,7 +351,7 @@ var _ = Describe("LifecycleImplementation", func() {
|
||||
},
|
||||
}
|
||||
s := runtime.NewScheme()
|
||||
_ = barmancloudv1.AddToScheme(s)
|
||||
barmancloudv1.AddKnownTypes(s)
|
||||
cli := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(store).Build()
|
||||
|
||||
impl := LifecycleImplementation{Client: cli}
|
||||
@ -378,7 +378,7 @@ var _ = Describe("LifecycleImplementation", func() {
|
||||
},
|
||||
}
|
||||
s := runtime.NewScheme()
|
||||
_ = barmancloudv1.AddToScheme(s)
|
||||
barmancloudv1.AddKnownTypes(s)
|
||||
cli := fake.NewClientBuilder().WithScheme(s).WithRuntimeObjects(store).Build()
|
||||
|
||||
impl := LifecycleImplementation{Client: cli}
|
||||
|
||||
@ -47,7 +47,7 @@ var scheme = runtime.NewScheme()
|
||||
|
||||
func init() {
|
||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
||||
utilruntime.Must(barmancloudv1.AddToScheme(scheme))
|
||||
barmancloudv1.AddKnownTypes(scheme)
|
||||
// +kubebuilder:scaffold:scheme
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ package rbac
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||
@ -31,7 +32,6 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/specs"
|
||||
)
|
||||
|
||||
@ -62,9 +62,7 @@ func EnsureRole(
|
||||
return err
|
||||
}
|
||||
|
||||
return patchRole(ctx, c, roleKey, newRole.Rules, map[string]string{
|
||||
metadata.ClusterLabelName: cluster.Name,
|
||||
})
|
||||
return patchRole(ctx, c, roleKey, newRole.Rules, specs.BuildLabels(cluster))
|
||||
}
|
||||
|
||||
// EnsureRoleRules updates the rules of an existing Role to match
|
||||
@ -90,6 +88,143 @@ func EnsureRoleRules(
|
||||
return err
|
||||
}
|
||||
|
||||
// EnsureRoleBinding ensures the RoleBinding for the given Cluster
|
||||
// is present and carries the recommended labels.
|
||||
//
|
||||
// This function is called from the Pre hook (gRPC). It creates the
|
||||
// RoleBinding if it does not exist, then reconciles labels and
|
||||
// Subjects:
|
||||
// - Labels are written per-key. Keys the plugin manages overwrite
|
||||
// existing values; unrelated keys (anything outside the desired
|
||||
// set) are left alone.
|
||||
// - Subjects are additive. The plugin guarantees its own Subject
|
||||
// is bound, but never removes Subjects added by other actors —
|
||||
// a Subject is a grant of access, and silently revoking access
|
||||
// someone else granted is the wrong default.
|
||||
//
|
||||
// RoleRef is immutable in Kubernetes. If the existing RoleBinding
|
||||
// points to a different Role, the plugin fails loudly so the
|
||||
// operator notices and recreates the object.
|
||||
func EnsureRoleBinding(ctx context.Context, c client.Client, cluster *cnpgv1.Cluster) error {
|
||||
desiredRoleBinding := specs.BuildRoleBinding(cluster)
|
||||
if err := specs.SetControllerReference(cluster, desiredRoleBinding); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
roleBinding, err := getOrCreateRoleBinding(ctx, c, desiredRoleBinding)
|
||||
if err != nil || roleBinding == nil {
|
||||
// Either an error, or we just created the object with the
|
||||
// desired state — nothing to patch.
|
||||
return err
|
||||
}
|
||||
|
||||
return reconcileRoleBinding(ctx, c, roleBinding, desiredRoleBinding)
|
||||
}
|
||||
|
||||
// getOrCreateRoleBinding returns the existing RoleBinding when it
|
||||
// is already present on the API server, or nil after a successful
|
||||
// Create when the just-created object already carries the desired
|
||||
// state (so the caller can skip the patch path).
|
||||
//
|
||||
// On a stale-informer-cache race during plugin pod startup, where
|
||||
// Get returns NotFound but Create returns AlreadyExists, the
|
||||
// function re-Gets to return the racing winner — the caller then
|
||||
// falls through to reconciliation against that real object.
|
||||
func getOrCreateRoleBinding(
|
||||
ctx context.Context,
|
||||
c client.Client,
|
||||
desired *rbacv1.RoleBinding,
|
||||
) (*rbacv1.RoleBinding, error) {
|
||||
contextLogger := log.FromContext(ctx)
|
||||
|
||||
rb := &rbacv1.RoleBinding{}
|
||||
err := c.Get(ctx, client.ObjectKeyFromObject(desired), rb)
|
||||
if err == nil {
|
||||
return rb, nil
|
||||
}
|
||||
if !apierrs.IsNotFound(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
createErr := c.Create(ctx, desired)
|
||||
switch {
|
||||
case createErr == nil:
|
||||
contextLogger.Info("Created RoleBinding",
|
||||
"name", desired.Name, "namespace", desired.Namespace)
|
||||
// Just-created with the desired state — caller skips patch.
|
||||
return nil, nil
|
||||
case apierrs.IsAlreadyExists(createErr):
|
||||
contextLogger.Debug(
|
||||
"RoleBinding already exists, likely a stale informer cache; re-fetching",
|
||||
"name", desired.Name, "namespace", desired.Namespace)
|
||||
// Re-Get to return the racing winner so the caller can
|
||||
// reconcile against the real existing object.
|
||||
fetched := &rbacv1.RoleBinding{}
|
||||
if err := c.Get(ctx, client.ObjectKeyFromObject(desired), fetched); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return fetched, nil
|
||||
default:
|
||||
return nil, createErr
|
||||
}
|
||||
}
|
||||
|
||||
// reconcileRoleBinding brings an existing RoleBinding's labels and
|
||||
// Subjects into alignment with desired. It re-Gets the object on
|
||||
// conflict-retry so each attempt observes fresh server state, and
|
||||
// uses optimistic locking so a competing writer's patch is rejected
|
||||
// with 409 instead of silently last-write-winning.
|
||||
//
|
||||
// On the first attempt the function uses the existing object passed
|
||||
// in by the caller, avoiding a second Get on the steady-state path.
|
||||
func reconcileRoleBinding(
|
||||
ctx context.Context,
|
||||
c client.Client,
|
||||
existing, desired *rbacv1.RoleBinding,
|
||||
) error {
|
||||
contextLogger := log.FromContext(ctx)
|
||||
first := true
|
||||
return retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
var roleBinding *rbacv1.RoleBinding
|
||||
if first {
|
||||
roleBinding = existing
|
||||
first = false
|
||||
} else {
|
||||
roleBinding = &rbacv1.RoleBinding{}
|
||||
if err := c.Get(ctx, client.ObjectKeyFromObject(desired), roleBinding); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// RoleRef is immutable in Kubernetes; we cannot patch it.
|
||||
// Divergence at the canonical name is corruption regardless
|
||||
// of who wrote the existing object — fail loudly so the
|
||||
// operator notices and deletes the RoleBinding, and the
|
||||
// next Pre call recreates it correctly.
|
||||
if !equality.Semantic.DeepEqual(roleBinding.RoleRef, desired.RoleRef) {
|
||||
return fmt.Errorf(
|
||||
"RoleBinding %s/%s has divergent immutable RoleRef "+
|
||||
"(existing=%+v, desired=%+v); delete the RoleBinding to allow recreation",
|
||||
roleBinding.Namespace, roleBinding.Name,
|
||||
roleBinding.RoleRef, desired.RoleRef)
|
||||
}
|
||||
|
||||
if !roleBindingNeedsUpdate(roleBinding, desired) {
|
||||
return nil
|
||||
}
|
||||
|
||||
contextLogger.Info("Patching role binding",
|
||||
"name", roleBinding.Name, "namespace", roleBinding.Namespace)
|
||||
|
||||
oldRoleBinding := roleBinding.DeepCopy()
|
||||
roleBinding.Labels = mergeLabels(roleBinding.Labels, desired.Labels)
|
||||
roleBinding.Subjects = mergeSubjects(roleBinding.Subjects, desired.Subjects)
|
||||
|
||||
return c.Patch(ctx, roleBinding,
|
||||
client.MergeFromWithOptions(oldRoleBinding, client.MergeFromWithOptimisticLock{}))
|
||||
})
|
||||
}
|
||||
|
||||
// ensureRoleExists creates the Role if it does not exist. Returns
|
||||
// nil on success and nil on AlreadyExists (another writer created
|
||||
// it concurrently). The caller always follows up with patchRole.
|
||||
@ -155,22 +290,32 @@ func patchRole(
|
||||
|
||||
oldRole := role.DeepCopy()
|
||||
role.Rules = desiredRules
|
||||
role.Labels = mergeLabels(role.Labels, desiredLabels)
|
||||
|
||||
if desiredLabels != nil {
|
||||
if role.Labels == nil {
|
||||
role.Labels = make(map[string]string, len(desiredLabels))
|
||||
}
|
||||
for k, v := range desiredLabels {
|
||||
role.Labels[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return c.Patch(ctx, &role, client.MergeFrom(oldRole))
|
||||
return c.Patch(ctx, &role,
|
||||
client.MergeFromWithOptions(oldRole, client.MergeFromWithOptimisticLock{}))
|
||||
})
|
||||
}
|
||||
|
||||
// labelsNeedUpdate returns true if any key in desired is missing
|
||||
// or has a different value in existing.
|
||||
// mergeLabels writes the desired labels onto existing per-key.
|
||||
// Keys in desired overwrite the existing value; keys not in desired
|
||||
// (any unrelated label a user may have set) are left alone.
|
||||
func mergeLabels(existing, desired map[string]string) map[string]string {
|
||||
if len(desired) == 0 {
|
||||
return existing
|
||||
}
|
||||
if existing == nil {
|
||||
existing = make(map[string]string, len(desired))
|
||||
}
|
||||
for k, v := range desired {
|
||||
existing[k] = v
|
||||
}
|
||||
return existing
|
||||
}
|
||||
|
||||
// labelsNeedUpdate returns true if a Patch is required to bring
|
||||
// existing labels into the state mergeLabels would produce, i.e.
|
||||
// any desired key is missing or has a different value in existing.
|
||||
func labelsNeedUpdate(existing, desired map[string]string) bool {
|
||||
for k, v := range desired {
|
||||
if existing[k] != v {
|
||||
@ -179,3 +324,46 @@ func labelsNeedUpdate(existing, desired map[string]string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// containsSubject reports whether subjects contains an element that
|
||||
// is semantically equal to subject.
|
||||
func containsSubject(subjects []rbacv1.Subject, subject rbacv1.Subject) bool {
|
||||
for _, s := range subjects {
|
||||
if equality.Semantic.DeepEqual(s, subject) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// mergeSubjects appends desired Subjects that are not already
|
||||
// present in existing.
|
||||
//
|
||||
// This is intentionally asymmetric to mergeLabels: labels are
|
||||
// metadata, so replacing stale plugin-set values is safe. A
|
||||
// Subject is a grant of access, so removing a Subject silently
|
||||
// revokes permissions an external operator chose to grant. The
|
||||
// plugin only requires that ITS Subject is present, not that it
|
||||
// is exclusive.
|
||||
func mergeSubjects(existing, desired []rbacv1.Subject) []rbacv1.Subject {
|
||||
for _, d := range desired {
|
||||
if !containsSubject(existing, d) {
|
||||
existing = append(existing, d)
|
||||
}
|
||||
}
|
||||
return existing
|
||||
}
|
||||
|
||||
// roleBindingNeedsUpdate returns true if a Patch is required to
|
||||
// bring existing into alignment with desired — any desired Subject
|
||||
// missing (see mergeSubjects), or any desired label key missing
|
||||
// or holding a stale value (see mergeLabels).
|
||||
func roleBindingNeedsUpdate(existing, desired *rbacv1.RoleBinding) bool {
|
||||
for _, s := range desired.Subjects {
|
||||
if !containsSubject(existing.Subjects, s) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return labelsNeedUpdate(existing.Labels, desired.Labels)
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ import (
|
||||
|
||||
barmanapi "github.com/cloudnative-pg/barman-cloud/pkg/api"
|
||||
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||
"github.com/cloudnative-pg/cloudnative-pg/pkg/utils"
|
||||
machineryapi "github.com/cloudnative-pg/machinery/pkg/api"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
@ -42,11 +43,47 @@ import (
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/rbac"
|
||||
)
|
||||
|
||||
func expectRequiredLabels(labels map[string]string, clusterName string) {
|
||||
ExpectWithOffset(1, labels).To(HaveKeyWithValue(metadata.ClusterLabelName, clusterName))
|
||||
ExpectWithOffset(1, labels).To(HaveKeyWithValue(utils.KubernetesAppLabelName, metadata.AppLabelValue))
|
||||
ExpectWithOffset(1, labels).To(HaveKeyWithValue(utils.KubernetesAppInstanceLabelName, clusterName))
|
||||
ExpectWithOffset(1, labels).To(HaveKeyWithValue(utils.KubernetesAppManagedByLabelName, metadata.ManagedByLabelValue))
|
||||
ExpectWithOffset(1, labels).To(HaveKeyWithValue(utils.KubernetesAppComponentLabelName, utils.DatabaseComponentName))
|
||||
ExpectWithOffset(1, labels).To(HaveKeyWithValue(utils.KubernetesAppVersionLabelName, metadata.Data.Version))
|
||||
}
|
||||
|
||||
// newPatchCountingClient returns a fake client plus a pointer to a
|
||||
// counter incremented on every Patch call. Useful for asserting
|
||||
// that a "no-op" reconcile path issues no Patch — more reliable
|
||||
// than comparing ResourceVersion across reads, which depends on
|
||||
// fake-client RV-bumping semantics that are not part of the
|
||||
// controller-runtime contract.
|
||||
func newPatchCountingClient(initObjs ...client.Object) (client.Client, *int) {
|
||||
count := 0
|
||||
c := fake.NewClientBuilder().
|
||||
WithScheme(newScheme()).
|
||||
WithObjects(initObjs...).
|
||||
WithInterceptorFuncs(interceptor.Funcs{
|
||||
Patch: func(
|
||||
ctx context.Context,
|
||||
client client.WithWatch,
|
||||
obj client.Object,
|
||||
patch client.Patch,
|
||||
opts ...client.PatchOption,
|
||||
) error {
|
||||
count++
|
||||
return client.Patch(ctx, obj, patch, opts...)
|
||||
},
|
||||
}).
|
||||
Build()
|
||||
return c, &count
|
||||
}
|
||||
|
||||
func newScheme() *runtime.Scheme {
|
||||
s := runtime.NewScheme()
|
||||
utilruntime.Must(rbacv1.AddToScheme(s))
|
||||
utilruntime.Must(cnpgv1.AddToScheme(s))
|
||||
utilruntime.Must(barmancloudv1.AddToScheme(s))
|
||||
barmancloudv1.AddKnownTypes(s)
|
||||
return s
|
||||
}
|
||||
|
||||
@ -124,33 +161,23 @@ var _ = Describe("EnsureRole", func() {
|
||||
Expect(role.OwnerReferences[0].Name).To(Equal("test-cluster"))
|
||||
Expect(role.OwnerReferences[0].Kind).To(Equal("Cluster"))
|
||||
|
||||
Expect(role.Labels).To(HaveKeyWithValue(metadata.ClusterLabelName, "test-cluster"))
|
||||
expectRequiredLabels(role.Labels, "test-cluster")
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the Role exists with matching rules", func() {
|
||||
var patchCount *int
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||
fakeClient, patchCount = newPatchCountingClient()
|
||||
Expect(rbac.EnsureRole(ctx, fakeClient, cluster, objects)).To(Succeed())
|
||||
*patchCount = 0
|
||||
})
|
||||
|
||||
It("should not patch the Role", func() {
|
||||
var before rbacv1.Role
|
||||
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: "default",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &before)).To(Succeed())
|
||||
|
||||
err := rbac.EnsureRole(ctx, fakeClient, cluster, objects)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var after rbacv1.Role
|
||||
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: "default",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &after)).To(Succeed())
|
||||
|
||||
Expect(after.ResourceVersion).To(Equal(before.ResourceVersion))
|
||||
Expect(*patchCount).To(BeZero())
|
||||
})
|
||||
})
|
||||
|
||||
@ -210,7 +237,7 @@ var _ = Describe("EnsureRole", func() {
|
||||
Name: "test-cluster-barman-cloud",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
"app.kubernetes.io/managed-by": "helm",
|
||||
"custom-label": "custom-value",
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -227,8 +254,40 @@ var _ = Describe("EnsureRole", func() {
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &role)).To(Succeed())
|
||||
|
||||
Expect(role.Labels).To(HaveKeyWithValue("app.kubernetes.io/managed-by", "helm"))
|
||||
Expect(role.Labels).To(HaveKeyWithValue(metadata.ClusterLabelName, "test-cluster"))
|
||||
Expect(role.Labels).To(HaveKeyWithValue("custom-label", "custom-value"))
|
||||
expectRequiredLabels(role.Labels, "test-cluster")
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the Role exists with a stale label value", func() {
|
||||
BeforeEach(func() {
|
||||
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||
existing := &rbacv1.Role{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-cluster-barman-cloud",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
// Stale value as if written by an older plugin
|
||||
// version.
|
||||
utils.KubernetesAppVersionLabelName: "0.0.0-stale",
|
||||
},
|
||||
},
|
||||
}
|
||||
Expect(fakeClient.Create(ctx, existing)).To(Succeed())
|
||||
})
|
||||
|
||||
It("should overwrite the stale value with the current plugin's value", func() {
|
||||
err := rbac.EnsureRole(ctx, fakeClient, cluster, objects)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var role rbacv1.Role
|
||||
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: "default",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &role)).To(Succeed())
|
||||
|
||||
Expect(role.Labels).To(HaveKeyWithValue(
|
||||
utils.KubernetesAppVersionLabelName, metadata.Data.Version))
|
||||
})
|
||||
})
|
||||
|
||||
@ -257,12 +316,348 @@ var _ = Describe("EnsureRole", func() {
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &role)).To(Succeed())
|
||||
|
||||
Expect(role.Labels).To(HaveKeyWithValue(metadata.ClusterLabelName, "test-cluster"))
|
||||
expectRequiredLabels(role.Labels, "test-cluster")
|
||||
Expect(role.Rules).To(HaveLen(3))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("EnsureRoleBinding", func() {
|
||||
var (
|
||||
ctx context.Context
|
||||
cluster *cnpgv1.Cluster
|
||||
fakeClient client.Client
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
ctx = context.Background()
|
||||
cluster = newCluster("test-cluster", "default")
|
||||
})
|
||||
|
||||
Context("when the RoleBinding does not exist", func() {
|
||||
BeforeEach(func() {
|
||||
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||
})
|
||||
|
||||
It("should create the RoleBinding with owner reference, labels, and correct subjects", func() {
|
||||
err := rbac.EnsureRoleBinding(ctx, fakeClient, cluster)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var rb rbacv1.RoleBinding
|
||||
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: "default",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &rb)).To(Succeed())
|
||||
|
||||
Expect(rb.OwnerReferences).To(HaveLen(1))
|
||||
Expect(rb.OwnerReferences[0].Name).To(Equal("test-cluster"))
|
||||
Expect(rb.OwnerReferences[0].Kind).To(Equal("Cluster"))
|
||||
|
||||
expectRequiredLabels(rb.Labels, "test-cluster")
|
||||
|
||||
Expect(rb.Subjects).To(HaveLen(1))
|
||||
Expect(rb.Subjects[0].Name).To(Equal("test-cluster"))
|
||||
Expect(rb.Subjects[0].Kind).To(Equal("ServiceAccount"))
|
||||
|
||||
Expect(rb.RoleRef.Kind).To(Equal("Role"))
|
||||
Expect(rb.RoleRef.Name).To(Equal("test-cluster-barman-cloud"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the RoleBinding exists with matching state", func() {
|
||||
var patchCount *int
|
||||
|
||||
BeforeEach(func() {
|
||||
fakeClient, patchCount = newPatchCountingClient()
|
||||
Expect(rbac.EnsureRoleBinding(ctx, fakeClient, cluster)).To(Succeed())
|
||||
*patchCount = 0
|
||||
})
|
||||
|
||||
It("should not patch the RoleBinding", func() {
|
||||
err := rbac.EnsureRoleBinding(ctx, fakeClient, cluster)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
Expect(*patchCount).To(BeZero())
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the RoleBinding exists with extra user-added subjects", func() {
|
||||
BeforeEach(func() {
|
||||
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||
existing := &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-cluster-barman-cloud",
|
||||
Namespace: "default",
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "user-debug-sa",
|
||||
APIGroup: "",
|
||||
},
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
APIGroup: "rbac.authorization.k8s.io",
|
||||
Kind: "Role",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
},
|
||||
}
|
||||
Expect(fakeClient.Create(ctx, existing)).To(Succeed())
|
||||
})
|
||||
|
||||
It("should add the plugin's subject without removing user-added ones", func() {
|
||||
err := rbac.EnsureRoleBinding(ctx, fakeClient, cluster)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var rb rbacv1.RoleBinding
|
||||
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: "default",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &rb)).To(Succeed())
|
||||
|
||||
// Additive policy: the user-added subject must remain.
|
||||
Expect(rb.Subjects).To(ContainElement(rbacv1.Subject{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "user-debug-sa",
|
||||
APIGroup: "",
|
||||
}))
|
||||
// The plugin's required subject must be present.
|
||||
Expect(rb.Subjects).To(ContainElement(rbacv1.Subject{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "test-cluster",
|
||||
Namespace: "default",
|
||||
APIGroup: "",
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the RoleBinding exists with a stale label value", func() {
|
||||
BeforeEach(func() {
|
||||
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||
existing := &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-cluster-barman-cloud",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
utils.KubernetesAppVersionLabelName: "0.0.0-stale",
|
||||
},
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "test-cluster",
|
||||
Namespace: "default",
|
||||
APIGroup: "",
|
||||
},
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
APIGroup: "rbac.authorization.k8s.io",
|
||||
Kind: "Role",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
},
|
||||
}
|
||||
Expect(fakeClient.Create(ctx, existing)).To(Succeed())
|
||||
})
|
||||
|
||||
It("should overwrite the stale value with the current plugin's value", func() {
|
||||
err := rbac.EnsureRoleBinding(ctx, fakeClient, cluster)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var rb rbacv1.RoleBinding
|
||||
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: "default",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &rb)).To(Succeed())
|
||||
|
||||
Expect(rb.Labels).To(HaveKeyWithValue(
|
||||
utils.KubernetesAppVersionLabelName, metadata.Data.Version))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the RoleBinding has pre-existing unrelated labels", func() {
|
||||
BeforeEach(func() {
|
||||
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||
existing := &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-cluster-barman-cloud",
|
||||
Namespace: "default",
|
||||
Labels: map[string]string{
|
||||
"custom-label": "custom-value",
|
||||
},
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "test-cluster",
|
||||
Namespace: "default",
|
||||
APIGroup: "",
|
||||
},
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
APIGroup: "rbac.authorization.k8s.io",
|
||||
Kind: "Role",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
},
|
||||
}
|
||||
Expect(fakeClient.Create(ctx, existing)).To(Succeed())
|
||||
})
|
||||
|
||||
It("should preserve unrelated labels while adding the required labels", func() {
|
||||
err := rbac.EnsureRoleBinding(ctx, fakeClient, cluster)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var rb rbacv1.RoleBinding
|
||||
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: "default",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &rb)).To(Succeed())
|
||||
|
||||
Expect(rb.Labels).To(HaveKeyWithValue("custom-label", "custom-value"))
|
||||
expectRequiredLabels(rb.Labels, "test-cluster")
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the RoleBinding has a divergent RoleRef", func() {
|
||||
BeforeEach(func() {
|
||||
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||
existing := &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-cluster-barman-cloud",
|
||||
Namespace: "default",
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "test-cluster",
|
||||
Namespace: "default",
|
||||
APIGroup: "",
|
||||
},
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
APIGroup: "rbac.authorization.k8s.io",
|
||||
Kind: "Role",
|
||||
Name: "wrong-role",
|
||||
},
|
||||
}
|
||||
Expect(fakeClient.Create(ctx, existing)).To(Succeed())
|
||||
})
|
||||
|
||||
It("should return a descriptive error since RoleRef is immutable", func() {
|
||||
err := rbac.EnsureRoleBinding(ctx, fakeClient, cluster)
|
||||
Expect(err).To(HaveOccurred())
|
||||
Expect(err.Error()).To(ContainSubstring("RoleRef"))
|
||||
Expect(err.Error()).To(ContainSubstring("wrong-role"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when an AlreadyExists race happens during a stale-cache create (plugin pod startup)", func() {
|
||||
var preExisting *rbacv1.RoleBinding
|
||||
|
||||
BeforeEach(func() {
|
||||
preExisting = &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-cluster-barman-cloud",
|
||||
Namespace: "default",
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "test-cluster",
|
||||
Namespace: "default",
|
||||
APIGroup: "",
|
||||
},
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
APIGroup: "rbac.authorization.k8s.io",
|
||||
Kind: "Role",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
},
|
||||
}
|
||||
|
||||
// First Get returns NotFound (simulates cold informer
|
||||
// cache after plugin pod restart). Subsequent Gets
|
||||
// fall through to real fake-client behavior.
|
||||
gets := 0
|
||||
fakeClient = fake.NewClientBuilder().
|
||||
WithScheme(newScheme()).
|
||||
WithObjects(preExisting).
|
||||
WithInterceptorFuncs(interceptor.Funcs{
|
||||
Get: func(
|
||||
ctx context.Context,
|
||||
c client.WithWatch,
|
||||
key client.ObjectKey,
|
||||
obj client.Object,
|
||||
opts ...client.GetOption,
|
||||
) error {
|
||||
gets++
|
||||
if gets == 1 {
|
||||
return apierrs.NewNotFound(
|
||||
rbacv1.Resource("rolebindings"), key.Name)
|
||||
}
|
||||
return c.Get(ctx, key, obj, opts...)
|
||||
},
|
||||
}).
|
||||
Build()
|
||||
})
|
||||
|
||||
It("should tolerate the AlreadyExists and reconcile from the existing object", func() {
|
||||
err := rbac.EnsureRoleBinding(ctx, fakeClient, cluster)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var rb rbacv1.RoleBinding
|
||||
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: "default",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &rb)).To(Succeed())
|
||||
|
||||
Expect(rb.Subjects).To(ContainElement(rbacv1.Subject{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "test-cluster",
|
||||
Namespace: "default",
|
||||
APIGroup: "",
|
||||
}))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when the RoleBinding exists without labels (upgrade scenario)", func() {
|
||||
BeforeEach(func() {
|
||||
fakeClient = fake.NewClientBuilder().WithScheme(newScheme()).Build()
|
||||
existing := &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "test-cluster-barman-cloud",
|
||||
Namespace: "default",
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
Kind: "ServiceAccount",
|
||||
Name: "test-cluster",
|
||||
Namespace: "default",
|
||||
APIGroup: "",
|
||||
},
|
||||
},
|
||||
RoleRef: rbacv1.RoleRef{
|
||||
APIGroup: "rbac.authorization.k8s.io",
|
||||
Kind: "Role",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
},
|
||||
}
|
||||
Expect(fakeClient.Create(ctx, existing)).To(Succeed())
|
||||
})
|
||||
|
||||
It("should add the required labels", func() {
|
||||
err := rbac.EnsureRoleBinding(ctx, fakeClient, cluster)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
var rb rbacv1.RoleBinding
|
||||
Expect(fakeClient.Get(ctx, client.ObjectKey{
|
||||
Namespace: "default",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}, &rb)).To(Succeed())
|
||||
|
||||
expectRequiredLabels(rb.Labels, "test-cluster")
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("EnsureRoleRules", func() {
|
||||
var (
|
||||
ctx context.Context
|
||||
@ -306,23 +701,21 @@ var _ = Describe("EnsureRoleRules", func() {
|
||||
})
|
||||
|
||||
It("should not patch when rules already match", func() {
|
||||
// Seed with the same objects so rules match
|
||||
// Replace the seeded client with a counting one,
|
||||
// then re-seed via EnsureRole so the desired rules
|
||||
// are already in place when EnsureRoleRules runs.
|
||||
var patchCount *int
|
||||
fakeClient, patchCount = newPatchCountingClient()
|
||||
cluster := newCluster("test-cluster", "default")
|
||||
Expect(rbac.EnsureRole(ctx, fakeClient, cluster, objects)).To(Succeed())
|
||||
*patchCount = 0
|
||||
|
||||
roleKey := client.ObjectKey{
|
||||
Namespace: "default",
|
||||
Name: "test-cluster-barman-cloud",
|
||||
}
|
||||
|
||||
var before rbacv1.Role
|
||||
Expect(fakeClient.Get(ctx, roleKey, &before)).To(Succeed())
|
||||
|
||||
Expect(rbac.EnsureRoleRules(ctx, fakeClient, roleKey, objects)).To(Succeed())
|
||||
|
||||
var after rbacv1.Role
|
||||
Expect(fakeClient.Get(ctx, roleKey, &after)).To(Succeed())
|
||||
Expect(after.ResourceVersion).To(Equal(before.ResourceVersion))
|
||||
Expect(*patchCount).To(BeZero())
|
||||
})
|
||||
|
||||
It("should not modify labels", func() {
|
||||
|
||||
@ -27,14 +27,12 @@ import (
|
||||
"github.com/cloudnative-pg/cnpg-i-machinery/pkg/pluginhelper/object"
|
||||
"github.com/cloudnative-pg/cnpg-i/pkg/reconciler"
|
||||
"github.com/cloudnative-pg/machinery/pkg/log"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
apierrs "k8s.io/apimachinery/pkg/api/errors"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/config"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/rbac"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator/specs"
|
||||
)
|
||||
|
||||
// ReconcilerImplementation implements the Reconciler capability
|
||||
@ -117,7 +115,7 @@ func (r ReconcilerImplementation) Pre(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := r.ensureRoleBinding(ctx, &cluster); err != nil {
|
||||
if err := rbac.EnsureRoleBinding(ctx, r.Client, &cluster); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@ -136,34 +134,3 @@ func (r ReconcilerImplementation) Post(
|
||||
Behavior: reconciler.ReconcilerHooksResult_BEHAVIOR_CONTINUE,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r ReconcilerImplementation) ensureRoleBinding(
|
||||
ctx context.Context,
|
||||
cluster *cnpgv1.Cluster,
|
||||
) error {
|
||||
var roleBinding rbacv1.RoleBinding
|
||||
if err := r.Client.Get(ctx, client.ObjectKey{
|
||||
Namespace: cluster.Namespace,
|
||||
Name: specs.GetRBACName(cluster.Name),
|
||||
}, &roleBinding); err != nil {
|
||||
if apierrs.IsNotFound(err) {
|
||||
return r.createRoleBinding(ctx, cluster)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: this assumes role bindings never change.
|
||||
// Is that true? Should we relax this assumption?
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r ReconcilerImplementation) createRoleBinding(
|
||||
ctx context.Context,
|
||||
cluster *cnpgv1.Cluster,
|
||||
) error {
|
||||
roleBinding := specs.BuildRoleBinding(cluster)
|
||||
if err := specs.SetControllerReference(cluster, roleBinding); err != nil {
|
||||
return err
|
||||
}
|
||||
return r.Client.Create(ctx, roleBinding)
|
||||
}
|
||||
|
||||
41
internal/cnpgi/operator/specs/labels.go
Normal file
41
internal/cnpgi/operator/specs/labels.go
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright © contributors to CloudNativePG, established as
|
||||
CloudNativePG a Series of LF Projects, LLC.
|
||||
|
||||
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.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package specs
|
||||
|
||||
import (
|
||||
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||
"github.com/cloudnative-pg/cloudnative-pg/pkg/utils"
|
||||
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||
)
|
||||
|
||||
// BuildLabels returns the Kubernetes recommended labels applied to
|
||||
// every object managed by this plugin for the given Cluster. See
|
||||
// https://github.com/cloudnative-pg/plugin-barman-cloud/issues/545.
|
||||
func BuildLabels(cluster *cnpgv1.Cluster) map[string]string {
|
||||
return map[string]string{
|
||||
metadata.ClusterLabelName: cluster.Name,
|
||||
utils.KubernetesAppLabelName: metadata.AppLabelValue,
|
||||
utils.KubernetesAppInstanceLabelName: cluster.Name,
|
||||
utils.KubernetesAppVersionLabelName: metadata.Data.Version,
|
||||
utils.KubernetesAppComponentLabelName: utils.DatabaseComponentName,
|
||||
utils.KubernetesAppManagedByLabelName: metadata.ManagedByLabelValue,
|
||||
}
|
||||
}
|
||||
68
internal/cnpgi/operator/specs/labels_test.go
Normal file
68
internal/cnpgi/operator/specs/labels_test.go
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright © contributors to CloudNativePG, established as
|
||||
CloudNativePG a Series of LF Projects, LLC.
|
||||
|
||||
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.
|
||||
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package specs
|
||||
|
||||
import (
|
||||
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||
"github.com/cloudnative-pg/cloudnative-pg/pkg/utils"
|
||||
. "github.com/onsi/ginkgo/v2"
|
||||
. "github.com/onsi/gomega"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||
)
|
||||
|
||||
var _ = Describe("BuildLabels", func() {
|
||||
It("should return the recommended labels with plugin identity", func() {
|
||||
cluster := &cnpgv1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-cluster",
|
||||
Namespace: "default",
|
||||
},
|
||||
}
|
||||
labels := BuildLabels(cluster)
|
||||
|
||||
Expect(labels).To(HaveKeyWithValue(metadata.ClusterLabelName, "my-cluster"))
|
||||
Expect(labels).To(HaveKeyWithValue(utils.KubernetesAppLabelName, metadata.AppLabelValue))
|
||||
Expect(labels).To(HaveKeyWithValue(utils.KubernetesAppInstanceLabelName, "my-cluster"))
|
||||
Expect(labels).To(HaveKeyWithValue(utils.KubernetesAppVersionLabelName, metadata.Data.Version))
|
||||
Expect(labels).To(HaveKeyWithValue(utils.KubernetesAppComponentLabelName, utils.DatabaseComponentName))
|
||||
Expect(labels).To(HaveKeyWithValue(utils.KubernetesAppManagedByLabelName, metadata.ManagedByLabelValue))
|
||||
Expect(labels).To(HaveLen(6))
|
||||
})
|
||||
|
||||
It("should report the plugin version regardless of the cluster's Postgres image", func() {
|
||||
cluster := &cnpgv1.Cluster{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "pg16-cluster",
|
||||
Namespace: "default",
|
||||
},
|
||||
Spec: cnpgv1.ClusterSpec{
|
||||
ImageCatalogRef: &cnpgv1.ImageCatalogRef{
|
||||
Major: 16,
|
||||
},
|
||||
},
|
||||
}
|
||||
labels := BuildLabels(cluster)
|
||||
|
||||
Expect(labels).To(HaveKeyWithValue(utils.KubernetesAppVersionLabelName, metadata.Data.Version))
|
||||
Expect(labels).To(HaveKeyWithValue(utils.KubernetesAppInstanceLabelName, "pg16-cluster"))
|
||||
})
|
||||
})
|
||||
@ -29,7 +29,6 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
|
||||
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/metadata"
|
||||
)
|
||||
|
||||
// BuildRole builds the Role object for this cluster
|
||||
@ -41,15 +40,15 @@ func BuildRole(
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: cluster.Namespace,
|
||||
Name: GetRBACName(cluster.Name),
|
||||
Labels: map[string]string{
|
||||
metadata.ClusterLabelName: cluster.Name,
|
||||
},
|
||||
Labels: BuildLabels(cluster),
|
||||
},
|
||||
Rules: BuildRoleRules(barmanObjects),
|
||||
}
|
||||
}
|
||||
|
||||
// BuildRoleRules builds the RBAC PolicyRules for the given ObjectStores.
|
||||
//
|
||||
//nolint:goconst
|
||||
func BuildRoleRules(barmanObjects []barmancloudv1.ObjectStore) []rbacv1.PolicyRule {
|
||||
secretsSet := stringset.New()
|
||||
barmanObjectsSet := stringset.New()
|
||||
@ -131,6 +130,7 @@ func BuildRoleBinding(
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: cluster.Namespace,
|
||||
Name: GetRBACName(cluster.Name),
|
||||
Labels: BuildLabels(cluster),
|
||||
},
|
||||
Subjects: []rbacv1.Subject{
|
||||
{
|
||||
|
||||
@ -46,7 +46,7 @@ import (
|
||||
func newFakeScheme() *runtime.Scheme {
|
||||
s := runtime.NewScheme()
|
||||
utilruntime.Must(rbacv1.AddToScheme(s))
|
||||
utilruntime.Must(barmancloudv1.AddToScheme(s))
|
||||
barmancloudv1.AddKnownTypes(s)
|
||||
return s
|
||||
}
|
||||
|
||||
|
||||
@ -27,8 +27,6 @@ import (
|
||||
"github.com/spf13/viper"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
crscheme "sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
// AddCNPGToScheme registers CNPG types into the given scheme using
|
||||
@ -46,11 +44,11 @@ func AddCNPGToScheme(ctx context.Context, s *runtime.Scheme) {
|
||||
}
|
||||
|
||||
schemeGroupVersion := schema.GroupVersion{Group: cnpgGroup, Version: cnpgVersion}
|
||||
schemeBuilder := &crscheme.Builder{GroupVersion: schemeGroupVersion}
|
||||
schemeBuilder.Register(&cnpgv1.Cluster{}, &cnpgv1.ClusterList{})
|
||||
schemeBuilder.Register(&cnpgv1.Backup{}, &cnpgv1.BackupList{})
|
||||
schemeBuilder.Register(&cnpgv1.ScheduledBackup{}, &cnpgv1.ScheduledBackupList{})
|
||||
utilruntime.Must(schemeBuilder.AddToScheme(s))
|
||||
s.AddKnownTypes(schemeGroupVersion,
|
||||
&cnpgv1.Cluster{}, &cnpgv1.ClusterList{},
|
||||
&cnpgv1.Backup{}, &cnpgv1.BackupList{},
|
||||
&cnpgv1.ScheduledBackup{}, &cnpgv1.ScheduledBackupList{},
|
||||
)
|
||||
|
||||
log.FromContext(ctx).Info("CNPG types registration", "schemeGroupVersion", schemeGroupVersion)
|
||||
}
|
||||
|
||||
@ -91,12 +91,11 @@ func addScheme(cl client.Client) error {
|
||||
if err := certmanagerv1.AddToScheme(scheme); err != nil {
|
||||
return fmt.Errorf("failed to add cert-manager/v1 to scheme: %w", err)
|
||||
}
|
||||
if err := pluginBarmanCloudV1.AddToScheme(scheme); err != nil {
|
||||
return fmt.Errorf("failed to add plugin-barman-cloud/v1 to scheme: %w", err)
|
||||
}
|
||||
if err := cloudnativepgv1.AddToScheme(scheme); err != nil {
|
||||
return fmt.Errorf("failed to add cloudnativepg/v1 to scheme: %w", err)
|
||||
}
|
||||
|
||||
pluginBarmanCloudV1.AddKnownTypes(scheme)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -129,6 +129,48 @@ These strategies help you safeguard backups without requiring broad delete
|
||||
permissions, ensuring both security and compliance with minimal operational
|
||||
overhead.
|
||||
|
||||
### S3 Lifecycle Policy
|
||||
|
||||
Barman Cloud requires the following permissions in the S3 bucket:
|
||||
|
||||
- [`s3:AbortMultipartUpload`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_AbortMultipartUpload.html)
|
||||
- [`s3:DeleteObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObject.html)
|
||||
- [`s3:GetObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html)
|
||||
- [`s3:ListBucketMultipartUploads`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListMultipartUploads.html)
|
||||
- [`s3:ListBucket`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html)
|
||||
- [`s3:ListMultipartUploadParts`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListParts.html)
|
||||
- [`s3:PutObject`](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)
|
||||
|
||||
Here's an example of what such a bucket policy may look like:
|
||||
|
||||
```json
|
||||
{
|
||||
"Statement": [
|
||||
{
|
||||
"Action": [
|
||||
"s3:AbortMultipartUpload",
|
||||
"s3:DeleteObject",
|
||||
"s3:GetObject",
|
||||
"s3:ListBucket",
|
||||
"s3:ListBucketMultipartUploads",
|
||||
"s3:ListMultipartUploadParts",
|
||||
"s3:PutObject"
|
||||
],
|
||||
"Effect": "Allow",
|
||||
"Principal": {
|
||||
"AWS": "arn:aws:iam::123456789012:user/MaryMajor"
|
||||
},
|
||||
"Resource": [
|
||||
"arn:aws:s3:::amzn-s3-demo-bucket1",
|
||||
"arn:aws:s3:::amzn-s3-demo-bucket1/*"
|
||||
],
|
||||
"Sid": "statement1",
|
||||
}
|
||||
],
|
||||
"Version":"2012-10-17"
|
||||
}
|
||||
```
|
||||
|
||||
### S3-Compatible Storage Providers
|
||||
|
||||
You can use S3-compatible services like **MinIO**, **Linode (Akamai) Object Storage**,
|
||||
|
||||
@ -15,8 +15,8 @@
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.10.0",
|
||||
"@docusaurus/preset-classic": "3.10.0",
|
||||
"@docusaurus/core": "3.10.1",
|
||||
"@docusaurus/preset-classic": "3.10.1",
|
||||
"@easyops-cn/docusaurus-search-local": "^0.55.0",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
@ -25,9 +25,9 @@
|
||||
"react-dom": "^19.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.10.0",
|
||||
"@docusaurus/tsconfig": "3.10.0",
|
||||
"@docusaurus/types": "3.10.0",
|
||||
"@docusaurus/module-type-aliases": "3.10.1",
|
||||
"@docusaurus/tsconfig": "3.10.1",
|
||||
"@docusaurus/types": "3.10.1",
|
||||
"typescript": "~6.0.0"
|
||||
},
|
||||
"browserslist": {
|
||||
|
||||
530
web/yarn.lock
530
web/yarn.lock
@ -1510,6 +1510,26 @@
|
||||
fs-extra "^11.1.1"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/babel@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/babel/-/babel-3.10.1.tgz#2f714f682117658ba43d308e9b35b6a73a105227"
|
||||
integrity sha512-DZzFO1K3v/GoEt1fx1DiYHF4en+PuhtQf1AkQJa5zu3CoeKSpr5cpQRUlz3jr0m44wyzmSXu9bVpfir+N4+8bg==
|
||||
dependencies:
|
||||
"@babel/core" "^7.25.9"
|
||||
"@babel/generator" "^7.25.9"
|
||||
"@babel/plugin-syntax-dynamic-import" "^7.8.3"
|
||||
"@babel/plugin-transform-runtime" "^7.25.9"
|
||||
"@babel/preset-env" "^7.25.9"
|
||||
"@babel/preset-react" "^7.25.9"
|
||||
"@babel/preset-typescript" "^7.25.9"
|
||||
"@babel/runtime" "^7.25.9"
|
||||
"@babel/traverse" "^7.25.9"
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
babel-plugin-dynamic-import-node "^2.3.3"
|
||||
fs-extra "^11.1.1"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/bundler@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/bundler/-/bundler-3.10.0.tgz#878c4c46bfa3434671ea37a43da184238a6aae26"
|
||||
@ -1540,6 +1560,36 @@
|
||||
webpack "^5.95.0"
|
||||
webpackbar "^6.0.1"
|
||||
|
||||
"@docusaurus/bundler@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/bundler/-/bundler-3.10.1.tgz#82fa5079f3787a67502e25f82d37d05ec5de0cc3"
|
||||
integrity sha512-HIqQPvbqnnQRe4NsBd1774KRarjXqS6wHsWELtyuSs1gCfvixJO2jUGH/OEBtr1Gvzpw+ze5CjGMvSJ8UE1KUw==
|
||||
dependencies:
|
||||
"@babel/core" "^7.25.9"
|
||||
"@docusaurus/babel" "3.10.1"
|
||||
"@docusaurus/cssnano-preset" "3.10.1"
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
babel-loader "^9.2.1"
|
||||
clean-css "^5.3.3"
|
||||
copy-webpack-plugin "^11.0.0"
|
||||
css-loader "^6.11.0"
|
||||
css-minimizer-webpack-plugin "^5.0.1"
|
||||
cssnano "^6.1.2"
|
||||
file-loader "^6.2.0"
|
||||
html-minifier-terser "^7.2.0"
|
||||
mini-css-extract-plugin "^2.9.2"
|
||||
null-loader "^4.0.1"
|
||||
postcss "^8.5.4"
|
||||
postcss-loader "^7.3.4"
|
||||
postcss-preset-env "^10.2.1"
|
||||
terser-webpack-plugin "^5.3.9"
|
||||
tslib "^2.6.0"
|
||||
url-loader "^4.1.1"
|
||||
webpack "^5.95.0"
|
||||
webpackbar "^7.0.0"
|
||||
|
||||
"@docusaurus/core@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-3.10.0.tgz#642e71a0209d62c3f5ef275ed9d74a881f40df39"
|
||||
@ -1588,6 +1638,54 @@
|
||||
webpack-dev-server "^5.2.2"
|
||||
webpack-merge "^6.0.1"
|
||||
|
||||
"@docusaurus/core@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/core/-/core-3.10.1.tgz#3f8bdb97451b4df14f2a3b39ab0186366fbf8fbe"
|
||||
integrity sha512-3pf2fXXw0eVk8WnC3T4LIigRDupcpvngpKo9Vy7mYyBhuddc0klDUuZAIfzMoK6z05pdlk6EFC/vBSX43+1O5w==
|
||||
dependencies:
|
||||
"@docusaurus/babel" "3.10.1"
|
||||
"@docusaurus/bundler" "3.10.1"
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/mdx-loader" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-common" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
boxen "^6.2.1"
|
||||
chalk "^4.1.2"
|
||||
chokidar "^3.5.3"
|
||||
cli-table3 "^0.6.3"
|
||||
combine-promises "^1.1.0"
|
||||
commander "^5.1.0"
|
||||
core-js "^3.31.1"
|
||||
detect-port "^1.5.1"
|
||||
escape-html "^1.0.3"
|
||||
eta "^2.2.0"
|
||||
eval "^0.1.8"
|
||||
execa "^5.1.1"
|
||||
fs-extra "^11.1.1"
|
||||
html-tags "^3.3.1"
|
||||
html-webpack-plugin "^5.6.0"
|
||||
leven "^3.1.0"
|
||||
lodash "^4.17.21"
|
||||
open "^8.4.0"
|
||||
p-map "^4.0.0"
|
||||
prompts "^2.4.2"
|
||||
react-helmet-async "npm:@slorber/react-helmet-async@1.3.0"
|
||||
react-loadable "npm:@docusaurus/react-loadable@6.0.0"
|
||||
react-loadable-ssr-addon-v5-slorber "^1.0.3"
|
||||
react-router "^5.3.4"
|
||||
react-router-config "^5.1.1"
|
||||
react-router-dom "^5.3.4"
|
||||
semver "^7.5.4"
|
||||
serve-handler "^6.1.7"
|
||||
tinypool "^1.0.2"
|
||||
tslib "^2.6.0"
|
||||
update-notifier "^6.0.2"
|
||||
webpack "^5.95.0"
|
||||
webpack-bundle-analyzer "^4.10.2"
|
||||
webpack-dev-server "^5.2.2"
|
||||
webpack-merge "^6.0.1"
|
||||
|
||||
"@docusaurus/cssnano-preset@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.10.0.tgz#be1b435c33df09d743473d3fadda67b4568dfae3"
|
||||
@ -1598,6 +1696,16 @@
|
||||
postcss-sort-media-queries "^5.2.0"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/cssnano-preset@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/cssnano-preset/-/cssnano-preset-3.10.1.tgz#4b6bafeca8bb9423364d2fd6683c28e2f85a4665"
|
||||
integrity sha512-eNfHGcTKCSq6xmcavAkX3RRclHaE2xRCMParlDXLdXVP01/a2e/jKXMj/0ULnLFQSNwwuI62L0Ge8J+nZsR7UQ==
|
||||
dependencies:
|
||||
cssnano-preset-advanced "^6.1.2"
|
||||
postcss "^8.5.4"
|
||||
postcss-sort-media-queries "^5.2.0"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/logger@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.10.0.tgz#2bacbd004dd78e3da926dbe8f6fa9a930856575d"
|
||||
@ -1606,6 +1714,14 @@
|
||||
chalk "^4.1.2"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/logger@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/logger/-/logger-3.10.1.tgz#34c964e32e18f120e30f80171a38cfefe72cfb4b"
|
||||
integrity sha512-oPjNFnfJsRCkePVjkGrxWGq4MvJKRQT0r9jOP0eRBTZ7Wr9FAbzdP/Gjs0I2Ss6YRkPoEgygKG112OkE6skvJw==
|
||||
dependencies:
|
||||
chalk "^4.1.2"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/mdx-loader@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.10.0.tgz#1d4b050d751389ecf38dee48bcb61e53df8ffb82"
|
||||
@ -1636,6 +1752,36 @@
|
||||
vfile "^6.0.1"
|
||||
webpack "^5.88.1"
|
||||
|
||||
"@docusaurus/mdx-loader@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/mdx-loader/-/mdx-loader-3.10.1.tgz#050ae9bc614158a4ec07a628aa75fa9ae90d7e82"
|
||||
integrity sha512-GRmeb/wQ+iXRrFwcHBfgQhrJxGElgCsoTWZYDhccjsZVne1p8MK/EpQVIloXttz76TCe78kKD5AEG9n1xc1oxQ==
|
||||
dependencies:
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
"@mdx-js/mdx" "^3.0.0"
|
||||
"@slorber/remark-comment" "^1.0.0"
|
||||
escape-html "^1.0.3"
|
||||
estree-util-value-to-estree "^3.0.1"
|
||||
file-loader "^6.2.0"
|
||||
fs-extra "^11.1.1"
|
||||
image-size "^2.0.2"
|
||||
mdast-util-mdx "^3.0.0"
|
||||
mdast-util-to-string "^4.0.0"
|
||||
rehype-raw "^7.0.0"
|
||||
remark-directive "^3.0.0"
|
||||
remark-emoji "^4.0.0"
|
||||
remark-frontmatter "^5.0.0"
|
||||
remark-gfm "^4.0.0"
|
||||
stringify-object "^3.3.0"
|
||||
tslib "^2.6.0"
|
||||
unified "^11.0.3"
|
||||
unist-util-visit "^5.0.0"
|
||||
url-loader "^4.1.1"
|
||||
vfile "^6.0.1"
|
||||
webpack "^5.88.1"
|
||||
|
||||
"@docusaurus/module-type-aliases@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.10.0.tgz#749928f104d563f11f046bf0c9ab6489a470c7c8"
|
||||
@ -1649,19 +1795,32 @@
|
||||
react-helmet-async "npm:@slorber/react-helmet-async@1.3.0"
|
||||
react-loadable "npm:@docusaurus/react-loadable@6.0.0"
|
||||
|
||||
"@docusaurus/plugin-content-blog@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.10.0.tgz#10095291b637440847854ecb2c8afcd8746debd7"
|
||||
integrity sha512-RuTz68DhB7CL96QO5UsFbciD7GPYq6QV+YMfF9V0+N4ZgLhJIBgpVAr8GobrKF6NRe5cyWWETU5z5T834piG9g==
|
||||
"@docusaurus/module-type-aliases@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/module-type-aliases/-/module-type-aliases-3.10.1.tgz#22d39177c296786eb6e0d940699cd590cc93ca77"
|
||||
integrity sha512-YoOZKUdGlp8xSYhuAkGdSo5Ydkbq4V4eK3sD8v0a2hloxCWdQbNBhkc+Ko9QyjpESc0BYcIGM5iHVAy5hdFV6w==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/logger" "3.10.0"
|
||||
"@docusaurus/mdx-loader" "3.10.0"
|
||||
"@docusaurus/theme-common" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/utils" "3.10.0"
|
||||
"@docusaurus/utils-common" "3.10.0"
|
||||
"@docusaurus/utils-validation" "3.10.0"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@types/history" "^4.7.11"
|
||||
"@types/react" "*"
|
||||
"@types/react-router-config" "*"
|
||||
"@types/react-router-dom" "*"
|
||||
react-helmet-async "npm:@slorber/react-helmet-async@1.3.0"
|
||||
react-loadable "npm:@docusaurus/react-loadable@6.0.0"
|
||||
|
||||
"@docusaurus/plugin-content-blog@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.10.1.tgz#0bd8de700ccbd8e95d920df2613304ef59abe72b"
|
||||
integrity sha512-mmkgE6Q2+K74tnkou7tXlpDLvoCU/qkSa2GSQ3XUiHWvcebCoDQzS670RR3tO8PmaWlIyWWISYWzZLuMfxunRA==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/mdx-loader" "3.10.1"
|
||||
"@docusaurus/theme-common" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-common" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
cheerio "1.0.0-rc.12"
|
||||
combine-promises "^1.1.0"
|
||||
feed "^4.2.2"
|
||||
@ -1674,7 +1833,31 @@
|
||||
utility-types "^3.10.0"
|
||||
webpack "^5.88.1"
|
||||
|
||||
"@docusaurus/plugin-content-docs@3.10.0", "@docusaurus/plugin-content-docs@^2 || ^3":
|
||||
"@docusaurus/plugin-content-docs@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.10.1.tgz#261e0e982e4a937c05b462e3c5729374f433b752"
|
||||
integrity sha512-2jRVrtzjf8LClGTHQlwlwuD3wQXRx3WEoF7XUarJ8Ou+0onV+SLtejsyfY9JLpfUh9hPhXM4pbBGkyAY4Bi3HQ==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/mdx-loader" "3.10.1"
|
||||
"@docusaurus/module-type-aliases" "3.10.1"
|
||||
"@docusaurus/theme-common" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-common" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
"@types/react-router-config" "^5.0.7"
|
||||
combine-promises "^1.1.0"
|
||||
fs-extra "^11.1.1"
|
||||
js-yaml "^4.1.0"
|
||||
lodash "^4.17.21"
|
||||
schema-dts "^1.1.2"
|
||||
tslib "^2.6.0"
|
||||
utility-types "^3.10.0"
|
||||
webpack "^5.88.1"
|
||||
|
||||
"@docusaurus/plugin-content-docs@^2 || ^3":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.10.0.tgz#9c4ea1d5a405340f28c281d2e4586c695a7c65a5"
|
||||
integrity sha512-9BjHhf15ct8Z7TThTC0xRndKDVvMKmVsAGAN7W9FpNRzfMdScOGcXtLmcCWtJGvAezjOJIm6CxOYCy3Io5+RnQ==
|
||||
@ -1698,142 +1881,142 @@
|
||||
utility-types "^3.10.0"
|
||||
webpack "^5.88.1"
|
||||
|
||||
"@docusaurus/plugin-content-pages@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.10.0.tgz#7670cbb3c849f434949f542bfdfded1580a13165"
|
||||
integrity sha512-5amX8kEJI+nIGtuLVjYk59Y5utEJ3CHETFOPEE4cooIRLA4xM4iBsA6zFgu4ljcopeYwvBzFEWf5g2I6Yb9SkA==
|
||||
"@docusaurus/plugin-content-pages@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.10.1.tgz#8c6ffc2079ed0262548ecc4df1dea6add6aa9673"
|
||||
integrity sha512-huJpaRPMl42nsFwuCXvV8bVDj2MazuwRJIUylI/RSlmZeJssVoZXeCjVf1y+1Drtpa9SKcdGn8yoJ76IRJijtw==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/mdx-loader" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/utils" "3.10.0"
|
||||
"@docusaurus/utils-validation" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/mdx-loader" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
fs-extra "^11.1.1"
|
||||
tslib "^2.6.0"
|
||||
webpack "^5.88.1"
|
||||
|
||||
"@docusaurus/plugin-css-cascade-layers@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.10.0.tgz#71e318d842be95f92be6c3dca00ceea4971d0edb"
|
||||
integrity sha512-6q1vtt5FJcg5osgkHeM1euErECNqEZ5Z1j69yiNx2luEBIso+nxCkS9nqj8w+MK5X7rvKEToGhFfOFWncs51pQ==
|
||||
"@docusaurus/plugin-css-cascade-layers@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-css-cascade-layers/-/plugin-css-cascade-layers-3.10.1.tgz#440578d95cbe1a6120936fa83df868d2626cd1d8"
|
||||
integrity sha512-r//fn+MNHkE1wCof8T29VAQezt1enGCpsFxoziBbvLgBM4JfXN2P3rxrBaavHmvLvm7lYkpJeitcDthwnmWCTw==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/utils" "3.10.0"
|
||||
"@docusaurus/utils-validation" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/plugin-debug@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-3.10.0.tgz#e77f924604e1e09d5d90fe0bdf23a3be8ea3307e"
|
||||
integrity sha512-XcljKN+G+nmmK69uQA1d9BlYU3ZftG3T3zpK8/7Hf/wrOlV7TA4Ampdrdwkg0jElKdKAoSnPhCO0/U3bQGsVQQ==
|
||||
"@docusaurus/plugin-debug@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-debug/-/plugin-debug-3.10.1.tgz#b8b7b24d9a7d185fd8a56a030f90145d3bfd8239"
|
||||
integrity sha512-9KqOpKNfAyqGZykRb9LhIT/vyRF6sm/ykhjj/39JvaJahDS+jZJE0Z1Wfz9q3DUNDTMNN0Q7u/kk4rKKU+IJuA==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/utils" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
fs-extra "^11.1.1"
|
||||
react-json-view-lite "^2.3.0"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/plugin-google-analytics@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.10.0.tgz#22c7e976fe4d970c7cd1c73c9723d9a5786c6e37"
|
||||
integrity sha512-hTEoodatpBZnUat5nFExbuTGA1lhWGy7vZGuTew5Q3QDtGKFpSJLYmZJhdTjvCFwv1+qQ67hgAVlKdJOB8TXow==
|
||||
"@docusaurus/plugin-google-analytics@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.10.1.tgz#ac15afc77386e0352edb8a1698d993aa5de36ffc"
|
||||
integrity sha512-8o0P1KtmgdYQHH+oInitPpRWI0Of5XednAX4+DMhQNSmGSRNrsEEHg1ebv35m9AgRClfAytCJ5jA9KvcASTyuA==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/utils-validation" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/plugin-google-gtag@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.10.0.tgz#c38a2ba638257851cc845b934506b80c08d47f96"
|
||||
integrity sha512-iB/Zzjv/eelJRbdULZqzWCbgMgJ7ht4ONVjXtN3+BI/muil6S87gQ1OJyPwlXD+ELdKkitC7bWv5eJdYOZLhrQ==
|
||||
"@docusaurus/plugin-google-gtag@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.10.1.tgz#0482b83b9bc411aa99a432be2b39d2e53a00e2e0"
|
||||
integrity sha512-pu3xIUo5o/zCMLfUY9BO5KOwSH0zIsAGyFRPvXHayFSA5XIhCU/SFuB0g0ZNjFn9niZLCaNvoeAuOGFJZq0fdw==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/utils-validation" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
"@types/gtag.js" "^0.0.20"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/plugin-google-tag-manager@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.10.0.tgz#5469c923cc1ad4608399d0b17e5fcacd8e030d56"
|
||||
integrity sha512-FEjZxqKgLHa+Wez/EgKxRwvArNCWIScfyEQD95rot7jkxp6nonjI5XIbGfO/iYhM5Qinwe8aIEQHP2KZtpqVuA==
|
||||
"@docusaurus/plugin-google-tag-manager@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.10.1.tgz#eaf5765d6f82b4fb661d92a793d1883f9d1ec106"
|
||||
integrity sha512-f6fyGHiCm7kJHBtAisGQS5oNBnpnMTYQZxDXeVrnw/3zWU+LMA22pr6UHGYkBKDbN+qPC5QHG3NuOfzQLq3+Lw==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/utils-validation" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/plugin-sitemap@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.10.0.tgz#35d59d46803f279f22aa64fc1bd18c048f12662b"
|
||||
integrity sha512-DVTSLjB97hIjmayGnGcBfognCeI7ZuUKgEnU7Oz81JYqXtVg94mVTthDjq3QHTylYNeCUbkaW8VF0FDLcc8pPw==
|
||||
"@docusaurus/plugin-sitemap@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.10.1.tgz#66a6974bb2fd1b9d8f5cb0f3c5ecd2201c118565"
|
||||
integrity sha512-C26MbmmqgdjkDq1htaZ3aD7LzEDKFWXfpyQpt0EOUThuq5nV77zDaedV20yHcVo9p+3ey9aZ4pbHA0D3QcZTzg==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/logger" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/utils" "3.10.0"
|
||||
"@docusaurus/utils-common" "3.10.0"
|
||||
"@docusaurus/utils-validation" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-common" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
fs-extra "^11.1.1"
|
||||
sitemap "^7.1.1"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/plugin-svgr@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-svgr/-/plugin-svgr-3.10.0.tgz#8ada2e6dd8318d20206a9b044fc091a5794ba3f0"
|
||||
integrity sha512-lNljBESaETZqVBMPqkrGchr+UPT1eZzEPLmJhz8I76BxbjqgsUnRvrq6lQJ9sYjgmgX52KB7kkgczqd2yzoswQ==
|
||||
"@docusaurus/plugin-svgr@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/plugin-svgr/-/plugin-svgr-3.10.1.tgz#c217c24d6d23fd2bc6f54d44c040635b49d6b36e"
|
||||
integrity sha512-6SFxsmjWFkVLDmBUvFK6i72QjUwqyQFe4Ovz+SUJophJjOyVG3ZZG5IQpBC/kX/Gfv1yWeU9nWauH6F6Q7QX/Q==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/utils" "3.10.0"
|
||||
"@docusaurus/utils-validation" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
"@svgr/core" "8.1.0"
|
||||
"@svgr/webpack" "^8.1.0"
|
||||
tslib "^2.6.0"
|
||||
webpack "^5.88.1"
|
||||
|
||||
"@docusaurus/preset-classic@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-3.10.0.tgz#74b6facdaf568bcd41ec90cae9aebb7ca0ac8619"
|
||||
integrity sha512-kw/Ye02Hc6xP1OdTswy8yxQEHg0fdPpyWAQRxr5b2x3h7LlG2Zgbb5BDFROnXDDMpUxB7YejlocJIE5HIEfpNA==
|
||||
"@docusaurus/preset-classic@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/preset-classic/-/preset-classic-3.10.1.tgz#faf330d96aedc9083a59bec09d966ae4dfc8b2fb"
|
||||
integrity sha512-YO/FL8v1zmbxoTso6mjMz/RDjhaTJxb1UpFFTDdY5847LLDCeyYiYlrhyTbgN1RIN3xnkLKZ9Lj1x8hUzI4JOg==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/plugin-content-blog" "3.10.0"
|
||||
"@docusaurus/plugin-content-docs" "3.10.0"
|
||||
"@docusaurus/plugin-content-pages" "3.10.0"
|
||||
"@docusaurus/plugin-css-cascade-layers" "3.10.0"
|
||||
"@docusaurus/plugin-debug" "3.10.0"
|
||||
"@docusaurus/plugin-google-analytics" "3.10.0"
|
||||
"@docusaurus/plugin-google-gtag" "3.10.0"
|
||||
"@docusaurus/plugin-google-tag-manager" "3.10.0"
|
||||
"@docusaurus/plugin-sitemap" "3.10.0"
|
||||
"@docusaurus/plugin-svgr" "3.10.0"
|
||||
"@docusaurus/theme-classic" "3.10.0"
|
||||
"@docusaurus/theme-common" "3.10.0"
|
||||
"@docusaurus/theme-search-algolia" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/plugin-content-blog" "3.10.1"
|
||||
"@docusaurus/plugin-content-docs" "3.10.1"
|
||||
"@docusaurus/plugin-content-pages" "3.10.1"
|
||||
"@docusaurus/plugin-css-cascade-layers" "3.10.1"
|
||||
"@docusaurus/plugin-debug" "3.10.1"
|
||||
"@docusaurus/plugin-google-analytics" "3.10.1"
|
||||
"@docusaurus/plugin-google-gtag" "3.10.1"
|
||||
"@docusaurus/plugin-google-tag-manager" "3.10.1"
|
||||
"@docusaurus/plugin-sitemap" "3.10.1"
|
||||
"@docusaurus/plugin-svgr" "3.10.1"
|
||||
"@docusaurus/theme-classic" "3.10.1"
|
||||
"@docusaurus/theme-common" "3.10.1"
|
||||
"@docusaurus/theme-search-algolia" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
|
||||
"@docusaurus/theme-classic@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.10.0.tgz#d937915c691189f27ced649c822994d839ea565b"
|
||||
integrity sha512-9msCAsRdN+UG+RwPwCFb0uKy4tGoPh5YfBozXeGUtIeAgsMdn6f3G/oY861luZ3t8S2ET8S9Y/1GnpJAGWytww==
|
||||
"@docusaurus/theme-classic@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/theme-classic/-/theme-classic-3.10.1.tgz#deed8cf73cc0f56113e53775cbb3b168c3c61566"
|
||||
integrity sha512-VU1RK0qb2pab0si4r7HFK37cYco8VzqLj3u1PspVipSr/z/GPVKHO4/HXbnePqHoWDk8urjyGSeatH0NIMBM1A==
|
||||
dependencies:
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/logger" "3.10.0"
|
||||
"@docusaurus/mdx-loader" "3.10.0"
|
||||
"@docusaurus/module-type-aliases" "3.10.0"
|
||||
"@docusaurus/plugin-content-blog" "3.10.0"
|
||||
"@docusaurus/plugin-content-docs" "3.10.0"
|
||||
"@docusaurus/plugin-content-pages" "3.10.0"
|
||||
"@docusaurus/theme-common" "3.10.0"
|
||||
"@docusaurus/theme-translations" "3.10.0"
|
||||
"@docusaurus/types" "3.10.0"
|
||||
"@docusaurus/utils" "3.10.0"
|
||||
"@docusaurus/utils-common" "3.10.0"
|
||||
"@docusaurus/utils-validation" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/mdx-loader" "3.10.1"
|
||||
"@docusaurus/module-type-aliases" "3.10.1"
|
||||
"@docusaurus/plugin-content-blog" "3.10.1"
|
||||
"@docusaurus/plugin-content-docs" "3.10.1"
|
||||
"@docusaurus/plugin-content-pages" "3.10.1"
|
||||
"@docusaurus/theme-common" "3.10.1"
|
||||
"@docusaurus/theme-translations" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-common" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
"@mdx-js/react" "^3.0.0"
|
||||
clsx "^2.0.0"
|
||||
copy-text-to-clipboard "^3.2.0"
|
||||
@ -1866,20 +2049,38 @@
|
||||
tslib "^2.6.0"
|
||||
utility-types "^3.10.0"
|
||||
|
||||
"@docusaurus/theme-search-algolia@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.10.0.tgz#0ff57fe58db6abde8f5ad2877e459cd2fa6e7464"
|
||||
integrity sha512-f5FPKI08e3JRG63vR/o4qeuUVHUHzFzM0nnF+AkB67soAZgNsKJRf2qmUZvlQkGwlV+QFkKe4D0ANMh1jToU3g==
|
||||
"@docusaurus/theme-common@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/theme-common/-/theme-common-3.10.1.tgz#cbfec82b1b107be5c229811ed9caae14a501361c"
|
||||
integrity sha512-0YtmIeoNo1fIw65LO8+/1dPgmDV86UmhMkow37gzjytuiCSQm9xob6PJy0L4kuQEMTLfUOGvkXvZr7GPrHquMA==
|
||||
dependencies:
|
||||
"@docusaurus/mdx-loader" "3.10.1"
|
||||
"@docusaurus/module-type-aliases" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-common" "3.10.1"
|
||||
"@types/history" "^4.7.11"
|
||||
"@types/react" "*"
|
||||
"@types/react-router-config" "*"
|
||||
clsx "^2.0.0"
|
||||
parse-numeric-range "^1.3.0"
|
||||
prism-react-renderer "^2.3.0"
|
||||
tslib "^2.6.0"
|
||||
utility-types "^3.10.0"
|
||||
|
||||
"@docusaurus/theme-search-algolia@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.10.1.tgz#6f422058711629ce8d7c2f17e1e54efa075c626e"
|
||||
integrity sha512-OTaARARVZj2GvkJQjB+1jOIxntRaXea+G+fMsNqrZBAU1O1vJKDW22R7kECOHW27oJCLFN9HKaZeRrfAUyviug==
|
||||
dependencies:
|
||||
"@algolia/autocomplete-core" "^1.19.2"
|
||||
"@docsearch/react" "^3.9.0 || ^4.3.2"
|
||||
"@docusaurus/core" "3.10.0"
|
||||
"@docusaurus/logger" "3.10.0"
|
||||
"@docusaurus/plugin-content-docs" "3.10.0"
|
||||
"@docusaurus/theme-common" "3.10.0"
|
||||
"@docusaurus/theme-translations" "3.10.0"
|
||||
"@docusaurus/utils" "3.10.0"
|
||||
"@docusaurus/utils-validation" "3.10.0"
|
||||
"@docusaurus/core" "3.10.1"
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/plugin-content-docs" "3.10.1"
|
||||
"@docusaurus/theme-common" "3.10.1"
|
||||
"@docusaurus/theme-translations" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-validation" "3.10.1"
|
||||
algoliasearch "^5.37.0"
|
||||
algoliasearch-helper "^3.26.0"
|
||||
clsx "^2.0.0"
|
||||
@ -1889,7 +2090,15 @@
|
||||
tslib "^2.6.0"
|
||||
utility-types "^3.10.0"
|
||||
|
||||
"@docusaurus/theme-translations@3.10.0", "@docusaurus/theme-translations@^2 || ^3":
|
||||
"@docusaurus/theme-translations@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.10.1.tgz#c3119a015652290eea560ca45ac775963d6eb75b"
|
||||
integrity sha512-cLMyaKivjBVWKMJuWqyFVVgtqe8DPJNPkog0bn8W1MDVAKcPdxRFycBfC1We1RaNp7Rdk513bmtW78RR6OBxBw==
|
||||
dependencies:
|
||||
fs-extra "^11.1.1"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/theme-translations@^2 || ^3":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/theme-translations/-/theme-translations-3.10.0.tgz#8fdc23d29bd7f907db49c36cf65e2123d96be300"
|
||||
integrity sha512-L9IbFLwTc5+XdgH45iQYufLn0SVZd6BUNelDbKIFlH+E4hhjuj/XHWAFMX/w2K59rfy8wak9McOaei7BSUfRPA==
|
||||
@ -1897,10 +2106,10 @@
|
||||
fs-extra "^11.1.1"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/tsconfig@3.10.0":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/tsconfig/-/tsconfig-3.10.0.tgz#f40a57248828f0503a5f355cf30aa59941c9baaa"
|
||||
integrity sha512-TXdC3WXuPrdQAexLvjUJfnYf3YKEgEqAs5nK0Q88pRBCW7t7oN4ILvWYb3A5Z1wlSXyXGWW/mCUmLEhdWsjnDQ==
|
||||
"@docusaurus/tsconfig@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/tsconfig/-/tsconfig-3.10.1.tgz#1db31b4a4a5c914bdffa80070a35b6365d34f2e8"
|
||||
integrity sha512-rYvB7yqkdqWIpAbDzQljGfM4cDBkLTbhmagZBEcsyj6oPUsz47lmW2pYdN1j+7sGFgltbAmQH62xfbrij4Eh6Q==
|
||||
|
||||
"@docusaurus/types@3.10.0":
|
||||
version "3.10.0"
|
||||
@ -1918,6 +2127,22 @@
|
||||
webpack "^5.95.0"
|
||||
webpack-merge "^5.9.0"
|
||||
|
||||
"@docusaurus/types@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/types/-/types-3.10.1.tgz#d42837938ae43ca2be0ca47e63e00476b5eb94be"
|
||||
integrity sha512-XYMK8k1szDCFMw2V+Xyen0g7Kee1sP3dtFnl7vkGkZOkeAJ/oPDQPL8iz4HBKOo/cwU8QeV6onVjMqtP+tFzsw==
|
||||
dependencies:
|
||||
"@mdx-js/mdx" "^3.0.0"
|
||||
"@types/history" "^4.7.11"
|
||||
"@types/mdast" "^4.0.2"
|
||||
"@types/react" "*"
|
||||
commander "^5.1.0"
|
||||
joi "^17.9.2"
|
||||
react-helmet-async "npm:@slorber/react-helmet-async@1.3.0"
|
||||
utility-types "^3.10.0"
|
||||
webpack "^5.95.0"
|
||||
webpack-merge "^5.9.0"
|
||||
|
||||
"@docusaurus/utils-common@3.10.0", "@docusaurus/utils-common@^2 || ^3":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.10.0.tgz#2a6dc76b312664fca7234d33607c085318ff1ae3"
|
||||
@ -1926,6 +2151,14 @@
|
||||
"@docusaurus/types" "3.10.0"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/utils-common@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/utils-common/-/utils-common-3.10.1.tgz#6350b4898691e765de750f90eade0e0fa7902d99"
|
||||
integrity sha512-5mFSgEADtnFxFH7RLw02QA5MpU5JVUCj0MPeIvi/aF4Fi45tQRIuTwXoXDqJ+1VfQJuYJGz3SI63wmGz4HvXzA==
|
||||
dependencies:
|
||||
"@docusaurus/types" "3.10.1"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/utils-validation@3.10.0", "@docusaurus/utils-validation@^2 || ^3":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.10.0.tgz#a2418d7f31980d991fd3a1f39c8aad8820b36812"
|
||||
@ -1940,6 +2173,20 @@
|
||||
lodash "^4.17.21"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/utils-validation@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/utils-validation/-/utils-validation-3.10.1.tgz#ddbcce997a5506424cdd16abf6845cc51692acae"
|
||||
integrity sha512-cRv1X69jwaWv47waglllgZVWzeBFLhl53XT/XED/83BerVBTC5FTP8WTcVl8Z6sZOegDSwitu/wpCSPCDOT6lg==
|
||||
dependencies:
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/utils" "3.10.1"
|
||||
"@docusaurus/utils-common" "3.10.1"
|
||||
fs-extra "^11.2.0"
|
||||
joi "^17.9.2"
|
||||
js-yaml "^4.1.0"
|
||||
lodash "^4.17.21"
|
||||
tslib "^2.6.0"
|
||||
|
||||
"@docusaurus/utils@3.10.0", "@docusaurus/utils@^2 || ^3":
|
||||
version "3.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.10.0.tgz#ea7d7b0d325b60f728decc00bb3908d00ef86faf"
|
||||
@ -1967,6 +2214,33 @@
|
||||
utility-types "^3.10.0"
|
||||
webpack "^5.88.1"
|
||||
|
||||
"@docusaurus/utils@3.10.1":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@docusaurus/utils/-/utils-3.10.1.tgz#535968caa2c9bff69f997a081b98b95b3c5d3785"
|
||||
integrity sha512-3ojeJry9xBYdJO6qoyyzqeJFSJBVx2mXhyDzSdjwL2+URFQMf+h25gG38iswGImicK0ELjTd1EL2xzk8hf3QPw==
|
||||
dependencies:
|
||||
"@docusaurus/logger" "3.10.1"
|
||||
"@docusaurus/types" "3.10.1"
|
||||
"@docusaurus/utils-common" "3.10.1"
|
||||
escape-string-regexp "^4.0.0"
|
||||
execa "^5.1.1"
|
||||
file-loader "^6.2.0"
|
||||
fs-extra "^11.1.1"
|
||||
github-slugger "^1.5.0"
|
||||
globby "^11.1.0"
|
||||
gray-matter "^4.0.3"
|
||||
jiti "^1.20.0"
|
||||
js-yaml "^4.1.0"
|
||||
lodash "^4.17.21"
|
||||
micromatch "^4.0.5"
|
||||
p-queue "^6.6.2"
|
||||
prompts "^2.4.2"
|
||||
resolve-pathname "^3.0.0"
|
||||
tslib "^2.6.0"
|
||||
url-loader "^4.1.1"
|
||||
utility-types "^3.10.0"
|
||||
webpack "^5.88.1"
|
||||
|
||||
"@easyops-cn/autocomplete.js@^0.38.1":
|
||||
version "0.38.1"
|
||||
resolved "https://registry.yarnpkg.com/@easyops-cn/autocomplete.js/-/autocomplete.js-0.38.1.tgz#46dff5795a9a032fa9b9250fdf63ca6c61c07629"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user