mirror of
https://github.com/kubernetes-sigs/external-dns.git
synced 2026-05-04 14:21:33 +02:00
Merge remote-tracking branch 'upstream/master' into mrozentsvayg/cloudflare-custom-hostname
This commit is contained in:
commit
147df48ff5
25
.github/workflows/lint-test-chart.yaml
vendored
25
.github/workflows/lint-test-chart.yaml
vendored
@ -18,6 +18,25 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
version: latest
|
||||
|
||||
- name: Run Helm Schema check
|
||||
working-directory: charts/external-dns
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
helm plugin install https://github.com/losisin/helm-values-schema-json.git
|
||||
helm schema
|
||||
if [[ -n "$(git status --porcelain --untracked-files=no)" ]]
|
||||
then
|
||||
echo "Schema not up to date. Please run helm schema and commit changes!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Install Helm Docs
|
||||
uses: action-stars/install-tool-from-github-release@ece2623611b240002e0dd73a0d685505733122f6 # v0.2.4
|
||||
with:
|
||||
@ -52,12 +71,6 @@ jobs:
|
||||
- name: Run Artifact Hub lint
|
||||
run: ah lint --kind helm || exit 1
|
||||
|
||||
- name: Install Helm
|
||||
uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0
|
||||
with:
|
||||
token: ${{ github.token }}
|
||||
version: latest
|
||||
|
||||
- name: Install Python
|
||||
uses: actions/setup-python@42375524e23c412d93fb67b49958b491fce71c38 # v5.4.0
|
||||
with:
|
||||
|
||||
41
Makefile
41
Makefile
@ -12,7 +12,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# cover-html creates coverage report for whole project excluding vendor and opens result in the default browser
|
||||
#? cover: Creates coverage report for whole project excluding vendor and opens result in the default browser
|
||||
.PHONY: cover cover-html
|
||||
.DEFAULT_GOAL := build
|
||||
|
||||
@ -24,11 +24,11 @@ cover:
|
||||
gocovmerge `ls *.coverprofile` > cover.out
|
||||
rm *.coverprofile
|
||||
|
||||
#? cover-html: Run tests with coverage and open coverage report in the browser
|
||||
cover-html: cover
|
||||
go tool cover -html cover.out
|
||||
|
||||
# find or download controller-gen
|
||||
# download controller-gen if necessary
|
||||
#? controller-gen: download controller-gen if necessary
|
||||
controller-gen:
|
||||
ifeq (, $(shell which controller-gen))
|
||||
@{ \
|
||||
@ -40,15 +40,16 @@ else
|
||||
CONTROLLER_GEN=$(shell which controller-gen)
|
||||
endif
|
||||
|
||||
#? golangci-lint: Install golangci-lint tool
|
||||
golangci-lint:
|
||||
@command -v golangci-lint > /dev/null || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.63.4
|
||||
|
||||
# Run the golangci-lint tool
|
||||
#? go-lint: Run the golangci-lint tool
|
||||
.PHONY: go-lint
|
||||
go-lint: golangci-lint
|
||||
golangci-lint run --timeout=30m ./...
|
||||
|
||||
# Run the licensecheck script to check for license headers
|
||||
#? licensecheck: Run the to check for license headers
|
||||
.PHONY: licensecheck
|
||||
licensecheck:
|
||||
@echo ">> checking license header"
|
||||
@ -60,25 +61,25 @@ licensecheck:
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
# Requires to install spectral. See https://github.com/stoplightio/spectral
|
||||
#? oas-lint: Requires to install spectral. See github.com/stoplightio/spectral
|
||||
oas-lint:
|
||||
spectral lint api/*.yaml
|
||||
|
||||
# Run all the linters
|
||||
#? lint: Run all the linters
|
||||
.PHONY: lint
|
||||
lint: licensecheck go-lint oas-lint
|
||||
|
||||
# generates CRD using controller-gen
|
||||
#? crd: Generates CRD using controller-gen
|
||||
.PHONY: crd
|
||||
crd: controller-gen
|
||||
${CONTROLLER_GEN} crd:crdVersions=v1 paths="./endpoint/..." output:crd:stdout > docs/contributing/crd-source/crd-manifest.yaml
|
||||
|
||||
# The verify target runs tasks similar to the CI tasks, but without code coverage
|
||||
#? test: The verify target runs tasks similar to the CI tasks, but without code coverage
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -race -coverprofile=profile.cov ./...
|
||||
|
||||
# The build targets allow to build the binary and container image
|
||||
#? build: The build targets allow to build the binary and container image
|
||||
.PHONY: build
|
||||
|
||||
BINARY ?= external-dns
|
||||
@ -148,9 +149,9 @@ clean:
|
||||
@rm -rf build
|
||||
@go clean -cache
|
||||
|
||||
# Builds and push container images to the staging bucket.
|
||||
.PHONY: release.staging
|
||||
|
||||
.PHONY: release.staging
|
||||
#? release.staging: Builds and push container images to the staging bucket.
|
||||
release.staging: test
|
||||
IMAGE=$(IMAGE_STAGING) $(MAKE) build.push/multiarch
|
||||
|
||||
@ -161,17 +162,25 @@ release.prod: test
|
||||
ko:
|
||||
scripts/install-ko.sh
|
||||
|
||||
# generate-flags-documentation: Generate documentation (docs/flags.md)
|
||||
.PHONY: generate-flags-documentation
|
||||
#? generate-flags-documentation: Generate documentation (docs/flags.md)
|
||||
generate-flags-documentation:
|
||||
go run internal/gen/docs/flags/main.go
|
||||
|
||||
pre-commit-install: ## Install pre-commit hooks
|
||||
#? pre-commit-install: Install pre-commit hooks
|
||||
pre-commit-install:
|
||||
@pre-commit install
|
||||
@pre-commit gc
|
||||
|
||||
pre-commit-uninstall: ## Uninstall hooks
|
||||
#? pre-commit-uninstall: Uninstall pre-commit hooks
|
||||
pre-commit-uninstall:
|
||||
@pre-commit uninstall
|
||||
|
||||
pre-commit-validate: ## Validate files with pre-commit hooks
|
||||
#? pre-commit-validate: Validate files with pre-commit hooks
|
||||
pre-commit-validate:
|
||||
@pre-commit run --all-files
|
||||
|
||||
.PHONY: help
|
||||
#? help: Get more info on available commands
|
||||
help: Makefile
|
||||
@sed -n 's/^#?//p' $< | column -t -s ':' | sort | sed -e 's/^/ /'
|
||||
|
||||
@ -21,3 +21,6 @@
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
ci/
|
||||
schema/
|
||||
.schema.yaml
|
||||
|
||||
11
charts/external-dns/.schema.yaml
Normal file
11
charts/external-dns/.schema.yaml
Normal file
@ -0,0 +1,11 @@
|
||||
# ref: https://github.com/losisin/helm-values-schema-json.git
|
||||
input:
|
||||
- schema/values.yaml
|
||||
- values.yaml
|
||||
|
||||
draft: 7
|
||||
indent: 2
|
||||
output: values.schema.json
|
||||
|
||||
schemaRoot:
|
||||
additionalProperties: true
|
||||
@ -18,6 +18,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [UNRELEASED]
|
||||
|
||||
### Added
|
||||
|
||||
- Added ability to generate schema with `helm plugin schema`. ([#5075](https://github.com/kubernetes-sigs/external-dns/pull/5075)) _@ivankatliarchuk_
|
||||
- Added `docs/contributing/dev-guide.md#helm-values` guide. ([#5075](https://github.com/kubernetes-sigs/external-dns/pull/5075)) _@ivankatliarchuk_
|
||||
|
||||
### Changed
|
||||
|
||||
- Regenerate JSON schema with `helm-values-schema-json' plugin. ([#5075](https://github.com/kubernetes-sigs/external-dns/pull/5075)) _@ivankatliarchuk_
|
||||
|
||||
## [v1.15.2] - 2025-02-14
|
||||
|
||||
### Changed
|
||||
|
||||
- Added `transportservers` resource to ClusterRole when specifying `f5-transportserver` or `f5-virtualserver` as a source. ([#5066](https://github.com/kubernetes-sigs/external-dns/pull/5066)) _@visokoo_
|
||||
@ -25,8 +36,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Fixed
|
||||
|
||||
- Fixed handling of non-string types in `serviceAccount.metadata.annotations` field. ([#5067](https://github.com/kubernetes-sigs/external-dns/pull/5067)) _@hjoshi123_
|
||||
- Fixed regression where `affinity.nodeAffinity` was being ignored. ([#5046](https://github.com/kubernetes-sigs/external-dns/pull/5046)) _@mkhpalm_
|
||||
|
||||
## [v1.15.1] - 2023-09-10
|
||||
## [v1.15.1] - 2025-01-27
|
||||
|
||||
### Added
|
||||
|
||||
@ -225,6 +237,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
RELEASE LINKS
|
||||
-->
|
||||
[UNRELEASED]: https://github.com/kubernetes-sigs/external-dns/tree/master/charts/external-dns
|
||||
[v1.15.2]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.15.2
|
||||
[v1.15.1]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.15.1
|
||||
[v1.15.0]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.15.0
|
||||
[v1.14.5]: https://github.com/kubernetes-sigs/external-dns/releases/tag/external-dns-helm-chart-1.14.5
|
||||
|
||||
@ -2,7 +2,7 @@ apiVersion: v2
|
||||
name: external-dns
|
||||
description: ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.
|
||||
type: application
|
||||
version: 1.15.1
|
||||
version: 1.15.2
|
||||
appVersion: 0.15.1
|
||||
keywords:
|
||||
- kubernetes
|
||||
@ -21,14 +21,8 @@ maintainers:
|
||||
annotations:
|
||||
artifacthub.io/changes: |
|
||||
- kind: added
|
||||
description: "Added ability to configure `imagePullSecrets` via helm `global` value."
|
||||
- kind: added
|
||||
description: "Added options to configure `labelFilter` and `managedRecordTypes` via dedicated helm values."
|
||||
- kind: changed
|
||||
description: "Allow templating `serviceaccount.annotations` keys and values, by rendering them using the `tpl` built-in function."
|
||||
- kind: changed
|
||||
description: "Updated _ExternalDNS_ OCI image version to [v0.15.1](https://github.com/kubernetes-sigs/external-dns/releases/tag/v0.15.1)."
|
||||
description: "Added `transportservers` resource to ClusterRole when specifying `f5-transportserver` or `f5-virtualserver` as a source."
|
||||
- kind: fixed
|
||||
description: "Fixed automatic addition of pod selector labels to `affinity` and `topologySpreadConstraints` if not defined."
|
||||
description: "Fixed handling of non-string types in `serviceAccount.metadata.annotations` field."
|
||||
- kind: fixed
|
||||
description: "Fixed missing Ingress permissions when using Istio sources."
|
||||
description: "Fixed regression where `affinity.nodeAffinity` was being ignored."
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# external-dns
|
||||
|
||||
  
|
||||
  
|
||||
|
||||
ExternalDNS synchronizes exposed Kubernetes Services and Ingresses with DNS providers.
|
||||
|
||||
@ -27,7 +27,7 @@ helm repo add external-dns https://kubernetes-sigs.github.io/external-dns/
|
||||
After you've installed the repo you can install the chart.
|
||||
|
||||
```shell
|
||||
helm upgrade --install external-dns external-dns/external-dns --version 1.15.1
|
||||
helm upgrade --install external-dns external-dns/external-dns --version 1.15.2
|
||||
```
|
||||
|
||||
## Providers
|
||||
@ -151,7 +151,7 @@ If `namespaced` is set to `true`, please ensure that `sources` my only contains
|
||||
| secretConfiguration.subPath | string | `nil` | Sub-path for mounting the `Secret`, this can be templated. |
|
||||
| securityContext | object | See _values.yaml_ | [Security context](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) for the `external-dns` container. |
|
||||
| service.annotations | object | `{}` | Service annotations. |
|
||||
| service.ipFamilies | list | `[]` | Service IP families. |
|
||||
| service.ipFamilies | list | `[]` | Service IP families (e.g. IPv4 and/or IPv6). |
|
||||
| service.ipFamilyPolicy | string | `nil` | Service IP family policy. |
|
||||
| service.port | int | `7979` | Service HTTP port. |
|
||||
| serviceAccount.annotations | object | `{}` | Annotations to add to the service account. Templates are allowed in both the key and the value. Example: `example.com/annotation/{{ .Values.nameOverride }}: {{ .Values.nameOverride }}` |
|
||||
|
||||
19
charts/external-dns/schema/values.yaml
Normal file
19
charts/external-dns/schema/values.yaml
Normal file
@ -0,0 +1,19 @@
|
||||
# Custom values for schema creation.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your schema.
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
|
||||
provider:
|
||||
webhook:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 300m
|
||||
memory: 200Mi
|
||||
@ -204,6 +204,10 @@ spec:
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- with .nodeAffinity }}
|
||||
nodeAffinity:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- with .podAffinity }}
|
||||
podAffinity:
|
||||
{{- with .preferredDuringSchedulingIgnoredDuringExecution }}
|
||||
|
||||
@ -1,94 +1,691 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"type": "object",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"global": {
|
||||
"affinity": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"provider": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
"automountServiceAccountToken": {
|
||||
"type": "null"
|
||||
},
|
||||
"commonLabels": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"deploymentAnnotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"deploymentStrategy": {
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"type": {
|
||||
"enum": [
|
||||
"Recreate",
|
||||
"RollingUpdate"
|
||||
],
|
||||
"type": [
|
||||
"string"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"dnsConfig": {
|
||||
"type": "null"
|
||||
},
|
||||
"dnsPolicy": {
|
||||
"type": "null"
|
||||
},
|
||||
"domainFilters": {
|
||||
"type": "array"
|
||||
},
|
||||
"env": {
|
||||
"type": "array"
|
||||
},
|
||||
"excludeDomains": {
|
||||
"type": "array"
|
||||
},
|
||||
"extraArgs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"uniqueItems": true
|
||||
},
|
||||
"extraContainers": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"extraVolumeMounts": {
|
||||
"type": "array"
|
||||
},
|
||||
"extraVolumes": {
|
||||
"type": "array"
|
||||
},
|
||||
"fullnameOverride": {
|
||||
"type": "null"
|
||||
},
|
||||
"global": {
|
||||
"properties": {
|
||||
"imagePullSecrets": {
|
||||
"items": {
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"image": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"pullPolicy": {
|
||||
"enum": [
|
||||
"IfNotPresent",
|
||||
"Always"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"repository": {
|
||||
"type": "string"
|
||||
},
|
||||
"tag": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"imagePullSecrets": {
|
||||
"items": {
|
||||
"type": "object"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"initContainers": {
|
||||
"type": "array"
|
||||
},
|
||||
"interval": {
|
||||
"type": "string"
|
||||
},
|
||||
"labelFilter": {
|
||||
"pattern": "^[a-zA-Z0-9._-]+=[a-zA-Z0-9._-]+$",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"livenessProbe": {
|
||||
"properties": {
|
||||
"failureThreshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"httpGet": {
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"initialDelaySeconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"periodSeconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"successThreshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timeoutSeconds": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"logFormat": {
|
||||
"default": "text",
|
||||
"enum": [
|
||||
"text",
|
||||
"json"
|
||||
],
|
||||
"type": [
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"logLevel": {
|
||||
"default": "info",
|
||||
"enum": [
|
||||
"panic",
|
||||
"debug",
|
||||
"info",
|
||||
"warning",
|
||||
"error",
|
||||
"fatal"
|
||||
],
|
||||
"type": [
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"managedRecordTypes": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"uniqueItems": true
|
||||
},
|
||||
"nameOverride": {
|
||||
"type": "null"
|
||||
},
|
||||
"namespaced": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"nodeSelector": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"podAnnotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"podLabels": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"podSecurityContext": {
|
||||
"properties": {
|
||||
"fsGroup": {
|
||||
"type": "integer"
|
||||
},
|
||||
"runAsNonRoot": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"seccompProfile": {
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"policy": {
|
||||
"default": "upsert-only",
|
||||
"enum": [
|
||||
"sync",
|
||||
"upsert-only"
|
||||
],
|
||||
"type": [
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"priorityClassName": {
|
||||
"type": "null"
|
||||
},
|
||||
"provider": {
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"webhook": {
|
||||
"properties": {
|
||||
"args": {
|
||||
"type": "array"
|
||||
},
|
||||
"env": {
|
||||
"type": "array"
|
||||
},
|
||||
"extraVolumeMounts": {
|
||||
"type": "array"
|
||||
},
|
||||
"image": {
|
||||
"properties": {
|
||||
"pullPolicy": {
|
||||
"type": "string"
|
||||
},
|
||||
"repository": {
|
||||
"type": "null"
|
||||
},
|
||||
"tag": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"limits": {
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"type": "string"
|
||||
},
|
||||
"memory": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"livenessProbe": {
|
||||
"properties": {
|
||||
"failureThreshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"httpGet": {
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"initialDelaySeconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"periodSeconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"successThreshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timeoutSeconds": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"readinessProbe": {
|
||||
"properties": {
|
||||
"failureThreshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"httpGet": {
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"initialDelaySeconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"periodSeconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"successThreshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timeoutSeconds": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"requests": {
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"type": "string"
|
||||
},
|
||||
"memory": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"resources": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"securityContext": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"service": {
|
||||
"properties": {
|
||||
"port": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"serviceMonitor": {
|
||||
"properties": {
|
||||
"bearerTokenFile": {
|
||||
"type": "null"
|
||||
},
|
||||
"interval": {
|
||||
"type": "null"
|
||||
},
|
||||
"metricRelabelings": {
|
||||
"type": "array"
|
||||
},
|
||||
"relabelings": {
|
||||
"type": "array"
|
||||
},
|
||||
"scheme": {
|
||||
"type": "null"
|
||||
},
|
||||
"scrapeTimeout": {
|
||||
"type": "null"
|
||||
},
|
||||
"tlsConfig": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"rbac": {
|
||||
"additionalProperties": true,
|
||||
"properties": {
|
||||
"additionalPermissions": {
|
||||
"type": "array"
|
||||
},
|
||||
"create": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"readinessProbe": {
|
||||
"properties": {
|
||||
"failureThreshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"httpGet": {
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"port": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"initialDelaySeconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"periodSeconds": {
|
||||
"type": "integer"
|
||||
},
|
||||
"successThreshold": {
|
||||
"type": "integer"
|
||||
},
|
||||
"timeoutSeconds": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"registry": {
|
||||
"default": "txt",
|
||||
"enum": [
|
||||
"txt",
|
||||
"aws-sd",
|
||||
"dynamodb",
|
||||
"noop"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"resources": {
|
||||
"properties": {
|
||||
"limits": {
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"type": "string"
|
||||
},
|
||||
"memory": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"requests": {
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"type": "string"
|
||||
},
|
||||
"memory": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"revisionHistoryLimit": {
|
||||
"minimum": 0,
|
||||
"type": [
|
||||
"integer",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"secretConfiguration": {
|
||||
"$comment": "This value is DEPRECATED as secrets should be configured external to the chart and exposed to the container via extraVolumes & extraVolumeMounts.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"mountPath": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
"type": "null"
|
||||
},
|
||||
"subPath": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"patternProperties": {
|
||||
".+": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
"type": "null"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"securityContext": {
|
||||
"properties": {
|
||||
"allowPrivilegeEscalation": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"capabilities": {
|
||||
"properties": {
|
||||
"drop": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"privileged": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"readOnlyRootFilesystem": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"runAsGroup": {
|
||||
"type": "integer"
|
||||
},
|
||||
"runAsNonRoot": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"runAsUser": {
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"service": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"annotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"ipFamilies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"IPv6",
|
||||
"IPv4"
|
||||
]
|
||||
}
|
||||
"IPv4",
|
||||
"IPv6"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"maxItems": 2,
|
||||
"minItems": 0,
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"uniqueItems": true
|
||||
},
|
||||
"ipFamilyPolicy": {
|
||||
"enum": [
|
||||
"SingleStack",
|
||||
"PreferDualStack",
|
||||
"RequireDualStack",
|
||||
null
|
||||
],
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"SingleStack",
|
||||
"PreferDualStack",
|
||||
"RequireDualStack"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"port": {
|
||||
"default": 7979,
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"serviceAccount": {
|
||||
"properties": {
|
||||
"annotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"automountServiceAccountToken": {
|
||||
"type": "null"
|
||||
},
|
||||
"create": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"labels": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"name": {
|
||||
"type": "null"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"serviceMonitor": {
|
||||
"properties": {
|
||||
"additionalLabels": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"annotations": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
},
|
||||
"bearerTokenFile": {
|
||||
"type": "null"
|
||||
},
|
||||
"enabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"interval": {
|
||||
"type": "null"
|
||||
},
|
||||
"metricRelabelings": {
|
||||
"type": "array"
|
||||
},
|
||||
"namespace": {
|
||||
"type": "null"
|
||||
},
|
||||
"relabelings": {
|
||||
"type": "array"
|
||||
},
|
||||
"scheme": {
|
||||
"type": "null"
|
||||
},
|
||||
"scrapeTimeout": {
|
||||
"type": "null"
|
||||
},
|
||||
"targetLabels": {
|
||||
"type": "array"
|
||||
},
|
||||
"tlsConfig": {
|
||||
"properties": {},
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"shareProcessNamespace": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"sources": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"terminationGracePeriodSeconds": {
|
||||
"type": "null"
|
||||
},
|
||||
"tolerations": {
|
||||
"type": "array"
|
||||
},
|
||||
"topologySpreadConstraints": {
|
||||
"type": "array"
|
||||
},
|
||||
"triggerLoopOnEvent": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"txtOwnerId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"txtPrefix": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"txtSuffix": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
|
||||
@ -4,18 +4,18 @@
|
||||
|
||||
global:
|
||||
# -- Global image pull secrets.
|
||||
imagePullSecrets: []
|
||||
imagePullSecrets: [] # @schema item: object
|
||||
|
||||
image:
|
||||
image: # @schema additionalProperties: false
|
||||
# -- Image repository for the `external-dns` container.
|
||||
repository: registry.k8s.io/external-dns/external-dns
|
||||
# -- (string) Image tag for the `external-dns` container, this will default to `.Chart.AppVersion` if not set.
|
||||
tag:
|
||||
# -- Image tag for the `external-dns` container, this will default to `.Chart.AppVersion` if not set.
|
||||
tag: # @schema type:[string, null]
|
||||
# -- Image pull policy for the `external-dns` container.
|
||||
pullPolicy: IfNotPresent
|
||||
pullPolicy: IfNotPresent # @schema enum:[IfNotPresent, Always];
|
||||
|
||||
# -- Image pull secrets.
|
||||
imagePullSecrets: []
|
||||
imagePullSecrets: [] # @schema item: object
|
||||
|
||||
# -- (string) Override the name of the chart.
|
||||
nameOverride:
|
||||
@ -42,13 +42,15 @@ service:
|
||||
# -- Service annotations.
|
||||
annotations: {}
|
||||
# -- Service HTTP port.
|
||||
port: 7979
|
||||
# -- Service IP families.
|
||||
ipFamilies: []
|
||||
# -- (string) Service IP family policy.
|
||||
ipFamilyPolicy:
|
||||
port: 7979 # @schema minimum:0; default:7979
|
||||
# -- Service IP families (e.g. IPv4 and/or IPv6).
|
||||
ipFamilies: [] # @schema type: [array, null]; item: string; itemEnum: ["IPv4", "IPv6"]; minItems:0; maxItems:2; uniqueItems: true;
|
||||
# - IPv4
|
||||
# - IPv6
|
||||
# -- Service IP family policy.
|
||||
ipFamilyPolicy: # @schema type: [string, null]; enum:[SingleStack, PreferDualStack, RequireDualStack, null];
|
||||
|
||||
rbac:
|
||||
rbac: # @schema additionalProperties: true
|
||||
# -- If `true`, create a `ClusterRole` & `ClusterRoleBinding` with access to the Kubernetes API.
|
||||
create: true
|
||||
# -- Additional rules to add to the `ClusterRole`.
|
||||
@ -61,11 +63,11 @@ deploymentAnnotations: {}
|
||||
extraContainers: {}
|
||||
|
||||
# -- [Deployment Strategy](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy).
|
||||
deploymentStrategy:
|
||||
type: Recreate
|
||||
deploymentStrategy: # @schema additionalProperties: true
|
||||
type: Recreate # @schema enum:[Recreate, RollingUpdate]; type:string; default: Recreate
|
||||
|
||||
# -- (int) Specify the number of old `ReplicaSets` to retain to allow rollback of the `Deployment``.
|
||||
revisionHistoryLimit:
|
||||
revisionHistoryLimit: # @schema type:[integer, null];minimum:0
|
||||
|
||||
# -- Labels to add to the `Pod`.
|
||||
podLabels: {}
|
||||
@ -189,10 +191,10 @@ serviceMonitor:
|
||||
targetLabels: []
|
||||
|
||||
# -- Log level.
|
||||
logLevel: info
|
||||
logLevel: info # @schema enum:[panic, debug, info, warning, error, fatal]; type:string; default: "info"
|
||||
|
||||
# -- Log format.
|
||||
logFormat: text
|
||||
logFormat: text # @schema enum:["text", "json"]; type:string; default: "text"
|
||||
|
||||
# -- Interval for DNS updates.
|
||||
interval: 1m
|
||||
@ -209,19 +211,19 @@ sources:
|
||||
- ingress
|
||||
|
||||
# -- How DNS records are synchronized between sources and providers; available values are `sync` & `upsert-only`.
|
||||
policy: upsert-only
|
||||
policy: upsert-only # @schema enum:[sync, upsert-only]; type:string; default: "upsert-only"
|
||||
|
||||
# -- Specify the registry for storing ownership and labels.
|
||||
# Valid values are `txt`, `aws-sd`, `dynamodb` & `noop`.
|
||||
registry: txt
|
||||
registry: txt # @schema enum:[txt, aws-sd, dynamodb, noop]; default: "txt"
|
||||
# -- (string) Specify an identifier for this instance of _ExternalDNS_ wWhen using a registry other than `noop`.
|
||||
txtOwnerId:
|
||||
txtOwnerId: # @schema type:[string, null]; default: null
|
||||
# -- (string) Specify a prefix for the domain names of TXT records created for the `txt` registry.
|
||||
# Mutually exclusive with `txtSuffix`.
|
||||
txtPrefix:
|
||||
txtPrefix: # @schema type:[string, null]; default: null
|
||||
# -- (string) Specify a suffix for the domain names of TXT records created for the `txt` registry.
|
||||
# Mutually exclusive with `txtPrefix`.
|
||||
txtSuffix:
|
||||
txtSuffix: # @schema type:[string, null]; default: null
|
||||
|
||||
# -- Limit possible target zones by domain suffixes.
|
||||
domainFilters: []
|
||||
@ -229,11 +231,11 @@ domainFilters: []
|
||||
# -- Intentionally exclude domains from being managed.
|
||||
excludeDomains: []
|
||||
|
||||
# -- (string) Filter resources queried for endpoints by label selector
|
||||
labelFilter:
|
||||
# -- Filter resources queried for endpoints by label selector
|
||||
labelFilter: # @schema pattern:^[a-zA-Z0-9._-]+=[a-zA-Z0-9._-]+$; type: [string,null];
|
||||
|
||||
# -- Record types to manage (default: A, AAAA, CNAME)
|
||||
managedRecordTypes: []
|
||||
managedRecordTypes: [] # @schema type: [array, null]; item: string; uniqueItems: true;
|
||||
|
||||
provider:
|
||||
# -- _ExternalDNS_ provider name; for the available providers and how to configure them see [README](https://github.com/kubernetes-sigs/external-dns/blob/master/charts/external-dns/README.md#providers).
|
||||
@ -294,7 +296,7 @@ provider:
|
||||
relabelings: []
|
||||
|
||||
# -- Extra arguments to provide to _ExternalDNS_.
|
||||
extraArgs: []
|
||||
extraArgs: [] # @schema type: [array, null]; item: string; uniqueItems: true;
|
||||
|
||||
secretConfiguration:
|
||||
# -- If `true`, create a `Secret` to store sensitive provider configuration (**DEPRECATED**).
|
||||
|
||||
@ -210,6 +210,42 @@ Modify chart or values and validate the diff
|
||||
❯❯ kubectl diff -f _scratch/external-dns --recursive=true --show-managed-fields=false
|
||||
```
|
||||
|
||||
### Helm Values
|
||||
|
||||
This helm chart comes with a JSON schema generated from values with [helm schema](https://github.com/losisin/helm-values-schema-json.git) plugin.
|
||||
|
||||
1. Install required plugin(s)
|
||||
|
||||
```sh
|
||||
❯❯ scripts/helm-tools.sh --install
|
||||
```
|
||||
|
||||
2. Ensure that the schema is always up-to-date
|
||||
|
||||
```sh
|
||||
❯❯ scripts/helm-tools.sh --diff
|
||||
```
|
||||
|
||||
3. When not up-to-date, update JSON schema
|
||||
|
||||
```sh
|
||||
❯❯ scripts/helm-tools.sh --schema
|
||||
```
|
||||
|
||||
4. Runs a series of tests to verify that the chart is well-formed, linted and JSON schema is valid
|
||||
|
||||
```sh
|
||||
❯❯ scripts/helm-tools.sh --lint
|
||||
```
|
||||
|
||||
5. Auto-generate documentation for helm charts into markdown files.
|
||||
|
||||
```sh
|
||||
❯❯ scripts/helm-tools.sh --docs
|
||||
```
|
||||
|
||||
6. Add an entry to the chart [CHANGELOG.md](../../charts/external-dns/CHANGELOG.md) under `## UNRELEASED` section and `open` pull request
|
||||
|
||||
## Deploy with kubernetes manifests
|
||||
|
||||
> Note; kubernetes manifest are not up to date. Consider to create an `examples` folder
|
||||
|
||||
145
docs/proposal/001-leader-election.md
Normal file
145
docs/proposal/001-leader-election.md
Normal file
@ -0,0 +1,145 @@
|
||||
```yaml
|
||||
---
|
||||
title: leader election proposal
|
||||
version: 0.15.1
|
||||
authors: @ivankatliarchuk
|
||||
creation-date: 2025-jan-30
|
||||
status: not-planned
|
||||
---
|
||||
```
|
||||
|
||||
# Leader Election
|
||||
|
||||
In Kubernetes, **leader election** is a mechanism used by applications, controllers, or distributed systems to designate one instance or node as the "leader" that is responsible for managing specific tasks, while others operate as followers or standbys.
|
||||
This ensures coordinated and fault-tolerant operations in highly available systems.
|
||||
|
||||
- [Kubernetes Coordinated Leader Election](https://kubernetes.io/docs/concepts/cluster-administration/coordinated-leader-election/)
|
||||
- [Kubernetes Concepts: Leases](https://kubernetes.io/docs/concepts/architecture/leases/)
|
||||
|
||||
## **Leader Election in Kubernetes**
|
||||
|
||||
The leader election mechanism implemented in Go code relies on Kubernetes coordination features, specifically Lease object in the `coordination.k8s.io` API Group. Lease locks provide a way to acquire a lease on a shared resource, which can be used to determine the leader among a group of nodes.
|
||||
|
||||
***Leader Election Sequence Diagram***
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant R1 as Replica 1 (Leader)
|
||||
participant LR as Lock Resource
|
||||
participant R2 as Replica 2 (Standby)
|
||||
participant R3 as Replica 3 (Standby)
|
||||
|
||||
R1->>LR: Update Lock Resource
|
||||
Note over LR: currentLeader: R1<br>timeStamp: 12:21<br>leaseDuration: 10s
|
||||
|
||||
loop Every polling period
|
||||
R2->>LR: Poll leader status
|
||||
LR-->>R2: Return lock info
|
||||
R3->>LR: Poll leader status
|
||||
LR-->>R3: Return lock info
|
||||
end
|
||||
|
||||
Note over R2,R3: Replicas remain on standby<br>as long as leader is active
|
||||
```
|
||||
|
||||
***Leader Election Flow***
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph Active Replica
|
||||
A[Replica 1]
|
||||
end
|
||||
subgraph Kubernetes Resource Lock
|
||||
A["fa:fa-server Replica 1"] --> |Hold The Lock| C@{ label: "Lock" }
|
||||
end
|
||||
subgraph Standby Replicas
|
||||
D["fa:fa-server Replica 2"] -->|Poll| C
|
||||
E["fa:fa-server Replica 3"] -->|Poll| C["fa:fa-lock Lock"]
|
||||
end
|
||||
style C color:#8C52FF,fill:#A6A6A6
|
||||
style A color:#8C52FF,fill:#00BF63
|
||||
style D color:#000000,fill:#FFDE59
|
||||
style E color:#000000,fill:#FFDE59
|
||||
```
|
||||
|
||||
***How Leader Is Elected***
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Start Leader Election] -->|Replica 1 Becomes Leader| B(Update Lock Resource)
|
||||
B --> C{Is Leader Active?}
|
||||
C -->|Yes| D[Replicas 2 & 3 Poll Leader Status]
|
||||
C -->|No| E[Trigger New Election]
|
||||
E -->|New Leader Found| F[Replica X Becomes Leader]
|
||||
E -->|No Leader| G[Retry Election]
|
||||
F --> B
|
||||
G --> C
|
||||
D --> C
|
||||
```
|
||||
|
||||
### Enable Leader Election
|
||||
|
||||
Minimum supported Kubernetes version is `v1.26`.
|
||||
|
||||
> Currently, this feature is "opt-in". The `--enable-leader-election` flag must be explicitly provided to activate it in the service.
|
||||
|
||||
| **Flag** | **Description** |
|
||||
|:---------------------------|:------------------------------------------------------|
|
||||
| `--enable-leader-election` | This flag is required to enable leader election logic |
|
||||
|
||||
```yml
|
||||
args:
|
||||
--registry=txt \
|
||||
--source=fake \
|
||||
--enable-leader-election
|
||||
```
|
||||
|
||||
## **How Leader Election Works in Kubernetes**
|
||||
|
||||
1. **Lease API**:
|
||||
- Kubernetes provides a built-in `Lease` object in the `coordination.k8s.io/v1` API group, specifically designed for leader election.
|
||||
- The leader writes a lease object with metadata (such as its identity and timestamp) to signal that it is the current leader.
|
||||
|
||||
2. **Election Process**:
|
||||
- All participating pods (or nodes) periodically check for the lease.
|
||||
- The lease contains details of the current leader's identity (e.g., a pod name).
|
||||
- If the lease expires or is not renewed, other contenders can try to acquire leadership by writing their identity into the lease object.
|
||||
|
||||
3. **Heartbeat (Lease Renewal)**:
|
||||
- The current leader must periodically update the lease to retain leadership.
|
||||
- If the leader fails to renew the lease within the configured timeout, leadership is relinquished, and another instance can take over.
|
||||
|
||||
---
|
||||
|
||||
### **Key Concepts**
|
||||
|
||||
- **Lease Duration**: Defines how long the leader is considered valid after the last lease renewal. Short lease durations result in faster failovers but higher contention and potential performance impact.
|
||||
- **Leader Identity**: Usually the name or ID of the pod that holds the leadership role.
|
||||
- **Backoff and Contention**: Followers typically wait and retry with a backoff period to avoid overwhelming the system when a leader is lost.
|
||||
|
||||
---
|
||||
|
||||
### **Why Leader Election is Important**
|
||||
|
||||
Leader election ensures that:
|
||||
|
||||
- **High Availability**: Fail-over to a new leader ensures availability even if the current leader goes down.
|
||||
- **Data Consistency**: Only one leader acts on critical tasks, preventing duplicate work or conflicting updates.
|
||||
- **Workload Distribution**: Secondary replicas can be on standby, reducing resource contention.
|
||||
|
||||
---
|
||||
|
||||
### **Use Cases**
|
||||
|
||||
Leader election functionality is critical for building reliable, fault-tolerant, and scalable applications on Kubernetes.
|
||||
|
||||
- **Cluster Upgrades**: Leader election ensures smooth cluster upgrades by designating one instance as responsible for orchestrating upgrades or managing specific components during the process.
|
||||
By preventing multiple instances from making changes concurrently, it avoids conflicts and reduces downtime, ensuring consistency across the cluster.
|
||||
- **Workload Running on Spot Instances**: For workloads running on cost-effective but ephemeral spot instances, leader election is crucial for resiliency.
|
||||
When a spot instance running the leader is preempted, the failover process enables a standby instance to seamlessly take over leadership, ensuring continued execution of critical tasks.
|
||||
- **Requirement for Disaster Recovery**: In disaster recovery scenarios, leader election provides fault tolerance by allowing another instance to take over when the primary leader becomes unavailable.
|
||||
This guarantees operational continuity even in the face of unexpected failures, supporting robust disaster recovery strategies.
|
||||
- **High Availability (HA) Scenarios**: In highly available systems, leader election ensures that a single active leader manages essential processes or state, while backups remain ready to step in instantly in case of failure.
|
||||
This minimizes recovery time objectives (RTO) and eliminates single points of failure.
|
||||
- **Enhanced Reliability in Distributed Systems**: Incorporating leader election into your distributed system enhances its overall reliability. It avoids the pitfalls of uncoordinated task execution, providing deterministic behavior and ensuring only one instance manages critical tasks at any given time.
|
||||
- **Conflict Prevention**: Leader election serves as a guard against conflicts arising from multiple instances attempting to execute the same tasks. By ensuring that only the elected leader acts on shared resources or processes, it prevents data corruption, inconsistencies, and wasted computational effort.
|
||||
@ -4,8 +4,8 @@
|
||||
title: New Feature or Deprecation/Removal Proposal
|
||||
version: if applicable
|
||||
authors: you, me
|
||||
creation-date: 2025-01-01
|
||||
status: draft
|
||||
creation-date: 2025-jan-01
|
||||
status: draft|approved|rejected|not-planned|partially-implemented|implemented
|
||||
---
|
||||
```
|
||||
|
||||
|
||||
@ -1101,8 +1101,10 @@ args:
|
||||
```
|
||||
|
||||
Can't specify multiple or separate values with commas: `key1=val1,key2=val2` at the moment.
|
||||
Filter only by value `--aws-zone-tags==tag-value` is not supported.
|
||||
|
||||
```sh
|
||||
args:
|
||||
--aws-zone-tags=team=k8s,vertical=platform
|
||||
--aws-zone-tags=team=k8s,vertical=platform # this is not supported
|
||||
--aws-zone-tags==tag-value # this is not supported
|
||||
```
|
||||
|
||||
83
go.mod
83
go.mod
@ -5,25 +5,25 @@ go 1.23.5
|
||||
require (
|
||||
cloud.google.com/go/compute/metadata v0.6.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0
|
||||
github.com/F5Networks/k8s-bigip-ctlr/v2 v2.19.0
|
||||
github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.6.1
|
||||
github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.6.2
|
||||
github.com/IBM/go-sdk-core/v5 v5.18.5
|
||||
github.com/IBM/networking-go-sdk v0.51.1
|
||||
github.com/Yamashou/gqlgenc v0.30.3
|
||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.84
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.0
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.5
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.58
|
||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.18.1
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.39.9
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.48.6
|
||||
github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.34.10
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.13
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.88
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.1
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.6
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.59
|
||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.18.4
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.40.1
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.48.7
|
||||
github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.34.11
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.14
|
||||
github.com/bodgit/tsig v1.2.2
|
||||
github.com/cenkalti/backoff/v4 v4.3.0
|
||||
github.com/civo/civogo v0.3.93
|
||||
@ -31,7 +31,7 @@ require (
|
||||
github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381
|
||||
github.com/datawire/ambassador v1.12.4
|
||||
github.com/denverdino/aliyungo v0.0.0-20230411124812-ab98a9173ace
|
||||
github.com/digitalocean/godo v1.136.0
|
||||
github.com/digitalocean/godo v1.137.0
|
||||
github.com/dnsimple/dnsimple-go v1.7.0
|
||||
github.com/exoscale/egoscale v0.102.3
|
||||
github.com/ffledgling/pdns-go v0.0.0-20180219074714-524e7daccd99
|
||||
@ -47,8 +47,8 @@ require (
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/openshift/api v0.0.0-20230607130528-611114dca681
|
||||
github.com/openshift/client-go v0.0.0-20230607134213-3cd0021bbee3
|
||||
github.com/oracle/oci-go-sdk/v65 v65.83.0
|
||||
github.com/ovh/go-ovh v1.6.0
|
||||
github.com/oracle/oci-go-sdk/v65 v65.83.1
|
||||
github.com/ovh/go-ovh v1.7.0
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pluralsh/gqlclient v1.12.2
|
||||
@ -57,22 +57,22 @@ require (
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.32
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1091
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1091
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.1091
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1097
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1097
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.1097
|
||||
github.com/transip/gotransip/v6 v6.26.0
|
||||
github.com/ultradns/ultradns-sdk-go v1.3.7
|
||||
go.etcd.io/etcd/client/v3 v3.5.18
|
||||
go.uber.org/ratelimit v0.3.1
|
||||
golang.org/x/net v0.34.0
|
||||
golang.org/x/net v0.35.0
|
||||
golang.org/x/oauth2 v0.26.0
|
||||
golang.org/x/sync v0.11.0
|
||||
golang.org/x/time v0.10.0
|
||||
google.golang.org/api v0.219.0
|
||||
google.golang.org/api v0.221.0
|
||||
gopkg.in/ns1/ns1-go.v2 v2.13.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
istio.io/api v1.24.2
|
||||
istio.io/client-go v1.24.2
|
||||
istio.io/api v1.24.3
|
||||
istio.io/client-go v1.24.3
|
||||
k8s.io/api v0.32.1
|
||||
k8s.io/apimachinery v0.32.1
|
||||
k8s.io/client-go v0.32.1
|
||||
@ -81,26 +81,26 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/auth v0.14.0 // indirect
|
||||
cloud.google.com/go/auth v0.14.1 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7 // indirect
|
||||
code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f // indirect
|
||||
github.com/99designs/gqlgen v0.17.61 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 // indirect
|
||||
github.com/Masterminds/semver v1.4.2 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
|
||||
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.28 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.32 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.32 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.19 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.20 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.14 // indirect
|
||||
github.com/aws/smithy-go v1.22.2 // indirect
|
||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
@ -188,23 +188,24 @@ require (
|
||||
go.etcd.io/etcd/api/v3 v3.5.18 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.18 // indirect
|
||||
go.mongodb.org/mongo-driver v1.17.2 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
|
||||
go.opentelemetry.io/otel v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.32.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.32.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect
|
||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
||||
go.uber.org/atomic v1.10.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.26.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/crypto v0.33.0 // indirect
|
||||
golang.org/x/mod v0.22.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/term v0.28.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
golang.org/x/sys v0.30.0 // indirect
|
||||
golang.org/x/term v0.29.0 // indirect
|
||||
golang.org/x/text v0.22.0 // indirect
|
||||
golang.org/x/tools v0.28.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect
|
||||
google.golang.org/grpc v1.70.0 // indirect
|
||||
google.golang.org/protobuf v1.36.4 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
|
||||
178
go.sum
178
go.sum
@ -2,8 +2,8 @@ bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxo
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go/auth v0.14.0 h1:A5C4dKV/Spdvxcl0ggWwWEzzP7AZMJSEIgrkngwhGYM=
|
||||
cloud.google.com/go/auth v0.14.0/go.mod h1:CYsoRL1PdiDuqeQpZE0bP2pnPrGqFcOkI0nldEQis+A=
|
||||
cloud.google.com/go/auth v0.14.1 h1:AwoJbzUdxA/whv1qj3TLKwh3XX5sikny2fc40wUl+h0=
|
||||
cloud.google.com/go/auth v0.14.1/go.mod h1:4JHUxlGXisL0AW8kXPtUF6ztuOksyfUQNFjfsOCXkPM=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M=
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.7/go.mod h1:NTbTTzfvPl1Y3V1nPpOgl2w6d/FjO7NNUQaWSox6ZMc=
|
||||
cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
|
||||
@ -18,10 +18,10 @@ github.com/Azure/azure-sdk-for-go v16.2.1+incompatible h1:KnPIugL51v3N3WwvaSmZbx
|
||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1 h1:1mvYtZfWQAnwNah/C+Z+Jb9rQH95LPE2vlmMuWAHJk8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1/go.mod h1:75I/mXtme1JyWFtz8GocPHVFyH421IBoZErnO16dd0k=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.1 h1:Bk5uOhSAenHyR5P61D/NzeQCv+4fEVV8mOkJ82NqpWw=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.1/go.mod h1:QZ4pw3or1WPmRBxf0cHd1tknzrT54WPBOQoGutCPvSU=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 h1:F0gBpfdPLGsw+nsgk6aqqkZS1jiixa5WwFe3fk/T3Ys=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2/go.mod h1:SqINnQ9lVVdRlyC8cd1lCI0SdX4n2paeABd2K8ggfnE=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 h1:lpOxwrQ919lCZoNCd69rVt8u1eLZuMORrGXqy8sNf3c=
|
||||
@ -43,16 +43,16 @@ github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6L
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM=
|
||||
github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 h1:kYRSnvJju5gYVyhkij+RTJ/VR6QIUaCfWeaFm2ycsjQ=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 h1:H5xDQaE3XowWfhZRUpnfC+rGZMEVoSiji+b+/HFAPU4=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/F5Networks/k8s-bigip-ctlr/v2 v2.19.0 h1:IZEN1/wXkfHfHKE89fWpOZ797NbR7CCrYjwBnXiRZxI=
|
||||
github.com/F5Networks/k8s-bigip-ctlr/v2 v2.19.0/go.mod h1:JwdtGjHFTmUM1zjzvvCotCCyP55S146IuVPOJZ7D/Jw=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
|
||||
github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.6.1 h1:XAz4wwcUlPnqLtDkeRKRRzcNXY7m/92pAaYpsHL32Ro=
|
||||
github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.6.1/go.mod h1:1oYb5+X7zh9MDtKr9f/KjMLSz+3tZpXBqfwRdu9wiws=
|
||||
github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.6.2 h1:MADnrzQB08k54k2sz6IyXjcaXOKxvMoayU05NG0CEuE=
|
||||
github.com/IBM-Cloud/ibm-cloud-cli-sdk v1.6.2/go.mod h1:1oYb5+X7zh9MDtKr9f/KjMLSz+3tZpXBqfwRdu9wiws=
|
||||
github.com/IBM/go-sdk-core/v5 v5.18.5 h1:g0JRl3sYXJczB/yuDlrN6x22LJ6jIxhp0Sa4ARNW60c=
|
||||
github.com/IBM/go-sdk-core/v5 v5.18.5/go.mod h1:KonTFRR+8ZSgw5cxBSYo6E4WZoY1+7n1kfHM82VcjFU=
|
||||
github.com/IBM/networking-go-sdk v0.51.1 h1:xRlDFxSMejMmJ7JPFZ9cflL86uJpbqUzuL/1D/pP7/g=
|
||||
@ -98,8 +98,8 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAu
|
||||
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
||||
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5 h1:P5U+E4x5OkVEKQDklVPmzs71WM56RTTRqV4OrDC//Y4=
|
||||
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.84 h1:8IpC2i1mtsuUt13cbZtVCtQRSjzuMvLiDrbOJcaS+Z4=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.84/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.88 h1:87jNTxliGqU2yB3H09xCd4U3cZCmR4AkOMqWgaluo5Q=
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.88/go.mod h1:SOSDHfe1kX91v3W5QiBsWSLqeLxImobbMX1mxrFHsVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
|
||||
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
|
||||
github.com/andybalholm/brotli v0.0.0-20190621154722-5f990b63d2d6/go.mod h1:+lx6/Aqd1kLJ1GQfkvOnaZ1WGmLpMpbprPuIOOZX30U=
|
||||
@ -121,42 +121,42 @@ github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQ
|
||||
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
|
||||
github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.0 h1:b1wM5CcE65Ujwn565qcwgtOTT1aT4ADOHHgglKjG7fk=
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.0/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.5 h1:4lS2IB+wwkj5J43Tq/AwvnscBerBJtQQ6YS7puzCI1k=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.5/go.mod h1:SNzldMlDVbN6nWxM7XsUiNXPSa1LWlqiXtvh/1PrJGg=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.58 h1:/d7FUpAPU8Lf2KUdjniQvfNdlMID0Sd9pS23FJ3SS9Y=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.58/go.mod h1:aVYW33Ow10CyMQGFgC0ptMRIqJWvJ4nxZb0sUiuQT/A=
|
||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.18.1 h1:ZUkvHnTYJj4URe24GFGjm2u5FpjKnUUV1ZiI7r4/y3g=
|
||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.18.1/go.mod h1:dSkBQQO1LcOD5wSHuM6FqrkgfirJs+tAKm/laeSa0Oc=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27 h1:7lOW8NUwE9UZekS1DYoiPdVAqZ6A+LheHWb+mHbNOq8=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27/go.mod h1:w1BASFIPOPUae7AgaH4SbjNbfdkxuggLyGfNFTn8ITY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 h1:lWm9ucLSRFiI4dQQafLrEOmEDGry3Swrz0BIRdiHJqQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31/go.mod h1:Huu6GG0YTfbPphQkDSo4dEGmQRTKb9k9G7RdtyQWxuI=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 h1:ACxDklUKKXb48+eg5ROZXi1vDgfMyfIA/WyvqHcHI0o=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31/go.mod h1:yadnfsDwqXeVaohbGc/RaD287PuyRw2wugkh5ZL2J6k=
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.1 h1:iTDl5U6oAhkNPba0e1t1hrwAo02ZMqbrGq4k5JBWM5E=
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.1/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.6 h1:fqgqEKK5HaZVWLQoLiC9Q+xDlSp+1LYidp6ybGE2OGg=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.6/go.mod h1:Ft+WLODzDQmCTHDvqAH1JfC2xxbZ0MxpZAcJqmE1LTQ=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.59 h1:9btwmrt//Q6JcSdgJOLI98sdr5p7tssS9yAsGe8aKP4=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.59/go.mod h1:NM8fM6ovI3zak23UISdWidyZuI1ghNe2xjzUZAyT+08=
|
||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.18.4 h1:phn1rkXqpC2IMSrYF9lC99BnvctRo4ArDG5S8XcoJMA=
|
||||
github.com/aws/aws-sdk-go-v2/feature/dynamodb/attributevalue v1.18.4/go.mod h1:8Nk8uFZ5rACaV8aiP31yQZPh9kasjSFMDj/GOrFT91E=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.28 h1:KwsodFKVQTlI5EyhRSugALzsV6mG/SGrdjlMXSZSdso=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.28/go.mod h1:EY3APf9MzygVhKuPXAc5H+MkGb8k/DOSQjWS0LgkKqI=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.32 h1:BjUcr3X3K0wZPGFg2bxOWW3VPN8rkE3/61zhP+IHviA=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.32/go.mod h1:80+OGC/bgzzFFTUmcuwD0lb4YutwQeKLFpmt6hoWapU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.32 h1:m1GeXHVMJsRsUAqG6HjZWx9dj7F5TR+cF1bjyfYyBd4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.32/go.mod h1:IitoQxGfaKdVLNg0hD8/DXmAqNy0H4K2H2Sf91ti8sI=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.39.9 h1:gC1SKYPagK6aiL6BrQOl0U5D3vSLQUw6mMaFe9DzoC8=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.39.9/go.mod h1:+pfCvXbSNLZ7lG+tydnY5IN4WUoz+WsGDrl2rg2DEew=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.19 h1:3n3jgZnhHXSHGHudTOtN3WHkgouE4Jw5rXkBNnPpPo8=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.19/go.mod h1:K7wcnwLh1oGGwASzdY6mryhtkPgst/CxmEw78LmlyOU=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.40.1 h1:JUvURAe0mNRzYd+1uTHEiojeyWtNPIQ5EXnDKfgKGUU=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.40.1/go.mod h1:FcMiR2AALpkrpik6JzbYu+iEfktzrs3XOq5Shk9nvik=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.20 h1:uUTR6EInXq1uf/Bz/0V9bc4jT3sKQ3UuFOjxeUVjeCM=
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.24.20/go.mod h1:jpQRvf4Atm1US92/h+6U3NLeoygPdFid9OYw8awLEa8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 h1:D4oz8/CzT9bAEYtVhSBmFj2dNOtaHOtMKc2vHBwYizA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2/go.mod h1:Za3IHqTQ+yNcRHxu1OFucBh0ACZT4j4VQFF0BqpZcLY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.12 h1:V1h3Cxmn0tN5EhL31uvqSLKsMlPlqiYxRwAEdwNeIJ8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.12/go.mod h1:KzXJPn2wqsZJlNSx70gmDkRDVTmyF/RRXxTP2yMxUwc=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12 h1:O+8vD2rGjfihBewr5bT+QUfYUHIxCVgG61LHoT59shM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12/go.mod h1:usVdWJaosa66NMvmCrr08NcWDBRv4E6+YFG2pUdw1Lk=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.48.6 h1:O7L9iEodiF07vJoXShMrw2XyeAqZhLUIXqWEitCq6EE=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.48.6/go.mod h1:E93uWfli9RToQzVA7+bYnynKOFcYOhNWqhY1hWSMZRc=
|
||||
github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.34.10 h1:G3u05YD9rurafUNF4CTVQZ+Fhb5qIPl4CrXJTU+gN0U=
|
||||
github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.34.10/go.mod h1:8W5a2c+QnClUwxJp+jHnoyWxT2GywMsP7ia3fcQ0oHE=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 h1:c5WJ3iHz7rLIgArznb3JCSQT3uUMiz9DLZhIX+1G8ok=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.14/go.mod h1:+JJQTxB6N4niArC14YNtxcQtwEqzS3o9Z32n7q33Rfs=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 h1:f1L/JtUkVODD+k1+IiSJUUv8A++2qVr+Xvb3xWXETMU=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13/go.mod h1:tvqlFoja8/s0o+UruA1Nrezo/df0PzdunMDDurUfg6U=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.13 h1:3LXNnmtH3TURctC23hnC0p/39Q5gre3FI7BNOiDcVWc=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.13/go.mod h1:7Yn+p66q/jt38qMoVfNvjbm3D89mGBnkwDcijgtih8w=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.13 h1:eWoHfLIzYeUtJEuoUmD5PwTE+fLaIPN9NZ7UXd9CW0s=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.10.13/go.mod h1:x5t8Ve0J7JK9VHKSPSRAdBrWAgr/5hH3UeCFMLoyUGQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.13 h1:SYVGSFQHlchIcy6e7x12bsrxClCXSP5et8cqVhL8cuw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.13/go.mod h1:kizuDaLX37bG5WZaoxGPQR/LNFXpxp0vsUnqfkWXfNE=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.48.7 h1:oPqYaMfI6XYKXD5jlJ4JHipkKcA2Ska3JLLz11ukf0E=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.48.7/go.mod h1:DFFR1FKSHaBJZF2eMW+6PsSg97pldSoHQnRx4tH2Mek=
|
||||
github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.34.11 h1:0P8AxY1gL1XAMtbh5oJ4dKa19vH+hWrOunHAKgzoI6k=
|
||||
github.com/aws/aws-sdk-go-v2/service/servicediscovery v1.34.11/go.mod h1:vqJsXcYIagfc/7a+68TvAM2GogOSY6aK0bbROwq7uoM=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.15 h1:/eE3DogBjYlvlbhd2ssWyeuovWunHLxfgw3s/OJa4GQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.15/go.mod h1:2PCJYpi7EKeA5SkStAmZlF6fi0uUABuhtF8ILHjGc3Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.14 h1:M/zwXiL2iXUrHputuXgmO94TVNmcenPHxgLXLutodKE=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.14/go.mod h1:RVwIw3y/IqxC2YEXSIkAzRDdEU1iRabDPaYjpGCbCGQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.14 h1:TzeR06UCMUq+KA3bDkujxK1GVGy+G8qQN/QVYzGLkQE=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.33.14/go.mod h1:dspXf/oYWGWo6DEvj98wpaTeqt5+DMidZD0A9BYTizc=
|
||||
github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ=
|
||||
github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg=
|
||||
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
|
||||
@ -257,8 +257,8 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/digitalocean/godo v1.136.0 h1:DTxugljFJSMBPfEGq4KeXpnKeAHicggNqogcrw/YdZw=
|
||||
github.com/digitalocean/godo v1.136.0/go.mod h1:PU8JB6I1XYkQIdHFop8lLAY9ojp6M0XcU0TWaQSxbrc=
|
||||
github.com/digitalocean/godo v1.137.0 h1:bkPG5ram9bHErbCWCKT6j/fMs8jisckhczd3IvueJHg=
|
||||
github.com/digitalocean/godo v1.137.0/go.mod h1:PU8JB6I1XYkQIdHFop8lLAY9ojp6M0XcU0TWaQSxbrc=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/dnsimple/dnsimple-go v1.7.0 h1:JKu9xJtZ3SqOC+BuYgAWeab7+EEx0sz422vu8j611ZY=
|
||||
github.com/dnsimple/dnsimple-go v1.7.0/go.mod h1:EKpuihlWizqYafSnQHGCd/gyvy3HkEQJ7ODB4KdV8T8=
|
||||
@ -848,10 +848,10 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxS
|
||||
github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw=
|
||||
github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4=
|
||||
github.com/oracle/oci-go-sdk/v65 v65.83.0 h1:KFI0oyyCTPmgevHF+QlN02Zdf23Jx1p1X+4KPyH14H8=
|
||||
github.com/oracle/oci-go-sdk/v65 v65.83.0/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0=
|
||||
github.com/ovh/go-ovh v1.6.0 h1:ixLOwxQdzYDx296sXcgS35TOPEahJkpjMGtzPadCjQI=
|
||||
github.com/ovh/go-ovh v1.6.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
|
||||
github.com/oracle/oci-go-sdk/v65 v65.83.1 h1:Cgojq322B7NwOPOa/arfgVz+5+vRbb2lJtiADVQfgHE=
|
||||
github.com/oracle/oci-go-sdk/v65 v65.83.1/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0=
|
||||
github.com/ovh/go-ovh v1.7.0 h1:V14nF7FwDjQrZt9g7jzcvAAQ3HN6DNShRFRMC3jLoPw=
|
||||
github.com/ovh/go-ovh v1.7.0/go.mod h1:cTVDnl94z4tl8pP1uZ/8jlVxntjSIf09bNcQ5TJSC7c=
|
||||
github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2 h1:CXwSGu/LYmbjEab5aMCs5usQRVBGThelUKBNnoSOuso=
|
||||
github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0=
|
||||
github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
|
||||
@ -936,8 +936,8 @@ github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
|
||||
github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rubenv/sql-migrate v0.0.0-20200212082348-64f95ea68aa3/go.mod h1:rtQlpHw+eR6UrqaS3kX1VYeaCxzCVdimDS7g5Ln4pPc=
|
||||
github.com/rubenv/sql-migrate v0.0.0-20200616145509-8d140a17f351/go.mod h1:DCgfY80j8GYL7MLEfvcpSFvjD0L5yZq/aZUJmhZklyg=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
@ -1018,12 +1018,12 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1091 h1:RxogX8ZCPBmZ6PY7DjnWnwGRkAkYEEinT5WNNxbLVeo=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1091/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1091 h1:36WwNgrtoGKszQovUj3+0CjNsM1gMQ3a5lvZx2bkjng=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1091/go.mod h1:cWRGvOUnMQMky4oliMX1dXT6Z4CbsSGOIxaUcrD5Zvw=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.1091 h1:nNPu5tK4RYMzy1igVv2KDFZBdptI/hEBJYRBsEnSiZA=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.1091/go.mod h1:PFelV0G8C5lfhFSz/VO4ee4sfg4sEIq/g8HzlytjmQk=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1097 h1:3wV4Lq32bzwtFJutzjdZGM+QYUff/E8fp0nLLugWDtI=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1097/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1097 h1:bXAszuWU0a+MmQ5YDWNZYB7lhWtPgTioCFDLzuyma+A=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1097/go.mod h1:YDURTkRoR7iySup30Wvxt/SChJOZ0dV+P7NBoekQFdg=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.1097 h1:qg6EGXlghoTIHOLmegnxBkbkmpds2ZUVG9ti8htUU44=
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/privatedns v1.0.1097/go.mod h1:zsaqJnLZrmwF8m5zJDuXIW9IUJ3lokrxwgBtcCupFIM=
|
||||
github.com/terra-farm/udnssdk v1.3.5 h1:MNR3adfuuEK/l04+jzo8WW/0fnorY+nW515qb3vEr6I=
|
||||
github.com/terra-farm/udnssdk v1.3.5/go.mod h1:8RnM56yZTR7mYyUIvrDgXzdRaEyFIzqdEi7+um26Sv8=
|
||||
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
@ -1091,18 +1091,20 @@ go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
|
||||
go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U=
|
||||
go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg=
|
||||
go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M=
|
||||
go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8=
|
||||
go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4=
|
||||
go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ=
|
||||
go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM=
|
||||
go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
@ -1147,8 +1149,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
|
||||
golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
|
||||
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@ -1210,8 +1212,8 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220725212005-46097bf591d3/go.mod h1:AaygXjzTFtRAg2ttMY5RMuhpJ3cNnI0XpyFJD1iQRSM=
|
||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
||||
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@ -1281,13 +1283,13 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||
golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1295,8 +1297,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -1351,8 +1353,8 @@ gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZ
|
||||
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.219.0 h1:nnKIvxKs/06jWawp2liznTBnMRQBEPpGo7I+oEypTX0=
|
||||
google.golang.org/api v0.219.0/go.mod h1:K6OmjGm+NtLrIkHxv1U3a0qIf/0JOvAHd5O/6AoyKYE=
|
||||
google.golang.org/api v0.221.0 h1:qzaJfLhDsbMeFee8zBRdt/Nc+xmOuafD/dbdgGfutOU=
|
||||
google.golang.org/api v0.221.0/go.mod h1:7sOU2+TL4TxUTdbi0gWgAIg7tH5qBXxoyhtL+9x3biQ=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@ -1368,8 +1370,8 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47 h1:91mG8dNTpkC0uChJUQ9zCiRqx3GEEFOWaRZ0mI6Oj2I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250124145028-65684f501c47/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk=
|
||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
@ -1394,8 +1396,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
|
||||
google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
@ -1451,10 +1453,10 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
istio.io/api v1.24.2 h1:jYjcN6Iq0RPtQj/3KMFsybxmfqmjGN/dxhL7FGJEdIM=
|
||||
istio.io/api v1.24.2/go.mod h1:MQnRok7RZ20/PE56v0LxmoWH0xVxnCQPNuf9O7PAN1I=
|
||||
istio.io/client-go v1.24.2 h1:JTTfBV6dv+AAW+AfccyrdX4T1f9CpsXd1Yzo1s/IYAI=
|
||||
istio.io/client-go v1.24.2/go.mod h1:dgZ9EmJzh1EECzf6nQhwNL4R6RvlyeH/RXeNeNp/MRg=
|
||||
istio.io/api v1.24.3 h1:iwWWPM0uEQ+oxRHvIWoB8MQ4bjF3dRQj+M5IDVczg0M=
|
||||
istio.io/api v1.24.3/go.mod h1:MQnRok7RZ20/PE56v0LxmoWH0xVxnCQPNuf9O7PAN1I=
|
||||
istio.io/client-go v1.24.3 h1:TB8IcM3yyMCDzKRJo0YfFOUGNQmkhwH/JE/Yr3lzVAk=
|
||||
istio.io/client-go v1.24.3/go.mod h1:zSyw/c4luKQKosFIHQaWAQOA0c3bODu4SahQCAMlKA4=
|
||||
k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8=
|
||||
k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
|
||||
k8s.io/api v0.18.4/go.mod h1:lOIQAKYgai1+vz9J7YcDZwC26Z0zQewYOGWdyIPUUQ4=
|
||||
|
||||
49
internal/testutils/log.go
Normal file
49
internal/testutils/log.go
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package testutils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"testing"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// LogsToBuffer redirects log(s) output to a buffer for testing purposes
|
||||
//
|
||||
// Usage: LogsToBuffer(t)
|
||||
// Example:
|
||||
//
|
||||
// buf := LogsToBuffer(log.DebugLevel, t)
|
||||
// ... do something that logs ...
|
||||
// assert.Contains(t, buf.String(), "expected debug log message")
|
||||
func LogsToBuffer(level log.Level, t *testing.T) *bytes.Buffer {
|
||||
t.Helper()
|
||||
buf := new(bytes.Buffer)
|
||||
log.SetOutput(buf)
|
||||
log.SetLevel(level)
|
||||
klog.SetOutput(buf)
|
||||
flags := &flag.FlagSet{}
|
||||
klog.InitFlags(flags)
|
||||
// make sure klog doesn't write to stderr by default in tests
|
||||
_ = flags.Set("logtostderr", "false")
|
||||
_ = flags.Set("alsologtostderr", "false")
|
||||
_ = flags.Set("stderrthreshold", "4")
|
||||
return buf
|
||||
}
|
||||
11
mkdocs.yml
11
mkdocs.yml
@ -25,11 +25,12 @@ nav:
|
||||
- TXT: docs/registry/txt.md
|
||||
- DynamoDB: docs/registry/dynamodb.md
|
||||
- Advanced Topics:
|
||||
- Initial Design: docs/initial-design.md
|
||||
- TTL: docs/ttl.md
|
||||
- NAT64: docs/nat64.md
|
||||
- MultiTarget: docs/proposal/multi-target.md
|
||||
- Rate Limits: docs/rate-limits.md
|
||||
- Initial Design: docs/initial-design.md
|
||||
- Leader Election: docs/proposal/001-leader-election.md
|
||||
- MultiTarget: docs/proposal/multi-target.md
|
||||
- NAT64: docs/nat64.md
|
||||
- Rate Limits: docs/rate-limits.md
|
||||
- TTL: docs/ttl.md
|
||||
- Contributing:
|
||||
- Kubernetes Contributions: CONTRIBUTING.md
|
||||
- Release: docs/release.
|
||||
|
||||
76
provider/aws/aws_fixtures_test.go
Normal file
76
provider/aws/aws_fixtures_test.go
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package aws
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/external-dns/internal/testutils"
|
||||
)
|
||||
|
||||
func TestAWSRecordsV1(t *testing.T) {
|
||||
var zones HostedZones
|
||||
unmarshalTestHelper("/fixtures/160-plus-zones.yaml", &zones, t)
|
||||
|
||||
stub := NewRoute53APIFixtureStub(&zones)
|
||||
provider := providerFilters(stub,
|
||||
WithZoneIDFilters(
|
||||
"Z10242883PKPS38KA4S6C", "Z10295763LSQ170JCTR78",
|
||||
"Z102957NOTEXISTS", "Z09418121E8V6WT4FASZE",
|
||||
),
|
||||
WithDomainFilters("w2.w1.ex.com", "ex.com"),
|
||||
)
|
||||
|
||||
ctx := context.Background()
|
||||
z, err := provider.Zones(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 3, len(z))
|
||||
}
|
||||
|
||||
func TestAWSZonesFilterWithTags(t *testing.T) {
|
||||
var zones HostedZones
|
||||
unmarshalTestHelper("/fixtures/160-plus-zones.yaml", &zones, t)
|
||||
|
||||
stub := NewRoute53APIFixtureStub(&zones)
|
||||
provider := providerFilters(stub,
|
||||
WithZoneTagFilters([]string{"level=5", "owner=ext-dns"}),
|
||||
)
|
||||
|
||||
ctx := context.Background()
|
||||
z, err := provider.Zones(ctx)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 24, len(z))
|
||||
assert.Equal(t, 169, stub.calls["listtagsforresource"])
|
||||
}
|
||||
|
||||
func TestAWSZonesSecondRequestHitsTheCache(t *testing.T) {
|
||||
var zones HostedZones
|
||||
unmarshalTestHelper("/fixtures/160-plus-zones.yaml", &zones, t)
|
||||
|
||||
stub := NewRoute53APIFixtureStub(&zones)
|
||||
provider := providerFilters(stub)
|
||||
|
||||
ctx := context.Background()
|
||||
_, err := provider.Zones(ctx)
|
||||
assert.NoError(t, err)
|
||||
b := testutils.LogsToBuffer(log.DebugLevel, t)
|
||||
_, _ = provider.Zones(ctx)
|
||||
assert.Contains(t, b.String(), "level=debug msg=\"Using cached zones list\"")
|
||||
}
|
||||
148
provider/aws/aws_utils_test.go
Normal file
148
provider/aws/aws_utils_test.go
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package aws
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/service/route53"
|
||||
route53types "github.com/aws/aws-sdk-go-v2/service/route53/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/yaml.v3"
|
||||
"sigs.k8s.io/external-dns/endpoint"
|
||||
"sigs.k8s.io/external-dns/provider"
|
||||
)
|
||||
|
||||
type HostedZones struct {
|
||||
Zones []*HostedZone `yaml:"zones"`
|
||||
}
|
||||
|
||||
type HostedZone struct {
|
||||
Name string
|
||||
ID string
|
||||
Tags []route53types.Tag `yaml:"tags"`
|
||||
}
|
||||
|
||||
var _ Route53API = &Route53APIFixtureStub{}
|
||||
|
||||
type Route53APIFixtureStub struct {
|
||||
zones map[string]*route53types.HostedZone
|
||||
zoneTags map[string][]route53types.Tag
|
||||
calls map[string]int
|
||||
}
|
||||
|
||||
func providerFilters(client *Route53APIFixtureStub, options ...func(awsProvider *AWSProvider)) *AWSProvider {
|
||||
p := &AWSProvider{
|
||||
clients: map[string]Route53API{defaultAWSProfile: client},
|
||||
evaluateTargetHealth: false,
|
||||
dryRun: false,
|
||||
domainFilter: endpoint.NewDomainFilter([]string{}),
|
||||
zoneIDFilter: provider.NewZoneIDFilter([]string{}),
|
||||
zoneTypeFilter: provider.NewZoneTypeFilter(""),
|
||||
zoneTagFilter: provider.NewZoneTagFilter([]string{}),
|
||||
zonesCache: &zonesListCache{duration: 1 * time.Second},
|
||||
}
|
||||
for _, o := range options {
|
||||
o(p)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func WithDomainFilters(filters ...string) func(awsProvider *AWSProvider) {
|
||||
return func(awsProvider *AWSProvider) {
|
||||
awsProvider.domainFilter = endpoint.NewDomainFilter(filters)
|
||||
}
|
||||
}
|
||||
|
||||
func WithZoneIDFilters(filters ...string) func(awsProvider *AWSProvider) {
|
||||
return func(awsProvider *AWSProvider) {
|
||||
awsProvider.zoneIDFilter = provider.NewZoneIDFilter(filters)
|
||||
}
|
||||
}
|
||||
|
||||
func WithZoneTagFilters(filters []string) func(awsProvider *AWSProvider) {
|
||||
return func(awsProvider *AWSProvider) {
|
||||
awsProvider.zoneTagFilter = provider.NewZoneTagFilter(filters)
|
||||
}
|
||||
}
|
||||
|
||||
func NewRoute53APIFixtureStub(zones *HostedZones) *Route53APIFixtureStub {
|
||||
route53Zones := make(map[string]*route53types.HostedZone)
|
||||
zoneTags := make(map[string][]route53types.Tag)
|
||||
for _, zone := range zones.Zones {
|
||||
route53Zones[zone.ID] = &route53types.HostedZone{
|
||||
Id: &zone.ID,
|
||||
Name: &zone.Name,
|
||||
}
|
||||
zoneTags[cleanZoneID(zone.ID)] = zone.Tags
|
||||
}
|
||||
return &Route53APIFixtureStub{
|
||||
zones: route53Zones,
|
||||
zoneTags: zoneTags,
|
||||
calls: make(map[string]int),
|
||||
}
|
||||
}
|
||||
|
||||
func (r Route53APIFixtureStub) ListResourceRecordSets(ctx context.Context, input *route53.ListResourceRecordSetsInput, optFns ...func(options *route53.Options)) (*route53.ListResourceRecordSetsOutput, error) {
|
||||
// TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (r Route53APIFixtureStub) ChangeResourceRecordSets(ctx context.Context, input *route53.ChangeResourceRecordSetsInput, optFns ...func(options *route53.Options)) (*route53.ChangeResourceRecordSetsOutput, error) {
|
||||
// TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (r Route53APIFixtureStub) CreateHostedZone(ctx context.Context, input *route53.CreateHostedZoneInput, optFns ...func(*route53.Options)) (*route53.CreateHostedZoneOutput, error) {
|
||||
// TODO implement me
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (r Route53APIFixtureStub) ListHostedZones(ctx context.Context, input *route53.ListHostedZonesInput, optFns ...func(options *route53.Options)) (*route53.ListHostedZonesOutput, error) {
|
||||
r.calls["listhostedzones"]++
|
||||
output := &route53.ListHostedZonesOutput{}
|
||||
for _, zone := range r.zones {
|
||||
output.HostedZones = append(output.HostedZones, *zone)
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
func (r Route53APIFixtureStub) ListTagsForResource(ctx context.Context, input *route53.ListTagsForResourceInput, optFns ...func(options *route53.Options)) (*route53.ListTagsForResourceOutput, error) {
|
||||
r.calls["listtagsforresource"]++
|
||||
tags := r.zoneTags[*input.ResourceId]
|
||||
return &route53.ListTagsForResourceOutput{
|
||||
ResourceTagSet: &route53types.ResourceTagSet{
|
||||
ResourceId: input.ResourceId,
|
||||
ResourceType: input.ResourceType,
|
||||
Tags: tags,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func unmarshalTestHelper(input string, obj any, t *testing.T) {
|
||||
t.Helper()
|
||||
path, _ := os.Getwd()
|
||||
file, err := os.Open(path + input)
|
||||
assert.NoError(t, err)
|
||||
defer file.Close()
|
||||
dec := yaml.NewDecoder(file)
|
||||
err = dec.Decode(obj)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
3215
provider/aws/fixtures/160-plus-zones.yaml
Normal file
3215
provider/aws/fixtures/160-plus-zones.yaml
Normal file
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ import (
|
||||
|
||||
// ZoneTagFilter holds a list of zone tags to filter by
|
||||
type ZoneTagFilter struct {
|
||||
zoneTags []string
|
||||
tagsMap map[string]string
|
||||
}
|
||||
|
||||
// NewZoneTagFilter returns a new ZoneTagFilter given a list of zone tags
|
||||
@ -30,22 +30,29 @@ func NewZoneTagFilter(tags []string) ZoneTagFilter {
|
||||
if len(tags) == 1 && len(tags[0]) == 0 {
|
||||
tags = []string{}
|
||||
}
|
||||
return ZoneTagFilter{zoneTags: tags}
|
||||
tagsMap := make(map[string]string)
|
||||
// tags pre-processing, to make sure the pre-processing is not happening at the time of filtering
|
||||
for _, tag := range tags {
|
||||
parts := strings.SplitN(tag, "=", 2)
|
||||
key := strings.TrimSpace(parts[0])
|
||||
if key == "" {
|
||||
continue
|
||||
}
|
||||
if len(parts) == 2 {
|
||||
value := strings.TrimSpace(parts[1])
|
||||
tagsMap[key] = value
|
||||
} else {
|
||||
tagsMap[key] = ""
|
||||
}
|
||||
}
|
||||
return ZoneTagFilter{tagsMap: tagsMap}
|
||||
}
|
||||
|
||||
// Match checks whether a zone's set of tags matches the provided tag values
|
||||
func (f ZoneTagFilter) Match(tagsMap map[string]string) bool {
|
||||
for _, tagFilter := range f.zoneTags {
|
||||
filterParts := strings.SplitN(tagFilter, "=", 2)
|
||||
switch len(filterParts) {
|
||||
case 1:
|
||||
if _, hasTag := tagsMap[filterParts[0]]; !hasTag {
|
||||
return false
|
||||
}
|
||||
case 2:
|
||||
if value, hasTag := tagsMap[filterParts[0]]; !hasTag || value != filterParts[1] {
|
||||
return false
|
||||
}
|
||||
for key, v := range f.tagsMap {
|
||||
if value, hasTag := tagsMap[key]; !hasTag || (v != "" && value != v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
@ -53,5 +60,5 @@ func (f ZoneTagFilter) Match(tagsMap map[string]string) bool {
|
||||
|
||||
// IsEmpty returns true if there are no tags for the filter
|
||||
func (f ZoneTagFilter) IsEmpty() bool {
|
||||
return len(f.zoneTags) == 0
|
||||
return len(f.tagsMap) == 0
|
||||
}
|
||||
|
||||
@ -57,7 +57,7 @@ var basicZoneTags = []struct {
|
||||
"empty tag filter matches all", []string{""}, map[string]string{"tag0": "value0"}, true,
|
||||
},
|
||||
{
|
||||
"tag filter without key and equal sign", []string{"tag1=value1", "=haha"}, map[string]string{"tag1": "value1"}, false,
|
||||
"tag filter without key and equal sign", []string{"tag1=value1", "=haha"}, map[string]string{"tag1": "value1"}, true,
|
||||
},
|
||||
}
|
||||
|
||||
@ -74,16 +74,17 @@ func TestZoneTagFilterNotSupportedFormat(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
tags []string
|
||||
want []string
|
||||
want map[string]string
|
||||
}{
|
||||
{desc: "multiple or separate values with commas", tags: []string{"key1=val1,key2=val2"}, want: []string{"key1=val1,key2=val2"}},
|
||||
{desc: "exclude tag", tags: []string{"!key1"}, want: []string{"!key1"}},
|
||||
{desc: "exclude tags", tags: []string{"!key1=val"}, want: []string{"!key1=val"}},
|
||||
{desc: "multiple or separate values with commas", tags: []string{"key1=val1,key2=val2"}, want: map[string]string{"key1": "val1,key2=val2"}},
|
||||
{desc: "exclude tag", tags: []string{"!key1"}, want: map[string]string{"!key1": ""}},
|
||||
{desc: "exclude tags", tags: []string{"!key1=val"}, want: map[string]string{"!key1": "val"}},
|
||||
{desc: "key is empty", tags: []string{"=val"}, want: map[string]string{}},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(fmt.Sprintf("%s", tc.desc), func(t *testing.T) {
|
||||
got := NewZoneTagFilter(tc.tags)
|
||||
assert.Equal(t, tc.want, got.zoneTags)
|
||||
assert.Equal(t, tc.want, got.tagsMap)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
122
scripts/helm-tools.sh
Executable file
122
scripts/helm-tools.sh
Executable file
@ -0,0 +1,122 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# JSON Schema https://json-schema.org/
|
||||
# JSON Schema spec https://json-schema.org/draft/2020-12/json-schema-validation
|
||||
# Helm Schema https://helm.sh/docs/topics/charts/#schema-files
|
||||
|
||||
# Execute
|
||||
# scripts/helm-tools.sh
|
||||
# scripts/helm-tools.sh -h
|
||||
# scripts/helm-tools.sh --install
|
||||
# scripts/helm-tools.sh --diff
|
||||
# scripts/helm-tools.sh --schema
|
||||
# scripts/helm-tools.sh --lint
|
||||
# scripts/helm-tools.sh --docs
|
||||
|
||||
show_help() {
|
||||
cat << EOF
|
||||
'external-dns' helm linter helper commands
|
||||
|
||||
Usage: $(basename "$0") <options>
|
||||
-d, --diff Schema diff validation
|
||||
--docs Re-generate helm documentation
|
||||
-h, --help Display help
|
||||
-i, --install Install required tooling
|
||||
-l, --lint Lint chart
|
||||
-s, --schema Generate schema
|
||||
--show-docs Show available documentation
|
||||
EOF
|
||||
}
|
||||
|
||||
install() {
|
||||
if [[ -x $(which helm) ]]; then
|
||||
echo "installing https://github.com/losisin/helm-values-schema-json.git plugin"
|
||||
helm plugin install https://github.com/losisin/helm-values-schema-json.git | true
|
||||
helm plugin list | grep "schema"
|
||||
|
||||
echo "installing helm-docs"
|
||||
go install github.com/norwoodj/helm-docs/cmd/helm-docs@latest | true
|
||||
|
||||
if [[ -x $(which brew) ]]; then
|
||||
echo "installing chart-testing https://github.com/helm/chart-testing"
|
||||
brew install chart-testing
|
||||
fi
|
||||
else
|
||||
echo "helm is not installed"
|
||||
echo "install helm https://helm.sh/docs/intro/install/ and try again"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
update_schema() {
|
||||
cd charts/external-dns
|
||||
# uses .schema.yamle
|
||||
helm schema
|
||||
}
|
||||
|
||||
diff_schema() {
|
||||
cd charts/external-dns
|
||||
helm schema \
|
||||
-output diff-schema.schema.json
|
||||
trap 'rm -rf -- "diff-schema.schema.json"' EXIT
|
||||
CURRENT_SCHEMA=$(cat values.schema.json)
|
||||
GENERATED_SCHEMA=$(cat diff-schema.schema.json)
|
||||
if [ "$CURRENT_SCHEMA" != "$GENERATED_SCHEMA" ]; then
|
||||
echo "Schema must be re-generated! Run 'scripts/helm-tools.sh --schema'" 1>&2
|
||||
diff -Nau diff-schema.schema.json values.schema.json
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
lint_chart() {
|
||||
cd charts/external-dns
|
||||
helm lint . --debug --strict \
|
||||
--values values.yaml \
|
||||
--values ci/ci-values.yaml
|
||||
# lint with chart testing tool
|
||||
ct lint --target-branch=master --check-version-increment=false
|
||||
}
|
||||
|
||||
helm_docs() {
|
||||
cd charts/external-dns
|
||||
helm-docs
|
||||
}
|
||||
|
||||
show_docs() {
|
||||
open "https://github.com/losisin/helm-values-schema-json?tab=readme-ov-file"
|
||||
}
|
||||
|
||||
function main() {
|
||||
case $1 in
|
||||
--show-docs)
|
||||
show_docs
|
||||
;;
|
||||
-d|--diff)
|
||||
diff_schema
|
||||
;;
|
||||
--docs)
|
||||
helm_docs
|
||||
;;
|
||||
-i|--install)
|
||||
install
|
||||
;;
|
||||
-l|--lint)
|
||||
lint_chart
|
||||
;;
|
||||
-s|--schema)
|
||||
update_schema
|
||||
;;
|
||||
-h|--help)
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
echo "unknown sub-command" >&2
|
||||
show_help
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@ -18,6 +18,7 @@ package source
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
@ -45,7 +46,11 @@ func (ms *dedupSource) Endpoints(ctx context.Context) ([]*endpoint.Endpoint, err
|
||||
}
|
||||
|
||||
for _, ep := range endpoints {
|
||||
identifier := ep.DNSName + " / " + ep.SetIdentifier + " / " + ep.Targets.String()
|
||||
if ep == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
identifier := strings.Join([]string{ep.RecordType, ep.DNSName, ep.SetIdentifier, ep.Targets.String()}, "/")
|
||||
|
||||
if _, ok := collected[identifier]; ok {
|
||||
log.Debugf("Removing duplicate endpoint %s", ep)
|
||||
|
||||
@ -90,6 +90,38 @@ func testDedupEndpoints(t *testing.T) {
|
||||
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
"two endpoints with same dnsname, same type, and same target return one endpoint",
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "foo.example.org", RecordType: "A", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
{DNSName: "foo.example.org", RecordType: "A", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
},
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "foo.example.org", RecordType: "A", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
"two endpoints with same dnsname, different record type, and same target return two endpoints",
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "foo.example.org", RecordType: "A", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
{DNSName: "foo.example.org", RecordType: "AAAA", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
},
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "foo.example.org", RecordType: "A", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
{DNSName: "foo.example.org", RecordType: "AAAA", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
},
|
||||
},
|
||||
{
|
||||
"two endpoints with same dnsname, one with record type, one without, and same target return two endpoints",
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "foo.example.org", RecordType: "A", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
},
|
||||
[]*endpoint.Endpoint{
|
||||
{DNSName: "foo.example.org", RecordType: "A", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
{DNSName: "foo.example.org", Targets: endpoint.Targets{"1.2.3.4"}},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(tc.title, func(t *testing.T) {
|
||||
mockSource := new(testutils.MockSource)
|
||||
|
||||
@ -55,6 +55,7 @@ type virtualServiceSource struct {
|
||||
ignoreHostnameAnnotation bool
|
||||
serviceInformer coreinformers.ServiceInformer
|
||||
virtualserviceInformer networkingv1alpha3informer.VirtualServiceInformer
|
||||
gatewayInformer networkingv1alpha3informer.GatewayInformer
|
||||
}
|
||||
|
||||
// NewIstioVirtualServiceSource creates a new virtualServiceSource with the given config.
|
||||
@ -79,6 +80,7 @@ func NewIstioVirtualServiceSource(
|
||||
serviceInformer := informerFactory.Core().V1().Services()
|
||||
istioInformerFactory := istioinformers.NewSharedInformerFactoryWithOptions(istioClient, 0, istioinformers.WithNamespace(namespace))
|
||||
virtualServiceInformer := istioInformerFactory.Networking().V1alpha3().VirtualServices()
|
||||
gatewayInformer := istioInformerFactory.Networking().V1alpha3().Gateways()
|
||||
|
||||
// Add default resource event handlers to properly initialize informer.
|
||||
serviceInformer.Informer().AddEventHandler(
|
||||
@ -97,6 +99,14 @@ func NewIstioVirtualServiceSource(
|
||||
},
|
||||
)
|
||||
|
||||
gatewayInformer.Informer().AddEventHandler(
|
||||
cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: func(obj interface{}) {
|
||||
log.Debug("gateway added")
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
informerFactory.Start(ctx.Done())
|
||||
istioInformerFactory.Start(ctx.Done())
|
||||
|
||||
@ -118,6 +128,7 @@ func NewIstioVirtualServiceSource(
|
||||
ignoreHostnameAnnotation: ignoreHostnameAnnotation,
|
||||
serviceInformer: serviceInformer,
|
||||
virtualserviceInformer: virtualServiceInformer,
|
||||
gatewayInformer: gatewayInformer,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@ -186,7 +197,7 @@ func (sc *virtualServiceSource) AddEventHandler(ctx context.Context, handler fun
|
||||
sc.virtualserviceInformer.Informer().AddEventHandler(eventHandlerFunc(handler))
|
||||
}
|
||||
|
||||
func (sc *virtualServiceSource) getGateway(ctx context.Context, gatewayStr string, virtualService *networkingv1alpha3.VirtualService) (*networkingv1alpha3.Gateway, error) {
|
||||
func (sc *virtualServiceSource) getGateway(_ context.Context, gatewayStr string, virtualService *networkingv1alpha3.VirtualService) (*networkingv1alpha3.Gateway, error) {
|
||||
if gatewayStr == "" || gatewayStr == IstioMeshGateway {
|
||||
// This refers to "all sidecars in the mesh"; ignore.
|
||||
return nil, nil
|
||||
@ -201,7 +212,7 @@ func (sc *virtualServiceSource) getGateway(ctx context.Context, gatewayStr strin
|
||||
namespace = virtualService.Namespace
|
||||
}
|
||||
|
||||
gateway, err := sc.istioClient.NetworkingV1alpha3().Gateways(namespace).Get(ctx, name, metav1.GetOptions{})
|
||||
gateway, err := sc.gatewayInformer.Lister().Gateways(namespace).Get(name)
|
||||
if errors.IsNotFound(err) {
|
||||
log.Warnf("VirtualService (%s/%s) references non-existent gateway: %s ", virtualService.Namespace, virtualService.Name, gatewayStr)
|
||||
return nil, nil
|
||||
|
||||
@ -29,13 +29,10 @@ import (
|
||||
istionetworking "istio.io/api/networking/v1alpha3"
|
||||
networkingv1alpha3 "istio.io/client-go/pkg/apis/networking/v1alpha3"
|
||||
istiofake "istio.io/client-go/pkg/clientset/versioned/fake"
|
||||
fakenetworking3 "istio.io/client-go/pkg/clientset/versioned/typed/networking/v1alpha3/fake"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
networkv1 "k8s.io/api/networking/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
k8sclienttesting "k8s.io/client-go/testing"
|
||||
|
||||
"sigs.k8s.io/external-dns/endpoint"
|
||||
)
|
||||
@ -700,6 +697,20 @@ func testEndpointsFromVirtualServiceConfig(t *testing.T) {
|
||||
t.Run(ti.title, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for i := range ti.ingresses {
|
||||
if ti.ingresses[i].namespace == "" {
|
||||
ti.ingresses[i].namespace = "test"
|
||||
}
|
||||
}
|
||||
|
||||
if ti.gwconfig.namespace == "" {
|
||||
ti.gwconfig.namespace = "test"
|
||||
}
|
||||
|
||||
if ti.vsconfig.namespace == "" {
|
||||
ti.vsconfig.namespace = "test"
|
||||
}
|
||||
|
||||
if source, err := newTestVirtualServiceSource(ti.lbServices, ti.ingresses, []fakeGatewayConfig{ti.gwconfig}); err != nil {
|
||||
require.NoError(t, err)
|
||||
} else if endpoints, err := source.endpointsFromVirtualService(context.Background(), ti.vsconfig.Config()); err != nil {
|
||||
@ -2182,34 +2193,6 @@ func TestVirtualServiceSourceGetGateway(t *testing.T) {
|
||||
Spec: istionetworking.Gateway{},
|
||||
Status: v1alpha1.IstioStatus{},
|
||||
}, expectedErrStr: ""},
|
||||
{name: "ErrorGettingGateway", fields: fields{
|
||||
virtualServiceSource: func() *virtualServiceSource {
|
||||
istioFake := istiofake.NewSimpleClientset()
|
||||
istioFake.NetworkingV1alpha3().(*fakenetworking3.FakeNetworkingV1alpha3).PrependReactor("get", "gateways", func(action k8sclienttesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, &networkingv1alpha3.Gateway{}, fmt.Errorf("error getting gateway")
|
||||
})
|
||||
vs, _ := NewIstioVirtualServiceSource(
|
||||
context.TODO(),
|
||||
fake.NewSimpleClientset(),
|
||||
istioFake,
|
||||
"",
|
||||
"",
|
||||
"{{.Name}}",
|
||||
false,
|
||||
false,
|
||||
)
|
||||
return vs.(*virtualServiceSource)
|
||||
}(),
|
||||
}, args: args{
|
||||
ctx: context.TODO(),
|
||||
gatewayStr: "foo/bar",
|
||||
virtualService: &networkingv1alpha3.VirtualService{
|
||||
TypeMeta: metav1.TypeMeta{},
|
||||
ObjectMeta: metav1.ObjectMeta{Name: "gateway", Namespace: "error"},
|
||||
Spec: istionetworking.VirtualService{},
|
||||
Status: v1alpha1.IstioStatus{},
|
||||
},
|
||||
}, want: nil, expectedErrStr: "error getting gateway"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user