diff --git a/.gitignore b/.gitignore index a9b45ed2..5959d984 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ Dockerfile.cross # Temporary files and directories tmp + +config/local-setup/**/*.env diff --git a/Makefile b/Makefile index 82e83c38..27706636 100644 --- a/Makefile +++ b/Makefile @@ -149,7 +149,9 @@ local-setup: $(KIND) ## Setup local development kind cluster and dependencies $(MAKE) kind-create-cluster .PHONY: local-deploy -local-deploy: docker-build kind-load-image deploy ## Deploy the dns operator into local kind cluster from the current code +local-deploy: docker-build kind-load-image ## Deploy the dns operator into local kind cluster from the current code + $(KUBECTL) config use-context kind-$(KIND_CLUSTER_NAME) + $(MAKE) deploy ##@ Build @@ -159,13 +161,13 @@ build: manifests generate fmt vet ## Build manager binary. .PHONY: run run: manifests generate fmt vet ## Run a controller from your host. - go run ./cmd/main.go + go run ./cmd/main.go --zap-log-level=3 # If you wish built the manager image targeting other platforms you can use the --platform flag. # (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it. # More info: https://docs.docker.com/develop/develop-images/build_enhancements/ .PHONY: docker-build -docker-build: test ## Build docker image with the manager. +docker-build: ## Build docker image with the manager. $(CONTAINER_TOOL) build -t ${IMG} . .PHONY: docker-push diff --git a/api/v1alpha1/dnsrecord_types.go b/api/v1alpha1/dnsrecord_types.go index 0164e41f..f36a88d5 100644 --- a/api/v1alpha1/dnsrecord_types.go +++ b/api/v1alpha1/dnsrecord_types.go @@ -18,93 +18,12 @@ package v1alpha1 import ( "fmt" + "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + externaldns "sigs.k8s.io/external-dns/endpoint" ) -// ProviderSpecificProperty holds the name and value of a configuration which is specific to individual DNS providers -type ProviderSpecificProperty struct { - Name string `json:"name,omitempty"` - Value string `json:"value,omitempty"` -} - -// Targets is a representation of a list of targets for an endpoint. -type Targets []string - -// TTL is a structure defining the TTL of a DNS record -type TTL int64 - -// Labels store metadata related to the endpoint -// it is then stored in a persistent storage via serialization -type Labels map[string]string - -// ProviderSpecific holds configuration which is specific to individual DNS providers -type ProviderSpecific []ProviderSpecificProperty - -// Endpoint is a high-level way of a connection between a service and an IP -type Endpoint struct { - // The hostname of the DNS record - DNSName string `json:"dnsName,omitempty"` - // The targets the DNS record points to - Targets Targets `json:"targets,omitempty"` - // RecordType type of record, e.g. CNAME, A, SRV, TXT etc - RecordType string `json:"recordType,omitempty"` - // Identifier to distinguish multiple records with the same name and type (e.g. Route53 records with routing policies other than 'simple') - SetIdentifier string `json:"setIdentifier,omitempty"` - // TTL for the record - RecordTTL TTL `json:"recordTTL,omitempty"` - // Labels stores labels defined for the Endpoint - // +optional - Labels Labels `json:"labels,omitempty"` - // ProviderSpecific stores provider specific config - // +optional - ProviderSpecific ProviderSpecific `json:"providerSpecific,omitempty"` -} - -// SetID returns an id that should be unique across a set of endpoints -func (e *Endpoint) SetID() string { - return e.DNSName + e.SetIdentifier -} - -// WithSetIdentifier applies the given set identifier to the endpoint. -func (e *Endpoint) WithSetIdentifier(setIdentifier string) *Endpoint { - e.SetIdentifier = setIdentifier - return e -} - -// GetProviderSpecificProperty returns a ProviderSpecificProperty if the property exists. -func (e *Endpoint) GetProviderSpecificProperty(key string) (ProviderSpecificProperty, bool) { - for _, providerSpecific := range e.ProviderSpecific { - if providerSpecific.Name == key { - return providerSpecific, true - } - } - return ProviderSpecificProperty{}, false -} - -// SetProviderSpecific sets a provider specific key/value pair. -func (e *Endpoint) SetProviderSpecific(name, value string) { - if e.ProviderSpecific == nil { - e.ProviderSpecific = ProviderSpecific{} - } - - for i, pair := range e.ProviderSpecific { - if pair.Name == name { - e.ProviderSpecific[i].Value = value - return - } - } - - e.ProviderSpecific = append(e.ProviderSpecific, ProviderSpecificProperty{ - Name: name, - Value: value, - }) -} - -func (e *Endpoint) String() string { - return fmt.Sprintf("%s %d IN %s %s %s %s", e.DNSName, e.RecordTTL, e.RecordType, e.SetIdentifier, e.Targets, e.ProviderSpecific) -} - // DNSRecordSpec defines the desired state of DNSRecord type DNSRecordSpec struct { // +kubebuilder:validation:Required @@ -112,7 +31,7 @@ type DNSRecordSpec struct { ManagedZoneRef *ManagedZoneReference `json:"managedZone,omitempty"` // +kubebuilder:validation:MinItems=1 // +optional - Endpoints []*Endpoint `json:"endpoints,omitempty"` + Endpoints []*externaldns.Endpoint `json:"endpoints,omitempty"` } // DNSRecordStatus defines the observed state of DNSRecord @@ -140,7 +59,7 @@ type DNSRecordStatus struct { // // Note: This will not be required if/when we switch to using external-dns since when // running with a "sync" policy it will clean up unused records automatically. - Endpoints []*Endpoint `json:"endpoints,omitempty"` + Endpoints []*externaldns.Endpoint `json:"endpoints,omitempty"` } //+kubebuilder:object:root=true @@ -182,6 +101,33 @@ const ( DefaultGeo string = "default" ) +// GetRootDomain returns the shortest domain that is shared across all spec.Endpoints dns names. +// Validates that all endpoints share an equal root domain and returns an error if they don't. +func (s *DNSRecord) GetRootDomain() (string, error) { + domain := "" + dnsNames := []string{} + for idx := range s.Spec.Endpoints { + dnsNames = append(dnsNames, s.Spec.Endpoints[idx].DNSName) + } + for idx := range dnsNames { + if domain == "" || len(domain) > len(dnsNames[idx]) { + domain = dnsNames[idx] + } + } + + if domain == "" { + return "", fmt.Errorf("unable to determine root domain from %v", dnsNames) + } + + for idx := range dnsNames { + if !strings.HasSuffix(dnsNames[idx], domain) { + return "", fmt.Errorf("inconsitent domains, got %s, expected suffix %s", dnsNames[idx], domain) + } + } + + return domain, nil +} + func init() { SchemeBuilder.Register(&DNSRecord{}, &DNSRecordList{}) } diff --git a/api/v1alpha1/dnsrecord_types_test.go b/api/v1alpha1/dnsrecord_types_test.go new file mode 100644 index 00000000..4d0cacd1 --- /dev/null +++ b/api/v1alpha1/dnsrecord_types_test.go @@ -0,0 +1,81 @@ +package v1alpha1 + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/external-dns/endpoint" +) + +func TestDNSRecord_GetRootDomain(t *testing.T) { + tests := []struct { + name string + dnsNames []string + want string + wantErr bool + }{ + { + name: "single endpoint", + dnsNames: []string{ + "test.example.com", + }, + want: "test.example.com", + wantErr: false, + }, + { + name: "multiple endpoints matching", + dnsNames: []string{ + "bar.baz.test.example.com", + "bar.test.example.com", + "test.example.com", + "foo.bar.baz.test.example.com", + }, + want: "test.example.com", + wantErr: false, + }, + { + name: "no endpoints", + dnsNames: []string{}, + want: "", + wantErr: true, + }, + { + name: "multiple endpoints mismatching", + dnsNames: []string{ + "foo.bar.test.example.com", + "bar.test.example.com", + "baz.example.com", + }, + want: "", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + s := &DNSRecord{ + TypeMeta: metav1.TypeMeta{ + Kind: "DNSRecord", + APIVersion: GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "testRecord", + Namespace: "testNS", + }, + Spec: DNSRecordSpec{ + Endpoints: []*endpoint.Endpoint{}, + }, + } + for idx := range tt.dnsNames { + s.Spec.Endpoints = append(s.Spec.Endpoints, &endpoint.Endpoint{DNSName: tt.dnsNames[idx]}) + } + got, err := s.GetRootDomain() + if (err != nil) != tt.wantErr { + t.Errorf("GetRootDomain() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("GetRootDomain() got = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index bb4e529b..9b68c431 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -24,6 +24,7 @@ package v1alpha1 import ( "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/external-dns/endpoint" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -255,11 +256,11 @@ func (in *DNSRecordSpec) DeepCopyInto(out *DNSRecordSpec) { } if in.Endpoints != nil { in, out := &in.Endpoints, &out.Endpoints - *out = make([]*Endpoint, len(*in)) + *out = make([]*endpoint.Endpoint, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] - *out = new(Endpoint) + *out = new(endpoint.Endpoint) (*in).DeepCopyInto(*out) } } @@ -288,11 +289,11 @@ func (in *DNSRecordStatus) DeepCopyInto(out *DNSRecordStatus) { } if in.Endpoints != nil { in, out := &in.Endpoints, &out.Endpoints - *out = make([]*Endpoint, len(*in)) + *out = make([]*endpoint.Endpoint, len(*in)) for i := range *in { if (*in)[i] != nil { in, out := &(*in)[i], &(*out)[i] - *out = new(Endpoint) + *out = new(endpoint.Endpoint) (*in).DeepCopyInto(*out) } } @@ -309,59 +310,6 @@ func (in *DNSRecordStatus) DeepCopy() *DNSRecordStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Endpoint) DeepCopyInto(out *Endpoint) { - *out = *in - if in.Targets != nil { - in, out := &in.Targets, &out.Targets - *out = make(Targets, len(*in)) - copy(*out, *in) - } - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make(Labels, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.ProviderSpecific != nil { - in, out := &in.ProviderSpecific, &out.ProviderSpecific - *out = make(ProviderSpecific, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Endpoint. -func (in *Endpoint) DeepCopy() *Endpoint { - if in == nil { - return nil - } - out := new(Endpoint) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in Labels) DeepCopyInto(out *Labels) { - { - in := &in - *out = make(Labels, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Labels. -func (in Labels) DeepCopy() Labels { - if in == nil { - return nil - } - out := new(Labels) - in.DeepCopyInto(out) - return *out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ManagedHost) DeepCopyInto(out *ManagedHost) { *out = *in @@ -529,56 +477,3 @@ func (in *ProviderRef) DeepCopy() *ProviderRef { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in ProviderSpecific) DeepCopyInto(out *ProviderSpecific) { - { - in := &in - *out = make(ProviderSpecific, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProviderSpecific. -func (in ProviderSpecific) DeepCopy() ProviderSpecific { - if in == nil { - return nil - } - out := new(ProviderSpecific) - in.DeepCopyInto(out) - return *out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ProviderSpecificProperty) DeepCopyInto(out *ProviderSpecificProperty) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProviderSpecificProperty. -func (in *ProviderSpecificProperty) DeepCopy() *ProviderSpecificProperty { - if in == nil { - return nil - } - out := new(ProviderSpecificProperty) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in Targets) DeepCopyInto(out *Targets) { - { - in := &in - *out = make(Targets, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Targets. -func (in Targets) DeepCopy() Targets { - if in == nil { - return nil - } - out := new(Targets) - in.DeepCopyInto(out) - return *out -} diff --git a/bundle/manifests/dns-operator.clusterserviceversion.yaml b/bundle/manifests/dns-operator.clusterserviceversion.yaml index a33dc472..0be3de40 100644 --- a/bundle/manifests/dns-operator.clusterserviceversion.yaml +++ b/bundle/manifests/dns-operator.clusterserviceversion.yaml @@ -71,7 +71,7 @@ metadata: capabilities: Basic Install categories: Integration & Delivery containerImage: quay.io/kuadrant/dns-operator:latest - createdAt: "2024-02-16T12:20:36Z" + createdAt: "2024-03-05T14:47:38Z" description: A Kubernetes Operator to manage the lifecycle of DNS resources operators.operatorframework.io/builder: operator-sdk-v1.33.0 operators.operatorframework.io/project_layout: go.kubebuilder.io/v4 diff --git a/bundle/manifests/kuadrant.io_dnsrecords.yaml b/bundle/manifests/kuadrant.io_dnsrecords.yaml index b635ce62..eed45a53 100644 --- a/bundle/manifests/kuadrant.io_dnsrecords.yaml +++ b/bundle/manifests/kuadrant.io_dnsrecords.yaml @@ -69,8 +69,8 @@ spec: format: int64 type: integer recordType: - description: RecordType type of record, e.g. CNAME, A, SRV, - TXT etc + description: RecordType type of record, e.g. CNAME, A, AAAA, + SRV, TXT etc type: string setIdentifier: description: Identifier to distinguish multiple records with @@ -206,8 +206,8 @@ spec: format: int64 type: integer recordType: - description: RecordType type of record, e.g. CNAME, A, SRV, - TXT etc + description: RecordType type of record, e.g. CNAME, A, AAAA, + SRV, TXT etc type: string setIdentifier: description: Identifier to distinguish multiple records with diff --git a/config/crd/bases/kuadrant.io_dnsrecords.yaml b/config/crd/bases/kuadrant.io_dnsrecords.yaml index ef73c0d3..ac503169 100644 --- a/config/crd/bases/kuadrant.io_dnsrecords.yaml +++ b/config/crd/bases/kuadrant.io_dnsrecords.yaml @@ -69,8 +69,8 @@ spec: format: int64 type: integer recordType: - description: RecordType type of record, e.g. CNAME, A, SRV, - TXT etc + description: RecordType type of record, e.g. CNAME, A, AAAA, + SRV, TXT etc type: string setIdentifier: description: Identifier to distinguish multiple records with @@ -206,8 +206,8 @@ spec: format: int64 type: integer recordType: - description: RecordType type of record, e.g. CNAME, A, SRV, - TXT etc + description: RecordType type of record, e.g. CNAME, A, AAAA, + SRV, TXT etc type: string setIdentifier: description: Identifier to distinguish multiple records with diff --git a/config/local-setup/managedzone/aws/kustomization.yaml b/config/local-setup/managedzone/aws/kustomization.yaml new file mode 100644 index 00000000..b69e4dd4 --- /dev/null +++ b/config/local-setup/managedzone/aws/kustomization.yaml @@ -0,0 +1,40 @@ +resources: + - managed_zone.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: + - name: aws-managed-zone-config + envs: + - managed-zone-config.env + +secretGenerator: + - name: aws-credentials + envs: + - aws-credentials.env + type: "kuadrant.io/aws" + +replacements: + - source: + kind: ConfigMap + name: aws-managed-zone-config + version: v1 + fieldPath: data.AWS_DNS_PUBLIC_ZONE_ID + targets: + - select: + kind: ManagedZone + name: dev-mz-aws + fieldPaths: + - spec.id + - source: + kind: ConfigMap + name: aws-managed-zone-config + version: v1 + fieldPath: data.ZONE_ROOT_DOMAIN + targets: + - select: + kind: ManagedZone + name: dev-mz-aws + fieldPaths: + - spec.domainName diff --git a/config/local-setup/managedzone/aws/managed_zone.yaml b/config/local-setup/managedzone/aws/managed_zone.yaml new file mode 100644 index 00000000..7b02cb64 --- /dev/null +++ b/config/local-setup/managedzone/aws/managed_zone.yaml @@ -0,0 +1,10 @@ +apiVersion: kuadrant.io/v1alpha1 +kind: ManagedZone +metadata: + name: dev-mz-aws +spec: + id: DUMMY_ID + domainName: DUMMY_DOMAIN_NAME + description: "Dev Managed Zone" + dnsProviderSecretRef: + name: aws-credentials diff --git a/config/local-setup/managedzone/gcp/kustomization.yaml b/config/local-setup/managedzone/gcp/kustomization.yaml new file mode 100644 index 00000000..a0e92cfa --- /dev/null +++ b/config/local-setup/managedzone/gcp/kustomization.yaml @@ -0,0 +1,40 @@ +resources: + - managed_zone.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: + - name: gcp-managed-zone-config + envs: + - managed-zone-config.env + +secretGenerator: + - name: gcp-credentials + envs: + - gcp-credentials.env + type: "kuadrant.io/gcp" + +replacements: + - source: + kind: ConfigMap + name: gcp-managed-zone-config + version: v1 + fieldPath: data.ZONE_NAME + targets: + - select: + kind: ManagedZone + name: dev-mz-gcp + fieldPaths: + - spec.id + - source: + kind: ConfigMap + name: gcp-managed-zone-config + version: v1 + fieldPath: data.ZONE_DNS_NAME + targets: + - select: + kind: ManagedZone + name: dev-mz-gcp + fieldPaths: + - spec.domainName diff --git a/config/local-setup/managedzone/gcp/managed_zone.yaml b/config/local-setup/managedzone/gcp/managed_zone.yaml new file mode 100644 index 00000000..634ae75a --- /dev/null +++ b/config/local-setup/managedzone/gcp/managed_zone.yaml @@ -0,0 +1,10 @@ +apiVersion: kuadrant.io/v1alpha1 +kind: ManagedZone +metadata: + name: dev-mz-gcp +spec: + id: DUMMY_ID + domainName: DUMMY_DOMAIN_NAME + description: "Dev Managed Zone" + dnsProviderSecretRef: + name: gcp-credentials diff --git a/go.mod b/go.mod index 0f35086a..49124e48 100644 --- a/go.mod +++ b/go.mod @@ -3,25 +3,35 @@ module github.com/kuadrant/dns-operator go 1.21 require ( - github.com/aws/aws-sdk-go v1.44.175 + github.com/aws/aws-sdk-go v1.44.311 github.com/go-logr/logr v1.2.4 github.com/onsi/ginkgo/v2 v2.11.0 github.com/onsi/gomega v1.27.10 github.com/prometheus/client_golang v1.17.0 - google.golang.org/api v0.126.0 + github.com/sirupsen/logrus v1.9.3 + google.golang.org/api v0.134.0 k8s.io/api v0.28.3 k8s.io/apimachinery v0.28.3 k8s.io/client-go v0.28.3 k8s.io/utils v0.0.0-20230726121419-3b25d923346b sigs.k8s.io/controller-runtime v0.16.3 - sigs.k8s.io/gateway-api v1.0.0 + sigs.k8s.io/external-dns v0.14.0 + sigs.k8s.io/gateway-api v0.7.1 ) require ( cloud.google.com/go/compute v1.20.1 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect + code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f // indirect + github.com/F5Networks/k8s-bigip-ctlr/v2 v2.13.1 // indirect + github.com/Masterminds/semver v1.4.2 // indirect + github.com/alecthomas/kingpin v2.2.6+incompatible // indirect + github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 // indirect + github.com/datawire/ambassador v1.12.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch/v5 v5.7.0 // indirect @@ -40,18 +50,22 @@ require ( github.com/google/pprof v0.0.0-20221212185716-aee1124e3a93 // indirect github.com/google/s2a-go v0.1.4 // indirect github.com/google/uuid v1.3.1 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect - github.com/googleapis/gax-go/v2 v2.11.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect + github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/linki/instrumented_http v0.3.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/openshift/api v0.0.0-20230607130528-611114dca681 // indirect + github.com/openshift/client-go v0.0.0-20230607134213-3cd0021bbee3 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/projectcontour/contour v1.25.2 // indirect github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect @@ -70,12 +84,16 @@ require ( golang.org/x/tools v0.14.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect - google.golang.org/grpc v1.55.0 // indirect + google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230720185612-659f7aaaa771 // indirect + google.golang.org/grpc v1.56.3 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + istio.io/api v1.19.0-alpha.1 // indirect + istio.io/client-go v1.18.1 // indirect k8s.io/apiextensions-apiserver v0.28.3 // indirect k8s.io/component-base v0.28.3 // indirect k8s.io/klog/v2 v2.100.1 // indirect diff --git a/go.sum b/go.sum index aabe1a2a..7dfc0dde 100644 --- a/go.sum +++ b/go.sum @@ -1,69 +1,323 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= 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/compute v1.20.1 h1:6aKEtlUiwEpJzM001l0yFkpXmUVXaN8W+fbkb2AZNbg= cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= +code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f h1:UrKzEwTgeiff9vxdrfdqxibzpWjxLnuXDI5m6z3GJAk= +code.cloudfoundry.org/gofileutils v0.0.0-20170111115228-4d0c80011a0f/go.mod h1:sk5LnIjB/nIEU7yP5sDQExVm62wu0pBh3yrElngUisI= +git.lukeshu.com/go/libsystemd v0.5.3/go.mod h1:FfDoP0i92r4p5Vn4NCLxvjkd7rCOe6otPa4L6hZg9WM= +github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= +github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= +github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= +github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= +github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= +github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/F5Networks/k8s-bigip-ctlr/v2 v2.13.1 h1:GgMdpvQjm7WBuO2xRwMuaEPwc3fdUbAljf+3uxwk8MA= +github.com/F5Networks/k8s-bigip-ctlr/v2 v2.13.1/go.mod h1:GJ5fTJ9GuGe2CzEYd8hk/KinNXDNJ0QYqWluiPdLn/s= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= +github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.4.2 h1:WBLTQ37jOCzSLtXNdoo8bNM8876KhNqOKvrlGITgsTc= +github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/sprig v2.17.1+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/Masterminds/sprig/v3 v3.1.0/go.mod h1:ONGMf7UfYGAbMXCZmQLy8x3lCDIPrEZE/rU8pmrbihA= +github.com/Masterminds/squirrel v1.2.0/go.mod h1:yaPeOnPG5ZRwL9oKdTsO/prlkPbXWZlRVMQ/gGlzIuA= +github.com/Masterminds/squirrel v1.4.0/go.mod h1:yaPeOnPG5ZRwL9oKdTsO/prlkPbXWZlRVMQ/gGlzIuA= +github.com/Masterminds/vcs v1.13.1/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM= +github.com/alecthomas/kingpin v2.2.6+incompatible h1:5svnBTFgJjZvGKyYBtMB0+m5wvrbUHiqye8wRJMlnYI= +github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +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= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/aws/aws-sdk-go v1.44.175 h1:c0NzHHnPXV5kJoTUFQxFN5cUPpX1SxO635XnwL5/oIY= -github.com/aws/aws-sdk-go v1.44.175/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aokoli/goutils v1.1.0/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +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 v1.44.311 h1:60i8hyVMOXqabKJQPCq4qKRBQ6hRafI/WOcDxGM+J7Q= +github.com/aws/aws-sdk-go v1.44.311/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381 h1:rdRS5BT13Iae9ssvcslol66gfOOXjaLYwqerEn/cl9s= +github.com/cloudfoundry-community/go-cfclient v0.0.0-20190201205600-f136f9222381/go.mod h1:e5+USP2j8Le2M0Jo3qKPFnNhuo1wueU4nWHCXBOfQ14= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0 h1:sDMmm+q/3+BukdIpxwO365v/Rbspp2Nt5XntgQRXq8Q= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20200107194136-26c1120b8d41/go.mod h1:Dq467ZllaHgAtVp4p1xUQWBrFXR9s/wyoTpG8zOJGkY= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/datawire/ambassador v1.12.4 h1:g+agFHayLqETkCgFgEQi9qk4zakE0UAhgK8xVUEcDDI= +github.com/datawire/ambassador v1.12.4/go.mod h1:2grBLdYgILzrgTpenDMB5OeyhObIUaT+KwkLkZI1KDE= +github.com/datawire/dlib v1.2.0/go.mod h1:t0upKFHApJskdVFH/gyksG5+vMCl0GCKeEZIEJBBv4g= +github.com/datawire/pf v0.0.0-20180510150411-31a823f9495a/go.mod h1:H8uUmE8qqo7z9u30MYB9riLyRckPHOPBk9ZdCuH+dQQ= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE= +github.com/deislabs/oras v0.8.1/go.mod h1:Mx0rMSbBNaNfY9hjpccEnxkOqJL6KGjtxNHPLC4G4As= +github.com/denisenkom/go-mssqldb v0.0.0-20191001013358-cfbb681360f0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= +github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v1.4.2-0.20200203170920-46ec8731fbce/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dsnet/compress v0.0.1/go.mod h1:Aw8dCMJ7RioblQeTqt88akK31OvO8Dhf5JflhBbQEHo= +github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/ecodia/golang-awaitility v0.0.0-20180710094957-fb55e59708c7/go.mod h1:etn7NbLy5UviLk20XMZbSn/0AigF3Zfx7wwaEZ3fyIk= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= -github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/envoyproxy/protoc-gen-validate v0.3.0-java.0.20200609174644-bd816e4522c1/go.mod h1:bjmEhrMDubXDd0uKxnWwRmgSsiEv2CkJliIHnj6ETm8= +github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U= +github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= github.com/go-logr/zapr v1.2.4/go.mod h1:FyHWQIzQORZ0QVE1BtVHv3cKtNLuXsbNLtpuhNapBOA= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= +github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.18.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= +github.com/go-openapi/analysis v0.19.2/go.mod h1:3P1osvZa9jKjb8ed2TPng3f0i/UY9snX6gxi44djMjk= +github.com/go-openapi/analysis v0.19.5/go.mod h1:hkEAkxagaIvIP7VTn8ygJNkd4kAYON2rCu0v0ObL0AU= +github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.18.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= +github.com/go-openapi/errors v0.19.2/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA4kxxpKBC94= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.18.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.20.0 h1:ESKJdU9ASRfaPNOPRx12IUyA1vn3R9GiE3KYD14BXdQ= github.com/go-openapi/jsonpointer v0.20.0/go.mod h1:6PGzBjjIIumbLYysB73Klnms1mwnU4G3YHOECG3CedA= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.18.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.18.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= +github.com/go-openapi/loads v0.19.2/go.mod h1:QAskZPMX5V0C2gvfkGZzJlINuP7Hx/4+ix5jWFxsNPs= +github.com/go-openapi/loads v0.19.4/go.mod h1:zZVHonKd8DXyxyw4yfnVjPzBjIQcLt0CCsn0N0ZrQsk= +github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= +github.com/go-openapi/runtime v0.19.0/go.mod h1:OwNfisksmmaZse4+gpV3Ne9AyMOlP1lt4sK4FXt0O64= +github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.18.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= +github.com/go-openapi/strfmt v0.19.0/go.mod h1:+uW+93UVvGGq2qGaZxdDeJqSAqBqBdl+ZPMF/cC8nDY= +github.com/go-openapi/strfmt v0.19.3/go.mod h1:0yX7dbo8mKIvc3XSKp7MNfxw4JytCfCD6+bY1AVL9LU= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.18.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= +github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA= +github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.1/go.mod h1:FurDp9+EDPE4aIUS3ZLyD+7/9fpx7YRt/ukY6jIHf0w= +github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80= +github.com/gobuffalo/logger v1.0.1/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= +github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= +github.com/gobuffalo/packr/v2 v2.7.1/go.mod h1:qYEvAazPaVxy7Y7KR0W8qYEE+RymX74kETFqjFoFlOc= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godror/godror v0.13.3/go.mod h1:2ouUT4kdhUBk7TAkHWD4SN0CdI0pgEQbo8FVHhbSKWg= +github.com/gofrs/flock v0.7.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= @@ -78,6 +332,13 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho= +github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8= +github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -91,78 +352,387 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20221212185716-aee1124e3a93 h1:D5iJJZKAi0rU4e/5E58BkrnN+xeCDjAIqcm1GGxAGSI= github.com/google/pprof v0.0.0-20221212185716-aee1124e3a93/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/shlex v0.0.0-20181106134648-c34317bd91bf/go.mod h1:RpwtwJQFrIEPstU94h88MWPXP2ektJZ8cZ0YntAmXiE= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k= -github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k= -github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4= -github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI= +github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= +github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= +github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.1.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= +github.com/googleapis/gnostic v0.3.1/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU= +github.com/gookit/color v1.2.3/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1KB7xg= +github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= +github.com/gopherjs/gopherjs v0.0.0-20180628210949-0892b62f0d9f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= +github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= +github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.7.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linki/instrumented_http v0.3.0 h1:dsN92+mXpfZtjJraartcQ99jnuw7fqsnPDjr85ma2dA= +github.com/linki/instrumented_http v0.3.0/go.mod h1:pjYbItoegfuVi2GUOMhEqzvm/SJKuEL3H0tc8QRLRFk= +github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= +github.com/lyft/protoc-gen-star v0.4.10/go.mod h1:mE8fbna26u7aEA2QCVvvfBU/ZrPgocG1206xAFPcs94= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11 h1:YFh+sjyJTMQSYjKwM4dFKhJPJC/wfo98tPUc17HdoYw= +github.com/martini-contrib/render v0.0.0-20150707142108-ec18f8345a11/go.mod h1:Ah2dBMoxZEqk118as2T4u4fjfXarE0pPnMJaArZQZsI= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-oci8 v0.0.7/go.mod h1:wjDx6Xm9q7dFtHJvIlrI99JytznLw5wQ4R+9mNXJwGI= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.12.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= +github.com/mholt/archiver/v3 v3.3.0/go.mod h1:YnQtqsp+94Rwd0D/rk5cnLrxusUBUXg+08Ebtr1Mqao= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.6/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/nwaples/rardecode v1.0.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= +github.com/openshift/api v0.0.0-20230607130528-611114dca681 h1:kSvo4fjZyYRu7z7PVkZlqcYhoS4mZHVFYVUkG3WkvIE= +github.com/openshift/api v0.0.0-20230607130528-611114dca681/go.mod h1:4VWG+W22wrB4HfBL88P40DxLEpSOaiBVxUnfalfJo9k= +github.com/openshift/client-go v0.0.0-20230607134213-3cd0021bbee3 h1:uVCq/Sx2y4UZh+qCsCL1BBUJpc3DULHkN4j7XHHgHtw= +github.com/openshift/client-go v0.0.0-20230607134213-3cd0021bbee3/go.mod h1:M+VUIcqx5IvgzejcbgmQnxETPrXRYlcufHpw2bAgz9Y= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +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/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= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/projectcontour/contour v1.25.2 h1:68FO5+PJ10UTF5cwj2IATTKPYSkW0jxTg3Q//8A6nCI= +github.com/projectcontour/contour v1.25.2/go.mod h1:yfnLls/nZckkbrjZpN2Y96T3iSoWL325YGEw8eueEJ0= +github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.6.0/go.mod h1:ZLOG9ck3JLRdB5MgO8f+lLTe83AXG6ro35rLTxvnIl4= github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.0.11/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.3.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.4.0/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/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= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v0.0.0-20180725160413-e900ae048470/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -171,25 +741,83 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= +github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= +github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +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.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.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= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -200,25 +828,48 @@ golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -227,12 +878,16 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -240,10 +895,39 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180425194835-bb9c189858d9/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -251,6 +935,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= @@ -260,7 +945,10 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/text v0.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= +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= @@ -268,14 +956,35 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/time v0.0.0-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= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190617190820-da514acc4774/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191004055002-72853e10c5a3/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= @@ -286,34 +995,56 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3mwe7XcUU= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o= -google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw= +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.134.0 h1:ktL4Goua+UBgoP1eL1/60LwZJqa1sIzkLmvoR3hR6Gw= +google.golang.org/api v0.134.0/go.mod h1:sjRL3UnjTx5UqNQS9EWr9N8p7xbHpy1k0XGRLCf3Spk= 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= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc h1:8DyZCyvI8mE1IdLy/60bS+52xfymkE72wv1asokgtao= -google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM= -google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= +google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130 h1:Au6te5hbKUV8pIYWHqOUZ1pva5qK/rwbIhoXEUB9Lu8= +google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y= +google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130 h1:XVeBY8d/FaK4848myy41HBqnDwvxeV3zMZhwN1TvAMU= +google.golang.org/genproto/googleapis/api v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:mPBs5jNgx2GuQGvFwUvVKqtn6HsUw9nP64BedgvqEsQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230720185612-659f7aaaa771 h1:Z8qdAF9GFsmcUuWQ5KVYIpP3PCKydn/YKORnghIalu4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230720185612-659f7aaaa771/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM= +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= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= -google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= +google.golang.org/grpc v1.56.3 h1:8I4C0Yq1EjstUzUJzpcRVbuYA2mODtEmpWiQoN/b2nc= +google.golang.org/grpc v1.56.3/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -327,45 +1058,128 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/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= +gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= +gopkg.in/gorp.v1 v1.7.2/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +helm.sh/helm/v3 v3.2.4/go.mod h1:ZaXz/vzktgwjyGGFbUWtIQkscfE7WYoRGP2szqAFHR0= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +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.19.0-alpha.1 h1:piKxgZ1Y9abNin/zw9cp6AFKhhC3Z2UmJRTN0Tm5FEY= +istio.io/api v1.19.0-alpha.1/go.mod h1:dDMe1TsOtrRoUlBzdxqNolWXpXPQjLfbcXvqPMtQ6eo= +istio.io/client-go v1.18.1 h1:qSpKeJ0+3L9wAEfs30KaTWkifhz7YRmyXsOPnC+zMqk= +istio.io/client-go v1.18.1/go.mod h1:ha62DtaYYStYdisMZw9OG5iG92irhr2sWK7C38qCdqI= +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= k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM= k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc= +k8s.io/apiextensions-apiserver v0.18.0/go.mod h1:18Cwn1Xws4xnWQNC00FLq1E350b9lUF+aOdIWDOZxgo= +k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= +k8s.io/apiextensions-apiserver v0.18.4/go.mod h1:NYeyeYq4SIpFlPxSAB6jHPIdvu3hL0pc36wuRChybio= k8s.io/apiextensions-apiserver v0.28.3 h1:Od7DEnhXHnHPZG+W9I97/fSQkVpVPQx2diy+2EtmY08= k8s.io/apiextensions-apiserver v0.28.3/go.mod h1:NE1XJZ4On0hS11aWWJUTNkmVB03j9LM7gJSisbRt8Lc= +k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= +k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= +k8s.io/apimachinery v0.18.4/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A= k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8= +k8s.io/apiserver v0.18.0/go.mod h1:3S2O6FeBBd6XTo0njUrLxiqk8GNy6wWOftjhJcXYnjw= +k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= +k8s.io/apiserver v0.18.4/go.mod h1:q+zoFct5ABNnYkGIaGQ3bcbUNdmPyOCoEBcg51LChY8= +k8s.io/cli-runtime v0.18.0/go.mod h1:1eXfmBsIJosjn9LjEBUd2WVPoPAY9XGTqTFcPMIBsUQ= +k8s.io/cli-runtime v0.18.4/go.mod h1:9/hS/Cuf7NVzWR5F/5tyS6xsnclxoPLVtwhnkJG1Y4g= +k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8= +k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU= +k8s.io/client-go v0.18.4/go.mod h1:f5sXwL4yAZRkAtzOxRWUhA/N8XzGCb+nPZI8PfobZ9g= k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4= k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo= +k8s.io/code-generator v0.18.0/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= +k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc= +k8s.io/code-generator v0.18.4/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c= +k8s.io/component-base v0.18.0/go.mod h1:u3BCg0z1uskkzrnAKFzulmYaEpZF7XC9Pf/uFyb1v2c= +k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= +k8s.io/component-base v0.18.4/go.mod h1:7jr/Ef5PGmKwQhyAz/pjByxJbC58mhKAhiaDu0vXfPk= k8s.io/component-base v0.28.3 h1:rDy68eHKxq/80RiMb2Ld/tbH8uAE75JdCqJyi6lXMzI= k8s.io/component-base v0.28.3/go.mod h1:fDJ6vpVNSk6cRo5wmDa6eKIG7UlIQkaFmZN2fYgIUD8= +k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/helm v2.16.9+incompatible/go.mod h1:LZzlS4LQBHfciFOurYBFkCMTaZ0D1l+p0teMg7TSULI= +k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= +k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= +k8s.io/kubectl v0.18.0/go.mod h1:LOkWx9Z5DXMEg5KtOjHhRiC1fqJPLyCr3KtQgEolCkU= +k8s.io/kubectl v0.18.4/go.mod h1:EzB+nfeUWk6fm6giXQ8P4Fayw3dsN+M7Wjy23mTRtB0= +k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/metrics v0.18.0/go.mod h1:8aYTW18koXqjLVKL7Ds05RPMX9ipJZI3mywYvBOxXd4= +k8s.io/metrics v0.18.4/go.mod h1:luze4fyI9JG4eLDZy0kFdYEebqNfi0QrG4xNEbPkHOs= +k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= +k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +rsc.io/letsencrypt v0.0.3/go.mod h1:buyQKZ6IXrRnB7TdkHP0RyEybLx18HHyOSoTyoOLqNY= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= +sigs.k8s.io/controller-runtime v0.6.1/go.mod h1:XRYBPdbf5XJu9kpS84VJiZ7h/u1hF3gEORz0efEja7A= sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigwG62c4= sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= -sigs.k8s.io/gateway-api v1.0.0 h1:iPTStSv41+d9p0xFydll6d7f7MOBGuqXM6p2/zVYMAs= -sigs.k8s.io/gateway-api v1.0.0/go.mod h1:4cUgr0Lnp5FZ0Cdq8FdRwCvpiWws7LVhLHGIudLlf4c= +sigs.k8s.io/controller-tools v0.3.1-0.20200517180335-820a4a27ea84/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI= +sigs.k8s.io/external-dns v0.14.0 h1:pgY3DdyoBei+ej1nyZUzRt9ECm9RRwb9s6/CPWe51tc= +sigs.k8s.io/external-dns v0.14.0/go.mod h1:d4Knr/BFz8U1Lc6yLhCzTRP6nJOz6fqR/MnqqJPcIlU= +sigs.k8s.io/gateway-api v0.7.1 h1:Tts2jeepVkPA5rVG/iO+S43s9n7Vp7jCDhZDQYtPigQ= +sigs.k8s.io/gateway-api v0.7.1/go.mod h1:Xv0+ZMxX0lu1nSSDIIPEfbVztgNZ+3cfiYrJsa2Ooso= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= +sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw= sigs.k8s.io/structured-merge-diff/v4 v4.3.0 h1:UZbZAZfX0wV2zr7YZorDz6GXROfDFj6LvqCRm4VUVKk= sigs.k8s.io/structured-merge-diff/v4 v4.3.0/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= +vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI= diff --git a/internal/controller/dnshealthcheckprobe_controller.go b/internal/controller/dnshealthcheckprobe_controller.go index 0424d53e..8fd92def 100644 --- a/internal/controller/dnshealthcheckprobe_controller.go +++ b/internal/controller/dnshealthcheckprobe_controller.go @@ -15,7 +15,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/log" - gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1" + gatewayapiv1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" "github.com/kuadrant/dns-operator/api/v1alpha1" "github.com/kuadrant/dns-operator/internal/common/slice" @@ -192,7 +192,7 @@ func getAdditionalHeaders(ctx context.Context, clt client.Client, probeObj *v1al return additionalHeaders, nil } -func (r *DNSHealthCheckProbeReconciler) getGatewayFor(ctx context.Context, probe *v1alpha1.DNSHealthCheckProbe) (*gatewayapiv1.Gateway, bool, error) { +func (r *DNSHealthCheckProbeReconciler) getGatewayFor(ctx context.Context, probe *v1alpha1.DNSHealthCheckProbe) (*gatewayapiv1beta1.Gateway, bool, error) { if probe.Labels == nil { return nil, false, nil } @@ -209,7 +209,7 @@ func (r *DNSHealthCheckProbeReconciler) getGatewayFor(ctx context.Context, probe Namespace: namespace, } - gw := &gatewayapiv1.Gateway{} + gw := &gatewayapiv1beta1.Gateway{} if err := r.Client.Get(ctx, objKey, gw); err != nil { return nil, false, err } @@ -244,7 +244,7 @@ func (r *DNSHealthCheckProbeReconciler) newProbeNotifierFor(ctx context.Context, } // Find the listener in the Gateway that matches the DNSRecord - listener, ok := slice.Find(gateway.Spec.Listeners, func(listener gatewayapiv1.Listener) bool { + listener, ok := slice.Find(gateway.Spec.Listeners, func(listener gatewayapiv1beta1.Listener) bool { dnsRecordName := fmt.Sprintf("%s-%s", gateway.Name, listener.Name) return dnsRecord.Name == dnsRecordName }) diff --git a/internal/controller/dnsrecord_controller.go b/internal/controller/dnsrecord_controller.go index 8aea0934..3a6fe412 100644 --- a/internal/controller/dnsrecord_controller.go +++ b/internal/controller/dnsrecord_controller.go @@ -31,6 +31,10 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/log" + externaldnsendpoint "sigs.k8s.io/external-dns/endpoint" + externaldnsplan "sigs.k8s.io/external-dns/plan" + externaldnsprovider "sigs.k8s.io/external-dns/provider" + externaldnsregistry "sigs.k8s.io/external-dns/registry" "github.com/kuadrant/dns-operator/api/v1alpha1" "github.com/kuadrant/dns-operator/internal/common/conditions" @@ -55,7 +59,7 @@ type DNSRecordReconciler struct { //+kubebuilder:rbac:groups=kuadrant.io,resources=dnsrecords/finalizers,verbs=update func (r *DNSRecordReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) + logger := log.FromContext(ctx) previous := &v1alpha1.DNSRecord{} err := r.Client.Get(ctx, client.ObjectKey{Namespace: req.Namespace, Name: req.Name}, previous) @@ -68,23 +72,21 @@ func (r *DNSRecordReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( } dnsRecord := previous.DeepCopy() - log.Log.V(3).Info("DNSRecordReconciler Reconcile", "dnsRecord", dnsRecord) - if dnsRecord.DeletionTimestamp != nil && !dnsRecord.DeletionTimestamp.IsZero() { if err := r.deleteRecord(ctx, dnsRecord); err != nil { - log.Log.Error(err, "Failed to delete DNSRecord", "record", dnsRecord) + logger.Error(err, "Failed to delete DNSRecord") return ctrl.Result{}, err } + logger.Info("Removing Finalizer", "name", DNSRecordFinalizer) controllerutil.RemoveFinalizer(dnsRecord, DNSRecordFinalizer) - - err = r.Update(ctx, dnsRecord) - if err != nil { + if err = r.Update(ctx, dnsRecord); client.IgnoreNotFound(err) != nil { return ctrl.Result{}, err } return ctrl.Result{}, nil } if !controllerutil.ContainsFinalizer(dnsRecord, DNSRecordFinalizer) { + logger.Info("Adding Finalizer", "name", DNSRecordFinalizer) controllerutil.AddFinalizer(dnsRecord, DNSRecordFinalizer) err = r.Update(ctx, dnsRecord) if err != nil { @@ -96,7 +98,7 @@ func (r *DNSRecordReconciler) Reconcile(ctx context.Context, req ctrl.Request) ( var reason, message string status := metav1.ConditionTrue reason = "ProviderSuccess" - message = "Provider ensured the managed zone" + message = "Provider ensured the dns record" // Publish the record err = r.publishRecord(ctx, dnsRecord) @@ -134,6 +136,8 @@ func (r *DNSRecordReconciler) SetupWithManager(mgr ctrl.Manager) error { // deleteRecord deletes record(s) in the DNSPRovider(i.e. route53) configured by the ManagedZone assigned to this // DNSRecord (dnsRecord.Status.ParentManagedZone). func (r *DNSRecordReconciler) deleteRecord(ctx context.Context, dnsRecord *v1alpha1.DNSRecord) error { + logger := log.FromContext(ctx) + managedZone := &v1alpha1.ManagedZone{ ObjectMeta: metav1.ObjectMeta{ Name: dnsRecord.Spec.ManagedZoneRef.Name, @@ -151,23 +155,18 @@ func (r *DNSRecordReconciler) deleteRecord(ctx context.Context, dnsRecord *v1alp return fmt.Errorf("the managed zone is not in a ready state : %s", managedZone.Name) } - dnsProvider, err := r.ProviderFactory.ProviderFor(ctx, managedZone) - if err != nil { - return err - } - - err = dnsProvider.Delete(dnsRecord, managedZone) + err = r.applyChanges(ctx, dnsRecord, managedZone, true) if err != nil { if strings.Contains(err.Error(), "was not found") || strings.Contains(err.Error(), "notFound") { - log.Log.Info("Record not found in managed zone, continuing", "dnsRecord", dnsRecord.Name, "managedZone", managedZone.Name) + logger.Info("Record not found in managed zone, continuing", "dnsRecord", dnsRecord.Name, "managedZone", managedZone.Name) return nil } else if strings.Contains(err.Error(), "no endpoints") { - log.Log.Info("DNS record had no endpoint, continuing", "dnsRecord", dnsRecord.Name, "managedZone", managedZone.Name) + logger.Info("DNS record had no endpoint, continuing", "dnsRecord", dnsRecord.Name, "managedZone", managedZone.Name) return nil } return err } - log.Log.Info("Deleted DNSRecord in manage zone", "dnsRecord", dnsRecord.Name, "managedZone", managedZone.Name) + logger.Info("Deleted DNSRecord in manage zone", "dnsRecord", dnsRecord.Name, "managedZone", managedZone.Name) return nil } @@ -175,6 +174,7 @@ func (r *DNSRecordReconciler) deleteRecord(ctx context.Context, dnsRecord *v1alp // publishRecord publishes record(s) to the DNSPRovider(i.e. route53) configured by the ManagedZone assigned to this // DNSRecord (dnsRecord.Status.ParentManagedZone). func (r *DNSRecordReconciler) publishRecord(ctx context.Context, dnsRecord *v1alpha1.DNSRecord) error { + logger := log.FromContext(ctx) managedZone := &v1alpha1.ManagedZone{ ObjectMeta: metav1.ObjectMeta{ @@ -193,19 +193,15 @@ func (r *DNSRecordReconciler) publishRecord(ctx context.Context, dnsRecord *v1al } if dnsRecord.Generation == dnsRecord.Status.ObservedGeneration { - log.Log.V(3).Info("Skipping managed zone to which the DNS dnsRecord is already published", "dnsRecord", dnsRecord.Name, "managedZone", managedZone.Name) + logger.V(3).Info("Skipping managed zone to which the DNS dnsRecord is already published", "dnsRecord", dnsRecord.Name, "managedZone", managedZone.Name) return nil } - dnsProvider, err := r.ProviderFactory.ProviderFor(ctx, managedZone) - if err != nil { - return err - } - err = dnsProvider.Ensure(dnsRecord, managedZone) + err = r.applyChanges(ctx, dnsRecord, managedZone, false) if err != nil { return err } - log.Log.Info("Published DNSRecord to manage zone", "dnsRecord", dnsRecord.Name, "managedZone", managedZone.Name) + logger.Info("Published DNSRecord to manage zone", "dnsRecord", dnsRecord.Name, "managedZone", managedZone.Name) return nil } @@ -221,3 +217,94 @@ func setDNSRecordCondition(dnsRecord *v1alpha1.DNSRecord, conditionType string, } meta.SetStatusCondition(&dnsRecord.Status.Conditions, cond) } + +func (r *DNSRecordReconciler) applyChanges(ctx context.Context, dnsRecord *v1alpha1.DNSRecord, managedZone *v1alpha1.ManagedZone, isDelete bool) error { + logger := log.FromContext(ctx) + + rootDomain, err := dnsRecord.GetRootDomain() + if err != nil { + return err + } + if !strings.HasSuffix(rootDomain, managedZone.Spec.DomainName) { + return fmt.Errorf("inconsitent domains, does not match managedzone, got %s, expected suffix %s", rootDomain, managedZone.Spec.DomainName) + } + rootDomainFilter := externaldnsendpoint.NewDomainFilter([]string{rootDomain}) + + providerConfig := provider.Config{ + DomainFilter: externaldnsendpoint.NewDomainFilter([]string{managedZone.Spec.DomainName}), + ZoneTypeFilter: externaldnsprovider.NewZoneTypeFilter(""), + ZoneIDFilter: externaldnsprovider.NewZoneIDFilter([]string{managedZone.Status.ID}), + } + logger.V(3).Info("applyChanges", "rootDomain", rootDomain, "rootDomainFilter", rootDomainFilter, "providerConfig", providerConfig) + dnsProvider, err := r.ProviderFactory.ProviderFor(ctx, managedZone, providerConfig) + if err != nil { + return err + } + + registry, err := externaldnsregistry.NewNoopRegistry(dnsProvider) + if err != nil { + return err + } + + policyID := "sync" + policy, exists := externaldnsplan.Policies[policyID] + if !exists { + return fmt.Errorf("unknown policy: %s", policyID) + } + + managedDNSRecordTypes := []string{externaldnsendpoint.RecordTypeA, externaldnsendpoint.RecordTypeAAAA, externaldnsendpoint.RecordTypeCNAME} + excludeDNSRecordTypes := []string{} + + //If we are deleting set the expected endpoints to an empty array + if isDelete { + dnsRecord.Spec.Endpoints = []*externaldnsendpoint.Endpoint{} + } + + //zoneEndpoints = Records in the current dns provider zone + zoneEndpoints, err := registry.Records(ctx) + if err != nil { + return err + } + + //specEndpoints = Records that this DNSRecord expects to exist + specEndpoints, err := registry.AdjustEndpoints(dnsRecord.Spec.Endpoints) + if err != nil { + return fmt.Errorf("adjusting specEndpoints: %w", err) + } + + //statusEndpoints = Records that were created/updated by this DNSRecord last + statusEndpoints, err := registry.AdjustEndpoints(dnsRecord.Status.Endpoints) + if err != nil { + return fmt.Errorf("adjusting statusEndpoints: %w", err) + } + + //Note: All endpoint lists should be in the same provider specific format at this point + logger.V(3).Info("applyChanges", "zoneEndpoints", zoneEndpoints) + logger.V(3).Info("applyChanges", "specEndpoints", specEndpoints) + logger.V(3).Info("applyChanges", "statusEndpoints", statusEndpoints) + + plan := &externaldnsplan.Plan{ + Policies: []externaldnsplan.Policy{policy}, + Current: zoneEndpoints, + Desired: specEndpoints, + //Note: We can't just filter domains by `managedZone.Spec.DomainName` it needs to be the exact root domain for this particular record + DomainFilter: externaldnsendpoint.MatchAllDomainFilters{&rootDomainFilter}, + ManagedRecords: managedDNSRecordTypes, + ExcludeRecords: excludeDNSRecordTypes, + OwnerID: registry.OwnerID(), + } + + plan = plan.Calculate() + + if plan.Changes.HasChanges() { + logger.Info("Applying changes") + err = registry.ApplyChanges(ctx, plan.Changes) + if err != nil { + return err + } + } else { + logger.Info("All records are already up to date") + } + + return nil +} diff --git a/internal/controller/managedzone_controller.go b/internal/controller/managedzone_controller.go index 348faa3b..673c18f3 100644 --- a/internal/controller/managedzone_controller.go +++ b/internal/controller/managedzone_controller.go @@ -29,6 +29,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/log" + externaldns "sigs.k8s.io/external-dns/endpoint" "github.com/kuadrant/dns-operator/api/v1alpha1" "github.com/kuadrant/dns-operator/internal/common/conditions" @@ -162,7 +163,7 @@ func (r *ManagedZoneReconciler) SetupWithManager(mgr ctrl.Manager) error { func (r *ManagedZoneReconciler) publishManagedZone(ctx context.Context, managedZone *v1alpha1.ManagedZone) error { - dnsProvider, err := r.ProviderFactory.ProviderFor(ctx, managedZone) + dnsProvider, err := r.ProviderFactory.ProviderFor(ctx, managedZone, provider.Config{}) if err != nil { return err } @@ -184,7 +185,7 @@ func (r *ManagedZoneReconciler) deleteManagedZone(ctx context.Context, managedZo return nil } - dnsProvider, err := r.ProviderFactory.ProviderFor(ctx, managedZone) + dnsProvider, err := r.ProviderFactory.ProviderFor(ctx, managedZone, provider.Config{}) if err != nil { var reason, message string status := metav1.ConditionFalse @@ -263,7 +264,7 @@ func (r *ManagedZoneReconciler) createParentZoneNSRecord(ctx context.Context, ma ManagedZoneRef: &v1alpha1.ManagedZoneReference{ Name: parentZone.Name, }, - Endpoints: []*v1alpha1.Endpoint{ + Endpoints: []*externaldns.Endpoint{ { DNSName: recordName, Targets: recordTargets, diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index d9c447d4..ea18ca52 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -35,6 +35,8 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + externaldnsendpoint "sigs.k8s.io/external-dns/endpoint" + externaldnsplan "sigs.k8s.io/external-dns/plan" "github.com/kuadrant/dns-operator/api/v1alpha1" "github.com/kuadrant/dns-operator/internal/health" @@ -54,14 +56,20 @@ var testEnv *envtest.Environment var ctx context.Context var cancel context.CancelFunc var dnsProviderFactory = &providerFake.Factory{ - ProviderForFunc: func(ctx context.Context, pa v1alpha1.ProviderAccessor) (provider.Provider, error) { + ProviderForFunc: func(ctx context.Context, pa v1alpha1.ProviderAccessor, c provider.Config) (provider.Provider, error) { return &providerFake.Provider{ - EnsureFunc: func(record *v1alpha1.DNSRecord, zone *v1alpha1.ManagedZone) error { - return nil + RecordsFunc: func(context.Context) ([]*externaldnsendpoint.Endpoint, error) { + return []*externaldnsendpoint.Endpoint{}, nil }, - DeleteFunc: func(record *v1alpha1.DNSRecord, zone *v1alpha1.ManagedZone) error { + ApplyChangesFunc: func(context.Context, *externaldnsplan.Changes) error { return nil }, + AdjustEndpointsFunc: func(eps []*externaldnsendpoint.Endpoint) ([]*externaldnsendpoint.Endpoint, error) { + return eps, nil + }, + GetDomainFilterFunc: func() externaldnsendpoint.DomainFilter { + return externaldnsendpoint.DomainFilter{} + }, EnsureManagedZoneFunc: func(zone *v1alpha1.ManagedZone) (provider.ManagedZoneOutput, error) { return provider.ManagedZoneOutput{}, nil }, diff --git a/internal/provider/aws/aws.go b/internal/provider/aws/aws.go index 354f8ce3..07b3153b 100644 --- a/internal/provider/aws/aws.go +++ b/internal/provider/aws/aws.go @@ -19,7 +19,6 @@ package aws import ( "context" "fmt" - "strconv" "time" "github.com/aws/aws-sdk-go/aws" @@ -29,31 +28,37 @@ import ( "github.com/go-logr/logr" v1 "k8s.io/api/core/v1" - kerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/log" + externaldnsendpoint "sigs.k8s.io/external-dns/endpoint" + externaldnsprovider "sigs.k8s.io/external-dns/provider" + externaldnsprovideraws "sigs.k8s.io/external-dns/provider/aws" "github.com/kuadrant/dns-operator/api/v1alpha1" "github.com/kuadrant/dns-operator/internal/provider" ) const ( - ProviderSpecificRegion = "aws/region" - ProviderSpecificFailover = "aws/failover" - ProviderSpecificGeolocationSubdivisionCode = "aws/geolocation-subdivision-code" - ProviderSpecificMultiValueAnswer = "aws/multi-value-answer" - ProviderSpecificHealthCheckID = "aws/health-check-id" + providerSpecificWeight = "aws/weight" + providerSpecificGeolocationCountryCode = "aws/geolocation-country-code" + providerSpecificGeolocationContinentCode = "aws/geolocation-continent-code" + awsBatchChangeSize = 1000 + awsBatchChangeInterval = time.Second + awsEvaluateTargetHealth = true + awsPreferCNAME = false + awsZoneCacheDuration = 0 * time.Second ) type Route53DNSProvider struct { - client *InstrumentedRoute53 - logger logr.Logger - ctx context.Context + *externaldnsprovideraws.AWSProvider + awsConfig externaldnsprovideraws.AWSConfig + logger logr.Logger + route53Client *route53.Route53 + ctx context.Context } var _ provider.Provider = &Route53DNSProvider{} -func NewProviderFromSecret(ctx context.Context, s *v1.Secret) (provider.Provider, error) { - +func NewProviderFromSecret(ctx context.Context, s *v1.Secret, c provider.Config) (provider.Provider, error) { config := aws.NewConfig() sessionOpts := session.Options{ Config: *config, @@ -72,34 +77,64 @@ func NewProviderFromSecret(ctx context.Context, s *v1.Secret) (provider.Provider sess.Config.WithRegion(string(s.Data["REGION"])) } - p := &Route53DNSProvider{ - client: &InstrumentedRoute53{route53.New(sess, config)}, - logger: log.Log.WithName("aws-route53").WithValues("region", config.Region), - ctx: ctx, + route53Client := route53.New(sess, config) + + awsConfig := externaldnsprovideraws.AWSConfig{ + DomainFilter: c.DomainFilter, + ZoneIDFilter: c.ZoneIDFilter, + ZoneTypeFilter: c.ZoneTypeFilter, + ZoneTagFilter: externaldnsprovider.NewZoneTagFilter([]string{}), + BatchChangeSize: awsBatchChangeSize, + BatchChangeInterval: awsBatchChangeInterval, + EvaluateTargetHealth: awsEvaluateTargetHealth, + PreferCNAME: awsPreferCNAME, + DryRun: false, + ZoneCacheDuration: awsZoneCacheDuration, } - if err := validateServiceEndpoints(p); err != nil { - return nil, fmt.Errorf("failed to validate AWS provider service endpoints: %v", err) + awsProvider, err := externaldnsprovideraws.NewAWSProvider(awsConfig, route53Client) + if err != nil { + return nil, fmt.Errorf("unable to create aws provider: %s", err) } + p := &Route53DNSProvider{ + AWSProvider: awsProvider, + awsConfig: awsConfig, + logger: log.Log.WithName("aws-route53").WithValues("region", config.Region), + route53Client: route53Client, + ctx: ctx, + } return p, nil } -type action string +// #### External DNS Provider #### -const ( - upsertAction action = "UPSERT" - deleteAction action = "DELETE" -) +func (p *Route53DNSProvider) AdjustEndpoints(endpoints []*externaldnsendpoint.Endpoint) ([]*externaldnsendpoint.Endpoint, error) { + endpoints, err := p.AWSProvider.AdjustEndpoints(endpoints) + if err != nil { + return nil, err + } -func (p *Route53DNSProvider) Ensure(record *v1alpha1.DNSRecord, managedZone *v1alpha1.ManagedZone) error { - return p.change(record, managedZone, upsertAction) -} + for _, ep := range endpoints { + if prop, ok := ep.GetProviderSpecificProperty(v1alpha1.ProviderSpecificWeight); ok { + ep.DeleteProviderSpecificProperty(v1alpha1.ProviderSpecificWeight) + ep.WithProviderSpecific(providerSpecificWeight, prop) + } -func (p *Route53DNSProvider) Delete(record *v1alpha1.DNSRecord, managedZone *v1alpha1.ManagedZone) error { - return p.change(record, managedZone, deleteAction) + if prop, ok := ep.GetProviderSpecificProperty(v1alpha1.ProviderSpecificGeoCode); ok { + ep.DeleteProviderSpecificProperty(v1alpha1.ProviderSpecificGeoCode) + if provider.IsISO3166Alpha2Code(prop) || prop == "*" { + ep.WithProviderSpecific(providerSpecificGeolocationCountryCode, prop) + } else { + ep.WithProviderSpecific(providerSpecificGeolocationContinentCode, prop) + } + } + } + return endpoints, nil } +// #### DNS Operator Provider #### + func (p *Route53DNSProvider) EnsureManagedZone(zone *v1alpha1.ManagedZone) (provider.ManagedZoneOutput, error) { var zoneID string if zone.Spec.ID != "" { @@ -111,7 +146,7 @@ func (p *Route53DNSProvider) EnsureManagedZone(zone *v1alpha1.ManagedZone) (prov var managedZoneOutput provider.ManagedZoneOutput if zoneID != "" { - getResp, err := p.client.GetHostedZone(&route53.GetHostedZoneInput{ + getResp, err := p.route53Client.GetHostedZone(&route53.GetHostedZoneInput{ Id: &zoneID, }) if err != nil { @@ -119,7 +154,7 @@ func (p *Route53DNSProvider) EnsureManagedZone(zone *v1alpha1.ManagedZone) (prov return managedZoneOutput, err } - _, err = p.client.UpdateHostedZoneComment(&route53.UpdateHostedZoneCommentInput{ + _, err = p.route53Client.UpdateHostedZoneComment(&route53.UpdateHostedZoneCommentInput{ Comment: &zone.Spec.Description, Id: &zoneID, }) @@ -139,7 +174,7 @@ func (p *Route53DNSProvider) EnsureManagedZone(zone *v1alpha1.ManagedZone) (prov //changes to the latest version and try again callerRef := time.Now().Format("20060102150405") // Create the hosted zone - createResp, err := p.client.CreateHostedZone(&route53.CreateHostedZoneInput{ + createResp, err := p.route53Client.CreateHostedZone(&route53.CreateHostedZoneInput{ CallerReference: &callerRef, Name: &zone.Spec.DomainName, HostedZoneConfig: &route53.HostedZoneConfig{ @@ -158,7 +193,7 @@ func (p *Route53DNSProvider) EnsureManagedZone(zone *v1alpha1.ManagedZone) (prov } func (p *Route53DNSProvider) DeleteManagedZone(zone *v1alpha1.ManagedZone) error { - _, err := p.client.DeleteHostedZone(&route53.DeleteHostedZoneInput{ + _, err := p.route53Client.DeleteHostedZone(&route53.DeleteHostedZoneInput{ Id: &zone.Status.ID, }) if err != nil { @@ -168,160 +203,6 @@ func (p *Route53DNSProvider) DeleteManagedZone(zone *v1alpha1.ManagedZone) error return nil } -func (p *Route53DNSProvider) change(record *v1alpha1.DNSRecord, managedZone *v1alpha1.ManagedZone, action action) error { - // Configure records. - if len(record.Spec.Endpoints) == 0 { - return nil - } - err := p.updateRecord(record, managedZone.Status.ID, string(action)) - if err != nil { - return fmt.Errorf("failed to update record in route53 hosted zone %s: %v", managedZone.Status.ID, err) - } - switch action { - case upsertAction: - p.logger.Info("Upserted DNS record", "record", record.Spec, "hostedZoneID", managedZone.Status.ID) - case deleteAction: - p.logger.Info("Deleted DNS record", "record", record.Spec, "hostedZoneID", managedZone.Status.ID) - } - return nil -} - -func (p *Route53DNSProvider) updateRecord(record *v1alpha1.DNSRecord, zoneID, action string) error { - - if len(record.Spec.Endpoints) == 0 { - return fmt.Errorf("no endpoints") - } - - input := route53.ChangeResourceRecordSetsInput{HostedZoneId: aws.String(zoneID)} - - expectedEndpointsMap := make(map[string]struct{}) - var changes []*route53.Change - for _, endpoint := range record.Spec.Endpoints { - expectedEndpointsMap[endpoint.SetID()] = struct{}{} - change, err := p.changeForEndpoint(endpoint, action) - if err != nil { - return err - } - changes = append(changes, change) - } - - // Delete any previously published records that are no longer present in record.Spec.Endpoints - if action != string(deleteAction) { - lastPublishedEndpoints := record.Status.Endpoints - for _, endpoint := range lastPublishedEndpoints { - if _, found := expectedEndpointsMap[endpoint.SetID()]; !found { - change, err := p.changeForEndpoint(endpoint, string(deleteAction)) - if err != nil { - return err - } - changes = append(changes, change) - } - } - } - - if len(changes) == 0 { - return nil - } - input.ChangeBatch = &route53.ChangeBatch{ - Changes: changes, - } - resp, err := p.client.ChangeResourceRecordSets(&input) - if err != nil { - return fmt.Errorf("couldn't update DNS record %s in zone %s: %v", record.Name, zoneID, err) - } - p.logger.Info("Updated DNS record", "record", record, "zone", zoneID, "response", resp) - return nil -} - -func (p *Route53DNSProvider) changeForEndpoint(endpoint *v1alpha1.Endpoint, action string) (*route53.Change, error) { - if endpoint.RecordType != string(v1alpha1.ARecordType) && endpoint.RecordType != string(v1alpha1.CNAMERecordType) && endpoint.RecordType != string(v1alpha1.NSRecordType) { - return nil, fmt.Errorf("unsupported record type %s", endpoint.RecordType) - } - domain, targets := endpoint.DNSName, endpoint.Targets - if len(domain) == 0 { - return nil, fmt.Errorf("domain is required") - } - if len(targets) == 0 { - return nil, fmt.Errorf("targets is required") - } - - var resourceRecords []*route53.ResourceRecord - for _, target := range endpoint.Targets { - resourceRecords = append(resourceRecords, &route53.ResourceRecord{Value: aws.String(target)}) - } - - resourceRecordSet := &route53.ResourceRecordSet{ - Name: aws.String(endpoint.DNSName), - Type: aws.String(endpoint.RecordType), - TTL: aws.Int64(int64(endpoint.RecordTTL)), - ResourceRecords: resourceRecords, - } - - if endpoint.SetIdentifier != "" { - resourceRecordSet.SetIdentifier = aws.String(endpoint.SetIdentifier) - } - if prop, ok := endpoint.GetProviderSpecificProperty(v1alpha1.ProviderSpecificWeight); ok { - weight, err := strconv.ParseInt(prop.Value, 10, 64) - if err != nil { - p.logger.Error(err, "Failed parsing value, using weight of 0", "weight", v1alpha1.ProviderSpecificWeight, "value", prop.Value) - weight = 0 - } - resourceRecordSet.Weight = aws.Int64(weight) - } - if prop, ok := endpoint.GetProviderSpecificProperty(ProviderSpecificRegion); ok { - resourceRecordSet.Region = aws.String(prop.Value) - } - if prop, ok := endpoint.GetProviderSpecificProperty(ProviderSpecificFailover); ok { - resourceRecordSet.Failover = aws.String(prop.Value) - } - if _, ok := endpoint.GetProviderSpecificProperty(ProviderSpecificMultiValueAnswer); ok { - resourceRecordSet.MultiValueAnswer = aws.Bool(true) - } - - var geolocation = &route53.GeoLocation{} - useGeolocation := false - - if prop, ok := endpoint.GetProviderSpecificProperty(v1alpha1.ProviderSpecificGeoCode); ok { - if provider.IsISO3166Alpha2Code(prop.Value) || prop.Value == "*" { - geolocation.CountryCode = aws.String(prop.Value) - } else { - geolocation.ContinentCode = aws.String(prop.Value) - } - useGeolocation = true - } - - if geolocation.ContinentCode == nil { - if prop, ok := endpoint.GetProviderSpecificProperty(ProviderSpecificGeolocationSubdivisionCode); ok { - geolocation.SubdivisionCode = aws.String(prop.Value) - useGeolocation = true - } - } - if useGeolocation { - resourceRecordSet.GeoLocation = geolocation - } - - if prop, ok := endpoint.GetProviderSpecificProperty(ProviderSpecificHealthCheckID); ok { - resourceRecordSet.HealthCheckId = aws.String(prop.Value) - } - - change := &route53.Change{ - Action: aws.String(action), - ResourceRecordSet: resourceRecordSet, - } - return change, nil -} - -// validateServiceEndpoints validates that provider clients can communicate with -// associated API endpoints by having each client make a list/describe/get call. -func validateServiceEndpoints(provider *Route53DNSProvider) error { - var errs []error - zoneInput := route53.ListHostedZonesInput{MaxItems: aws.String("1")} - if _, err := provider.client.ListHostedZones(&zoneInput); err != nil { - errs = append(errs, fmt.Errorf("failed to list route53 hosted zones: %v", err)) - } - return kerrors.NewAggregate(errs) -} - // Register this Provider with the provider factory func init() { provider.RegisterProvider("aws", NewProviderFromSecret) diff --git a/internal/provider/factory.go b/internal/provider/factory.go index 3e3200ac..1597fcd1 100644 --- a/internal/provider/factory.go +++ b/internal/provider/factory.go @@ -18,7 +18,7 @@ var errUnsupportedProvider = fmt.Errorf("provider type given is not supported") // ProviderConstructor constructs a provider given a Secret resource and a Context. // An error will be returned if the appropriate provider is not registered. -type ProviderConstructor func(context.Context, *v1.Secret) (Provider, error) +type ProviderConstructor func(context.Context, *v1.Secret, Config) (Provider, error) var ( constructors = make(map[string]ProviderConstructor) @@ -36,7 +36,7 @@ func RegisterProvider(name string, c ProviderConstructor) { // Factory is an interface that can be used to obtain Provider implementations. // It determines which provider implementation to use by introspecting the given ProviderAccessor resource. type Factory interface { - ProviderFor(context.Context, v1alpha1.ProviderAccessor) (Provider, error) + ProviderFor(context.Context, v1alpha1.ProviderAccessor, Config) (Provider, error) } // factory is the default Factory implementation @@ -51,7 +51,7 @@ func NewFactory(c client.Client) Factory { // ProviderFor will return a Provider interface for the given ProviderAccessor secret. // If the requested ProviderAccessor secret does not exist, an error will be returned. -func (f *factory) ProviderFor(ctx context.Context, pa v1alpha1.ProviderAccessor) (Provider, error) { +func (f *factory) ProviderFor(ctx context.Context, pa v1alpha1.ProviderAccessor, c Config) (Provider, error) { providerSecret := &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: pa.GetProviderRef().Name, @@ -70,7 +70,7 @@ func (f *factory) ProviderFor(ctx context.Context, pa v1alpha1.ProviderAccessor) constructorsLock.RLock() defer constructorsLock.RUnlock() if constructor, ok := constructors[providerType]; ok { - return constructor(ctx, providerSecret) + return constructor(ctx, providerSecret, c) } return nil, fmt.Errorf("provider '%s' not registered", providerType) diff --git a/internal/provider/fake/factory.go b/internal/provider/fake/factory.go index 002f5428..6ff65a9d 100644 --- a/internal/provider/fake/factory.go +++ b/internal/provider/fake/factory.go @@ -8,11 +8,11 @@ import ( ) type Factory struct { - ProviderForFunc func(ctx context.Context, pa v1alpha1.ProviderAccessor) (provider.Provider, error) + ProviderForFunc func(ctx context.Context, pa v1alpha1.ProviderAccessor, c provider.Config) (provider.Provider, error) } var _ provider.Factory = &Factory{} -func (f *Factory) ProviderFor(ctx context.Context, pa v1alpha1.ProviderAccessor) (provider.Provider, error) { - return f.ProviderForFunc(ctx, pa) +func (f *Factory) ProviderFor(ctx context.Context, pa v1alpha1.ProviderAccessor, c provider.Config) (provider.Provider, error) { + return f.ProviderForFunc(ctx, pa, c) } diff --git a/internal/provider/fake/provider.go b/internal/provider/fake/provider.go index 8d4ee816..70a644ec 100644 --- a/internal/provider/fake/provider.go +++ b/internal/provider/fake/provider.go @@ -1,27 +1,46 @@ package fake import ( + "context" + + externaldnsendpoint "sigs.k8s.io/external-dns/endpoint" + externaldnsplan "sigs.k8s.io/external-dns/plan" + "github.com/kuadrant/dns-operator/api/v1alpha1" "github.com/kuadrant/dns-operator/internal/provider" ) type Provider struct { - EnsureFunc func(*v1alpha1.DNSRecord, *v1alpha1.ManagedZone) error - DeleteFunc func(*v1alpha1.DNSRecord, *v1alpha1.ManagedZone) error + RecordsFunc func(context.Context) ([]*externaldnsendpoint.Endpoint, error) + ApplyChangesFunc func(context.Context, *externaldnsplan.Changes) error + AdjustEndpointsFunc func([]*externaldnsendpoint.Endpoint) ([]*externaldnsendpoint.Endpoint, error) + GetDomainFilterFunc func() externaldnsendpoint.DomainFilter EnsureManagedZoneFunc func(*v1alpha1.ManagedZone) (provider.ManagedZoneOutput, error) DeleteManagedZoneFunc func(*v1alpha1.ManagedZone) error } var _ provider.Provider = &Provider{} -func (p Provider) Ensure(record *v1alpha1.DNSRecord, managedZone *v1alpha1.ManagedZone) error { - return p.EnsureFunc(record, managedZone) +// #### External DNS Provider #### + +func (p Provider) Records(ctx context.Context) ([]*externaldnsendpoint.Endpoint, error) { + return p.RecordsFunc(ctx) +} + +func (p Provider) ApplyChanges(ctx context.Context, changes *externaldnsplan.Changes) error { + return p.ApplyChangesFunc(ctx, changes) +} + +func (p Provider) AdjustEndpoints(endpoints []*externaldnsendpoint.Endpoint) ([]*externaldnsendpoint.Endpoint, error) { + return p.AdjustEndpointsFunc(endpoints) } -func (p Provider) Delete(record *v1alpha1.DNSRecord, managedZone *v1alpha1.ManagedZone) error { - return p.DeleteFunc(record, managedZone) +func (p Provider) GetDomainFilter() externaldnsendpoint.DomainFilter { + return p.GetDomainFilterFunc() } +// #### DNS Operator Provider #### + func (p Provider) EnsureManagedZone(managedZone *v1alpha1.ManagedZone) (provider.ManagedZoneOutput, error) { return p.EnsureManagedZoneFunc(managedZone) } diff --git a/internal/provider/google/google.go b/internal/provider/google/google.go index 8b9b4a02..582af4a3 100644 --- a/internal/provider/google/google.go +++ b/internal/provider/google/google.go @@ -19,7 +19,6 @@ package google import ( "context" "fmt" - "net" "sort" "strconv" "strings" @@ -32,20 +31,19 @@ import ( v1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/log" + externaldnsendpoint "sigs.k8s.io/external-dns/endpoint" + externaldnsplan "sigs.k8s.io/external-dns/plan" + externaldnsprovider "sigs.k8s.io/external-dns/provider" "github.com/kuadrant/dns-operator/api/v1alpha1" "github.com/kuadrant/dns-operator/internal/provider" ) -type action string - const ( - GoogleBatchChangeSize = 1000 - GoogleBatchChangeInterval = time.Second - DryRun = false - upsertAction action = "UPSERT" - deleteAction action = "DELETE" - defaultGeo = "europe-west1" + googleRecordTTL = 300 + GoogleBatchChangeSize = 1000 + GoogleBatchChangeInterval = time.Second + DryRun = false ) // Based on the external-dns google provider https://github.com/kubernetes-sigs/external-dns/blob/master/provider/google/google.go @@ -135,6 +133,12 @@ type GoogleDNSProvider struct { batchChangeSize int // Interval between batch updates. batchChangeInterval time.Duration + // only consider hosted zones managing domains ending in this suffix + domainFilter externaldnsendpoint.DomainFilter + // filter for zones based on visibility + zoneTypeFilter externaldnsprovider.ZoneTypeFilter + // only consider hosted zones ending with this zone id + zoneIDFilter externaldnsprovider.ZoneIDFilter // A client for managing resource record sets resourceRecordSetsClient resourceRecordSetsClientInterface // A client for managing hosted zones @@ -147,7 +151,7 @@ type GoogleDNSProvider struct { var _ provider.Provider = &GoogleDNSProvider{} -func NewProviderFromSecret(ctx context.Context, s *v1.Secret) (provider.Provider, error) { +func NewProviderFromSecret(ctx context.Context, s *v1.Secret, c provider.Config) (provider.Provider, error) { if string(s.Data["GOOGLE"]) == "" || string(s.Data["PROJECT_ID"]) == "" { return nil, fmt.Errorf("GCP Provider credentials is empty") @@ -166,6 +170,9 @@ func NewProviderFromSecret(ctx context.Context, s *v1.Secret) (provider.Provider dryRun: DryRun, batchChangeSize: GoogleBatchChangeSize, batchChangeInterval: GoogleBatchChangeInterval, + domainFilter: c.DomainFilter, + zoneTypeFilter: c.ZoneTypeFilter, + zoneIDFilter: c.ZoneIDFilter, resourceRecordSetsClient: resourceRecordSetsService{dnsClient.ResourceRecordSets}, managedZonesClient: managedZonesService{dnsClient.ManagedZones}, changesClient: changesService{dnsClient.Changes}, @@ -175,168 +182,176 @@ func NewProviderFromSecret(ctx context.Context, s *v1.Secret) (provider.Provider return p, nil } -// ManagedZones +// #### External DNS Provider #### -func (g *GoogleDNSProvider) DeleteManagedZone(managedZone *v1alpha1.ManagedZone) error { - return g.managedZonesClient.Delete(g.project, managedZone.Status.ID).Do() -} +// Zones returns the list of hosted zones. +func (p *GoogleDNSProvider) Zones(ctx context.Context) (map[string]*dnsv1.ManagedZone, error) { + zones := make(map[string]*dnsv1.ManagedZone) -func (g *GoogleDNSProvider) EnsureManagedZone(managedZone *v1alpha1.ManagedZone) (provider.ManagedZoneOutput, error) { - var zoneID string + f := func(resp *dnsv1.ManagedZonesListResponse) error { + for _, zone := range resp.ManagedZones { + if zone.PeeringConfig == nil { + if p.domainFilter.Match(zone.DnsName) && p.zoneTypeFilter.Match(zone.Visibility) && (p.zoneIDFilter.Match(fmt.Sprintf("%v", zone.Id)) || p.zoneIDFilter.Match(fmt.Sprintf("%v", zone.Name))) { + zones[zone.Name] = zone + p.logger.Info(fmt.Sprintf("Matched %s (zone: %s) (visibility: %s)", zone.DnsName, zone.Name, zone.Visibility)) + } else { + p.logger.Info(fmt.Sprintf("Filtered %s (zone: %s) (visibility: %s)", zone.DnsName, zone.Name, zone.Visibility)) + } + } else { + p.logger.Info(fmt.Sprintf("Filtered peering zone %s (zone: %s) (visibility: %s)", zone.DnsName, zone.Name, zone.Visibility)) + } + } - if managedZone.Spec.ID != "" { - zoneID = managedZone.Spec.ID - } else { - zoneID = managedZone.Status.ID + return nil } - if zoneID != "" { - //Get existing managed zone - return g.getManagedZone(zoneID) + p.logger.Info(fmt.Sprintf("Matching zones against domain filters: %v", p.domainFilter)) + if err := p.managedZonesClient.List(p.project).Pages(ctx, f); err != nil { + return nil, err } - //Create new managed zone - return g.createManagedZone(managedZone) -} -func (g *GoogleDNSProvider) createManagedZone(managedZone *v1alpha1.ManagedZone) (provider.ManagedZoneOutput, error) { - zoneID := strings.Replace(managedZone.Spec.DomainName, ".", "-", -1) - zone := dnsv1.ManagedZone{ - Name: zoneID, - DnsName: ensureTrailingDot(managedZone.Spec.DomainName), - Description: managedZone.Spec.Description, + if len(zones) == 0 { + p.logger.Info(fmt.Sprintf("No zones in the project, %s, match domain filters: %v", p.project, p.domainFilter)) } - mz, err := g.managedZonesClient.Create(g.project, &zone).Do() - if err != nil { - return provider.ManagedZoneOutput{}, err + + for _, zone := range zones { + p.logger.Info(fmt.Sprintf("Considering zone: %s (domain: %s)", zone.Name, zone.DnsName)) } - return g.toManagedZoneOutput(mz) + + return zones, nil } -func (g *GoogleDNSProvider) getManagedZone(zoneID string) (provider.ManagedZoneOutput, error) { - mz, err := g.managedZonesClient.Get(g.project, zoneID).Do() +// Records returns records from the provider in google specific format +func (p *GoogleDNSProvider) Records(ctx context.Context) (endpoints []*externaldnsendpoint.Endpoint, _ error) { + zones, err := p.Zones(ctx) if err != nil { - return provider.ManagedZoneOutput{}, err + return nil, err } - return g.toManagedZoneOutput(mz) -} - -func (g *GoogleDNSProvider) toManagedZoneOutput(mz *dnsv1.ManagedZone) (provider.ManagedZoneOutput, error) { - var managedZoneOutput provider.ManagedZoneOutput - zoneID := mz.Name - var nameservers []*string - for i := range mz.NameServers { - nameservers = append(nameservers, &mz.NameServers[i]) + var records []*dnsv1.ResourceRecordSet + f := func(resp *dnsv1.ResourceRecordSetsListResponse) error { + for _, r := range resp.Rrsets { + if !p.SupportedRecordType(r.Type) { + continue + } + records = append(records, r) + } + return nil } - managedZoneOutput.ID = zoneID - managedZoneOutput.NameServers = nameservers - currentRecords, err := g.getResourceRecordSets(g.ctx, zoneID) - if err != nil { - return managedZoneOutput, err + for _, z := range zones { + if err := p.resourceRecordSetsClient.List(p.project, z.Name).Pages(ctx, f); err != nil { + return nil, err + } } - managedZoneOutput.RecordCount = int64(len(currentRecords)) - return managedZoneOutput, nil + return endpointsFromResourceRecordSets(records), nil } -//DNSRecords +func (p *GoogleDNSProvider) ApplyChanges(ctx context.Context, changes *externaldnsplan.Changes) error { + change := &dnsv1.Change{} + + change.Additions = append(change.Additions, p.newFilteredRecords(changes.Create)...) -func (g *GoogleDNSProvider) Ensure(record *v1alpha1.DNSRecord, managedZone *v1alpha1.ManagedZone) error { - return g.updateRecord(record, managedZone.Status.ID, upsertAction) + change.Additions = append(change.Additions, p.newFilteredRecords(changes.UpdateNew)...) + change.Deletions = append(change.Deletions, p.newFilteredRecords(changes.UpdateOld)...) + + change.Deletions = append(change.Deletions, p.newFilteredRecords(changes.Delete)...) + + return p.submitChange(ctx, change) } -func (g *GoogleDNSProvider) Delete(record *v1alpha1.DNSRecord, managedZone *v1alpha1.ManagedZone) error { - return g.updateRecord(record, managedZone.Status.ID, deleteAction) +// AdjustEndpoints takes source endpoints and translates them to a google specific format +func (p *GoogleDNSProvider) AdjustEndpoints(endpoints []*externaldnsendpoint.Endpoint) ([]*externaldnsendpoint.Endpoint, error) { + return endpointsToGoogleFormat(endpoints), nil } -func (g *GoogleDNSProvider) updateRecord(dnsRecord *v1alpha1.DNSRecord, zoneID string, action action) error { - // When updating records the Google DNS API expects you to delete any existing record and add the new one as part of - // the same change request. The record to be deleted must match exactly what currently exists in the provider or the - // change request will fail. To make sure we can always remove the records, we first get all records that exist in - // the zone and build up the deleting list from `dnsRecord.Status` but use the most recent version of it retrieved - // from the provider in the change request. - currentRecords, err := g.getResourceRecordSets(g.ctx, zoneID) - if err != nil { - return err - } - currentRecordsMap := make(map[string]*dnsv1.ResourceRecordSet) - for _, record := range currentRecords { - currentRecordsMap[record.Name] = record - } - statusRecords := toResourceRecordSets(dnsRecord.Status.Endpoints) - statusRecordsMap := make(map[string]*dnsv1.ResourceRecordSet) - for _, record := range statusRecords { - statusRecordsMap[record.Name] = record - } +func (p *GoogleDNSProvider) GetDomainFilter() externaldnsendpoint.DomainFilter { + return externaldnsendpoint.DomainFilter{} +} - var deletingRecords []*dnsv1.ResourceRecordSet - for name := range statusRecordsMap { - if record, ok := currentRecordsMap[name]; ok { - deletingRecords = append(deletingRecords, record) - } +// SupportedRecordType returns true if the record type is supported by the provider +func (p *GoogleDNSProvider) SupportedRecordType(recordType string) bool { + switch recordType { + case "MX": + return true + default: + return externaldnsprovider.SupportedRecordType(recordType) } - addingRecords := toResourceRecordSets(dnsRecord.Spec.Endpoints) +} - g.logger.V(1).Info("updateRecord", "currentRecords", currentRecords, "deletingRecords", deletingRecords, "addingRecords", addingRecords) +// newFilteredRecords returns a collection of RecordSets based on the given endpoints and domainFilter. +func (p *GoogleDNSProvider) newFilteredRecords(endpoints []*externaldnsendpoint.Endpoint) []*dnsv1.ResourceRecordSet { + records := []*dnsv1.ResourceRecordSet{} - change := &dnsv1.Change{} - if action == deleteAction { - change.Deletions = deletingRecords - } else { - change.Deletions = deletingRecords - change.Additions = addingRecords + for _, endpoint := range endpoints { + if p.domainFilter.Match(endpoint.DNSName) { + records = append(records, newRecord(endpoint)) + } } - return g.submitChange(change, zoneID) + return records } -func (g *GoogleDNSProvider) submitChange(change *dnsv1.Change, zone string) error { +// submitChange takes a zone and a Change and sends it to Google. +func (p *GoogleDNSProvider) submitChange(ctx context.Context, change *dnsv1.Change) error { if len(change.Additions) == 0 && len(change.Deletions) == 0 { - g.logger.Info("All records are already up to date") + p.logger.Info("All records are already up to date") return nil } - for batch, c := range g.batchChange(change, g.batchChangeSize) { - g.logger.V(1).Info("Change zone", "zone", zone, "batch", batch) - for _, del := range c.Deletions { - g.logger.V(1).Info("Del records", "name", del.Name, "type", del.Type, "Rrdatas", - del.Rrdatas, "RoutingPolicy", del.RoutingPolicy, "ttl", del.Ttl) - } - for _, add := range c.Additions { - g.logger.V(1).Info("Add records", "name", add.Name, "type", add.Type, "Rrdatas", - add.Rrdatas, "RoutingPolicy", add.RoutingPolicy, "ttl", add.Ttl) - } - if g.dryRun { - continue - } + zones, err := p.Zones(ctx) + if err != nil { + return err + } + + // separate into per-zone change sets to be passed to the API. + changes := separateChange(zones, change) + + for zone, change := range changes { + for batch, c := range batchChange(change, p.batchChangeSize) { + p.logger.Info(fmt.Sprintf("Change zone: %v batch #%d", zone, batch)) + for _, del := range c.Deletions { + p.logger.Info(fmt.Sprintf("Del records: %s %s %s %d", del.Name, del.Type, del.Rrdatas, del.Ttl)) + } + for _, add := range c.Additions { + p.logger.Info(fmt.Sprintf("Add records: %s %s %s %d", add.Name, add.Type, add.Rrdatas, add.Ttl)) + } + + if p.dryRun { + continue + } - if _, err := g.changesClient.Create(g.project, zone, c).Do(); err != nil { - return err + if _, err := p.changesClient.Create(p.project, zone, c).Do(); err != nil { + return err + } + + time.Sleep(p.batchChangeInterval) } - time.Sleep(g.batchChangeInterval) } + return nil } -func (g *GoogleDNSProvider) batchChange(change *dnsv1.Change, batchSize int) []*dnsv1.Change { +// batchChange separates a zone in multiple transaction. +func batchChange(change *dnsv1.Change, batchSize int) []*dnsv1.Change { changes := []*dnsv1.Change{} if batchSize == 0 { return append(changes, change) } - type dnsv1Change struct { + type dnsChange struct { additions []*dnsv1.ResourceRecordSet deletions []*dnsv1.ResourceRecordSet } - changesByName := map[string]*dnsv1Change{} + changesByName := map[string]*dnsChange{} for _, a := range change.Additions { change, ok := changesByName[a.Name] if !ok { - change = &dnsv1Change{} + change = &dnsChange{} changesByName[a.Name] = change } @@ -346,7 +361,7 @@ func (g *GoogleDNSProvider) batchChange(change *dnsv1.Change, batchSize int) []* for _, a := range change.Deletions { change, ok := changesByName[a.Name] if !ok { - change = &dnsv1Change{} + change = &dnsChange{} changesByName[a.Name] = change } @@ -367,8 +382,7 @@ func (g *GoogleDNSProvider) batchChange(change *dnsv1.Change, batchSize int) []* totalChangesByName := len(c.additions) + len(c.deletions) if totalChangesByName > batchSize { - g.logger.V(1).Info("Total changes for %s exceeds max batch size of %d, total changes: %d", name, - batchSize, totalChangesByName) + log.Log.Info(fmt.Sprintf("Total changes for %s exceeds max batch size of %d, total changes: %d", name, batchSize, totalChangesByName)) continue } @@ -391,110 +405,307 @@ func (g *GoogleDNSProvider) batchChange(change *dnsv1.Change, batchSize int) []* return changes } -// getResourceRecordSets returns the records for a managed zone of the currently configured provider. -func (g *GoogleDNSProvider) getResourceRecordSets(ctx context.Context, zoneID string) ([]*dnsv1.ResourceRecordSet, error) { - var records []*dnsv1.ResourceRecordSet +// separateChange separates a multi-zone change into a single change per zone. +func separateChange(zones map[string]*dnsv1.ManagedZone, change *dnsv1.Change) map[string]*dnsv1.Change { + changes := make(map[string]*dnsv1.Change) + zoneNameIDMapper := externaldnsprovider.ZoneIDName{} + for _, z := range zones { + zoneNameIDMapper[z.Name] = z.DnsName + changes[z.Name] = &dnsv1.Change{ + Additions: []*dnsv1.ResourceRecordSet{}, + Deletions: []*dnsv1.ResourceRecordSet{}, + } + } + for _, a := range change.Additions { + if zoneName, _ := zoneNameIDMapper.FindZone(externaldnsprovider.EnsureTrailingDot(a.Name)); zoneName != "" { + changes[zoneName].Additions = append(changes[zoneName].Additions, a) + } else { + log.Log.Info(fmt.Sprintf("No matching zone for record addition: %s %s %s %d", a.Name, a.Type, a.Rrdatas, a.Ttl)) + } + } - f := func(resp *dnsv1.ResourceRecordSetsListResponse) error { - records = append(records, resp.Rrsets...) - return nil + for _, d := range change.Deletions { + if zoneName, _ := zoneNameIDMapper.FindZone(externaldnsprovider.EnsureTrailingDot(d.Name)); zoneName != "" { + changes[zoneName].Deletions = append(changes[zoneName].Deletions, d) + } else { + log.Log.Info(fmt.Sprintf("No matching zone for record deletion: %s %s %s %d", d.Name, d.Type, d.Rrdatas, d.Ttl)) + } } - if err := g.resourceRecordSetsClient.List(g.project, zoneID).Pages(ctx, f); err != nil { - return nil, err + // separating a change could lead to empty sub changes, remove them here. + for zone, change := range changes { + if len(change.Additions) == 0 && len(change.Deletions) == 0 { + delete(changes, zone) + } } - return records, nil + return changes } -// toResourceRecordSets converts a list of endpoints into `ResourceRecordSet` resources. -func toResourceRecordSets(allEndpoints []*v1alpha1.Endpoint) []*dnsv1.ResourceRecordSet { - var records []*dnsv1.ResourceRecordSet +// endpointsFromResourceRecordSets converts a list of `ResourceRecordSet` into endpoints (google format). +func endpointsFromResourceRecordSets(resourceRecordSets []*dnsv1.ResourceRecordSet) []*externaldnsendpoint.Endpoint { + var endpoints []*externaldnsendpoint.Endpoint - // Google DNS requires a record to be created per `dnsName`, so the first thing we need to do is group all the - // endpoints with the same dnsName together. - endpointMap := make(map[string][]*v1alpha1.Endpoint) - for _, ep := range allEndpoints { - endpointMap[ep.DNSName] = append(endpointMap[ep.DNSName], ep) + for _, rrs := range resourceRecordSets { + if rrs.RoutingPolicy != nil { + endpoint := externaldnsendpoint.NewEndpointWithTTL(rrs.Name, rrs.Type, externaldnsendpoint.TTL(rrs.Ttl), []string{}...) + + if rrs.RoutingPolicy.Wrr != nil { + endpoint.WithProviderSpecific("routingpolicy", "weighted") + for i := range rrs.RoutingPolicy.Wrr.Items { + weight := strconv.FormatFloat(rrs.RoutingPolicy.Wrr.Items[i].Weight, 'f', -1, 64) + for idx := range rrs.RoutingPolicy.Wrr.Items[i].Rrdatas { + target := strings.TrimSuffix(rrs.RoutingPolicy.Wrr.Items[i].Rrdatas[idx], ".") + endpoint.Targets = append(endpoint.Targets, target) + endpoint.WithProviderSpecific(target, weight) + } + } + } else if rrs.RoutingPolicy.Geo != nil { + endpoint.WithProviderSpecific("routingpolicy", "geo") + for i := range rrs.RoutingPolicy.Geo.Items { + location := rrs.RoutingPolicy.Geo.Items[i].Location + for idx := range rrs.RoutingPolicy.Geo.Items[i].Rrdatas { + target := strings.TrimSuffix(rrs.RoutingPolicy.Geo.Items[i].Rrdatas[idx], ".") + endpoint.Targets = append(endpoint.Targets, target) + endpoint.WithProviderSpecific(target, location) + } + } + } else { + //Not good !! + continue + } + endpoints = append(endpoints, endpoint) + } else { + endpoints = append(endpoints, externaldnsendpoint.NewEndpointWithTTL(rrs.Name, rrs.Type, externaldnsendpoint.TTL(rrs.Ttl), rrs.Rrdatas...)) + } } + return endpoints +} + +// endpointsToProviderFormat converts a list of endpoints into a google specific format. +func endpointsToGoogleFormat(eps []*externaldnsendpoint.Endpoint) []*externaldnsendpoint.Endpoint { + endpointMap := make(map[string][]*externaldnsendpoint.Endpoint) + for i := range eps { + endpointMap[eps[i].DNSName] = append(endpointMap[eps[i].DNSName], eps[i]) + } + + translatedEndpoints := []*externaldnsendpoint.Endpoint{} + for dnsName, endpoints := range endpointMap { // A set of endpoints belonging to the same group(`dnsName`) must always be of the same type, have the same ttl // and contain the same rrdata (weighted or geo), so we can just get that from the first endpoint in the list. ttl := int64(endpoints[0].RecordTTL) recordType := endpoints[0].RecordType - _, weighted := endpoints[0].GetProviderSpecificProperty(v1alpha1.ProviderSpecificWeight) - _, geoCode := endpoints[0].GetProviderSpecificProperty(v1alpha1.ProviderSpecificGeoCode) + _, isWeighted := endpoints[0].GetProviderSpecificProperty(v1alpha1.ProviderSpecificWeight) + _, isGeo := endpoints[0].GetProviderSpecificProperty(v1alpha1.ProviderSpecificGeoCode) - record := &dnsv1.ResourceRecordSet{ - Name: ensureTrailingDot(dnsName), - Ttl: ttl, - Type: recordType, + if !isGeo && !isWeighted { + //ToDO DO we need to worry about there being more than one here? + translatedEndpoints = append(translatedEndpoints, endpoints[0]) + continue } - if weighted { - record.RoutingPolicy = &dnsv1.RRSetRoutingPolicy{ - Wrr: &dnsv1.RRSetRoutingPolicyWrrPolicy{}, - } - } else if geoCode { - record.RoutingPolicy = &dnsv1.RRSetRoutingPolicy{ - Geo: &dnsv1.RRSetRoutingPolicyGeoPolicy{}, - } + + translatedEndpoint := externaldnsendpoint.NewEndpointWithTTL(dnsName, recordType, externaldnsendpoint.TTL(ttl)) + + if isGeo { + translatedEndpoint.WithProviderSpecific("routingpolicy", "geo") + } else if isWeighted { + translatedEndpoint.WithProviderSpecific("routingpolicy", "weighted") } + //ToDo this has the potential to add duplicates for _, ep := range endpoints { - targets := make([]string, len(ep.Targets)) - copy(targets, ep.Targets) - if ep.RecordType == string(v1alpha1.CNAMERecordType) { - targets[0] = ensureTrailingDot(targets[0]) + for _, t := range ep.Targets { + if isGeo { + geo, _ := ep.GetProviderSpecificProperty(v1alpha1.ProviderSpecificGeoCode) + if geo == "*" { + continue + } + translatedEndpoint.WithProviderSpecific(t, geo) + } else if isWeighted { + weight, _ := ep.GetProviderSpecificProperty(v1alpha1.ProviderSpecificWeight) + translatedEndpoint.WithProviderSpecific(t, weight) + } + translatedEndpoint.Targets = append(translatedEndpoint.Targets, t) } + } + + translatedEndpoints = append(translatedEndpoints, translatedEndpoint) + } + + return translatedEndpoints +} - if !weighted && !geoCode { - record.Rrdatas = targets +// resourceRecordSetFromEndpoint converts an endpoint(google format) into a `ResourceRecordSet`. +func resourceRecordSetFromEndpoint(ep *externaldnsendpoint.Endpoint) *dnsv1.ResourceRecordSet { + + // no annotation results in a Ttl of 0, default to 300 for backwards-compatibility + var ttl int64 = googleRecordTTL + if ep.RecordTTL.IsConfigured() { + ttl = int64(ep.RecordTTL) + } + + rrs := &dnsv1.ResourceRecordSet{ + Name: externaldnsprovider.EnsureTrailingDot(ep.DNSName), + Ttl: ttl, + Type: ep.RecordType, + } + + if rp, ok := ep.GetProviderSpecificProperty("routingpolicy"); ok && ep.RecordType != externaldnsendpoint.RecordTypeTXT { + if rp == "geo" { + rrs.RoutingPolicy = &dnsv1.RRSetRoutingPolicy{ + Geo: &dnsv1.RRSetRoutingPolicyGeoPolicy{}, } - if weighted { - weightProp, _ := ep.GetProviderSpecificProperty(v1alpha1.ProviderSpecificWeight) - weight, err := strconv.ParseFloat(weightProp.Value, 64) - if err != nil { - weight = 0 + //Map location to targets, can ony have one location the same + targetMap := make(map[string][]string) + for i := range ep.Targets { + if location, ok := ep.GetProviderSpecificProperty(ep.Targets[i]); ok { + targetMap[location] = append(targetMap[location], externaldnsprovider.EnsureTrailingDot(ep.Targets[i])) } - item := &dnsv1.RRSetRoutingPolicyWrrPolicyWrrPolicyItem{ - Rrdatas: targets, - Weight: weight, + } + for l, t := range targetMap { + item := &dnsv1.RRSetRoutingPolicyGeoPolicyGeoPolicyItem{ + Location: l, + Rrdatas: t, } - record.RoutingPolicy.Wrr.Items = append(record.RoutingPolicy.Wrr.Items, item) + rrs.RoutingPolicy.Geo.Items = append(rrs.RoutingPolicy.Geo.Items, item) } - if geoCode { - geoCodeProp, _ := ep.GetProviderSpecificProperty(v1alpha1.ProviderSpecificGeoCode) - geoCodeValue := geoCodeProp.Value - targetIsDefaultGroup := strings.HasPrefix(ep.Targets[0], v1alpha1.DefaultGeo) - // GCP doesn't accept * as value for default geolocations like AWS does. - // To ensure the dns chain doesn't break if a * is given we map the value to europe-west1 instead - // We cant drop the record as the chain will break - if geoCodeValue == "*" { - if !targetIsDefaultGroup { - continue + } else if rp == "weighted" { + rrs.RoutingPolicy = &dnsv1.RRSetRoutingPolicy{ + Wrr: &dnsv1.RRSetRoutingPolicyWrrPolicy{}, + } + + for i := range ep.Targets { + if weightStr, ok := ep.GetProviderSpecificProperty(ep.Targets[i]); ok { + weight, err := strconv.ParseFloat(weightStr, 64) + if err != nil { + weight = 0.0 } - geoCodeValue = defaultGeo - } - item := &dnsv1.RRSetRoutingPolicyGeoPolicyGeoPolicyItem{ - Location: geoCodeValue, - Rrdatas: targets, + item := &dnsv1.RRSetRoutingPolicyWrrPolicyWrrPolicyItem{ + Rrdatas: []string{externaldnsprovider.EnsureTrailingDot(ep.Targets[i])}, + Weight: weight, + } + rrs.RoutingPolicy.Wrr.Items = append(rrs.RoutingPolicy.Wrr.Items, item) } - record.RoutingPolicy.Geo.Items = append(record.RoutingPolicy.Geo.Items, item) } } - records = append(records, record) + + return rrs } - return records + + targets := make([]string, len(ep.Targets)) + copy(targets, []string(ep.Targets)) + if ep.RecordType == externaldnsendpoint.RecordTypeCNAME { + if len(targets) > 0 { + targets[0] = externaldnsprovider.EnsureTrailingDot(targets[0]) + } + } + + if ep.RecordType == externaldnsendpoint.RecordTypeMX { + for i, mxRecord := range ep.Targets { + targets[i] = externaldnsprovider.EnsureTrailingDot(mxRecord) + } + } + + if ep.RecordType == externaldnsendpoint.RecordTypeSRV { + for i, srvRecord := range ep.Targets { + targets[i] = externaldnsprovider.EnsureTrailingDot(srvRecord) + } + } + + rrs.Rrdatas = targets + + return rrs +} + +// newRecord returns a RecordSet based on the given endpoint(google format). +func newRecord(ep *externaldnsendpoint.Endpoint) *dnsv1.ResourceRecordSet { + return resourceRecordSetFromEndpoint(ep) +} + +// #### DNS Operator Provider #### + +func (p *GoogleDNSProvider) EnsureManagedZone(managedZone *v1alpha1.ManagedZone) (provider.ManagedZoneOutput, error) { + var zoneID string + + if managedZone.Spec.ID != "" { + zoneID = managedZone.Spec.ID + } else { + zoneID = managedZone.Status.ID + } + + if zoneID != "" { + //Get existing managed zone + return p.getManagedZone(zoneID) + } + //Create new managed zone + return p.createManagedZone(managedZone) +} + +func (p *GoogleDNSProvider) DeleteManagedZone(managedZone *v1alpha1.ManagedZone) error { + return p.managedZonesClient.Delete(p.project, managedZone.Status.ID).Do() } -// ensureTrailingDot ensures that the hostname receives a trailing dot if it hasn't already. -func ensureTrailingDot(hostname string) string { - if net.ParseIP(hostname) != nil { - return hostname +// ManagedZones + +func (p *GoogleDNSProvider) createManagedZone(managedZone *v1alpha1.ManagedZone) (provider.ManagedZoneOutput, error) { + zoneID := strings.Replace(managedZone.Spec.DomainName, ".", "-", -1) + zone := dnsv1.ManagedZone{ + Name: zoneID, + DnsName: externaldnsprovider.EnsureTrailingDot(managedZone.Spec.DomainName), + Description: managedZone.Spec.Description, } + mz, err := p.managedZonesClient.Create(p.project, &zone).Do() + if err != nil { + return provider.ManagedZoneOutput{}, err + } + return p.toManagedZoneOutput(mz) +} - return strings.TrimSuffix(hostname, ".") + "." +func (p *GoogleDNSProvider) getManagedZone(zoneID string) (provider.ManagedZoneOutput, error) { + mz, err := p.managedZonesClient.Get(p.project, zoneID).Do() + if err != nil { + return provider.ManagedZoneOutput{}, err + } + return p.toManagedZoneOutput(mz) +} + +func (p *GoogleDNSProvider) toManagedZoneOutput(mz *dnsv1.ManagedZone) (provider.ManagedZoneOutput, error) { + var managedZoneOutput provider.ManagedZoneOutput + + zoneID := mz.Name + var nameservers []*string + for i := range mz.NameServers { + nameservers = append(nameservers, &mz.NameServers[i]) + } + managedZoneOutput.ID = zoneID + managedZoneOutput.NameServers = nameservers + + currentRecords, err := p.getResourceRecordSets(p.ctx, zoneID) + if err != nil { + return managedZoneOutput, err + } + managedZoneOutput.RecordCount = int64(len(currentRecords)) + + return managedZoneOutput, nil +} + +// ToDo Can be replaced with a call to Records if/when we update that to optionally accept a zone id +// getResourceRecordSets returns the records for a managed zone of the currently configured provider. +func (p *GoogleDNSProvider) getResourceRecordSets(ctx context.Context, zoneID string) ([]*dnsv1.ResourceRecordSet, error) { + var records []*dnsv1.ResourceRecordSet + + f := func(resp *dnsv1.ResourceRecordSetsListResponse) error { + records = append(records, resp.Rrsets...) + return nil + } + + if err := p.resourceRecordSetsClient.List(p.project, zoneID).Pages(ctx, f); err != nil { + return nil, err + } + + return records, nil } // Register this Provider with the provider factory diff --git a/internal/provider/google/google_test.go b/internal/provider/google/google_test.go index ad3a215e..aa270a9d 100644 --- a/internal/provider/google/google_test.go +++ b/internal/provider/google/google_test.go @@ -12,7 +12,9 @@ import ( "github.com/aws/aws-sdk-go/aws" dnsv1 "google.golang.org/api/dns/v1" - "github.com/kuadrant/dns-operator/api/v1alpha1" + "k8s.io/apimachinery/pkg/api/equality" + externaldnsendpoint "sigs.k8s.io/external-dns/endpoint" + "github.com/kuadrant/dns-operator/internal/provider" ) @@ -131,44 +133,262 @@ func TestGoogleDNSProvider_toManagedZoneOutput(t *testing.T) { } } -func Test_toResourceRecordSets(t *testing.T) { +type MockResourceRecordSetsListCall struct { + PagesFunc func(ctx context.Context, f func(*dnsv1.ResourceRecordSetsListResponse) error) error +} + +func (m *MockResourceRecordSetsListCall) Pages(ctx context.Context, f func(*dnsv1.ResourceRecordSetsListResponse) error) error { + return m.PagesFunc(ctx, f) + +} + +type MockResourceRecordSetsClient struct { + ListFunc func(project string, managedZone string) resourceRecordSetsListCallInterface +} + +func (m *MockResourceRecordSetsClient) List(project string, managedZone string) resourceRecordSetsListCallInterface { + + return m.ListFunc(project, managedZone) + +} + +func sorted(endpoints []*externaldnsendpoint.Endpoint) { + sort.Slice(endpoints, func(i, j int) bool { + return endpoints[i].DNSName < endpoints[j].DNSName + }) +} + +func Test_endpointsFromResourceRecordSets(t *testing.T) { type args struct { - allEndpoints []*v1alpha1.Endpoint + resourceRecordSets []*dnsv1.ResourceRecordSet } tests := []struct { name string args args - want []*dnsv1.ResourceRecordSet + want []*externaldnsendpoint.Endpoint }{ { - name: "Successful test Geo & weight", + name: "test CNAME with geo and multiple targets", args: args{ - allEndpoints: []*v1alpha1.Endpoint{ + resourceRecordSets: []*dnsv1.ResourceRecordSet{ { - DNSName: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", - RecordType: "A", - RecordTTL: 60, - Targets: v1alpha1.Targets{ + Name: "lb-4ej5le.unittest.google.hcpapps.net.", + RoutingPolicy: &dnsv1.RRSetRoutingPolicy{ + Geo: &dnsv1.RRSetRoutingPolicyGeoPolicy{ + EnableFencing: false, + Items: []*dnsv1.RRSetRoutingPolicyGeoPolicyGeoPolicyItem{ + { + Location: "europe-west1", + Rrdatas: []string{ + "europe-west1.lb-4ej5le.unittest.google.hcpapps.net.", + }, + }, + { + Location: "us-east1", + Rrdatas: []string{ + "us-east1.lb-4ej5le.unittest.google.hcpapps.net.", + }, + }, + }, + }, + }, + Ttl: 300, + Type: "CNAME", + }, + }, + }, + want: []*externaldnsendpoint.Endpoint{ + { + DNSName: "lb-4ej5le.unittest.google.hcpapps.net", + RecordType: "CNAME", + RecordTTL: 300, + Targets: externaldnsendpoint.Targets{ + "europe-west1.lb-4ej5le.unittest.google.hcpapps.net", + "us-east1.lb-4ej5le.unittest.google.hcpapps.net", + }, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "geo", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "europe-west1.lb-4ej5le.unittest.google.hcpapps.net", + Value: "europe-west1", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "us-east1.lb-4ej5le.unittest.google.hcpapps.net", + Value: "us-east1", + }, + }, + }, + }, + }, + { + name: "test CNAME with weights and multiple targets", + args: args{ + resourceRecordSets: []*dnsv1.ResourceRecordSet{ + { + Name: "default.lb-4ej5le.unittest.google.hcpapps.net.", + RoutingPolicy: &dnsv1.RRSetRoutingPolicy{ + Wrr: &dnsv1.RRSetRoutingPolicyWrrPolicy{ + Items: []*dnsv1.RRSetRoutingPolicyWrrPolicyWrrPolicyItem{ + { + Rrdatas: []string{ + "2c71gf.lb-4ej5le.unittest.google.hcpapps.net.", + }, + Weight: 120, + }, + { + Rrdatas: []string{ + "lrnse3.lb-4ej5le.unittest.google.hcpapps.net.", + }, + Weight: 120, + }, + }, + }, + }, + Ttl: 60, + Type: "CNAME", + }, + }, + }, + want: []*externaldnsendpoint.Endpoint{ + { + DNSName: "default.lb-4ej5le.unittest.google.hcpapps.net", + RecordType: "CNAME", + RecordTTL: 60, + Targets: externaldnsendpoint.Targets{ + "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", + }, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "weighted", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + Value: "120", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", + Value: "120", + }, + }, + }, + }, + }, + { + name: "test A record", + args: args{ + resourceRecordSets: []*dnsv1.ResourceRecordSet{ + { + Name: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net.", + Rrdatas: []string{ "0.0.0.0", }, - ProviderSpecific: v1alpha1.ProviderSpecific{}, - SetIdentifier: "", + Ttl: 60, + Type: "A", + }, + }, + }, + want: []*externaldnsendpoint.Endpoint{ + { + DNSName: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + RecordType: "A", + RecordTTL: 60, + Targets: externaldnsendpoint.Targets{ + "0.0.0.0", }, + SetIdentifier: "", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := endpointsFromResourceRecordSets(tt.args.resourceRecordSets); !equality.Semantic.DeepEqual(got, tt.want) { + t.Errorf("endpointsFromResourceRecordSets() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_endpointsToGoogleFormat(t *testing.T) { + type args struct { + endpoints []*externaldnsendpoint.Endpoint + } + tests := []struct { + name string + args args + want []*externaldnsendpoint.Endpoint + }{ + { + name: "multiple weighted records", + args: args{ + endpoints: []*externaldnsendpoint.Endpoint{ { - DNSName: "europe-west1.lb-4ej5le.unittest.google.hcpapps.net", + DNSName: "default.lb-4ej5le.unittest.google.hcpapps.net", RecordType: "CNAME", SetIdentifier: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", RecordTTL: 60, - Targets: v1alpha1.Targets{ + Targets: externaldnsendpoint.Targets{ "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", }, - ProviderSpecific: v1alpha1.ProviderSpecific{ - v1alpha1.ProviderSpecificProperty{ + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ Name: "weight", - Value: "60", + Value: "120", }, }, }, + { + DNSName: "default.lb-4ej5le.unittest.google.hcpapps.net", + RecordType: "CNAME", + SetIdentifier: "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", + RecordTTL: 60, + Targets: externaldnsendpoint.Targets{ + "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", + }, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "weight", + Value: "120", + }, + }, + }, + }, + }, + want: []*externaldnsendpoint.Endpoint{ + { + DNSName: "default.lb-4ej5le.unittest.google.hcpapps.net", + RecordType: "CNAME", + RecordTTL: 60, + Targets: externaldnsendpoint.Targets{ + "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", + }, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "weighted", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + Value: "120", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", + Value: "120", + }, + }, + }, + }, + }, + { + name: "multiple geo targets", + args: args{ + endpoints: []*externaldnsendpoint.Endpoint{ { DNSName: "lb-4ej5le.unittest.google.hcpapps.net", RecordType: "CNAME", @@ -177,368 +397,637 @@ func Test_toResourceRecordSets(t *testing.T) { "europe-west1.lb-4ej5le.unittest.google.hcpapps.net", }, RecordTTL: 300, - ProviderSpecific: v1alpha1.ProviderSpecific{ - v1alpha1.ProviderSpecificProperty{ + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ Name: "geo-code", Value: "europe-west1", }, }, }, { - DNSName: "unittest.google.hcpapps.net", - RecordType: "CNAME", - RecordTTL: 300, + DNSName: "lb-4ej5le.unittest.google.hcpapps.net", + RecordType: "CNAME", + SetIdentifier: "us-east1", Targets: []string{ - "lb-4ej5le.unittest.google.hcpapps.net", + "us-east1.lb-4ej5le.unittest.google.hcpapps.net", + }, + RecordTTL: 300, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "geo-code", + Value: "us-east1", + }, }, - SetIdentifier: "", }, }, }, - want: []*dnsv1.ResourceRecordSet{ + want: []*externaldnsendpoint.Endpoint{ { - Name: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net.", - Rrdatas: []string{ - "0.0.0.0", + DNSName: "lb-4ej5le.unittest.google.hcpapps.net", + RecordType: "CNAME", + RecordTTL: 300, + Targets: externaldnsendpoint.Targets{ + "europe-west1.lb-4ej5le.unittest.google.hcpapps.net", + "us-east1.lb-4ej5le.unittest.google.hcpapps.net", }, - Ttl: 60, - Type: "A", - }, - { - Name: "europe-west1.lb-4ej5le.unittest.google.hcpapps.net.", - RoutingPolicy: &dnsv1.RRSetRoutingPolicy{ - Wrr: &dnsv1.RRSetRoutingPolicyWrrPolicy{ - Items: []*dnsv1.RRSetRoutingPolicyWrrPolicyWrrPolicyItem{ - { - Rrdatas: []string{ - "2c71gf.lb-4ej5le.unittest.google.hcpapps.net.", - }, - Weight: 60, - }, - }, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "geo", }, - }, - Ttl: 60, - Type: "CNAME", - }, - - { - Name: "lb-4ej5le.unittest.google.hcpapps.net.", - RoutingPolicy: &dnsv1.RRSetRoutingPolicy{ - Geo: &dnsv1.RRSetRoutingPolicyGeoPolicy{ - EnableFencing: false, - Items: []*dnsv1.RRSetRoutingPolicyGeoPolicyGeoPolicyItem{ - { - Location: "europe-west1", - Rrdatas: []string{ - "europe-west1.lb-4ej5le.unittest.google.hcpapps.net.", - }, - }, - }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "europe-west1.lb-4ej5le.unittest.google.hcpapps.net", + Value: "europe-west1", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "us-east1.lb-4ej5le.unittest.google.hcpapps.net", + Value: "us-east1", }, }, - Ttl: 300, - Type: "CNAME", - }, - - { - Name: "unittest.google.hcpapps.net.", - Rrdatas: []string{ - "lb-4ej5le.unittest.google.hcpapps.net.", - }, - Ttl: 300, - Type: "CNAME", }, }, }, { - name: "Successful test no Geo & weight", + name: "multiple geo and weighted targets", args: args{ - allEndpoints: []*v1alpha1.Endpoint{ + endpoints: []*externaldnsendpoint.Endpoint{ { - DNSName: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + DNSName: "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", RecordType: "A", - RecordTTL: 60, - Targets: v1alpha1.Targets{ - "0.0.0.0", + Targets: []string{ + "172.18.200.1", }, - SetIdentifier: "", + RecordTTL: 60, }, { - DNSName: "default.lb-4ej5le.unittest.google.hcpapps.net", - RecordType: "CNAME", - SetIdentifier: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + DNSName: "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "A", + Targets: []string{ + "172.18.200.2", + }, + RecordTTL: 60, + }, + { + DNSName: "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "A", + Targets: []string{ + "172.18.200.3", + }, + RecordTTL: 60, + }, + { + DNSName: "loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 300, + }, + { + DNSName: "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, RecordTTL: 60, - Targets: v1alpha1.Targets{ - "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + SetIdentifier: "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "weight", + Value: "200", + }, + }, + }, + { + DNSName: "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", }, - ProviderSpecific: v1alpha1.ProviderSpecific{ - v1alpha1.ProviderSpecificProperty{ + RecordTTL: 60, + SetIdentifier: "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ Name: "weight", - Value: "120", + Value: "100", }, }, }, { - DNSName: "lb-4ej5le.unittest.google.hcpapps.net", - RecordType: "CNAME", - SetIdentifier: "default", + DNSName: "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", Targets: []string{ - "default.lb-4ej5le.unittest.google.hcpapps.net", + "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", }, - RecordTTL: 300, - ProviderSpecific: v1alpha1.ProviderSpecific{ - v1alpha1.ProviderSpecificProperty{ + RecordTTL: 60, + SetIdentifier: "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "weight", + Value: "100", + }, + }, + }, + { + DNSName: "lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 300, + SetIdentifier: "europe-west1", + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ Name: "geo-code", - Value: "*", + Value: "europe-west1", + }, + }, + }, + { + DNSName: "lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 300, + SetIdentifier: "us-east1", + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "geo-code", + Value: "us-east1", }, }, }, { - DNSName: "unittest.google.hcpapps.net", + DNSName: "lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", RecordType: "CNAME", - RecordTTL: 300, Targets: []string{ - "lb-4ej5le.unittest.google.hcpapps.net", + "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 300, + SetIdentifier: "default", + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "geo-code", + Value: "*", + }, }, - SetIdentifier: "", }, }, }, - want: []*dnsv1.ResourceRecordSet{ + want: []*externaldnsendpoint.Endpoint{ { - Name: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net.", - Rrdatas: []string{ - "0.0.0.0", + DNSName: "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "A", + Targets: []string{ + "172.18.200.1", }, - Ttl: 60, - Type: "A", + RecordTTL: 60, }, { - Name: "default.lb-4ej5le.unittest.google.hcpapps.net.", - RoutingPolicy: &dnsv1.RRSetRoutingPolicy{ - Wrr: &dnsv1.RRSetRoutingPolicyWrrPolicy{ - Items: []*dnsv1.RRSetRoutingPolicyWrrPolicyWrrPolicyItem{ - { - Rrdatas: []string{ - "2c71gf.lb-4ej5le.unittest.google.hcpapps.net.", - }, - Weight: 120, - }, - }, + DNSName: "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "A", + Targets: []string{ + "172.18.200.2", + }, + RecordTTL: 60, + }, + { + DNSName: "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "A", + Targets: []string{ + "172.18.200.3", + }, + RecordTTL: 60, + }, + { + DNSName: "loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 300, + }, + { + DNSName: "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 60, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "weighted", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "200", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "100", }, }, - Ttl: 60, - Type: "CNAME", }, { - Name: "lb-4ej5le.unittest.google.hcpapps.net.", - RoutingPolicy: &dnsv1.RRSetRoutingPolicy{ - Geo: &dnsv1.RRSetRoutingPolicyGeoPolicy{ - EnableFencing: false, - Items: []*dnsv1.RRSetRoutingPolicyGeoPolicyGeoPolicyItem{ - { - Location: "europe-west1", - Rrdatas: []string{ - "default.lb-4ej5le.unittest.google.hcpapps.net.", - }, - }, - }, + DNSName: "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 60, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "weighted", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "100", }, }, - Ttl: 300, - Type: "CNAME", }, { - Name: "unittest.google.hcpapps.net.", - Rrdatas: []string{ - "lb-4ej5le.unittest.google.hcpapps.net.", + DNSName: "lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 300, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "geo", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "europe-west1", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "us-east1", + }, }, - Ttl: 300, - Type: "CNAME", }, }, }, { - name: "Successful test weight round robin with multiple targets", + name: "multiple geo and weighted targets already in google format", args: args{ - allEndpoints: []*v1alpha1.Endpoint{ + endpoints: []*externaldnsendpoint.Endpoint{ { - DNSName: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + DNSName: "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", RecordType: "A", - RecordTTL: 60, - Targets: v1alpha1.Targets{ - "0.0.0.0", + Targets: []string{ + "172.18.200.1", }, - SetIdentifier: "", + RecordTTL: 60, }, { - DNSName: "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", + DNSName: "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", RecordType: "A", - RecordTTL: 60, - Targets: v1alpha1.Targets{ - "0.0.0.1", + Targets: []string{ + "172.18.200.2", }, - SetIdentifier: "", + RecordTTL: 60, }, { - DNSName: "default.lb-4ej5le.unittest.google.hcpapps.net", - RecordType: "CNAME", - SetIdentifier: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", - RecordTTL: 60, - Targets: v1alpha1.Targets{ - "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + DNSName: "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "A", + Targets: []string{ + "172.18.200.3", }, - ProviderSpecific: v1alpha1.ProviderSpecific{ - v1alpha1.ProviderSpecificProperty{ - Name: "weight", - Value: "120", - }, + RecordTTL: 60, + }, + { + DNSName: "loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", }, + RecordTTL: 300, }, { - DNSName: "default.lb-4ej5le.unittest.google.hcpapps.net", - RecordType: "CNAME", - SetIdentifier: "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", - RecordTTL: 60, - Targets: v1alpha1.Targets{ - "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", + DNSName: "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", }, - ProviderSpecific: v1alpha1.ProviderSpecific{ - v1alpha1.ProviderSpecificProperty{ - Name: "weight", - Value: "120", + RecordTTL: 60, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "weighted", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "200", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "100", }, }, }, { - DNSName: "lb-4ej5le.unittest.google.hcpapps.net", - RecordType: "CNAME", - SetIdentifier: "default", + DNSName: "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", Targets: []string{ - "default.lb-4ej5le.unittest.google.hcpapps.net", + "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", }, - RecordTTL: 300, - ProviderSpecific: v1alpha1.ProviderSpecific{ - v1alpha1.ProviderSpecificProperty{ - Name: "geo-code", - Value: "*", + RecordTTL: 60, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "weighted", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "100", }, }, }, { - DNSName: "unittest.google.hcpapps.net", + DNSName: "lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", RecordType: "CNAME", - RecordTTL: 300, Targets: []string{ - "lb-4ej5le.unittest.google.hcpapps.net", + "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 300, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "geo", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "europe-west1", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "us-east1", + }, }, - SetIdentifier: "", }, }, }, - want: []*dnsv1.ResourceRecordSet{ + want: []*externaldnsendpoint.Endpoint{ { - Name: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net.", - Rrdatas: []string{ - "0.0.0.0", + DNSName: "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "A", + Targets: []string{ + "172.18.200.1", }, - Ttl: 60, - Type: "A", + RecordTTL: 60, }, { - Name: "lrnse3.lb-4ej5le.unittest.google.hcpapps.net.", - Rrdatas: []string{ - "0.0.0.1", + DNSName: "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "A", + Targets: []string{ + "172.18.200.2", }, - Ttl: 60, - Type: "A", + RecordTTL: 60, }, { - Name: "default.lb-4ej5le.unittest.google.hcpapps.net.", - RoutingPolicy: &dnsv1.RRSetRoutingPolicy{ - Wrr: &dnsv1.RRSetRoutingPolicyWrrPolicy{ - Items: []*dnsv1.RRSetRoutingPolicyWrrPolicyWrrPolicyItem{ - { - Rrdatas: []string{ - "2c71gf.lb-4ej5le.unittest.google.hcpapps.net.", - }, - Weight: 120, - }, - { - Rrdatas: []string{ - "lrnse3.lb-4ej5le.unittest.google.hcpapps.net.", - }, - Weight: 120, - }, - }, + DNSName: "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "A", + Targets: []string{ + "172.18.200.3", + }, + RecordTTL: 60, + }, + { + DNSName: "loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 300, + }, + { + DNSName: "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 60, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "weighted", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "cluster1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "200", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "cluster2.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "100", }, }, - Ttl: 60, - Type: "CNAME", }, { - Name: "lb-4ej5le.unittest.google.hcpapps.net.", - RoutingPolicy: &dnsv1.RRSetRoutingPolicy{ - Geo: &dnsv1.RRSetRoutingPolicyGeoPolicy{ - EnableFencing: false, - Items: []*dnsv1.RRSetRoutingPolicyGeoPolicyGeoPolicyItem{ - { - Location: "europe-west1", - Rrdatas: []string{ - "default.lb-4ej5le.unittest.google.hcpapps.net.", - }, - }, - }, + DNSName: "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 60, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "weighted", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "cluster3.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "100", }, }, - Ttl: 300, - Type: "CNAME", }, { - Name: "unittest.google.hcpapps.net.", - Rrdatas: []string{ - "lb-4ej5le.unittest.google.hcpapps.net.", + DNSName: "lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + RecordType: "CNAME", + Targets: []string{ + "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + }, + RecordTTL: 300, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "geo", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "europe-west1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "europe-west1", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "us-east1.lb-gw1-ns1.loadbalanced.mn.google.hcpapps.net", + Value: "us-east1", + }, }, - Ttl: 300, - Type: "CNAME", }, }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got := toResourceRecordSets(tt.args.allEndpoints) + got := endpointsToGoogleFormat(tt.args.endpoints) sorted(got) sorted(tt.want) - if !reflect.DeepEqual(got, tt.want) { - t.Errorf("toResourceRecordSets() = %+v, want %+v", got, tt.want) + if !equality.Semantic.DeepEqual(got, tt.want) { + t.Errorf("endpointsToGoogleFormat() = %+v, want %+v", got, tt.want) } - }) } } -func sorted(rrset []*dnsv1.ResourceRecordSet) { - sort.Slice(rrset, func(i, j int) bool { - return rrset[i].Name < rrset[j].Name - }) -} - -type MockResourceRecordSetsListCall struct { - PagesFunc func(ctx context.Context, f func(*dnsv1.ResourceRecordSetsListResponse) error) error -} - -func (m *MockResourceRecordSetsListCall) Pages(ctx context.Context, f func(*dnsv1.ResourceRecordSetsListResponse) error) error { - return m.PagesFunc(ctx, f) - -} - -type MockResourceRecordSetsClient struct { - ListFunc func(project string, managedZone string) resourceRecordSetsListCallInterface -} - -func (m *MockResourceRecordSetsClient) List(project string, managedZone string) resourceRecordSetsListCallInterface { - - return m.ListFunc(project, managedZone) +func Test_resourceRecordSetFromEndpoint(t *testing.T) { + type args struct { + endpoint *externaldnsendpoint.Endpoint + } + tests := []struct { + name string + args args + want *dnsv1.ResourceRecordSet + }{ + { + name: "test A record", + args: args{ + endpoint: &externaldnsendpoint.Endpoint{ + DNSName: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + RecordType: "A", + RecordTTL: 60, + Targets: externaldnsendpoint.Targets{ + "0.0.0.0", + }, + SetIdentifier: "", + }, + }, + want: &dnsv1.ResourceRecordSet{ + Name: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net.", + Rrdatas: []string{ + "0.0.0.0", + }, + Ttl: 60, + Type: "A", + }, + }, + { + name: "test CNAME with weight and multiple targets", + args: args{ + endpoint: &externaldnsendpoint.Endpoint{ + DNSName: "default.lb-4ej5le.unittest.google.hcpapps.net", + RecordType: "CNAME", + RecordTTL: 60, + Targets: externaldnsendpoint.Targets{ + "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", + }, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "weighted", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "2c71gf.lb-4ej5le.unittest.google.hcpapps.net", + Value: "120", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "lrnse3.lb-4ej5le.unittest.google.hcpapps.net", + Value: "120", + }, + }, + }, + }, + want: &dnsv1.ResourceRecordSet{ + Name: "default.lb-4ej5le.unittest.google.hcpapps.net.", + RoutingPolicy: &dnsv1.RRSetRoutingPolicy{ + Wrr: &dnsv1.RRSetRoutingPolicyWrrPolicy{ + Items: []*dnsv1.RRSetRoutingPolicyWrrPolicyWrrPolicyItem{ + { + Rrdatas: []string{ + "2c71gf.lb-4ej5le.unittest.google.hcpapps.net.", + }, + Weight: 120, + }, + { + Rrdatas: []string{ + "lrnse3.lb-4ej5le.unittest.google.hcpapps.net.", + }, + Weight: 120, + }, + }, + }, + }, + Ttl: 60, + Type: "CNAME", + }, + }, + { + name: "test CNAME with geo and multiple targets", + args: args{ + endpoint: &externaldnsendpoint.Endpoint{ + DNSName: "lb-4ej5le.unittest.google.hcpapps.net", + RecordType: "CNAME", + RecordTTL: 300, + Targets: externaldnsendpoint.Targets{ + "europe-west1.lb-4ej5le.unittest.google.hcpapps.net", + "us-east1.lb-4ej5le.unittest.google.hcpapps.net", + }, + ProviderSpecific: externaldnsendpoint.ProviderSpecific{ + externaldnsendpoint.ProviderSpecificProperty{ + Name: "routingpolicy", + Value: "geo", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "europe-west1.lb-4ej5le.unittest.google.hcpapps.net", + Value: "europe-west1", + }, + externaldnsendpoint.ProviderSpecificProperty{ + Name: "us-east1.lb-4ej5le.unittest.google.hcpapps.net", + Value: "us-east1", + }, + }, + }, + }, + want: &dnsv1.ResourceRecordSet{ + Name: "lb-4ej5le.unittest.google.hcpapps.net.", + RoutingPolicy: &dnsv1.RRSetRoutingPolicy{ + Geo: &dnsv1.RRSetRoutingPolicyGeoPolicy{ + EnableFencing: false, + Items: []*dnsv1.RRSetRoutingPolicyGeoPolicyGeoPolicyItem{ + { + Location: "europe-west1", + Rrdatas: []string{ + "europe-west1.lb-4ej5le.unittest.google.hcpapps.net.", + }, + }, + { + Location: "us-east1", + Rrdatas: []string{ + "us-east1.lb-4ej5le.unittest.google.hcpapps.net.", + }, + }, + }, + }, + }, + Ttl: 300, + Type: "CNAME", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := resourceRecordSetFromEndpoint(tt.args.endpoint); !equality.Semantic.DeepEqual(got, tt.want) { + t.Errorf("resourceRecordSetFromEndpoint() = %+v, want %+v", got, tt.want) + } + }) + } } diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 5b78f952..e6a4a452 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -4,17 +4,15 @@ import ( "errors" "regexp" + externaldnsendpoint "sigs.k8s.io/external-dns/endpoint" + externaldnsprovider "sigs.k8s.io/external-dns/provider" + "github.com/kuadrant/dns-operator/api/v1alpha1" ) // Provider knows how to manage DNS zones only as pertains to routing. type Provider interface { - - // Ensure will create or update record. - Ensure(record *v1alpha1.DNSRecord, managedZone *v1alpha1.ManagedZone) error - - // Delete will delete record. - Delete(record *v1alpha1.DNSRecord, managedZone *v1alpha1.ManagedZone) error + externaldnsprovider.Provider // Ensure will create or update a managed zone, returns an array of NameServers for that zone. EnsureManagedZone(managedZone *v1alpha1.ManagedZone) (ManagedZoneOutput, error) @@ -23,6 +21,15 @@ type Provider interface { DeleteManagedZone(managedZone *v1alpha1.ManagedZone) error } +type Config struct { + // only consider hosted zones managing domains ending in this suffix + DomainFilter externaldnsendpoint.DomainFilter + // filter for zones based on visibility + ZoneTypeFilter externaldnsprovider.ZoneTypeFilter + // only consider hosted zones ending with this zone id + ZoneIDFilter externaldnsprovider.ZoneIDFilter +} + type ProviderSpecificLabels struct { Weight string HealthCheckID string